aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm_hubs.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-08 13:51:42 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-11 18:11:20 -0500
commit5f2f38904019bbffb107767c55d9e781c94941ef (patch)
tree21a9578f10799f8bf6cf83dcef774974df4429c3 /sound/soc/codecs/wm_hubs.c
parent0f613c21d652079d39a4906cbe311587705632b5 (diff)
ASoC: wm_hubs: Improve single ended line output enable performance
The enable of the single ended line outputs on wm_hubs devices performs better if the output is enabled prior to starting VMID. Since inactive outputs are held at VMID anyway there is little cost to doing this for unused outputs. Add callbacks into wm_hubs and keep track of which outputs are really active so we can disable them once we're active. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm_hubs.c')
-rw-r--r--sound/soc/codecs/wm_hubs.c113
1 files changed, 105 insertions, 8 deletions
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index a53daf64aa46..f7650c5cc5c2 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -500,6 +500,36 @@ static int earpiece_event(struct snd_soc_dapm_widget *w,
500 return 0; 500 return 0;
501} 501}
502 502
503static int lineout_event(struct snd_soc_dapm_widget *w,
504 struct snd_kcontrol *control, int event)
505{
506 struct snd_soc_codec *codec = w->codec;
507 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
508 bool *flag;
509
510 switch (w->shift) {
511 case WM8993_LINEOUT1N_ENA_SHIFT:
512 flag = &hubs->lineout1n_ena;
513 break;
514 case WM8993_LINEOUT1P_ENA_SHIFT:
515 flag = &hubs->lineout1p_ena;
516 break;
517 case WM8993_LINEOUT2N_ENA_SHIFT:
518 flag = &hubs->lineout2n_ena;
519 break;
520 case WM8993_LINEOUT2P_ENA_SHIFT:
521 flag = &hubs->lineout2p_ena;
522 break;
523 default:
524 WARN(1, "Unknown line output");
525 return -EINVAL;
526 }
527
528 *flag = SND_SOC_DAPM_EVENT_ON(event);
529
530 return 0;
531}
532
503static const struct snd_kcontrol_new in1l_pga[] = { 533static const struct snd_kcontrol_new in1l_pga[] = {
504SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0), 534SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0),
505SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0), 535SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0),
@@ -675,14 +705,18 @@ SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
675SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0, 705SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
676 line2p_mix, ARRAY_SIZE(line2p_mix)), 706 line2p_mix, ARRAY_SIZE(line2p_mix)),
677 707
678SND_SOC_DAPM_OUT_DRV("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0, 708SND_SOC_DAPM_OUT_DRV_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
679 NULL, 0), 709 NULL, 0, lineout_event,
680SND_SOC_DAPM_OUT_DRV("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0, 710 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
681 NULL, 0), 711SND_SOC_DAPM_OUT_DRV_E("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
682SND_SOC_DAPM_OUT_DRV("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0, 712 NULL, 0, lineout_event,
683 NULL, 0), 713 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
684SND_SOC_DAPM_OUT_DRV("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0, 714SND_SOC_DAPM_OUT_DRV_E("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
685 NULL, 0), 715 NULL, 0, lineout_event,
716 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
717SND_SOC_DAPM_OUT_DRV_E("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
718 NULL, 0, lineout_event,
719 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
686 720
687SND_SOC_DAPM_OUTPUT("SPKOUTLP"), 721SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
688SND_SOC_DAPM_OUTPUT("SPKOUTLN"), 722SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
@@ -949,6 +983,11 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
949 int jd_scthr, int jd_thr, int micbias1_lvl, 983 int jd_scthr, int jd_thr, int micbias1_lvl,
950 int micbias2_lvl) 984 int micbias2_lvl)
951{ 985{
986 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
987
988 hubs->lineout1_se = !lineout1_diff;
989 hubs->lineout2_se = !lineout2_diff;
990
952 if (!lineout1_diff) 991 if (!lineout1_diff)
953 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 992 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
954 WM8993_LINEOUT1_MODE, 993 WM8993_LINEOUT1_MODE,
@@ -978,6 +1017,64 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
978} 1017}
979EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata); 1018EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
980 1019
1020void wm_hubs_vmid_ena(struct snd_soc_codec *codec)
1021{
1022 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1023 int val = 0;
1024
1025 if (hubs->lineout1_se)
1026 val |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA;
1027
1028 if (hubs->lineout2_se)
1029 val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
1030
1031 /* Enable the line outputs while we power up */
1032 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val);
1033}
1034EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena);
1035
1036void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
1037 enum snd_soc_bias_level level)
1038{
1039 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1040 int val;
1041
1042 switch (level) {
1043 case SND_SOC_BIAS_ON:
1044 /* Turn off any unneded single ended outputs */
1045 val = 0;
1046
1047 if (hubs->lineout1_se && hubs->lineout1n_ena)
1048 val |= WM8993_LINEOUT1N_ENA;
1049
1050 if (hubs->lineout1_se && hubs->lineout1p_ena)
1051 val |= WM8993_LINEOUT1P_ENA;
1052
1053 if (hubs->lineout2_se && hubs->lineout2n_ena)
1054 val |= WM8993_LINEOUT2N_ENA;
1055
1056 if (hubs->lineout2_se && hubs->lineout2p_ena)
1057 val |= WM8993_LINEOUT2P_ENA;
1058
1059 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3,
1060 WM8993_LINEOUT1N_ENA |
1061 WM8993_LINEOUT1P_ENA |
1062 WM8993_LINEOUT2N_ENA |
1063 WM8993_LINEOUT2P_ENA,
1064 val);
1065
1066 if (!hubs->lineout1n_ena && !hubs->lineout1p_ena &&
1067 !hubs->lineout2n_ena && !hubs->lineout2p_ena)
1068 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
1069 WM8993_LINEOUT_VMID_BUF_ENA, 0);
1070 break;
1071
1072 default:
1073 break;
1074 }
1075}
1076EXPORT_SYMBOL_GPL(wm_hubs_set_bias_level);
1077
981MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 1078MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
982MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1079MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
983MODULE_LICENSE("GPL"); 1080MODULE_LICENSE("GPL");