diff options
author | Pierre Moos <p-moos@ti.com> | 2012-01-06 13:41:23 +0100 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-03 01:18:00 +0200 |
commit | d40b8dc7c1928866ea9ab2bd4a0b71347b43aafa (patch) | |
tree | 1e3ecca2d540faace79adb692f637bdbaffe20a4 /sound | |
parent | a4161f85acc29eb8391f548dccd95811142cb8ab (diff) | |
download | kernel_samsung_tuna-d40b8dc7c1928866ea9ab2bd4a0b71347b43aafa.zip kernel_samsung_tuna-d40b8dc7c1928866ea9ab2bd4a0b71347b43aafa.tar.gz kernel_samsung_tuna-d40b8dc7c1928866ea9ab2bd4a0b71347b43aafa.tar.bz2 |
ASoC: twl6040: SW WA for DC Offset On EAR Differential Output
Correct Sequencing To Ensure No DC offset On EAR Outputs.
Fix the pops on switches between HF to EP
Change-Id: I497f8d6a2c2662406720a28e7906c5e58917fb24
Signed-off-by: Pierre Moos <p-moos@ti.com>
Signed-off-by: Francois Mazard <f-mazard@ti.com>
Conflicts:
sound/soc/codecs/twl6040.c
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/twl6040.c | 94 |
1 files changed, 91 insertions, 3 deletions
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index ab14f47..f03d6d1 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -799,9 +799,95 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) return 0; } -static int twl6040_dac_event(struct snd_soc_dapm_widget *w, +static int twl6040_hs_dac_left_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { + struct snd_soc_codec *codec = w->codec; + struct twl6040 *twl6040 = codec->control_data; + int hsrctl, earpiece_on; + + /* SW Workaround for DC Offset On EAR Differential Output Errata */ + if (twl6040_get_icrev(twl6040) < TWL6040_REV_1_3) { + hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); + earpiece_on = twl6040_read_reg_cache(codec, TWL6040_REG_EARCTL) + & TWL6040_EARENA; + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!(hsrctl & TWL6040_HSDACENAR)) + twl6040_write(codec, TWL6040_REG_HSRCTL, + hsrctl | TWL6040_HSDACENAR); + break; + + case SND_SOC_DAPM_PRE_PMD: + if (!(hsrctl & TWL6040_HSDACENAR)) + twl6040_write(codec, TWL6040_REG_HSRCTL, + hsrctl | TWL6040_HSDACENAR); + break; + + case SND_SOC_DAPM_POST_PMU: + if ((hsrctl & TWL6040_HSDACENAR) || earpiece_on) + twl6040_write(codec, TWL6040_REG_HSRCTL, + hsrctl & ~TWL6040_HSDACENAR); + break; + + case SND_SOC_DAPM_POST_PMD: + if (hsrctl & TWL6040_HSDACENAR) + twl6040_write(codec, TWL6040_REG_HSRCTL, + hsrctl & ~TWL6040_HSDACENAR); + break; + + default: + break; + } + } + + msleep(1); + return 0; +} + +static int twl6040_hs_dac_right_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct twl6040 *twl6040 = codec->control_data; + int hslctl; + int earpiece_on; + + /* SW Workaround for DC Offset On EAR Differential Output Errata */ + if (twl6040_get_icrev(twl6040) < TWL6040_REV_1_3) { + hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); + earpiece_on = twl6040_read_reg_cache(codec, TWL6040_REG_EARCTL) + & TWL6040_EARENA; + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!(hslctl & TWL6040_HSDACENAL)) + twl6040_write(codec, TWL6040_REG_HSLCTL, + hslctl | TWL6040_HSDACENAL); + break; + + case SND_SOC_DAPM_PRE_PMD: + if (!(hslctl & TWL6040_HSDACENAL)) + twl6040_write(codec, TWL6040_REG_HSLCTL, + hslctl | TWL6040_HSDACENAL); + break; + + case SND_SOC_DAPM_POST_PMU: + if ((hslctl & TWL6040_HSDACENAL) && earpiece_on) + twl6040_write(codec, TWL6040_REG_HSLCTL, + hslctl & ~TWL6040_HSDACENAL); + break; + + case SND_SOC_DAPM_POST_PMD: + if (hslctl & TWL6040_HSDACENAL) + twl6040_write(codec, TWL6040_REG_HSLCTL, + hslctl & ~TWL6040_HSDACENAL); + break; + + default: + break; + } + } + msleep(1); return 0; } @@ -1225,11 +1311,13 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { /* DACs */ SND_SOC_DAPM_DAC_E("HSDAC Left", "Headset Playback", TWL6040_REG_HSLCTL, 0, 0, - twl6040_dac_event, + twl6040_hs_dac_left_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_DAC_E("HSDAC Right", "Headset Playback", TWL6040_REG_HSRCTL, 0, 0, - twl6040_dac_event, + twl6040_hs_dac_right_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", TWL6040_REG_HFLCTL, 0, 0, |