aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-05-12 07:35:44 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-05-12 07:54:06 -0400
commit68a02db415d13f2fde571b131deb91de67719a27 (patch)
tree80ce8a7c7efeb5c1622272c40b309746d5868eb7
parente968194b45c4e8077dada75c5bae5660b37628fe (diff)
ASoC: littlemill: Use a widget to keep track of AIF2 clocking
Since we only need to clock AIF2 when it's actively in use start up the FLL for it using a supply widget which supplies AIF2CLK. This both makes the sequencing more robust and ensures we minimise power consumption. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/samsung/littlemill.c86
1 files changed, 53 insertions, 33 deletions
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index fd5ac47371a1..c82c646b8a08 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -67,7 +67,6 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
67 enum snd_soc_bias_level level) 67 enum snd_soc_bias_level level)
68{ 68{
69 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; 69 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
70 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
71 int ret; 70 int ret;
72 71
73 if (dapm->dev != aif1_dai->dev) 72 if (dapm->dev != aif1_dai->dev)
@@ -75,20 +74,6 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
75 74
76 switch (level) { 75 switch (level) {
77 case SND_SOC_BIAS_STANDBY: 76 case SND_SOC_BIAS_STANDBY:
78 ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_MCLK2,
79 32768, SND_SOC_CLOCK_IN);
80 if (ret < 0) {
81 pr_err("Failed to switch away from FLL2: %d\n", ret);
82 return ret;
83 }
84
85 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
86 0, 0, 0);
87 if (ret < 0) {
88 pr_err("Failed to stop FLL2: %d\n", ret);
89 return ret;
90 }
91
92 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, 77 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
93 32768, SND_SOC_CLOCK_IN); 78 32768, SND_SOC_CLOCK_IN);
94 if (ret < 0) { 79 if (ret < 0) {
@@ -104,24 +89,6 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
104 } 89 }
105 break; 90 break;
106 91
107 case SND_SOC_BIAS_PREPARE:
108 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
109 WM8994_FLL_SRC_BCLK, 64 * 8000,
110 8000 * 256);
111 if (ret < 0) {
112 pr_err("Failed to start FLL: %d\n", ret);
113 return ret;
114 }
115
116 ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_FLL2,
117 8000 * 256,
118 SND_SOC_CLOCK_IN);
119 if (ret < 0) {
120 pr_err("Failed to set SYSCLK: %d\n", ret);
121 return ret;
122 }
123 break;
124
125 default: 92 default:
126 break; 93 break;
127 } 94 }
@@ -197,11 +164,62 @@ static struct snd_soc_dai_link littlemill_dai[] = {
197 }, 164 },
198}; 165};
199 166
167static int bbclk_ev(struct snd_soc_dapm_widget *w,
168 struct snd_kcontrol *kcontrol, int event)
169{
170 struct snd_soc_card *card = w->dapm->card;
171 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
172 int ret;
173
174 switch (event) {
175 case SND_SOC_DAPM_PRE_PMU:
176 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
177 WM8994_FLL_SRC_BCLK, 64 * 8000,
178 8000 * 256);
179 if (ret < 0) {
180 pr_err("Failed to start FLL: %d\n", ret);
181 return ret;
182 }
183
184 ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_FLL2,
185 8000 * 256,
186 SND_SOC_CLOCK_IN);
187 if (ret < 0) {
188 pr_err("Failed to set SYSCLK: %d\n", ret);
189 return ret;
190 }
191 break;
192 case SND_SOC_DAPM_POST_PMD:
193 ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_MCLK2,
194 32768, SND_SOC_CLOCK_IN);
195 if (ret < 0) {
196 pr_err("Failed to switch away from FLL2: %d\n", ret);
197 return ret;
198 }
199
200 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
201 0, 0, 0);
202 if (ret < 0) {
203 pr_err("Failed to stop FLL2: %d\n", ret);
204 return ret;
205 }
206 break;
207 default:
208 return -EINVAL;
209 }
210
211 return 0;
212}
213
200static struct snd_soc_dapm_widget widgets[] = { 214static struct snd_soc_dapm_widget widgets[] = {
201 SND_SOC_DAPM_HP("Headphone", NULL), 215 SND_SOC_DAPM_HP("Headphone", NULL),
202 216
203 SND_SOC_DAPM_MIC("AMIC", NULL), 217 SND_SOC_DAPM_MIC("AMIC", NULL),
204 SND_SOC_DAPM_MIC("DMIC", NULL), 218 SND_SOC_DAPM_MIC("DMIC", NULL),
219
220 SND_SOC_DAPM_SUPPLY_S("Baseband Clock", -1, SND_SOC_NOPM, 0, 0,
221 bbclk_ev,
222 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
205}; 223};
206 224
207static struct snd_soc_dapm_route audio_paths[] = { 225static struct snd_soc_dapm_route audio_paths[] = {
@@ -214,6 +232,8 @@ static struct snd_soc_dapm_route audio_paths[] = {
214 { "DMIC", NULL, "MICBIAS2" }, /* Default for DMICBIAS jumper */ 232 { "DMIC", NULL, "MICBIAS2" }, /* Default for DMICBIAS jumper */
215 { "DMIC1DAT", NULL, "DMIC" }, 233 { "DMIC1DAT", NULL, "DMIC" },
216 { "DMIC2DAT", NULL, "DMIC" }, 234 { "DMIC2DAT", NULL, "DMIC" },
235
236 { "AIF2CLK", NULL, "Baseband Clock" },
217}; 237};
218 238
219static struct snd_soc_jack littlemill_headset; 239static struct snd_soc_jack littlemill_headset;