1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * wm9081.c -- WM9081 ALSA SoC Audio driver |
4 | * |
5 | * Author: Mark Brown |
6 | * |
7 | * Copyright 2009-12 Wolfson Microelectronics plc |
8 | */ |
9 | |
10 | #include <linux/module.h> |
11 | #include <linux/moduleparam.h> |
12 | #include <linux/init.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/device.h> |
15 | #include <linux/pm.h> |
16 | #include <linux/i2c.h> |
17 | #include <linux/regmap.h> |
18 | #include <linux/slab.h> |
19 | #include <sound/core.h> |
20 | #include <sound/pcm.h> |
21 | #include <sound/pcm_params.h> |
22 | #include <sound/soc.h> |
23 | #include <sound/initval.h> |
24 | #include <sound/tlv.h> |
25 | |
26 | #include <sound/wm9081.h> |
27 | #include "wm9081.h" |
28 | |
29 | static const struct reg_default wm9081_reg[] = { |
30 | { 2, 0x00B9 }, /* R2 - Analogue Lineout */ |
31 | { 3, 0x00B9 }, /* R3 - Analogue Speaker PGA */ |
32 | { 4, 0x0001 }, /* R4 - VMID Control */ |
33 | { 5, 0x0068 }, /* R5 - Bias Control 1 */ |
34 | { 7, 0x0000 }, /* R7 - Analogue Mixer */ |
35 | { 8, 0x0000 }, /* R8 - Anti Pop Control */ |
36 | { 9, 0x01DB }, /* R9 - Analogue Speaker 1 */ |
37 | { 10, 0x0018 }, /* R10 - Analogue Speaker 2 */ |
38 | { 11, 0x0180 }, /* R11 - Power Management */ |
39 | { 12, 0x0000 }, /* R12 - Clock Control 1 */ |
40 | { 13, 0x0038 }, /* R13 - Clock Control 2 */ |
41 | { 14, 0x4000 }, /* R14 - Clock Control 3 */ |
42 | { 16, 0x0000 }, /* R16 - FLL Control 1 */ |
43 | { 17, 0x0200 }, /* R17 - FLL Control 2 */ |
44 | { 18, 0x0000 }, /* R18 - FLL Control 3 */ |
45 | { 19, 0x0204 }, /* R19 - FLL Control 4 */ |
46 | { 20, 0x0000 }, /* R20 - FLL Control 5 */ |
47 | { 22, 0x0000 }, /* R22 - Audio Interface 1 */ |
48 | { 23, 0x0002 }, /* R23 - Audio Interface 2 */ |
49 | { 24, 0x0008 }, /* R24 - Audio Interface 3 */ |
50 | { 25, 0x0022 }, /* R25 - Audio Interface 4 */ |
51 | { 27, 0x0006 }, /* R27 - Interrupt Status Mask */ |
52 | { 28, 0x0000 }, /* R28 - Interrupt Polarity */ |
53 | { 29, 0x0000 }, /* R29 - Interrupt Control */ |
54 | { 30, 0x00C0 }, /* R30 - DAC Digital 1 */ |
55 | { 31, 0x0008 }, /* R31 - DAC Digital 2 */ |
56 | { 32, 0x09AF }, /* R32 - DRC 1 */ |
57 | { 33, 0x4201 }, /* R33 - DRC 2 */ |
58 | { 34, 0x0000 }, /* R34 - DRC 3 */ |
59 | { 35, 0x0000 }, /* R35 - DRC 4 */ |
60 | { 38, 0x0000 }, /* R38 - Write Sequencer 1 */ |
61 | { 39, 0x0000 }, /* R39 - Write Sequencer 2 */ |
62 | { 40, 0x0002 }, /* R40 - MW Slave 1 */ |
63 | { 42, 0x0000 }, /* R42 - EQ 1 */ |
64 | { 43, 0x0000 }, /* R43 - EQ 2 */ |
65 | { 44, 0x0FCA }, /* R44 - EQ 3 */ |
66 | { 45, 0x0400 }, /* R45 - EQ 4 */ |
67 | { 46, 0x00B8 }, /* R46 - EQ 5 */ |
68 | { 47, 0x1EB5 }, /* R47 - EQ 6 */ |
69 | { 48, 0xF145 }, /* R48 - EQ 7 */ |
70 | { 49, 0x0B75 }, /* R49 - EQ 8 */ |
71 | { 50, 0x01C5 }, /* R50 - EQ 9 */ |
72 | { 51, 0x169E }, /* R51 - EQ 10 */ |
73 | { 52, 0xF829 }, /* R52 - EQ 11 */ |
74 | { 53, 0x07AD }, /* R53 - EQ 12 */ |
75 | { 54, 0x1103 }, /* R54 - EQ 13 */ |
76 | { 55, 0x1C58 }, /* R55 - EQ 14 */ |
77 | { 56, 0xF373 }, /* R56 - EQ 15 */ |
78 | { 57, 0x0A54 }, /* R57 - EQ 16 */ |
79 | { 58, 0x0558 }, /* R58 - EQ 17 */ |
80 | { 59, 0x0564 }, /* R59 - EQ 18 */ |
81 | { 60, 0x0559 }, /* R60 - EQ 19 */ |
82 | { 61, 0x4000 }, /* R61 - EQ 20 */ |
83 | }; |
84 | |
85 | static struct { |
86 | int ratio; |
87 | int clk_sys_rate; |
88 | } clk_sys_rates[] = { |
89 | { 64, 0 }, |
90 | { 128, 1 }, |
91 | { 192, 2 }, |
92 | { 256, 3 }, |
93 | { 384, 4 }, |
94 | { 512, 5 }, |
95 | { 768, 6 }, |
96 | { 1024, 7 }, |
97 | { 1408, 8 }, |
98 | { 1536, 9 }, |
99 | }; |
100 | |
101 | static struct { |
102 | int rate; |
103 | int sample_rate; |
104 | } sample_rates[] = { |
105 | { 8000, 0 }, |
106 | { 11025, 1 }, |
107 | { 12000, 2 }, |
108 | { 16000, 3 }, |
109 | { 22050, 4 }, |
110 | { 24000, 5 }, |
111 | { 32000, 6 }, |
112 | { 44100, 7 }, |
113 | { 48000, 8 }, |
114 | { 88200, 9 }, |
115 | { 96000, 10 }, |
116 | }; |
117 | |
118 | static struct { |
119 | int div; /* *10 due to .5s */ |
120 | int bclk_div; |
121 | } bclk_divs[] = { |
122 | { 10, 0 }, |
123 | { 15, 1 }, |
124 | { 20, 2 }, |
125 | { 30, 3 }, |
126 | { 40, 4 }, |
127 | { 50, 5 }, |
128 | { 55, 6 }, |
129 | { 60, 7 }, |
130 | { 80, 8 }, |
131 | { 100, 9 }, |
132 | { 110, 10 }, |
133 | { 120, 11 }, |
134 | { 160, 12 }, |
135 | { 200, 13 }, |
136 | { 220, 14 }, |
137 | { 240, 15 }, |
138 | { 250, 16 }, |
139 | { 300, 17 }, |
140 | { 320, 18 }, |
141 | { 440, 19 }, |
142 | { 480, 20 }, |
143 | }; |
144 | |
145 | struct wm9081_priv { |
146 | struct regmap *regmap; |
147 | int sysclk_source; |
148 | int mclk_rate; |
149 | int sysclk_rate; |
150 | int fs; |
151 | int bclk; |
152 | int master; |
153 | int fll_fref; |
154 | int fll_fout; |
155 | int tdm_width; |
156 | struct wm9081_pdata pdata; |
157 | }; |
158 | |
159 | static bool wm9081_volatile_register(struct device *dev, unsigned int reg) |
160 | { |
161 | switch (reg) { |
162 | case WM9081_SOFTWARE_RESET: |
163 | case WM9081_INTERRUPT_STATUS: |
164 | return true; |
165 | default: |
166 | return false; |
167 | } |
168 | } |
169 | |
170 | static bool wm9081_readable_register(struct device *dev, unsigned int reg) |
171 | { |
172 | switch (reg) { |
173 | case WM9081_SOFTWARE_RESET: |
174 | case WM9081_ANALOGUE_LINEOUT: |
175 | case WM9081_ANALOGUE_SPEAKER_PGA: |
176 | case WM9081_VMID_CONTROL: |
177 | case WM9081_BIAS_CONTROL_1: |
178 | case WM9081_ANALOGUE_MIXER: |
179 | case WM9081_ANTI_POP_CONTROL: |
180 | case WM9081_ANALOGUE_SPEAKER_1: |
181 | case WM9081_ANALOGUE_SPEAKER_2: |
182 | case WM9081_POWER_MANAGEMENT: |
183 | case WM9081_CLOCK_CONTROL_1: |
184 | case WM9081_CLOCK_CONTROL_2: |
185 | case WM9081_CLOCK_CONTROL_3: |
186 | case WM9081_FLL_CONTROL_1: |
187 | case WM9081_FLL_CONTROL_2: |
188 | case WM9081_FLL_CONTROL_3: |
189 | case WM9081_FLL_CONTROL_4: |
190 | case WM9081_FLL_CONTROL_5: |
191 | case WM9081_AUDIO_INTERFACE_1: |
192 | case WM9081_AUDIO_INTERFACE_2: |
193 | case WM9081_AUDIO_INTERFACE_3: |
194 | case WM9081_AUDIO_INTERFACE_4: |
195 | case WM9081_INTERRUPT_STATUS: |
196 | case WM9081_INTERRUPT_STATUS_MASK: |
197 | case WM9081_INTERRUPT_POLARITY: |
198 | case WM9081_INTERRUPT_CONTROL: |
199 | case WM9081_DAC_DIGITAL_1: |
200 | case WM9081_DAC_DIGITAL_2: |
201 | case WM9081_DRC_1: |
202 | case WM9081_DRC_2: |
203 | case WM9081_DRC_3: |
204 | case WM9081_DRC_4: |
205 | case WM9081_WRITE_SEQUENCER_1: |
206 | case WM9081_WRITE_SEQUENCER_2: |
207 | case WM9081_MW_SLAVE_1: |
208 | case WM9081_EQ_1: |
209 | case WM9081_EQ_2: |
210 | case WM9081_EQ_3: |
211 | case WM9081_EQ_4: |
212 | case WM9081_EQ_5: |
213 | case WM9081_EQ_6: |
214 | case WM9081_EQ_7: |
215 | case WM9081_EQ_8: |
216 | case WM9081_EQ_9: |
217 | case WM9081_EQ_10: |
218 | case WM9081_EQ_11: |
219 | case WM9081_EQ_12: |
220 | case WM9081_EQ_13: |
221 | case WM9081_EQ_14: |
222 | case WM9081_EQ_15: |
223 | case WM9081_EQ_16: |
224 | case WM9081_EQ_17: |
225 | case WM9081_EQ_18: |
226 | case WM9081_EQ_19: |
227 | case WM9081_EQ_20: |
228 | return true; |
229 | default: |
230 | return false; |
231 | } |
232 | } |
233 | |
234 | static int wm9081_reset(struct regmap *map) |
235 | { |
236 | return regmap_write(map, WM9081_SOFTWARE_RESET, val: 0x9081); |
237 | } |
238 | |
239 | static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); |
240 | static const DECLARE_TLV_DB_SCALE(drc_out_tlv, -2250, 75, 0); |
241 | static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0); |
242 | static const DECLARE_TLV_DB_RANGE(drc_max_tlv, |
243 | 0, 0, TLV_DB_SCALE_ITEM(1200, 0, 0), |
244 | 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0), |
245 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), |
246 | 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0) |
247 | ); |
248 | static const DECLARE_TLV_DB_SCALE(drc_qr_tlv, 1200, 600, 0); |
249 | static const DECLARE_TLV_DB_SCALE(drc_startup_tlv, -300, 50, 0); |
250 | |
251 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); |
252 | |
253 | static const DECLARE_TLV_DB_SCALE(in_tlv, -600, 600, 0); |
254 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1); |
255 | static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); |
256 | |
257 | static const char *drc_high_text[] = { |
258 | "1" , |
259 | "1/2" , |
260 | "1/4" , |
261 | "1/8" , |
262 | "1/16" , |
263 | "0" , |
264 | }; |
265 | |
266 | static SOC_ENUM_SINGLE_DECL(drc_high, WM9081_DRC_3, 3, drc_high_text); |
267 | |
268 | static const char *drc_low_text[] = { |
269 | "1" , |
270 | "1/2" , |
271 | "1/4" , |
272 | "1/8" , |
273 | "0" , |
274 | }; |
275 | |
276 | static SOC_ENUM_SINGLE_DECL(drc_low, WM9081_DRC_3, 0, drc_low_text); |
277 | |
278 | static const char *drc_atk_text[] = { |
279 | "181us" , |
280 | "181us" , |
281 | "363us" , |
282 | "726us" , |
283 | "1.45ms" , |
284 | "2.9ms" , |
285 | "5.8ms" , |
286 | "11.6ms" , |
287 | "23.2ms" , |
288 | "46.4ms" , |
289 | "92.8ms" , |
290 | "185.6ms" , |
291 | }; |
292 | |
293 | static SOC_ENUM_SINGLE_DECL(drc_atk, WM9081_DRC_2, 12, drc_atk_text); |
294 | |
295 | static const char *drc_dcy_text[] = { |
296 | "186ms" , |
297 | "372ms" , |
298 | "743ms" , |
299 | "1.49s" , |
300 | "2.97s" , |
301 | "5.94s" , |
302 | "11.89s" , |
303 | "23.78s" , |
304 | "47.56s" , |
305 | }; |
306 | |
307 | static SOC_ENUM_SINGLE_DECL(drc_dcy, WM9081_DRC_2, 8, drc_dcy_text); |
308 | |
309 | static const char *drc_qr_dcy_text[] = { |
310 | "0.725ms" , |
311 | "1.45ms" , |
312 | "5.8ms" , |
313 | }; |
314 | |
315 | static SOC_ENUM_SINGLE_DECL(drc_qr_dcy, WM9081_DRC_2, 4, drc_qr_dcy_text); |
316 | |
317 | static const char *dac_deemph_text[] = { |
318 | "None" , |
319 | "32kHz" , |
320 | "44.1kHz" , |
321 | "48kHz" , |
322 | }; |
323 | |
324 | static SOC_ENUM_SINGLE_DECL(dac_deemph, WM9081_DAC_DIGITAL_2, 1, |
325 | dac_deemph_text); |
326 | |
327 | static const char *speaker_mode_text[] = { |
328 | "Class D" , |
329 | "Class AB" , |
330 | }; |
331 | |
332 | static SOC_ENUM_SINGLE_DECL(speaker_mode, WM9081_ANALOGUE_SPEAKER_2, 6, |
333 | speaker_mode_text); |
334 | |
335 | static int speaker_mode_get(struct snd_kcontrol *kcontrol, |
336 | struct snd_ctl_elem_value *ucontrol) |
337 | { |
338 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
339 | unsigned int reg; |
340 | |
341 | reg = snd_soc_component_read(component, WM9081_ANALOGUE_SPEAKER_2); |
342 | if (reg & WM9081_SPK_MODE) |
343 | ucontrol->value.enumerated.item[0] = 1; |
344 | else |
345 | ucontrol->value.enumerated.item[0] = 0; |
346 | |
347 | return 0; |
348 | } |
349 | |
350 | /* |
351 | * Stop any attempts to change speaker mode while the speaker is enabled. |
352 | * |
353 | * We also have some special anti-pop controls dependent on speaker |
354 | * mode which must be changed along with the mode. |
355 | */ |
356 | static int speaker_mode_put(struct snd_kcontrol *kcontrol, |
357 | struct snd_ctl_elem_value *ucontrol) |
358 | { |
359 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
360 | unsigned int reg_pwr = snd_soc_component_read(component, WM9081_POWER_MANAGEMENT); |
361 | unsigned int reg2 = snd_soc_component_read(component, WM9081_ANALOGUE_SPEAKER_2); |
362 | |
363 | /* Are we changing anything? */ |
364 | if (ucontrol->value.enumerated.item[0] == |
365 | ((reg2 & WM9081_SPK_MODE) != 0)) |
366 | return 0; |
367 | |
368 | /* Don't try to change modes while enabled */ |
369 | if (reg_pwr & WM9081_SPK_ENA) |
370 | return -EINVAL; |
371 | |
372 | if (ucontrol->value.enumerated.item[0]) { |
373 | /* Class AB */ |
374 | reg2 &= ~(WM9081_SPK_INV_MUTE | WM9081_OUT_SPK_CTRL); |
375 | reg2 |= WM9081_SPK_MODE; |
376 | } else { |
377 | /* Class D */ |
378 | reg2 |= WM9081_SPK_INV_MUTE | WM9081_OUT_SPK_CTRL; |
379 | reg2 &= ~WM9081_SPK_MODE; |
380 | } |
381 | |
382 | snd_soc_component_write(component, WM9081_ANALOGUE_SPEAKER_2, val: reg2); |
383 | |
384 | return 0; |
385 | } |
386 | |
387 | static const struct snd_kcontrol_new wm9081_snd_controls[] = { |
388 | SOC_SINGLE_TLV("IN1 Volume" , WM9081_ANALOGUE_MIXER, 1, 1, 1, in_tlv), |
389 | SOC_SINGLE_TLV("IN2 Volume" , WM9081_ANALOGUE_MIXER, 3, 1, 1, in_tlv), |
390 | |
391 | SOC_SINGLE_TLV("Playback Volume" , WM9081_DAC_DIGITAL_1, 1, 96, 0, dac_tlv), |
392 | |
393 | SOC_SINGLE("LINEOUT Switch" , WM9081_ANALOGUE_LINEOUT, 7, 1, 1), |
394 | SOC_SINGLE("LINEOUT ZC Switch" , WM9081_ANALOGUE_LINEOUT, 6, 1, 0), |
395 | SOC_SINGLE_TLV("LINEOUT Volume" , WM9081_ANALOGUE_LINEOUT, 0, 63, 0, out_tlv), |
396 | |
397 | SOC_SINGLE("DRC Switch" , WM9081_DRC_1, 15, 1, 0), |
398 | SOC_ENUM("DRC High Slope" , drc_high), |
399 | SOC_ENUM("DRC Low Slope" , drc_low), |
400 | SOC_SINGLE_TLV("DRC Input Volume" , WM9081_DRC_4, 5, 60, 1, drc_in_tlv), |
401 | SOC_SINGLE_TLV("DRC Output Volume" , WM9081_DRC_4, 0, 30, 1, drc_out_tlv), |
402 | SOC_SINGLE_TLV("DRC Minimum Volume" , WM9081_DRC_2, 2, 3, 1, drc_min_tlv), |
403 | SOC_SINGLE_TLV("DRC Maximum Volume" , WM9081_DRC_2, 0, 3, 0, drc_max_tlv), |
404 | SOC_ENUM("DRC Attack" , drc_atk), |
405 | SOC_ENUM("DRC Decay" , drc_dcy), |
406 | SOC_SINGLE("DRC Quick Release Switch" , WM9081_DRC_1, 2, 1, 0), |
407 | SOC_SINGLE_TLV("DRC Quick Release Volume" , WM9081_DRC_2, 6, 3, 0, drc_qr_tlv), |
408 | SOC_ENUM("DRC Quick Release Decay" , drc_qr_dcy), |
409 | SOC_SINGLE_TLV("DRC Startup Volume" , WM9081_DRC_1, 6, 18, 0, drc_startup_tlv), |
410 | |
411 | SOC_SINGLE("EQ Switch" , WM9081_EQ_1, 0, 1, 0), |
412 | |
413 | SOC_SINGLE("Speaker DC Volume" , WM9081_ANALOGUE_SPEAKER_1, 3, 5, 0), |
414 | SOC_SINGLE("Speaker AC Volume" , WM9081_ANALOGUE_SPEAKER_1, 0, 5, 0), |
415 | SOC_SINGLE("Speaker Switch" , WM9081_ANALOGUE_SPEAKER_PGA, 7, 1, 1), |
416 | SOC_SINGLE("Speaker ZC Switch" , WM9081_ANALOGUE_SPEAKER_PGA, 6, 1, 0), |
417 | SOC_SINGLE_TLV("Speaker Volume" , WM9081_ANALOGUE_SPEAKER_PGA, 0, 63, 0, |
418 | out_tlv), |
419 | SOC_ENUM("DAC Deemphasis" , dac_deemph), |
420 | SOC_ENUM_EXT("Speaker Mode" , speaker_mode, speaker_mode_get, speaker_mode_put), |
421 | }; |
422 | |
423 | static const struct snd_kcontrol_new wm9081_eq_controls[] = { |
424 | SOC_SINGLE_TLV("EQ1 Volume" , WM9081_EQ_1, 11, 24, 0, eq_tlv), |
425 | SOC_SINGLE_TLV("EQ2 Volume" , WM9081_EQ_1, 6, 24, 0, eq_tlv), |
426 | SOC_SINGLE_TLV("EQ3 Volume" , WM9081_EQ_1, 1, 24, 0, eq_tlv), |
427 | SOC_SINGLE_TLV("EQ4 Volume" , WM9081_EQ_2, 11, 24, 0, eq_tlv), |
428 | SOC_SINGLE_TLV("EQ5 Volume" , WM9081_EQ_2, 6, 24, 0, eq_tlv), |
429 | }; |
430 | |
431 | static const struct snd_kcontrol_new mixer[] = { |
432 | SOC_DAPM_SINGLE("IN1 Switch" , WM9081_ANALOGUE_MIXER, 0, 1, 0), |
433 | SOC_DAPM_SINGLE("IN2 Switch" , WM9081_ANALOGUE_MIXER, 2, 1, 0), |
434 | SOC_DAPM_SINGLE("Playback Switch" , WM9081_ANALOGUE_MIXER, 4, 1, 0), |
435 | }; |
436 | |
437 | struct _fll_div { |
438 | u16 fll_fratio; |
439 | u16 fll_outdiv; |
440 | u16 fll_clk_ref_div; |
441 | u16 n; |
442 | u16 k; |
443 | }; |
444 | |
445 | /* The size in bits of the FLL divide multiplied by 10 |
446 | * to allow rounding later */ |
447 | #define FIXED_FLL_SIZE ((1 << 16) * 10) |
448 | |
449 | static struct { |
450 | unsigned int min; |
451 | unsigned int max; |
452 | u16 fll_fratio; |
453 | int ratio; |
454 | } fll_fratios[] = { |
455 | { 0, 64000, 4, 16 }, |
456 | { 64000, 128000, 3, 8 }, |
457 | { 128000, 256000, 2, 4 }, |
458 | { 256000, 1000000, 1, 2 }, |
459 | { 1000000, 13500000, 0, 1 }, |
460 | }; |
461 | |
462 | static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, |
463 | unsigned int Fout) |
464 | { |
465 | u64 Kpart; |
466 | unsigned int K, Ndiv, Nmod, target; |
467 | unsigned int div; |
468 | int i; |
469 | |
470 | /* Fref must be <=13.5MHz */ |
471 | div = 1; |
472 | while ((Fref / div) > 13500000) { |
473 | div *= 2; |
474 | |
475 | if (div > 8) { |
476 | pr_err("Can't scale %dMHz input down to <=13.5MHz\n" , |
477 | Fref); |
478 | return -EINVAL; |
479 | } |
480 | } |
481 | fll_div->fll_clk_ref_div = div / 2; |
482 | |
483 | pr_debug("Fref=%u Fout=%u\n" , Fref, Fout); |
484 | |
485 | /* Apply the division for our remaining calculations */ |
486 | Fref /= div; |
487 | |
488 | /* Fvco should be 90-100MHz; don't check the upper bound */ |
489 | div = 0; |
490 | target = Fout * 2; |
491 | while (target < 90000000) { |
492 | div++; |
493 | target *= 2; |
494 | if (div > 7) { |
495 | pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n" , |
496 | Fout); |
497 | return -EINVAL; |
498 | } |
499 | } |
500 | fll_div->fll_outdiv = div; |
501 | |
502 | pr_debug("Fvco=%dHz\n" , target); |
503 | |
504 | /* Find an appropriate FLL_FRATIO and factor it out of the target */ |
505 | for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { |
506 | if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { |
507 | fll_div->fll_fratio = fll_fratios[i].fll_fratio; |
508 | target /= fll_fratios[i].ratio; |
509 | break; |
510 | } |
511 | } |
512 | if (i == ARRAY_SIZE(fll_fratios)) { |
513 | pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n" , Fref); |
514 | return -EINVAL; |
515 | } |
516 | |
517 | /* Now, calculate N.K */ |
518 | Ndiv = target / Fref; |
519 | |
520 | fll_div->n = Ndiv; |
521 | Nmod = target % Fref; |
522 | pr_debug("Nmod=%d\n" , Nmod); |
523 | |
524 | /* Calculate fractional part - scale up so we can round. */ |
525 | Kpart = FIXED_FLL_SIZE * (long long)Nmod; |
526 | |
527 | do_div(Kpart, Fref); |
528 | |
529 | K = Kpart & 0xFFFFFFFF; |
530 | |
531 | if ((K % 10) >= 5) |
532 | K += 5; |
533 | |
534 | /* Move down to proper range now rounding is done */ |
535 | fll_div->k = K / 10; |
536 | |
537 | pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n" , |
538 | fll_div->n, fll_div->k, |
539 | fll_div->fll_fratio, fll_div->fll_outdiv, |
540 | fll_div->fll_clk_ref_div); |
541 | |
542 | return 0; |
543 | } |
544 | |
545 | static int wm9081_set_fll(struct snd_soc_component *component, int fll_id, |
546 | unsigned int Fref, unsigned int Fout) |
547 | { |
548 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
549 | u16 reg1, reg4, reg5; |
550 | struct _fll_div fll_div; |
551 | int ret; |
552 | int clk_sys_reg; |
553 | |
554 | /* Any change? */ |
555 | if (Fref == wm9081->fll_fref && Fout == wm9081->fll_fout) |
556 | return 0; |
557 | |
558 | /* Disable the FLL */ |
559 | if (Fout == 0) { |
560 | dev_dbg(component->dev, "FLL disabled\n" ); |
561 | wm9081->fll_fref = 0; |
562 | wm9081->fll_fout = 0; |
563 | |
564 | return 0; |
565 | } |
566 | |
567 | ret = fll_factors(fll_div: &fll_div, Fref, Fout); |
568 | if (ret != 0) |
569 | return ret; |
570 | |
571 | reg5 = snd_soc_component_read(component, WM9081_FLL_CONTROL_5); |
572 | reg5 &= ~WM9081_FLL_CLK_SRC_MASK; |
573 | |
574 | switch (fll_id) { |
575 | case WM9081_SYSCLK_FLL_MCLK: |
576 | reg5 |= 0x1; |
577 | break; |
578 | |
579 | default: |
580 | dev_err(component->dev, "Unknown FLL ID %d\n" , fll_id); |
581 | return -EINVAL; |
582 | } |
583 | |
584 | /* Disable CLK_SYS while we reconfigure */ |
585 | clk_sys_reg = snd_soc_component_read(component, WM9081_CLOCK_CONTROL_3); |
586 | if (clk_sys_reg & WM9081_CLK_SYS_ENA) |
587 | snd_soc_component_write(component, WM9081_CLOCK_CONTROL_3, |
588 | val: clk_sys_reg & ~WM9081_CLK_SYS_ENA); |
589 | |
590 | /* Any FLL configuration change requires that the FLL be |
591 | * disabled first. */ |
592 | reg1 = snd_soc_component_read(component, WM9081_FLL_CONTROL_1); |
593 | reg1 &= ~WM9081_FLL_ENA; |
594 | snd_soc_component_write(component, WM9081_FLL_CONTROL_1, val: reg1); |
595 | |
596 | /* Apply the configuration */ |
597 | if (fll_div.k) |
598 | reg1 |= WM9081_FLL_FRAC_MASK; |
599 | else |
600 | reg1 &= ~WM9081_FLL_FRAC_MASK; |
601 | snd_soc_component_write(component, WM9081_FLL_CONTROL_1, val: reg1); |
602 | |
603 | snd_soc_component_write(component, WM9081_FLL_CONTROL_2, |
604 | val: (fll_div.fll_outdiv << WM9081_FLL_OUTDIV_SHIFT) | |
605 | (fll_div.fll_fratio << WM9081_FLL_FRATIO_SHIFT)); |
606 | snd_soc_component_write(component, WM9081_FLL_CONTROL_3, val: fll_div.k); |
607 | |
608 | reg4 = snd_soc_component_read(component, WM9081_FLL_CONTROL_4); |
609 | reg4 &= ~WM9081_FLL_N_MASK; |
610 | reg4 |= fll_div.n << WM9081_FLL_N_SHIFT; |
611 | snd_soc_component_write(component, WM9081_FLL_CONTROL_4, val: reg4); |
612 | |
613 | reg5 &= ~WM9081_FLL_CLK_REF_DIV_MASK; |
614 | reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT; |
615 | snd_soc_component_write(component, WM9081_FLL_CONTROL_5, val: reg5); |
616 | |
617 | /* Set gain to the recommended value */ |
618 | snd_soc_component_update_bits(component, WM9081_FLL_CONTROL_4, |
619 | WM9081_FLL_GAIN_MASK, val: 0); |
620 | |
621 | /* Enable the FLL */ |
622 | snd_soc_component_write(component, WM9081_FLL_CONTROL_1, val: reg1 | WM9081_FLL_ENA); |
623 | |
624 | /* Then bring CLK_SYS up again if it was disabled */ |
625 | if (clk_sys_reg & WM9081_CLK_SYS_ENA) |
626 | snd_soc_component_write(component, WM9081_CLOCK_CONTROL_3, val: clk_sys_reg); |
627 | |
628 | dev_dbg(component->dev, "FLL enabled at %dHz->%dHz\n" , Fref, Fout); |
629 | |
630 | wm9081->fll_fref = Fref; |
631 | wm9081->fll_fout = Fout; |
632 | |
633 | return 0; |
634 | } |
635 | |
636 | static int configure_clock(struct snd_soc_component *component) |
637 | { |
638 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
639 | int new_sysclk, i, target; |
640 | unsigned int reg; |
641 | int ret = 0; |
642 | int mclkdiv = 0; |
643 | int fll = 0; |
644 | |
645 | switch (wm9081->sysclk_source) { |
646 | case WM9081_SYSCLK_MCLK: |
647 | if (wm9081->mclk_rate > 12225000) { |
648 | mclkdiv = 1; |
649 | wm9081->sysclk_rate = wm9081->mclk_rate / 2; |
650 | } else { |
651 | wm9081->sysclk_rate = wm9081->mclk_rate; |
652 | } |
653 | wm9081_set_fll(component, WM9081_SYSCLK_FLL_MCLK, Fref: 0, Fout: 0); |
654 | break; |
655 | |
656 | case WM9081_SYSCLK_FLL_MCLK: |
657 | /* If we have a sample rate calculate a CLK_SYS that |
658 | * gives us a suitable DAC configuration, plus BCLK. |
659 | * Ideally we would check to see if we can clock |
660 | * directly from MCLK and only use the FLL if this is |
661 | * not the case, though care must be taken with free |
662 | * running mode. |
663 | */ |
664 | if (wm9081->master && wm9081->bclk) { |
665 | /* Make sure we can generate CLK_SYS and BCLK |
666 | * and that we've got 3MHz for optimal |
667 | * performance. */ |
668 | for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) { |
669 | target = wm9081->fs * clk_sys_rates[i].ratio; |
670 | new_sysclk = target; |
671 | if (target >= wm9081->bclk && |
672 | target > 3000000) |
673 | break; |
674 | } |
675 | |
676 | if (i == ARRAY_SIZE(clk_sys_rates)) |
677 | return -EINVAL; |
678 | |
679 | } else if (wm9081->fs) { |
680 | for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) { |
681 | new_sysclk = clk_sys_rates[i].ratio |
682 | * wm9081->fs; |
683 | if (new_sysclk > 3000000) |
684 | break; |
685 | } |
686 | |
687 | if (i == ARRAY_SIZE(clk_sys_rates)) |
688 | return -EINVAL; |
689 | |
690 | } else { |
691 | new_sysclk = 12288000; |
692 | } |
693 | |
694 | ret = wm9081_set_fll(component, WM9081_SYSCLK_FLL_MCLK, |
695 | Fref: wm9081->mclk_rate, Fout: new_sysclk); |
696 | if (ret == 0) { |
697 | wm9081->sysclk_rate = new_sysclk; |
698 | |
699 | /* Switch SYSCLK over to FLL */ |
700 | fll = 1; |
701 | } else { |
702 | wm9081->sysclk_rate = wm9081->mclk_rate; |
703 | } |
704 | break; |
705 | |
706 | default: |
707 | return -EINVAL; |
708 | } |
709 | |
710 | reg = snd_soc_component_read(component, WM9081_CLOCK_CONTROL_1); |
711 | if (mclkdiv) |
712 | reg |= WM9081_MCLKDIV2; |
713 | else |
714 | reg &= ~WM9081_MCLKDIV2; |
715 | snd_soc_component_write(component, WM9081_CLOCK_CONTROL_1, val: reg); |
716 | |
717 | reg = snd_soc_component_read(component, WM9081_CLOCK_CONTROL_3); |
718 | if (fll) |
719 | reg |= WM9081_CLK_SRC_SEL; |
720 | else |
721 | reg &= ~WM9081_CLK_SRC_SEL; |
722 | snd_soc_component_write(component, WM9081_CLOCK_CONTROL_3, val: reg); |
723 | |
724 | dev_dbg(component->dev, "CLK_SYS is %dHz\n" , wm9081->sysclk_rate); |
725 | |
726 | return ret; |
727 | } |
728 | |
729 | static int clk_sys_event(struct snd_soc_dapm_widget *w, |
730 | struct snd_kcontrol *kcontrol, int event) |
731 | { |
732 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: w->dapm); |
733 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
734 | |
735 | /* This should be done on init() for bypass paths */ |
736 | switch (wm9081->sysclk_source) { |
737 | case WM9081_SYSCLK_MCLK: |
738 | dev_dbg(component->dev, "Using %dHz MCLK\n" , wm9081->mclk_rate); |
739 | break; |
740 | case WM9081_SYSCLK_FLL_MCLK: |
741 | dev_dbg(component->dev, "Using %dHz MCLK with FLL\n" , |
742 | wm9081->mclk_rate); |
743 | break; |
744 | default: |
745 | dev_err(component->dev, "System clock not configured\n" ); |
746 | return -EINVAL; |
747 | } |
748 | |
749 | switch (event) { |
750 | case SND_SOC_DAPM_PRE_PMU: |
751 | configure_clock(component); |
752 | break; |
753 | |
754 | case SND_SOC_DAPM_POST_PMD: |
755 | /* Disable the FLL if it's running */ |
756 | wm9081_set_fll(component, fll_id: 0, Fref: 0, Fout: 0); |
757 | break; |
758 | } |
759 | |
760 | return 0; |
761 | } |
762 | |
763 | static const struct snd_soc_dapm_widget wm9081_dapm_widgets[] = { |
764 | SND_SOC_DAPM_INPUT("IN1" ), |
765 | SND_SOC_DAPM_INPUT("IN2" ), |
766 | |
767 | SND_SOC_DAPM_DAC("DAC" , NULL, WM9081_POWER_MANAGEMENT, 0, 0), |
768 | |
769 | SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer" , SND_SOC_NOPM, 0, 0, |
770 | mixer, ARRAY_SIZE(mixer)), |
771 | |
772 | SND_SOC_DAPM_PGA("LINEOUT PGA" , WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0), |
773 | |
774 | SND_SOC_DAPM_PGA("Speaker PGA" , WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0), |
775 | SND_SOC_DAPM_OUT_DRV("Speaker" , WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0), |
776 | |
777 | SND_SOC_DAPM_OUTPUT("LINEOUT" ), |
778 | SND_SOC_DAPM_OUTPUT("SPKN" ), |
779 | SND_SOC_DAPM_OUTPUT("SPKP" ), |
780 | |
781 | SND_SOC_DAPM_SUPPLY("CLK_SYS" , WM9081_CLOCK_CONTROL_3, 0, 0, clk_sys_event, |
782 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
783 | SND_SOC_DAPM_SUPPLY("CLK_DSP" , WM9081_CLOCK_CONTROL_3, 1, 0, NULL, 0), |
784 | SND_SOC_DAPM_SUPPLY("TOCLK" , WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0), |
785 | SND_SOC_DAPM_SUPPLY("TSENSE" , WM9081_POWER_MANAGEMENT, 7, 0, NULL, 0), |
786 | }; |
787 | |
788 | |
789 | static const struct snd_soc_dapm_route wm9081_audio_paths[] = { |
790 | { "DAC" , NULL, "CLK_SYS" }, |
791 | { "DAC" , NULL, "CLK_DSP" }, |
792 | { "DAC" , NULL, "AIF" }, |
793 | |
794 | { "Mixer" , "IN1 Switch" , "IN1" }, |
795 | { "Mixer" , "IN2 Switch" , "IN2" }, |
796 | { "Mixer" , "Playback Switch" , "DAC" }, |
797 | |
798 | { "LINEOUT PGA" , NULL, "Mixer" }, |
799 | { "LINEOUT PGA" , NULL, "TOCLK" }, |
800 | { "LINEOUT PGA" , NULL, "CLK_SYS" }, |
801 | |
802 | { "LINEOUT" , NULL, "LINEOUT PGA" }, |
803 | |
804 | { "Speaker PGA" , NULL, "Mixer" }, |
805 | { "Speaker PGA" , NULL, "TOCLK" }, |
806 | { "Speaker PGA" , NULL, "CLK_SYS" }, |
807 | |
808 | { "Speaker" , NULL, "Speaker PGA" }, |
809 | { "Speaker" , NULL, "TSENSE" }, |
810 | |
811 | { "SPKN" , NULL, "Speaker" }, |
812 | { "SPKP" , NULL, "Speaker" }, |
813 | }; |
814 | |
815 | static int wm9081_set_bias_level(struct snd_soc_component *component, |
816 | enum snd_soc_bias_level level) |
817 | { |
818 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
819 | |
820 | switch (level) { |
821 | case SND_SOC_BIAS_ON: |
822 | break; |
823 | |
824 | case SND_SOC_BIAS_PREPARE: |
825 | /* VMID=2*40k */ |
826 | snd_soc_component_update_bits(component, WM9081_VMID_CONTROL, |
827 | WM9081_VMID_SEL_MASK, val: 0x2); |
828 | |
829 | /* Normal bias current */ |
830 | snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1, |
831 | WM9081_STBY_BIAS_ENA, val: 0); |
832 | break; |
833 | |
834 | case SND_SOC_BIAS_STANDBY: |
835 | /* Initial cold start */ |
836 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { |
837 | regcache_cache_only(map: wm9081->regmap, enable: false); |
838 | regcache_sync(map: wm9081->regmap); |
839 | |
840 | /* Disable LINEOUT discharge */ |
841 | snd_soc_component_update_bits(component, WM9081_ANTI_POP_CONTROL, |
842 | WM9081_LINEOUT_DISCH, val: 0); |
843 | |
844 | /* Select startup bias source */ |
845 | snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1, |
846 | WM9081_BIAS_SRC | WM9081_BIAS_ENA, |
847 | WM9081_BIAS_SRC | WM9081_BIAS_ENA); |
848 | |
849 | /* VMID 2*4k; Soft VMID ramp enable */ |
850 | snd_soc_component_update_bits(component, WM9081_VMID_CONTROL, |
851 | WM9081_VMID_RAMP | |
852 | WM9081_VMID_SEL_MASK, |
853 | WM9081_VMID_RAMP | 0x6); |
854 | |
855 | mdelay(100); |
856 | |
857 | /* Normal bias enable & soft start off */ |
858 | snd_soc_component_update_bits(component, WM9081_VMID_CONTROL, |
859 | WM9081_VMID_RAMP, val: 0); |
860 | |
861 | /* Standard bias source */ |
862 | snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1, |
863 | WM9081_BIAS_SRC, val: 0); |
864 | } |
865 | |
866 | /* VMID 2*240k */ |
867 | snd_soc_component_update_bits(component, WM9081_VMID_CONTROL, |
868 | WM9081_VMID_SEL_MASK, val: 0x04); |
869 | |
870 | /* Standby bias current on */ |
871 | snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1, |
872 | WM9081_STBY_BIAS_ENA, |
873 | WM9081_STBY_BIAS_ENA); |
874 | break; |
875 | |
876 | case SND_SOC_BIAS_OFF: |
877 | /* Startup bias source and disable bias */ |
878 | snd_soc_component_update_bits(component, WM9081_BIAS_CONTROL_1, |
879 | WM9081_BIAS_SRC | WM9081_BIAS_ENA, |
880 | WM9081_BIAS_SRC); |
881 | |
882 | /* Disable VMID with soft ramping */ |
883 | snd_soc_component_update_bits(component, WM9081_VMID_CONTROL, |
884 | WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK, |
885 | WM9081_VMID_RAMP); |
886 | |
887 | /* Actively discharge LINEOUT */ |
888 | snd_soc_component_update_bits(component, WM9081_ANTI_POP_CONTROL, |
889 | WM9081_LINEOUT_DISCH, |
890 | WM9081_LINEOUT_DISCH); |
891 | |
892 | regcache_cache_only(map: wm9081->regmap, enable: true); |
893 | break; |
894 | } |
895 | |
896 | return 0; |
897 | } |
898 | |
899 | static int wm9081_set_dai_fmt(struct snd_soc_dai *dai, |
900 | unsigned int fmt) |
901 | { |
902 | struct snd_soc_component *component = dai->component; |
903 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
904 | unsigned int aif2 = snd_soc_component_read(component, WM9081_AUDIO_INTERFACE_2); |
905 | |
906 | aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV | |
907 | WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK); |
908 | |
909 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
910 | case SND_SOC_DAIFMT_CBS_CFS: |
911 | wm9081->master = 0; |
912 | break; |
913 | case SND_SOC_DAIFMT_CBS_CFM: |
914 | aif2 |= WM9081_LRCLK_DIR; |
915 | wm9081->master = 1; |
916 | break; |
917 | case SND_SOC_DAIFMT_CBM_CFS: |
918 | aif2 |= WM9081_BCLK_DIR; |
919 | wm9081->master = 1; |
920 | break; |
921 | case SND_SOC_DAIFMT_CBM_CFM: |
922 | aif2 |= WM9081_LRCLK_DIR | WM9081_BCLK_DIR; |
923 | wm9081->master = 1; |
924 | break; |
925 | default: |
926 | return -EINVAL; |
927 | } |
928 | |
929 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
930 | case SND_SOC_DAIFMT_DSP_B: |
931 | aif2 |= WM9081_AIF_LRCLK_INV; |
932 | fallthrough; |
933 | case SND_SOC_DAIFMT_DSP_A: |
934 | aif2 |= 0x3; |
935 | break; |
936 | case SND_SOC_DAIFMT_I2S: |
937 | aif2 |= 0x2; |
938 | break; |
939 | case SND_SOC_DAIFMT_RIGHT_J: |
940 | break; |
941 | case SND_SOC_DAIFMT_LEFT_J: |
942 | aif2 |= 0x1; |
943 | break; |
944 | default: |
945 | return -EINVAL; |
946 | } |
947 | |
948 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
949 | case SND_SOC_DAIFMT_DSP_A: |
950 | case SND_SOC_DAIFMT_DSP_B: |
951 | /* frame inversion not valid for DSP modes */ |
952 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
953 | case SND_SOC_DAIFMT_NB_NF: |
954 | break; |
955 | case SND_SOC_DAIFMT_IB_NF: |
956 | aif2 |= WM9081_AIF_BCLK_INV; |
957 | break; |
958 | default: |
959 | return -EINVAL; |
960 | } |
961 | break; |
962 | |
963 | case SND_SOC_DAIFMT_I2S: |
964 | case SND_SOC_DAIFMT_RIGHT_J: |
965 | case SND_SOC_DAIFMT_LEFT_J: |
966 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
967 | case SND_SOC_DAIFMT_NB_NF: |
968 | break; |
969 | case SND_SOC_DAIFMT_IB_IF: |
970 | aif2 |= WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV; |
971 | break; |
972 | case SND_SOC_DAIFMT_IB_NF: |
973 | aif2 |= WM9081_AIF_BCLK_INV; |
974 | break; |
975 | case SND_SOC_DAIFMT_NB_IF: |
976 | aif2 |= WM9081_AIF_LRCLK_INV; |
977 | break; |
978 | default: |
979 | return -EINVAL; |
980 | } |
981 | break; |
982 | default: |
983 | return -EINVAL; |
984 | } |
985 | |
986 | snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_2, val: aif2); |
987 | |
988 | return 0; |
989 | } |
990 | |
991 | static int wm9081_hw_params(struct snd_pcm_substream *substream, |
992 | struct snd_pcm_hw_params *params, |
993 | struct snd_soc_dai *dai) |
994 | { |
995 | struct snd_soc_component *component = dai->component; |
996 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
997 | int ret, i, best, best_val, cur_val; |
998 | unsigned int clk_ctrl2, aif1, aif2, aif3, aif4; |
999 | |
1000 | clk_ctrl2 = snd_soc_component_read(component, WM9081_CLOCK_CONTROL_2); |
1001 | clk_ctrl2 &= ~(WM9081_CLK_SYS_RATE_MASK | WM9081_SAMPLE_RATE_MASK); |
1002 | |
1003 | aif1 = snd_soc_component_read(component, WM9081_AUDIO_INTERFACE_1); |
1004 | |
1005 | aif2 = snd_soc_component_read(component, WM9081_AUDIO_INTERFACE_2); |
1006 | aif2 &= ~WM9081_AIF_WL_MASK; |
1007 | |
1008 | aif3 = snd_soc_component_read(component, WM9081_AUDIO_INTERFACE_3); |
1009 | aif3 &= ~WM9081_BCLK_DIV_MASK; |
1010 | |
1011 | aif4 = snd_soc_component_read(component, WM9081_AUDIO_INTERFACE_4); |
1012 | aif4 &= ~WM9081_LRCLK_RATE_MASK; |
1013 | |
1014 | wm9081->fs = params_rate(p: params); |
1015 | |
1016 | if (wm9081->tdm_width) { |
1017 | /* If TDM is set up then that fixes our BCLK. */ |
1018 | int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >> |
1019 | WM9081_AIFDAC_TDM_MODE_SHIFT) + 1; |
1020 | |
1021 | wm9081->bclk = wm9081->fs * wm9081->tdm_width * slots; |
1022 | } else { |
1023 | /* Otherwise work out a BCLK from the sample size */ |
1024 | wm9081->bclk = 2 * wm9081->fs; |
1025 | |
1026 | switch (params_width(p: params)) { |
1027 | case 16: |
1028 | wm9081->bclk *= 16; |
1029 | break; |
1030 | case 20: |
1031 | wm9081->bclk *= 20; |
1032 | aif2 |= 0x4; |
1033 | break; |
1034 | case 24: |
1035 | wm9081->bclk *= 24; |
1036 | aif2 |= 0x8; |
1037 | break; |
1038 | case 32: |
1039 | wm9081->bclk *= 32; |
1040 | aif2 |= 0xc; |
1041 | break; |
1042 | default: |
1043 | return -EINVAL; |
1044 | } |
1045 | } |
1046 | |
1047 | dev_dbg(component->dev, "Target BCLK is %dHz\n" , wm9081->bclk); |
1048 | |
1049 | ret = configure_clock(component); |
1050 | if (ret != 0) |
1051 | return ret; |
1052 | |
1053 | /* Select nearest CLK_SYS_RATE */ |
1054 | best = 0; |
1055 | best_val = abs((wm9081->sysclk_rate / clk_sys_rates[0].ratio) |
1056 | - wm9081->fs); |
1057 | for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { |
1058 | cur_val = abs((wm9081->sysclk_rate / |
1059 | clk_sys_rates[i].ratio) - wm9081->fs); |
1060 | if (cur_val < best_val) { |
1061 | best = i; |
1062 | best_val = cur_val; |
1063 | } |
1064 | } |
1065 | dev_dbg(component->dev, "Selected CLK_SYS_RATIO of %d\n" , |
1066 | clk_sys_rates[best].ratio); |
1067 | clk_ctrl2 |= (clk_sys_rates[best].clk_sys_rate |
1068 | << WM9081_CLK_SYS_RATE_SHIFT); |
1069 | |
1070 | /* SAMPLE_RATE */ |
1071 | best = 0; |
1072 | best_val = abs(wm9081->fs - sample_rates[0].rate); |
1073 | for (i = 1; i < ARRAY_SIZE(sample_rates); i++) { |
1074 | /* Closest match */ |
1075 | cur_val = abs(wm9081->fs - sample_rates[i].rate); |
1076 | if (cur_val < best_val) { |
1077 | best = i; |
1078 | best_val = cur_val; |
1079 | } |
1080 | } |
1081 | dev_dbg(component->dev, "Selected SAMPLE_RATE of %dHz\n" , |
1082 | sample_rates[best].rate); |
1083 | clk_ctrl2 |= (sample_rates[best].sample_rate |
1084 | << WM9081_SAMPLE_RATE_SHIFT); |
1085 | |
1086 | /* BCLK_DIV */ |
1087 | best = 0; |
1088 | best_val = INT_MAX; |
1089 | for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { |
1090 | cur_val = ((wm9081->sysclk_rate * 10) / bclk_divs[i].div) |
1091 | - wm9081->bclk; |
1092 | if (cur_val < 0) /* Table is sorted */ |
1093 | break; |
1094 | if (cur_val < best_val) { |
1095 | best = i; |
1096 | best_val = cur_val; |
1097 | } |
1098 | } |
1099 | wm9081->bclk = (wm9081->sysclk_rate * 10) / bclk_divs[best].div; |
1100 | dev_dbg(component->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n" , |
1101 | bclk_divs[best].div, wm9081->bclk); |
1102 | aif3 |= bclk_divs[best].bclk_div; |
1103 | |
1104 | /* LRCLK is a simple fraction of BCLK */ |
1105 | dev_dbg(component->dev, "LRCLK_RATE is %d\n" , wm9081->bclk / wm9081->fs); |
1106 | aif4 |= wm9081->bclk / wm9081->fs; |
1107 | |
1108 | /* Apply a ReTune Mobile configuration if it's in use */ |
1109 | if (wm9081->pdata.num_retune_configs) { |
1110 | struct wm9081_pdata *pdata = &wm9081->pdata; |
1111 | struct wm9081_retune_mobile_setting *s; |
1112 | int eq1; |
1113 | |
1114 | best = 0; |
1115 | best_val = abs(pdata->retune_configs[0].rate - wm9081->fs); |
1116 | for (i = 0; i < pdata->num_retune_configs; i++) { |
1117 | cur_val = abs(pdata->retune_configs[i].rate - |
1118 | wm9081->fs); |
1119 | if (cur_val < best_val) { |
1120 | best_val = cur_val; |
1121 | best = i; |
1122 | } |
1123 | } |
1124 | s = &pdata->retune_configs[best]; |
1125 | |
1126 | dev_dbg(component->dev, "ReTune Mobile %s tuned for %dHz\n" , |
1127 | s->name, s->rate); |
1128 | |
1129 | /* If the EQ is enabled then disable it while we write out */ |
1130 | eq1 = snd_soc_component_read(component, WM9081_EQ_1) & WM9081_EQ_ENA; |
1131 | if (eq1 & WM9081_EQ_ENA) |
1132 | snd_soc_component_write(component, WM9081_EQ_1, val: 0); |
1133 | |
1134 | /* Write out the other values */ |
1135 | for (i = 1; i < ARRAY_SIZE(s->config); i++) |
1136 | snd_soc_component_write(component, WM9081_EQ_1 + i, val: s->config[i]); |
1137 | |
1138 | eq1 |= (s->config[0] & ~WM9081_EQ_ENA); |
1139 | snd_soc_component_write(component, WM9081_EQ_1, val: eq1); |
1140 | } |
1141 | |
1142 | snd_soc_component_write(component, WM9081_CLOCK_CONTROL_2, val: clk_ctrl2); |
1143 | snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_2, val: aif2); |
1144 | snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_3, val: aif3); |
1145 | snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_4, val: aif4); |
1146 | |
1147 | return 0; |
1148 | } |
1149 | |
1150 | static int wm9081_mute(struct snd_soc_dai *codec_dai, int mute, int direction) |
1151 | { |
1152 | struct snd_soc_component *component = codec_dai->component; |
1153 | unsigned int reg; |
1154 | |
1155 | reg = snd_soc_component_read(component, WM9081_DAC_DIGITAL_2); |
1156 | |
1157 | if (mute) |
1158 | reg |= WM9081_DAC_MUTE; |
1159 | else |
1160 | reg &= ~WM9081_DAC_MUTE; |
1161 | |
1162 | snd_soc_component_write(component, WM9081_DAC_DIGITAL_2, val: reg); |
1163 | |
1164 | return 0; |
1165 | } |
1166 | |
1167 | static int wm9081_set_sysclk(struct snd_soc_component *component, int clk_id, |
1168 | int source, unsigned int freq, int dir) |
1169 | { |
1170 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
1171 | |
1172 | switch (clk_id) { |
1173 | case WM9081_SYSCLK_MCLK: |
1174 | case WM9081_SYSCLK_FLL_MCLK: |
1175 | wm9081->sysclk_source = clk_id; |
1176 | wm9081->mclk_rate = freq; |
1177 | break; |
1178 | |
1179 | default: |
1180 | return -EINVAL; |
1181 | } |
1182 | |
1183 | return 0; |
1184 | } |
1185 | |
1186 | static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, |
1187 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) |
1188 | { |
1189 | struct snd_soc_component *component = dai->component; |
1190 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
1191 | unsigned int aif1 = snd_soc_component_read(component, WM9081_AUDIO_INTERFACE_1); |
1192 | |
1193 | aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); |
1194 | |
1195 | if (slots < 0 || slots > 4) |
1196 | return -EINVAL; |
1197 | |
1198 | wm9081->tdm_width = slot_width; |
1199 | |
1200 | if (slots == 0) |
1201 | slots = 1; |
1202 | |
1203 | aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT; |
1204 | |
1205 | switch (rx_mask) { |
1206 | case 1: |
1207 | break; |
1208 | case 2: |
1209 | aif1 |= 0x10; |
1210 | break; |
1211 | case 4: |
1212 | aif1 |= 0x20; |
1213 | break; |
1214 | case 8: |
1215 | aif1 |= 0x30; |
1216 | break; |
1217 | default: |
1218 | return -EINVAL; |
1219 | } |
1220 | |
1221 | snd_soc_component_write(component, WM9081_AUDIO_INTERFACE_1, val: aif1); |
1222 | |
1223 | return 0; |
1224 | } |
1225 | |
1226 | #define WM9081_RATES SNDRV_PCM_RATE_8000_96000 |
1227 | |
1228 | #define WM9081_FORMATS \ |
1229 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
1230 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
1231 | |
1232 | static const struct snd_soc_dai_ops wm9081_dai_ops = { |
1233 | .hw_params = wm9081_hw_params, |
1234 | .set_fmt = wm9081_set_dai_fmt, |
1235 | .mute_stream = wm9081_mute, |
1236 | .set_tdm_slot = wm9081_set_tdm_slot, |
1237 | .no_capture_mute = 1, |
1238 | }; |
1239 | |
1240 | /* We report two channels because the CODEC processes a stereo signal, even |
1241 | * though it is only capable of handling a mono output. |
1242 | */ |
1243 | static struct snd_soc_dai_driver wm9081_dai = { |
1244 | .name = "wm9081-hifi" , |
1245 | .playback = { |
1246 | .stream_name = "AIF" , |
1247 | .channels_min = 1, |
1248 | .channels_max = 2, |
1249 | .rates = WM9081_RATES, |
1250 | .formats = WM9081_FORMATS, |
1251 | }, |
1252 | .ops = &wm9081_dai_ops, |
1253 | }; |
1254 | |
1255 | static int wm9081_probe(struct snd_soc_component *component) |
1256 | { |
1257 | struct wm9081_priv *wm9081 = snd_soc_component_get_drvdata(c: component); |
1258 | |
1259 | /* Enable zero cross by default */ |
1260 | snd_soc_component_update_bits(component, WM9081_ANALOGUE_LINEOUT, |
1261 | WM9081_LINEOUTZC, WM9081_LINEOUTZC); |
1262 | snd_soc_component_update_bits(component, WM9081_ANALOGUE_SPEAKER_PGA, |
1263 | WM9081_SPKPGAZC, WM9081_SPKPGAZC); |
1264 | |
1265 | if (!wm9081->pdata.num_retune_configs) { |
1266 | dev_dbg(component->dev, |
1267 | "No ReTune Mobile data, using normal EQ\n" ); |
1268 | snd_soc_add_component_controls(component, controls: wm9081_eq_controls, |
1269 | ARRAY_SIZE(wm9081_eq_controls)); |
1270 | } |
1271 | |
1272 | return 0; |
1273 | } |
1274 | |
1275 | static const struct snd_soc_component_driver soc_component_dev_wm9081 = { |
1276 | .probe = wm9081_probe, |
1277 | .set_sysclk = wm9081_set_sysclk, |
1278 | .set_bias_level = wm9081_set_bias_level, |
1279 | .controls = wm9081_snd_controls, |
1280 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), |
1281 | .dapm_widgets = wm9081_dapm_widgets, |
1282 | .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), |
1283 | .dapm_routes = wm9081_audio_paths, |
1284 | .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), |
1285 | .use_pmdown_time = 1, |
1286 | .endianness = 1, |
1287 | }; |
1288 | |
1289 | static const struct regmap_config wm9081_regmap = { |
1290 | .reg_bits = 8, |
1291 | .val_bits = 16, |
1292 | |
1293 | .max_register = WM9081_MAX_REGISTER, |
1294 | .reg_defaults = wm9081_reg, |
1295 | .num_reg_defaults = ARRAY_SIZE(wm9081_reg), |
1296 | .volatile_reg = wm9081_volatile_register, |
1297 | .readable_reg = wm9081_readable_register, |
1298 | .cache_type = REGCACHE_MAPLE, |
1299 | }; |
1300 | |
1301 | static int wm9081_i2c_probe(struct i2c_client *i2c) |
1302 | { |
1303 | struct wm9081_priv *wm9081; |
1304 | unsigned int reg; |
1305 | int ret; |
1306 | |
1307 | wm9081 = devm_kzalloc(dev: &i2c->dev, size: sizeof(struct wm9081_priv), |
1308 | GFP_KERNEL); |
1309 | if (wm9081 == NULL) |
1310 | return -ENOMEM; |
1311 | |
1312 | i2c_set_clientdata(client: i2c, data: wm9081); |
1313 | |
1314 | wm9081->regmap = devm_regmap_init_i2c(i2c, &wm9081_regmap); |
1315 | if (IS_ERR(ptr: wm9081->regmap)) { |
1316 | ret = PTR_ERR(ptr: wm9081->regmap); |
1317 | dev_err(&i2c->dev, "regmap_init() failed: %d\n" , ret); |
1318 | return ret; |
1319 | } |
1320 | |
1321 | ret = regmap_read(map: wm9081->regmap, WM9081_SOFTWARE_RESET, val: ®); |
1322 | if (ret != 0) { |
1323 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n" , ret); |
1324 | return ret; |
1325 | } |
1326 | if (reg != 0x9081) { |
1327 | dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n" , reg); |
1328 | return -EINVAL; |
1329 | } |
1330 | |
1331 | ret = wm9081_reset(map: wm9081->regmap); |
1332 | if (ret < 0) { |
1333 | dev_err(&i2c->dev, "Failed to issue reset\n" ); |
1334 | return ret; |
1335 | } |
1336 | |
1337 | if (dev_get_platdata(dev: &i2c->dev)) |
1338 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), |
1339 | sizeof(wm9081->pdata)); |
1340 | |
1341 | reg = 0; |
1342 | if (wm9081->pdata.irq_high) |
1343 | reg |= WM9081_IRQ_POL; |
1344 | if (!wm9081->pdata.irq_cmos) |
1345 | reg |= WM9081_IRQ_OP_CTRL; |
1346 | regmap_update_bits(map: wm9081->regmap, WM9081_INTERRUPT_CONTROL, |
1347 | WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, val: reg); |
1348 | |
1349 | regcache_cache_only(map: wm9081->regmap, enable: true); |
1350 | |
1351 | ret = devm_snd_soc_register_component(dev: &i2c->dev, |
1352 | component_driver: &soc_component_dev_wm9081, dai_drv: &wm9081_dai, num_dai: 1); |
1353 | if (ret < 0) |
1354 | return ret; |
1355 | |
1356 | return 0; |
1357 | } |
1358 | |
1359 | static void wm9081_i2c_remove(struct i2c_client *client) |
1360 | {} |
1361 | |
1362 | static const struct i2c_device_id wm9081_i2c_id[] = { |
1363 | { "wm9081" , 0 }, |
1364 | { } |
1365 | }; |
1366 | MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id); |
1367 | |
1368 | static struct i2c_driver wm9081_i2c_driver = { |
1369 | .driver = { |
1370 | .name = "wm9081" , |
1371 | }, |
1372 | .probe = wm9081_i2c_probe, |
1373 | .remove = wm9081_i2c_remove, |
1374 | .id_table = wm9081_i2c_id, |
1375 | }; |
1376 | |
1377 | module_i2c_driver(wm9081_i2c_driver); |
1378 | |
1379 | MODULE_DESCRIPTION("ASoC WM9081 driver" ); |
1380 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>" ); |
1381 | MODULE_LICENSE("GPL" ); |
1382 | |