aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMisael Lopez Cruz <misael.lopez@ti.com>2011-02-11 18:51:05 -0500
committerPeter Ujfalusi <peter.ujfalusi@ti.com>2011-07-04 12:36:27 -0400
commit6bba63b68da7188953bf3cc2e29d1eb4e6a69115 (patch)
tree16d029d7cba16e0ca59483cbf5a1207769bc019e /sound
parente17e4ab8018bf0f18084577243cb6800dadd303c (diff)
ASoC: twl6040: Remove pll and headset mode dependency
Remove dependency between pll (hppll, lppll) and headset power mode (low-power, high-performance), as headset power mode can be used with any pll. A new control is created to allow headset power mode configuration from userspace. Changing headset power mode during earpiece related usecases is not propagated down to the codec as earpiece requires HS DAC in HP mode. Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/twl6040.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 7845cdb65a4a..c8f7fc28a16d 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -79,6 +79,8 @@ struct twl6040_data {
79 int codec_powered; 79 int codec_powered;
80 int pll; 80 int pll;
81 int non_lp; 81 int non_lp;
82 int hs_power_mode;
83 int hs_power_mode_locked;
82 unsigned int clk_in; 84 unsigned int clk_in;
83 unsigned int sysclk; 85 unsigned int sysclk;
84 struct snd_pcm_hw_constraint_list *sysclk_constraints; 86 struct snd_pcm_hw_constraint_list *sysclk_constraints;
@@ -651,15 +653,26 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
651{ 653{
652 struct snd_soc_codec *codec = w->codec; 654 struct snd_soc_codec *codec = w->codec;
653 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 655 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
656 int ret = 0;
654 657
655 if (SND_SOC_DAPM_EVENT_ON(event)) 658 if (SND_SOC_DAPM_EVENT_ON(event)) {
656 priv->non_lp++; 659 priv->non_lp++;
657 else 660 if (!strcmp(w->name, "Earphone Driver")) {
661 /* Earphone doesn't support low power mode */
662 priv->hs_power_mode_locked = 1;
663 ret = headset_power_mode(codec, 1);
664 }
665 } else {
658 priv->non_lp--; 666 priv->non_lp--;
667 if (!strcmp(w->name, "Earphone Driver")) {
668 priv->hs_power_mode_locked = 0;
669 ret = headset_power_mode(codec, priv->hs_power_mode);
670 }
671 }
659 672
660 msleep(1); 673 msleep(1);
661 674
662 return 0; 675 return ret;
663} 676}
664 677
665static void twl6040_hs_jack_report(struct snd_soc_codec *codec, 678static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
@@ -964,6 +977,43 @@ static const struct snd_kcontrol_new hfr_mux_controls =
964static const struct snd_kcontrol_new ep_driver_switch_controls = 977static const struct snd_kcontrol_new ep_driver_switch_controls =
965 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); 978 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
966 979
980/* Headset power mode */
981static const char *twl6040_headset_power_texts[] = {
982 "Low-Power", "High-Perfomance",
983};
984
985static const struct soc_enum twl6040_headset_power_enum =
986 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_headset_power_texts),
987 twl6040_headset_power_texts);
988
989static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
990 struct snd_ctl_elem_value *ucontrol)
991{
992 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
993 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
994
995 ucontrol->value.enumerated.item[0] = priv->hs_power_mode;
996
997 return 0;
998}
999
1000static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
1001 struct snd_ctl_elem_value *ucontrol)
1002{
1003 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1004 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1005 int high_perf = ucontrol->value.enumerated.item[0];
1006 int ret = 0;
1007
1008 if (!priv->hs_power_mode_locked)
1009 ret = headset_power_mode(codec, high_perf);
1010
1011 if (!ret)
1012 priv->hs_power_mode = high_perf;
1013
1014 return ret;
1015}
1016
967static const struct snd_kcontrol_new twl6040_snd_controls[] = { 1017static const struct snd_kcontrol_new twl6040_snd_controls[] = {
968 /* Capture gains */ 1018 /* Capture gains */
969 SOC_DOUBLE_TLV("Capture Preamplifier Volume", 1019 SOC_DOUBLE_TLV("Capture Preamplifier Volume",
@@ -982,6 +1032,10 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
982 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), 1032 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
983 SOC_SINGLE_TLV("Earphone Playback Volume", 1033 SOC_SINGLE_TLV("Earphone Playback Volume",
984 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), 1034 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
1035
1036 SOC_ENUM_EXT("Headset Power Mode", twl6040_headset_power_enum,
1037 twl6040_headset_power_get_enum,
1038 twl6040_headset_power_put_enum),
985}; 1039};
986 1040
987static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { 1041static 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,
1339 if (ret) 1393 if (ret)
1340 return ret; 1394 return ret;
1341 1395
1342 headset_power_mode(codec, 0);
1343 priv->sysclk_constraints = &lp_constraints; 1396 priv->sysclk_constraints = &lp_constraints;
1344 break; 1397 break;
1345 case TWL6040_SYSCLK_SEL_HPPLL: 1398 case TWL6040_SYSCLK_SEL_HPPLL:
@@ -1348,7 +1401,6 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1348 if (ret) 1401 if (ret)
1349 return ret; 1402 return ret;
1350 1403
1351 headset_power_mode(codec, 1);
1352 priv->sysclk_constraints = &hp_constraints; 1404 priv->sysclk_constraints = &hp_constraints;
1353 break; 1405 break;
1354 default: 1406 default: