mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
Sound Control: (Optional) work around for WCD93xx audio issues
(Use this only for devices with audio reset issues) Also bump version to 3.1 Signed-off-by: Paul Reioux <reioux@gmail.com> wcd9xxx-core: add register write without mutex protection This is assuming the calling function will take care of the mutex. Signed-off-by: Paul Reioux <reioux@gmail.com> Signed-off-by: flar2 <asegaert@gmail.com>
This commit is contained in:
parent
468de4793b
commit
b5feb08ab6
4 changed files with 125 additions and 30 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -22,14 +22,48 @@
|
|||
#include <linux/mfd/wcd9xxx/wcd9310_registers.h>
|
||||
|
||||
#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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue