mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
misc: cs40l2x: Expose firmware amplitude controls
* Added sysfs controls for the firmware's separate GPIO-triggered playback and control-port-triggered playback amplitude controls. * Increased the minimum supported firmware revision to 4.1.0. Change-Id: Idae3fa1a839871cfa2760f14fc3b6ecf707fbd93 Signed-off-by: Jeff LaBundy <jeff.labundy@cirrus.com> Signed-off-by: Ravi Vembu <raviv@motorola.com>
This commit is contained in:
parent
d834ef678c
commit
be1a2bed27
2 changed files with 180 additions and 1 deletions
|
|
@ -828,6 +828,172 @@ static ssize_t cs40l2x_dig_scale_store(struct device *dev,
|
|||
return count;
|
||||
}
|
||||
|
||||
static int cs40l2x_gpio1_dig_scale_get(struct cs40l2x_private *cs40l2x,
|
||||
unsigned int *dig_scale)
|
||||
{
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
if (!mutex_is_locked(&cs40l2x->lock))
|
||||
return -EACCES;
|
||||
|
||||
ret = regmap_read(cs40l2x->regmap,
|
||||
cs40l2x_dsp_reg(cs40l2x, "GAIN_CONTROL",
|
||||
CS40L2X_XM_UNPACKED_TYPE), &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*dig_scale = (val & CS40L2X_GAIN_CTRL_GPIO_MASK)
|
||||
>> CS40L2X_GAIN_CTRL_GPIO_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs40l2x_gpio1_dig_scale_set(struct cs40l2x_private *cs40l2x,
|
||||
unsigned int dig_scale)
|
||||
{
|
||||
if (!mutex_is_locked(&cs40l2x->lock))
|
||||
return -EACCES;
|
||||
|
||||
if (dig_scale == CS40L2X_DIG_SCALE_RESET)
|
||||
return -EINVAL;
|
||||
|
||||
return regmap_update_bits(cs40l2x->regmap,
|
||||
cs40l2x_dsp_reg(cs40l2x, "GAIN_CONTROL",
|
||||
CS40L2X_XM_UNPACKED_TYPE),
|
||||
CS40L2X_GAIN_CTRL_GPIO_MASK,
|
||||
dig_scale << CS40L2X_GAIN_CTRL_GPIO_SHIFT);
|
||||
}
|
||||
|
||||
static ssize_t cs40l2x_gpio1_dig_scale_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct cs40l2x_private *cs40l2x = cs40l2x_get_private(dev);
|
||||
int ret;
|
||||
unsigned int dig_scale;
|
||||
|
||||
mutex_lock(&cs40l2x->lock);
|
||||
ret = cs40l2x_gpio1_dig_scale_get(cs40l2x, &dig_scale);
|
||||
mutex_unlock(&cs40l2x->lock);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to read digital scale\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", dig_scale);
|
||||
}
|
||||
|
||||
static ssize_t cs40l2x_gpio1_dig_scale_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct cs40l2x_private *cs40l2x = cs40l2x_get_private(dev);
|
||||
int ret;
|
||||
unsigned int dig_scale;
|
||||
|
||||
ret = kstrtou32(buf, 10, &dig_scale);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (dig_scale > CS40L2X_DIG_SCALE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cs40l2x->lock);
|
||||
ret = cs40l2x_gpio1_dig_scale_set(cs40l2x, dig_scale);
|
||||
mutex_unlock(&cs40l2x->lock);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to write digital scale\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int cs40l2x_cp_dig_scale_get(struct cs40l2x_private *cs40l2x,
|
||||
unsigned int *dig_scale)
|
||||
{
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
if (!mutex_is_locked(&cs40l2x->lock))
|
||||
return -EACCES;
|
||||
|
||||
ret = regmap_read(cs40l2x->regmap,
|
||||
cs40l2x_dsp_reg(cs40l2x, "GAIN_CONTROL",
|
||||
CS40L2X_XM_UNPACKED_TYPE), &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*dig_scale = (val & CS40L2X_GAIN_CTRL_TRIG_MASK)
|
||||
>> CS40L2X_GAIN_CTRL_TRIG_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs40l2x_cp_dig_scale_set(struct cs40l2x_private *cs40l2x,
|
||||
unsigned int dig_scale)
|
||||
{
|
||||
if (!mutex_is_locked(&cs40l2x->lock))
|
||||
return -EACCES;
|
||||
|
||||
if (dig_scale == CS40L2X_DIG_SCALE_RESET)
|
||||
return -EINVAL;
|
||||
|
||||
return regmap_update_bits(cs40l2x->regmap,
|
||||
cs40l2x_dsp_reg(cs40l2x, "GAIN_CONTROL",
|
||||
CS40L2X_XM_UNPACKED_TYPE),
|
||||
CS40L2X_GAIN_CTRL_TRIG_MASK,
|
||||
dig_scale << CS40L2X_GAIN_CTRL_TRIG_SHIFT);
|
||||
}
|
||||
|
||||
static ssize_t cs40l2x_cp_dig_scale_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct cs40l2x_private *cs40l2x = cs40l2x_get_private(dev);
|
||||
int ret;
|
||||
unsigned int dig_scale;
|
||||
|
||||
mutex_lock(&cs40l2x->lock);
|
||||
ret = cs40l2x_cp_dig_scale_get(cs40l2x, &dig_scale);
|
||||
mutex_unlock(&cs40l2x->lock);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to read digital scale\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", dig_scale);
|
||||
}
|
||||
|
||||
static ssize_t cs40l2x_cp_dig_scale_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct cs40l2x_private *cs40l2x = cs40l2x_get_private(dev);
|
||||
int ret;
|
||||
unsigned int dig_scale;
|
||||
|
||||
ret = kstrtou32(buf, 10, &dig_scale);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (dig_scale > CS40L2X_DIG_SCALE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&cs40l2x->lock);
|
||||
ret = cs40l2x_cp_dig_scale_set(cs40l2x, dig_scale);
|
||||
mutex_unlock(&cs40l2x->lock);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to write digital scale\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t cs40l2x_heartbeat_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
|
@ -935,6 +1101,10 @@ static DEVICE_ATTR(comp_enable, 0660, cs40l2x_comp_enable_show,
|
|||
cs40l2x_comp_enable_store);
|
||||
static DEVICE_ATTR(dig_scale, 0660, cs40l2x_dig_scale_show,
|
||||
cs40l2x_dig_scale_store);
|
||||
static DEVICE_ATTR(gpio1_dig_scale, 0660, cs40l2x_gpio1_dig_scale_show,
|
||||
cs40l2x_gpio1_dig_scale_store);
|
||||
static DEVICE_ATTR(cp_dig_scale, 0660, cs40l2x_cp_dig_scale_show,
|
||||
cs40l2x_cp_dig_scale_store);
|
||||
static DEVICE_ATTR(heartbeat, 0660, cs40l2x_heartbeat_show, NULL);
|
||||
static DEVICE_ATTR(num_waves, 0660, cs40l2x_num_waves_show, NULL);
|
||||
static DEVICE_ATTR(aoh_auto_enable, 0660, cs40l2x_aoh_auto_enable_show,
|
||||
|
|
@ -953,6 +1123,8 @@ static struct attribute *cs40l2x_dev_attrs[] = {
|
|||
&dev_attr_redc_stored.attr,
|
||||
&dev_attr_comp_enable.attr,
|
||||
&dev_attr_dig_scale.attr,
|
||||
&dev_attr_gpio1_dig_scale.attr,
|
||||
&dev_attr_cp_dig_scale.attr,
|
||||
&dev_attr_heartbeat.attr,
|
||||
&dev_attr_num_waves.attr,
|
||||
&dev_attr_aoh_auto_enable.attr,
|
||||
|
|
|
|||
|
|
@ -617,6 +617,12 @@
|
|||
#define CS40L2X_AMP_VOL_PCM_MASK 0x00003FF8
|
||||
#define CS40L2X_AMP_VOL_PCM_SHIFT 3
|
||||
|
||||
#define CS40L2X_GAIN_CTRL_GPIO_MASK 0x00FFC000
|
||||
#define CS40L2X_GAIN_CTRL_GPIO_SHIFT 14
|
||||
|
||||
#define CS40L2X_GAIN_CTRL_TRIG_MASK 0x00003FF0
|
||||
#define CS40L2X_GAIN_CTRL_TRIG_SHIFT 4
|
||||
|
||||
#define CS40L2X_OTP_BOOT_ERR 0x80000000
|
||||
#define CS40L2X_OTP_BOOT_DONE 0x00000002
|
||||
|
||||
|
|
@ -665,7 +671,7 @@
|
|||
#define CS40L2X_ALGO_REV_MASK 0xFF0000
|
||||
|
||||
#define CS40L2X_NUM_ALGOS_MAX 16
|
||||
#define CS40L2X_FW_REV_MIN 0x030000
|
||||
#define CS40L2X_FW_REV_MIN 0x040100
|
||||
|
||||
#define CS40L2X_ALGO_ID_SIZE 4
|
||||
#define CS40L2X_COEFF_COUNT_SIZE 4
|
||||
|
|
@ -724,6 +730,7 @@
|
|||
#define CS40L2X_DIG_SCALE_MAX 816 /* -102 dB */
|
||||
#define CS40L2X_DIG_SCALE_ZERO 0x800
|
||||
#define CS40L2X_DIG_SCALE_MASK 0x7FF
|
||||
#define CS40L2X_DIG_SCALE_RESET 0x80000000
|
||||
|
||||
#define CS40L2X_MAX_WLEN 4096
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue