aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorPierre Moos <p-moos@ti.com>2012-01-06 13:41:23 +0100
committerZiyann <jaraidaniel@gmail.com>2014-10-03 01:18:00 +0200
commitd40b8dc7c1928866ea9ab2bd4a0b71347b43aafa (patch)
tree1e3ecca2d540faace79adb692f637bdbaffe20a4 /sound
parenta4161f85acc29eb8391f548dccd95811142cb8ab (diff)
downloadkernel_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.c94
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,