diff options
author | Misael Lopez Cruz <misael.lopez@ti.com> | 2012-03-06 00:29:42 -0600 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-03 01:18:02 +0200 |
commit | d6e8692917a6035b42df42a8a0cae949ba9b6786 (patch) | |
tree | 4a9780769294e0061286f14758c7555e6e269b55 | |
parent | 104907e4cfdf593dab0efd015ed865249839da53 (diff) | |
download | kernel_samsung_tuna-d6e8692917a6035b42df42a8a0cae949ba9b6786.zip kernel_samsung_tuna-d6e8692917a6035b42df42a8a0cae949ba9b6786.tar.gz kernel_samsung_tuna-d6e8692917a6035b42df42a8a0cae949ba9b6786.tar.bz2 |
ASoC: twl6040: Reorder HSDAC/DRV power mode change
HSDAC and HSDRV power mode change cannot be performed when the
corresponding DAC is enabled, which is now explicitly rejected.
This constraint has an important impact on eapiece path, since
it can work only in high-performance mode.
In such case, we need to force the power mode before enabling
the DACs and restore previous mode after DACs have been disabled.
That sequence cannot be achieved if the event is associated with
a switch widget, so using a supply widget instead.
Change-Id: I3bddf3dc6fc038c78f83f1eb6f21f578c80cfee2
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
Conflicts:
sound/soc/codecs/twl6040.c
-rw-r--r-- | sound/soc/codecs/twl6040.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 36c3b53..fdf4438 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -788,6 +788,12 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) hslctl = snd_soc_read(codec, TWL6040_REG_HSLCTL); hsrctl = snd_soc_read(codec, TWL6040_REG_HSRCTL); + if ((hslctl & TWL6040_HSDACENAL) || (hsrctl & TWL6040_HSDACENAR)) { + dev_err(codec->dev, + "mode change not allowed when HSDACs are active\n"); + return -EPERM; + } + if (high_perf) val = 0; else @@ -873,7 +879,7 @@ static int twl6040_hf_dac_event(struct snd_soc_dapm_widget *w, return 0; } -static int twl6040_ep_event(struct snd_soc_dapm_widget *w, +static int twl6040_ep_mode_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; @@ -889,8 +895,6 @@ static int twl6040_ep_event(struct snd_soc_dapm_widget *w, ret = headset_power_mode(codec, priv->headset_mode); } - msleep(1); - return ret; } @@ -1336,10 +1340,11 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { TWL6040_REG_HSRCTL, 2, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_SWITCH_E("Earphone Enable", - SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, - twl6040_ep_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SWITCH("Earphone Enable", + SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls), + SND_SOC_DAPM_SUPPLY("Earphone Power Mode", SND_SOC_NOPM, 0, 0, + twl6040_ep_mode_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_OUT_DRV_E("Earphone Driver", SND_SOC_NOPM, 0, 0, NULL, 0, pga_event, @@ -1387,6 +1392,7 @@ static const struct snd_soc_dapm_route intercon[] = { /* Earphone playback path */ {"Earphone Enable", "Switch", "HSDAC Left"}, + {"Earphone Enable", NULL, "Earphone Power Mode"}, {"Earphone Driver", NULL, "Earphone Enable"}, {"EP", NULL, "Earphone Driver"}, |