diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c index 2efd4e2d97fa..42cecea197aa 100644 --- a/drivers/mfd/wcd9xxx-core.c +++ b/drivers/mfd/wcd9xxx-core.c @@ -82,6 +82,22 @@ int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg) } EXPORT_SYMBOL_GPL(wcd9xxx_reg_read); +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL +int wcd9xxx_reg_read_safe(struct wcd9xxx *wcd9xxx, unsigned short reg) +{ + u8 val; + int ret; + + ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, false); + + if (ret < 0) + return ret; + else + return val; +} +EXPORT_SYMBOL_GPL(wcd9xxx_reg_read_safe); +#endif + static int wcd9xxx_write(struct wcd9xxx *wcd9xxx, unsigned short reg, int bytes, void *src, bool interface_reg) { diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h index 508bf3bb55e7..40e3a83790c1 100644 --- a/include/linux/mfd/wcd9xxx/core.h +++ b/include/linux/mfd/wcd9xxx/core.h @@ -161,6 +161,9 @@ struct wcd9xxx { }; int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL +int wcd9xxx_reg_read_safe(struct wcd9xxx *wcd9xxx, unsigned short reg); +#endif int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, u8 val); int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); diff --git a/sound/soc/codecs/sound_control_3_gpl.c b/sound/soc/codecs/sound_control_3_gpl.c index b7c32860eb4c..446127138ef9 100644 --- a/sound/soc/codecs/sound_control_3_gpl.c +++ b/sound/soc/codecs/sound_control_3_gpl.c @@ -22,14 +22,48 @@ #include #define SOUND_CONTROL_MAJOR_VERSION 3 -#define SOUND_CONTROL_MINOR_VERSION 0 +#define SOUND_CONTROL_MINOR_VERSION 1 extern struct snd_soc_codec *fauxsound_codec_ptr; +static int snd_ctrl_locked = 0; + unsigned int tabla_read(struct snd_soc_codec *codec, unsigned int reg); int tabla_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value); +int reg_access(unsigned int reg) +{ + int ret = 1; + + switch (reg) { + case TABLA_A_CDC_RX1_VOL_CTL_B2_CTL: + case TABLA_A_CDC_RX2_VOL_CTL_B2_CTL: + case TABLA_A_CDC_RX3_VOL_CTL_B2_CTL: + case TABLA_A_CDC_RX4_VOL_CTL_B2_CTL: + case TABLA_A_CDC_RX5_VOL_CTL_B2_CTL: + case TABLA_A_CDC_RX6_VOL_CTL_B2_CTL: + case TABLA_A_CDC_RX7_VOL_CTL_B2_CTL: + case TABLA_A_CDC_TX1_VOL_CTL_GAIN: + case TABLA_A_CDC_TX2_VOL_CTL_GAIN: + case TABLA_A_CDC_TX3_VOL_CTL_GAIN: + case TABLA_A_CDC_TX4_VOL_CTL_GAIN: + case TABLA_A_CDC_TX5_VOL_CTL_GAIN: + case TABLA_A_CDC_TX6_VOL_CTL_GAIN: + case TABLA_A_CDC_TX7_VOL_CTL_GAIN: + case TABLA_A_CDC_TX8_VOL_CTL_GAIN: + case TABLA_A_CDC_TX9_VOL_CTL_GAIN: + case TABLA_A_CDC_TX10_VOL_CTL_GAIN: + if (snd_ctrl_locked) + ret = 0; + break; + default: + break; + } + return ret; +} +EXPORT_SYMBOL(reg_access); + static bool calc_checksum(unsigned int a, unsigned int b, unsigned int c) { unsigned char chksum = 0; @@ -46,7 +80,7 @@ static bool calc_checksum(unsigned int a, unsigned int b, unsigned int c) static ssize_t cam_mic_gain_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%u", + return sprintf(buf, "%u\n", tabla_read(fauxsound_codec_ptr, TABLA_A_CDC_TX6_VOL_CTL_GAIN)); @@ -69,7 +103,7 @@ static ssize_t cam_mic_gain_store(struct kobject *kobj, static ssize_t mic_gain_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%u", + return sprintf(buf, "%u\n", tabla_read(fauxsound_codec_ptr, TABLA_A_CDC_TX7_VOL_CTL_GAIN)); } @@ -92,7 +126,7 @@ static ssize_t mic_gain_store(struct kobject *kobj, static ssize_t speaker_gain_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%u %u", + return sprintf(buf, "%u %u\n", tabla_read(fauxsound_codec_ptr, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL), tabla_read(fauxsound_codec_ptr, @@ -119,7 +153,7 @@ static ssize_t speaker_gain_store(struct kobject *kobj, static ssize_t headphone_gain_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%u %u", + return sprintf(buf, "%u %u\n", tabla_read(fauxsound_codec_ptr, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL), tabla_read(fauxsound_codec_ptr, @@ -145,7 +179,7 @@ static ssize_t headphone_gain_store(struct kobject *kobj, static ssize_t headphone_pa_gain_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - return sprintf(buf, "%u %u", + return sprintf(buf, "%u %u\n", tabla_read(fauxsound_codec_ptr, TABLA_A_RX_HPH_L_GAIN), tabla_read(fauxsound_codec_ptr, TABLA_A_RX_HPH_R_GAIN)); } @@ -186,6 +220,26 @@ static ssize_t sound_control_version_show(struct kobject *kobj, struct kobj_attr SOUND_CONTROL_MINOR_VERSION); } +static ssize_t sound_control_locked_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int inp; + + sscanf(buf, "%d", &inp); + + if (inp == 0) + snd_ctrl_locked = 0; + else + snd_ctrl_locked = 1; + + return count; +} + +static ssize_t sound_control_locked_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", snd_ctrl_locked); +} + static struct kobj_attribute cam_mic_gain_attribute = __ATTR(gpl_cam_mic_gain, 0666, @@ -216,6 +270,12 @@ static struct kobj_attribute headphone_pa_gain_attribute = headphone_pa_gain_show, headphone_pa_gain_store); +static struct kobj_attribute sound_control_locked_attribute = + __ATTR(gpl_sound_control_locked, + 0666, + sound_control_locked_show, + sound_control_locked_store); + static struct kobj_attribute sound_control_version_attribute = __ATTR(gpl_sound_control_version, 0444, @@ -228,6 +288,7 @@ static struct attribute *sound_control_attrs[] = &speaker_gain_attribute.attr, &headphone_gain_attribute.attr, &headphone_pa_gain_attribute.attr, + &sound_control_locked_attribute.attr, &sound_control_version_attribute.attr, NULL, }; diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c index ed49a860334c..fe937983d121 100644 --- a/sound/soc/codecs/wcd9310.c +++ b/sound/soc/codecs/wcd9310.c @@ -3935,31 +3935,13 @@ static int tabla_volatile(struct snd_soc_codec *ssc, unsigned int reg) return 0; } - #define TABLA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) -#ifndef CONFIG_SOUND_CONTROL_HAX_GPL -static -#endif -int tabla_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - int ret; - BUG_ON(reg > TABLA_MAX_REGISTER); - if (!tabla_volatile(codec, reg)) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret != 0) - dev_err(codec->dev, "Cache write to %x failed: %d\n", - reg, ret); - } - - return wcd9xxx_reg_write(codec->control_data, reg, value); -} -#ifdef CONFIG_SOUND_CONTROL_HAX_GPL -EXPORT_SYMBOL(tabla_write); +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL +extern int reg_access(unsigned int reg); #endif -#ifndef CONFIG_SOUND_CONTROL_HAX_GPL +#ifndef CONFIG_SOUND_CONTROL_HAX_3_GPL static #endif unsigned int tabla_read(struct snd_soc_codec *codec, @@ -3983,10 +3965,43 @@ unsigned int tabla_read(struct snd_soc_codec *codec, val = wcd9xxx_reg_read(codec->control_data, reg); return val; } -#ifdef CONFIG_SOUND_CONTROL_HAX_GPL +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL EXPORT_SYMBOL(tabla_read); #endif +#ifndef CONFIG_SOUND_CONTROL_HAX_3_GPL +static +#endif +int tabla_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + int ret; +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL + int val; +#endif + + BUG_ON(reg > TABLA_MAX_REGISTER); + + if (!tabla_volatile(codec, reg)) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret != 0) + dev_err(codec->dev, "Cache write to %x failed: %d\n", + reg, ret); + } +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL + if (!reg_access(reg)) + val = wcd9xxx_reg_read_safe(codec->control_data, reg); + else + val = value; + return wcd9xxx_reg_write(codec->control_data, reg, val); +#else + return wcd9xxx_reg_write(codec->control_data, reg, value); +#endif +} +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL +EXPORT_SYMBOL(tabla_write); +#endif + static s16 tabla_get_current_v_ins(struct tabla_priv *tabla, bool hu) { s16 v_ins; @@ -8422,7 +8437,7 @@ static const struct file_operations codec_mbhc_debug_ops = { }; #endif -#ifdef CONFIG_SOUND_CONTROL_HAX_GPL +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL struct snd_kcontrol_new *gpl_faux_snd_controls_ptr = (struct snd_kcontrol_new *)tabla_snd_controls; struct snd_soc_codec *fauxsound_codec_ptr; @@ -8438,7 +8453,7 @@ static int tabla_codec_probe(struct snd_soc_codec *codec) int i; int ch_cnt; -#ifdef CONFIG_SOUND_CONTROL_HAX_GPL +#ifdef CONFIG_SOUND_CONTROL_HAX_3_GPL pr_info("tabla codec probe...\n"); fauxsound_codec_ptr = codec; #endif