From c5ba37489c4859c80d69b7c0b3f6d104e4338ab0 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 11 Feb 2011 17:51:05 -0600 Subject: [PATCH] --- yaml --- r: 260690 b: refs/heads/master c: 6bba63b68da7188953bf3cc2e29d1eb4e6a69115 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/sound/soc/codecs/twl6040.c | 62 +++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 90e27e06cf97..2afc35950734 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e17e4ab8018bf0f18084577243cb6800dadd303c +refs/heads/master: 6bba63b68da7188953bf3cc2e29d1eb4e6a69115 diff --git a/trunk/sound/soc/codecs/twl6040.c b/trunk/sound/soc/codecs/twl6040.c index 7845cdb65a4a..c8f7fc28a16d 100644 --- a/trunk/sound/soc/codecs/twl6040.c +++ b/trunk/sound/soc/codecs/twl6040.c @@ -79,6 +79,8 @@ struct twl6040_data { int codec_powered; int pll; int non_lp; + int hs_power_mode; + int hs_power_mode_locked; unsigned int clk_in; unsigned int sysclk; struct snd_pcm_hw_constraint_list *sysclk_constraints; @@ -651,15 +653,26 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = w->codec; struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + int ret = 0; - if (SND_SOC_DAPM_EVENT_ON(event)) + if (SND_SOC_DAPM_EVENT_ON(event)) { priv->non_lp++; - else + if (!strcmp(w->name, "Earphone Driver")) { + /* Earphone doesn't support low power mode */ + priv->hs_power_mode_locked = 1; + ret = headset_power_mode(codec, 1); + } + } else { priv->non_lp--; + if (!strcmp(w->name, "Earphone Driver")) { + priv->hs_power_mode_locked = 0; + ret = headset_power_mode(codec, priv->hs_power_mode); + } + } msleep(1); - return 0; + return ret; } static void twl6040_hs_jack_report(struct snd_soc_codec *codec, @@ -964,6 +977,43 @@ static const struct snd_kcontrol_new hfr_mux_controls = static const struct snd_kcontrol_new ep_driver_switch_controls = SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); +/* Headset power mode */ +static const char *twl6040_headset_power_texts[] = { + "Low-Power", "High-Perfomance", +}; + +static const struct soc_enum twl6040_headset_power_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_headset_power_texts), + twl6040_headset_power_texts); + +static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = priv->hs_power_mode; + + return 0; +} + +static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + int high_perf = ucontrol->value.enumerated.item[0]; + int ret = 0; + + if (!priv->hs_power_mode_locked) + ret = headset_power_mode(codec, high_perf); + + if (!ret) + priv->hs_power_mode = high_perf; + + return ret; +} + static const struct snd_kcontrol_new twl6040_snd_controls[] = { /* Capture gains */ SOC_DOUBLE_TLV("Capture Preamplifier Volume", @@ -982,6 +1032,10 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = { TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), SOC_SINGLE_TLV("Earphone Playback Volume", TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), + + SOC_ENUM_EXT("Headset Power Mode", twl6040_headset_power_enum, + twl6040_headset_power_get_enum, + twl6040_headset_power_put_enum), }; static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { @@ -1339,7 +1393,6 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, if (ret) return ret; - headset_power_mode(codec, 0); priv->sysclk_constraints = &lp_constraints; break; case TWL6040_SYSCLK_SEL_HPPLL: @@ -1348,7 +1401,6 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, if (ret) return ret; - headset_power_mode(codec, 1); priv->sysclk_constraints = &hp_constraints; break; default: