aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisael Lopez Cruz <misael.lopez@ti.com>2012-03-06 00:29:42 -0600
committerZiyann <jaraidaniel@gmail.com>2014-10-03 01:18:02 +0200
commitd6e8692917a6035b42df42a8a0cae949ba9b6786 (patch)
tree4a9780769294e0061286f14758c7555e6e269b55
parent104907e4cfdf593dab0efd015ed865249839da53 (diff)
downloadkernel_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.c20
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"},