summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0096-ASoC-wm8994-Improve-sequencing-of-AIF-channel-enable.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0096-ASoC-wm8994-Improve-sequencing-of-AIF-channel-enable.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0096-ASoC-wm8994-Improve-sequencing-of-AIF-channel-enable.patch389
1 files changed, 389 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0096-ASoC-wm8994-Improve-sequencing-of-AIF-channel-enable.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0096-ASoC-wm8994-Improve-sequencing-of-AIF-channel-enable.patch
new file mode 100644
index 00000000..a576f062
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0096-ASoC-wm8994-Improve-sequencing-of-AIF-channel-enable.patch
@@ -0,0 +1,389 @@
1From 18ea02a9ec95869c1210e6ea2f10dee99c36edbd Mon Sep 17 00:00:00 2001
2From: Mark Brown <broonie@opensource.wolfsonmicro.com>
3Date: Thu, 12 Apr 2012 19:47:11 +0100
4Subject: [PATCH 096/165] ASoC: wm8994: Improve sequencing of AIF channel
5 enables
6
7commit 1a38336b8611a04f0a624330c1f815421f4bf5f4 upstream.
8
9This ensures a clean startup of the channels, without this change some
10use cases could result in issues in a small proportion of cases.
11
12Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
13Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
14---
15 sound/soc/codecs/wm8994.c | 276 ++++++++++++++++++++++++++++++++++++---------
16 1 files changed, 222 insertions(+), 54 deletions(-)
17
18diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
19index 2f1f5f8..7806301 100644
20--- a/sound/soc/codecs/wm8994.c
21+++ b/sound/soc/codecs/wm8994.c
22@@ -883,61 +883,170 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
23 }
24 }
25
26-static int late_enable_ev(struct snd_soc_dapm_widget *w,
27- struct snd_kcontrol *kcontrol, int event)
28+static int aif1clk_ev(struct snd_soc_dapm_widget *w,
29+ struct snd_kcontrol *kcontrol, int event)
30 {
31 struct snd_soc_codec *codec = w->codec;
32- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
33+ struct wm8994 *control = codec->control_data;
34+ int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
35+ int dac;
36+ int adc;
37+ int val;
38+
39+ switch (control->type) {
40+ case WM8994:
41+ case WM8958:
42+ mask |= WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA;
43+ break;
44+ default:
45+ break;
46+ }
47
48 switch (event) {
49 case SND_SOC_DAPM_PRE_PMU:
50- if (wm8994->aif1clk_enable) {
51- snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
52- WM8994_AIF1CLK_ENA_MASK,
53- WM8994_AIF1CLK_ENA);
54- wm8994->aif1clk_enable = 0;
55- }
56- if (wm8994->aif2clk_enable) {
57- snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
58- WM8994_AIF2CLK_ENA_MASK,
59- WM8994_AIF2CLK_ENA);
60- wm8994->aif2clk_enable = 0;
61- }
62+ val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1);
63+ if ((val & WM8994_AIF1ADCL_SRC) &&
64+ (val & WM8994_AIF1ADCR_SRC))
65+ adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA;
66+ else if (!(val & WM8994_AIF1ADCL_SRC) &&
67+ !(val & WM8994_AIF1ADCR_SRC))
68+ adc = WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA;
69+ else
70+ adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA |
71+ WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA;
72+
73+ val = snd_soc_read(codec, WM8994_AIF1_CONTROL_2);
74+ if ((val & WM8994_AIF1DACL_SRC) &&
75+ (val & WM8994_AIF1DACR_SRC))
76+ dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA;
77+ else if (!(val & WM8994_AIF1DACL_SRC) &&
78+ !(val & WM8994_AIF1DACR_SRC))
79+ dac = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA;
80+ else
81+ dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA |
82+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA;
83+
84+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
85+ mask, adc);
86+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
87+ mask, dac);
88+ snd_soc_update_bits(codec, WM8994_CLOCKING_1,
89+ WM8994_AIF1DSPCLK_ENA |
90+ WM8994_SYSDSPCLK_ENA,
91+ WM8994_AIF1DSPCLK_ENA |
92+ WM8994_SYSDSPCLK_ENA);
93+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, mask,
94+ WM8994_AIF1ADC1R_ENA |
95+ WM8994_AIF1ADC1L_ENA |
96+ WM8994_AIF1ADC2R_ENA |
97+ WM8994_AIF1ADC2L_ENA);
98+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, mask,
99+ WM8994_AIF1DAC1R_ENA |
100+ WM8994_AIF1DAC1L_ENA |
101+ WM8994_AIF1DAC2R_ENA |
102+ WM8994_AIF1DAC2L_ENA);
103+ break;
104+
105+ case SND_SOC_DAPM_PRE_PMD:
106+ case SND_SOC_DAPM_POST_PMD:
107+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
108+ mask, 0);
109+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
110+ mask, 0);
111+
112+ val = snd_soc_read(codec, WM8994_CLOCKING_1);
113+ if (val & WM8994_AIF2DSPCLK_ENA)
114+ val = WM8994_SYSDSPCLK_ENA;
115+ else
116+ val = 0;
117+ snd_soc_update_bits(codec, WM8994_CLOCKING_1,
118+ WM8994_SYSDSPCLK_ENA |
119+ WM8994_AIF1DSPCLK_ENA, val);
120 break;
121 }
122
123- /* We may also have postponed startup of DSP, handle that. */
124- wm8958_aif_ev(w, kcontrol, event);
125-
126 return 0;
127 }
128
129-static int late_disable_ev(struct snd_soc_dapm_widget *w,
130- struct snd_kcontrol *kcontrol, int event)
131+static int aif2clk_ev(struct snd_soc_dapm_widget *w,
132+ struct snd_kcontrol *kcontrol, int event)
133 {
134 struct snd_soc_codec *codec = w->codec;
135- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
136+ int dac;
137+ int adc;
138+ int val;
139
140 switch (event) {
141+ case SND_SOC_DAPM_PRE_PMU:
142+ val = snd_soc_read(codec, WM8994_AIF2_CONTROL_1);
143+ if ((val & WM8994_AIF2ADCL_SRC) &&
144+ (val & WM8994_AIF2ADCR_SRC))
145+ adc = WM8994_AIF2ADCR_ENA;
146+ else if (!(val & WM8994_AIF2ADCL_SRC) &&
147+ !(val & WM8994_AIF2ADCR_SRC))
148+ adc = WM8994_AIF2ADCL_ENA;
149+ else
150+ adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA;
151+
152+
153+ val = snd_soc_read(codec, WM8994_AIF2_CONTROL_2);
154+ if ((val & WM8994_AIF2DACL_SRC) &&
155+ (val & WM8994_AIF2DACR_SRC))
156+ dac = WM8994_AIF2DACR_ENA;
157+ else if (!(val & WM8994_AIF2DACL_SRC) &&
158+ !(val & WM8994_AIF2DACR_SRC))
159+ dac = WM8994_AIF2DACL_ENA;
160+ else
161+ dac = WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA;
162+
163+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
164+ WM8994_AIF2ADCL_ENA |
165+ WM8994_AIF2ADCR_ENA, adc);
166+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
167+ WM8994_AIF2DACL_ENA |
168+ WM8994_AIF2DACR_ENA, dac);
169+ snd_soc_update_bits(codec, WM8994_CLOCKING_1,
170+ WM8994_AIF2DSPCLK_ENA |
171+ WM8994_SYSDSPCLK_ENA,
172+ WM8994_AIF2DSPCLK_ENA |
173+ WM8994_SYSDSPCLK_ENA);
174+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
175+ WM8994_AIF2ADCL_ENA |
176+ WM8994_AIF2ADCR_ENA,
177+ WM8994_AIF2ADCL_ENA |
178+ WM8994_AIF2ADCR_ENA);
179+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
180+ WM8994_AIF2DACL_ENA |
181+ WM8994_AIF2DACR_ENA,
182+ WM8994_AIF2DACL_ENA |
183+ WM8994_AIF2DACR_ENA);
184+ break;
185+
186+ case SND_SOC_DAPM_PRE_PMD:
187 case SND_SOC_DAPM_POST_PMD:
188- if (wm8994->aif1clk_disable) {
189- snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
190- WM8994_AIF1CLK_ENA_MASK, 0);
191- wm8994->aif1clk_disable = 0;
192- }
193- if (wm8994->aif2clk_disable) {
194- snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
195- WM8994_AIF2CLK_ENA_MASK, 0);
196- wm8994->aif2clk_disable = 0;
197- }
198+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
199+ WM8994_AIF2DACL_ENA |
200+ WM8994_AIF2DACR_ENA, 0);
201+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
202+ WM8994_AIF2ADCL_ENA |
203+ WM8994_AIF2ADCR_ENA, 0);
204+
205+ val = snd_soc_read(codec, WM8994_CLOCKING_1);
206+ if (val & WM8994_AIF1DSPCLK_ENA)
207+ val = WM8994_SYSDSPCLK_ENA;
208+ else
209+ val = 0;
210+ snd_soc_update_bits(codec, WM8994_CLOCKING_1,
211+ WM8994_SYSDSPCLK_ENA |
212+ WM8994_AIF2DSPCLK_ENA, val);
213 break;
214 }
215
216 return 0;
217 }
218
219-static int aif1clk_ev(struct snd_soc_dapm_widget *w,
220- struct snd_kcontrol *kcontrol, int event)
221+static int aif1clk_late_ev(struct snd_soc_dapm_widget *w,
222+ struct snd_kcontrol *kcontrol, int event)
223 {
224 struct snd_soc_codec *codec = w->codec;
225 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
226@@ -954,8 +1063,8 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
227 return 0;
228 }
229
230-static int aif2clk_ev(struct snd_soc_dapm_widget *w,
231- struct snd_kcontrol *kcontrol, int event)
232+static int aif2clk_late_ev(struct snd_soc_dapm_widget *w,
233+ struct snd_kcontrol *kcontrol, int event)
234 {
235 struct snd_soc_codec *codec = w->codec;
236 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
237@@ -972,6 +1081,63 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
238 return 0;
239 }
240
241+static int late_enable_ev(struct snd_soc_dapm_widget *w,
242+ struct snd_kcontrol *kcontrol, int event)
243+{
244+ struct snd_soc_codec *codec = w->codec;
245+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
246+
247+ switch (event) {
248+ case SND_SOC_DAPM_PRE_PMU:
249+ if (wm8994->aif1clk_enable) {
250+ aif1clk_ev(w, kcontrol, event);
251+ snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
252+ WM8994_AIF1CLK_ENA_MASK,
253+ WM8994_AIF1CLK_ENA);
254+ wm8994->aif1clk_enable = 0;
255+ }
256+ if (wm8994->aif2clk_enable) {
257+ aif2clk_ev(w, kcontrol, event);
258+ snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
259+ WM8994_AIF2CLK_ENA_MASK,
260+ WM8994_AIF2CLK_ENA);
261+ wm8994->aif2clk_enable = 0;
262+ }
263+ break;
264+ }
265+
266+ /* We may also have postponed startup of DSP, handle that. */
267+ wm8958_aif_ev(w, kcontrol, event);
268+
269+ return 0;
270+}
271+
272+static int late_disable_ev(struct snd_soc_dapm_widget *w,
273+ struct snd_kcontrol *kcontrol, int event)
274+{
275+ struct snd_soc_codec *codec = w->codec;
276+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
277+
278+ switch (event) {
279+ case SND_SOC_DAPM_POST_PMD:
280+ if (wm8994->aif1clk_disable) {
281+ snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
282+ WM8994_AIF1CLK_ENA_MASK, 0);
283+ aif1clk_ev(w, kcontrol, event);
284+ wm8994->aif1clk_disable = 0;
285+ }
286+ if (wm8994->aif2clk_disable) {
287+ snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
288+ WM8994_AIF2CLK_ENA_MASK, 0);
289+ aif2clk_ev(w, kcontrol, event);
290+ wm8994->aif2clk_disable = 0;
291+ }
292+ break;
293+ }
294+
295+ return 0;
296+}
297+
298 static int adc_mux_ev(struct snd_soc_dapm_widget *w,
299 struct snd_kcontrol *kcontrol, int event)
300 {
301@@ -1268,9 +1434,9 @@ static const struct snd_kcontrol_new aif2dacr_src_mux =
302 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
303
304 static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = {
305-SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev,
306+SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_late_ev,
307 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
308-SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev,
309+SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_late_ev,
310 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
311
312 SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
313@@ -1299,8 +1465,10 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
314 };
315
316 static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
317-SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
318-SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
319+SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev,
320+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
321+SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev,
322+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
323 SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
324 SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
325 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
326@@ -1353,30 +1521,30 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
327 SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
328 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
329
330-SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
331-SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
332-SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
333+SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0),
334+SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0),
335+SND_SOC_DAPM_SUPPLY("DSPINTCLK", SND_SOC_NOPM, 1, 0, NULL, 0),
336
337 SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL,
338- 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
339+ 0, SND_SOC_NOPM, 9, 0),
340 SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL,
341- 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
342+ 0, SND_SOC_NOPM, 8, 0),
343 SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
344- WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev,
345+ SND_SOC_NOPM, 9, 0, wm8958_aif_ev,
346 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
347 SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
348- WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev,
349+ SND_SOC_NOPM, 8, 0, wm8958_aif_ev,
350 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
351
352 SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL,
353- 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
354+ 0, SND_SOC_NOPM, 11, 0),
355 SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL,
356- 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
357+ 0, SND_SOC_NOPM, 10, 0),
358 SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
359- WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev,
360+ SND_SOC_NOPM, 11, 0, wm8958_aif_ev,
361 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
362 SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0,
363- WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev,
364+ SND_SOC_NOPM, 10, 0, wm8958_aif_ev,
365 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
366
367 SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
368@@ -1403,14 +1571,14 @@ SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
369 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
370
371 SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
372- WM8994_POWER_MANAGEMENT_4, 13, 0),
373+ SND_SOC_NOPM, 13, 0),
374 SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
375- WM8994_POWER_MANAGEMENT_4, 12, 0),
376+ SND_SOC_NOPM, 12, 0),
377 SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0,
378- WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev,
379+ SND_SOC_NOPM, 13, 0, wm8958_aif_ev,
380 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
381 SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
382- WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
383+ SND_SOC_NOPM, 12, 0, wm8958_aif_ev,
384 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
385
386 SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
387--
3881.7.7.6
389