diff options
Diffstat (limited to 'sound/soc/codecs/max98088.c')
-rw-r--r-- | sound/soc/codecs/max98088.c | 2125 |
1 files changed, 2125 insertions, 0 deletions
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c new file mode 100644 index 000000000000..4173b67c94d1 --- /dev/null +++ b/sound/soc/codecs/max98088.c | |||
@@ -0,0 +1,2125 @@ | |||
1 | /* | ||
2 | * max98088.c -- MAX98088 ALSA SoC Audio driver | ||
3 | * | ||
4 | * Copyright 2010 Maxim Integrated Products | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/moduleparam.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/pm.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/platform_device.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 | #include <linux/slab.h> | ||
26 | #include <asm/div64.h> | ||
27 | #include <sound/max98088.h> | ||
28 | #include "max98088.h" | ||
29 | |||
30 | enum max98088_type { | ||
31 | MAX98088, | ||
32 | MAX98089, | ||
33 | }; | ||
34 | |||
35 | struct max98088_cdata { | ||
36 | unsigned int rate; | ||
37 | unsigned int fmt; | ||
38 | int eq_sel; | ||
39 | }; | ||
40 | |||
41 | struct max98088_priv { | ||
42 | enum max98088_type devtype; | ||
43 | void *control_data; | ||
44 | struct max98088_pdata *pdata; | ||
45 | unsigned int sysclk; | ||
46 | struct max98088_cdata dai[2]; | ||
47 | int eq_textcnt; | ||
48 | const char **eq_texts; | ||
49 | struct soc_enum eq_enum; | ||
50 | u8 ina_state; | ||
51 | u8 inb_state; | ||
52 | unsigned int ex_mode; | ||
53 | unsigned int digmic; | ||
54 | unsigned int mic1pre; | ||
55 | unsigned int mic2pre; | ||
56 | unsigned int extmic_mode; | ||
57 | }; | ||
58 | |||
59 | static const u8 max98088_reg[M98088_REG_CNT] = { | ||
60 | 0x00, /* 00 IRQ status */ | ||
61 | 0x00, /* 01 MIC status */ | ||
62 | 0x00, /* 02 jack status */ | ||
63 | 0x00, /* 03 battery voltage */ | ||
64 | 0x00, /* 04 */ | ||
65 | 0x00, /* 05 */ | ||
66 | 0x00, /* 06 */ | ||
67 | 0x00, /* 07 */ | ||
68 | 0x00, /* 08 */ | ||
69 | 0x00, /* 09 */ | ||
70 | 0x00, /* 0A */ | ||
71 | 0x00, /* 0B */ | ||
72 | 0x00, /* 0C */ | ||
73 | 0x00, /* 0D */ | ||
74 | 0x00, /* 0E */ | ||
75 | 0x00, /* 0F interrupt enable */ | ||
76 | |||
77 | 0x00, /* 10 master clock */ | ||
78 | 0x00, /* 11 DAI1 clock mode */ | ||
79 | 0x00, /* 12 DAI1 clock control */ | ||
80 | 0x00, /* 13 DAI1 clock control */ | ||
81 | 0x00, /* 14 DAI1 format */ | ||
82 | 0x00, /* 15 DAI1 clock */ | ||
83 | 0x00, /* 16 DAI1 config */ | ||
84 | 0x00, /* 17 DAI1 TDM */ | ||
85 | 0x00, /* 18 DAI1 filters */ | ||
86 | 0x00, /* 19 DAI2 clock mode */ | ||
87 | 0x00, /* 1A DAI2 clock control */ | ||
88 | 0x00, /* 1B DAI2 clock control */ | ||
89 | 0x00, /* 1C DAI2 format */ | ||
90 | 0x00, /* 1D DAI2 clock */ | ||
91 | 0x00, /* 1E DAI2 config */ | ||
92 | 0x00, /* 1F DAI2 TDM */ | ||
93 | |||
94 | 0x00, /* 20 DAI2 filters */ | ||
95 | 0x00, /* 21 data config */ | ||
96 | 0x00, /* 22 DAC mixer */ | ||
97 | 0x00, /* 23 left ADC mixer */ | ||
98 | 0x00, /* 24 right ADC mixer */ | ||
99 | 0x00, /* 25 left HP mixer */ | ||
100 | 0x00, /* 26 right HP mixer */ | ||
101 | 0x00, /* 27 HP control */ | ||
102 | 0x00, /* 28 left REC mixer */ | ||
103 | 0x00, /* 29 right REC mixer */ | ||
104 | 0x00, /* 2A REC control */ | ||
105 | 0x00, /* 2B left SPK mixer */ | ||
106 | 0x00, /* 2C right SPK mixer */ | ||
107 | 0x00, /* 2D SPK control */ | ||
108 | 0x00, /* 2E sidetone */ | ||
109 | 0x00, /* 2F DAI1 playback level */ | ||
110 | |||
111 | 0x00, /* 30 DAI1 playback level */ | ||
112 | 0x00, /* 31 DAI2 playback level */ | ||
113 | 0x00, /* 32 DAI2 playbakc level */ | ||
114 | 0x00, /* 33 left ADC level */ | ||
115 | 0x00, /* 34 right ADC level */ | ||
116 | 0x00, /* 35 MIC1 level */ | ||
117 | 0x00, /* 36 MIC2 level */ | ||
118 | 0x00, /* 37 INA level */ | ||
119 | 0x00, /* 38 INB level */ | ||
120 | 0x00, /* 39 left HP volume */ | ||
121 | 0x00, /* 3A right HP volume */ | ||
122 | 0x00, /* 3B left REC volume */ | ||
123 | 0x00, /* 3C right REC volume */ | ||
124 | 0x00, /* 3D left SPK volume */ | ||
125 | 0x00, /* 3E right SPK volume */ | ||
126 | 0x00, /* 3F MIC config */ | ||
127 | |||
128 | 0x00, /* 40 MIC threshold */ | ||
129 | 0x00, /* 41 excursion limiter filter */ | ||
130 | 0x00, /* 42 excursion limiter threshold */ | ||
131 | 0x00, /* 43 ALC */ | ||
132 | 0x00, /* 44 power limiter threshold */ | ||
133 | 0x00, /* 45 power limiter config */ | ||
134 | 0x00, /* 46 distortion limiter config */ | ||
135 | 0x00, /* 47 audio input */ | ||
136 | 0x00, /* 48 microphone */ | ||
137 | 0x00, /* 49 level control */ | ||
138 | 0x00, /* 4A bypass switches */ | ||
139 | 0x00, /* 4B jack detect */ | ||
140 | 0x00, /* 4C input enable */ | ||
141 | 0x00, /* 4D output enable */ | ||
142 | 0xF0, /* 4E bias control */ | ||
143 | 0x00, /* 4F DAC power */ | ||
144 | |||
145 | 0x0F, /* 50 DAC power */ | ||
146 | 0x00, /* 51 system */ | ||
147 | 0x00, /* 52 DAI1 EQ1 */ | ||
148 | 0x00, /* 53 DAI1 EQ1 */ | ||
149 | 0x00, /* 54 DAI1 EQ1 */ | ||
150 | 0x00, /* 55 DAI1 EQ1 */ | ||
151 | 0x00, /* 56 DAI1 EQ1 */ | ||
152 | 0x00, /* 57 DAI1 EQ1 */ | ||
153 | 0x00, /* 58 DAI1 EQ1 */ | ||
154 | 0x00, /* 59 DAI1 EQ1 */ | ||
155 | 0x00, /* 5A DAI1 EQ1 */ | ||
156 | 0x00, /* 5B DAI1 EQ1 */ | ||
157 | 0x00, /* 5C DAI1 EQ2 */ | ||
158 | 0x00, /* 5D DAI1 EQ2 */ | ||
159 | 0x00, /* 5E DAI1 EQ2 */ | ||
160 | 0x00, /* 5F DAI1 EQ2 */ | ||
161 | |||
162 | 0x00, /* 60 DAI1 EQ2 */ | ||
163 | 0x00, /* 61 DAI1 EQ2 */ | ||
164 | 0x00, /* 62 DAI1 EQ2 */ | ||
165 | 0x00, /* 63 DAI1 EQ2 */ | ||
166 | 0x00, /* 64 DAI1 EQ2 */ | ||
167 | 0x00, /* 65 DAI1 EQ2 */ | ||
168 | 0x00, /* 66 DAI1 EQ3 */ | ||
169 | 0x00, /* 67 DAI1 EQ3 */ | ||
170 | 0x00, /* 68 DAI1 EQ3 */ | ||
171 | 0x00, /* 69 DAI1 EQ3 */ | ||
172 | 0x00, /* 6A DAI1 EQ3 */ | ||
173 | 0x00, /* 6B DAI1 EQ3 */ | ||
174 | 0x00, /* 6C DAI1 EQ3 */ | ||
175 | 0x00, /* 6D DAI1 EQ3 */ | ||
176 | 0x00, /* 6E DAI1 EQ3 */ | ||
177 | 0x00, /* 6F DAI1 EQ3 */ | ||
178 | |||
179 | 0x00, /* 70 DAI1 EQ4 */ | ||
180 | 0x00, /* 71 DAI1 EQ4 */ | ||
181 | 0x00, /* 72 DAI1 EQ4 */ | ||
182 | 0x00, /* 73 DAI1 EQ4 */ | ||
183 | 0x00, /* 74 DAI1 EQ4 */ | ||
184 | 0x00, /* 75 DAI1 EQ4 */ | ||
185 | 0x00, /* 76 DAI1 EQ4 */ | ||
186 | 0x00, /* 77 DAI1 EQ4 */ | ||
187 | 0x00, /* 78 DAI1 EQ4 */ | ||
188 | 0x00, /* 79 DAI1 EQ4 */ | ||
189 | 0x00, /* 7A DAI1 EQ5 */ | ||
190 | 0x00, /* 7B DAI1 EQ5 */ | ||
191 | 0x00, /* 7C DAI1 EQ5 */ | ||
192 | 0x00, /* 7D DAI1 EQ5 */ | ||
193 | 0x00, /* 7E DAI1 EQ5 */ | ||
194 | 0x00, /* 7F DAI1 EQ5 */ | ||
195 | |||
196 | 0x00, /* 80 DAI1 EQ5 */ | ||
197 | 0x00, /* 81 DAI1 EQ5 */ | ||
198 | 0x00, /* 82 DAI1 EQ5 */ | ||
199 | 0x00, /* 83 DAI1 EQ5 */ | ||
200 | 0x00, /* 84 DAI2 EQ1 */ | ||
201 | 0x00, /* 85 DAI2 EQ1 */ | ||
202 | 0x00, /* 86 DAI2 EQ1 */ | ||
203 | 0x00, /* 87 DAI2 EQ1 */ | ||
204 | 0x00, /* 88 DAI2 EQ1 */ | ||
205 | 0x00, /* 89 DAI2 EQ1 */ | ||
206 | 0x00, /* 8A DAI2 EQ1 */ | ||
207 | 0x00, /* 8B DAI2 EQ1 */ | ||
208 | 0x00, /* 8C DAI2 EQ1 */ | ||
209 | 0x00, /* 8D DAI2 EQ1 */ | ||
210 | 0x00, /* 8E DAI2 EQ2 */ | ||
211 | 0x00, /* 8F DAI2 EQ2 */ | ||
212 | |||
213 | 0x00, /* 90 DAI2 EQ2 */ | ||
214 | 0x00, /* 91 DAI2 EQ2 */ | ||
215 | 0x00, /* 92 DAI2 EQ2 */ | ||
216 | 0x00, /* 93 DAI2 EQ2 */ | ||
217 | 0x00, /* 94 DAI2 EQ2 */ | ||
218 | 0x00, /* 95 DAI2 EQ2 */ | ||
219 | 0x00, /* 96 DAI2 EQ2 */ | ||
220 | 0x00, /* 97 DAI2 EQ2 */ | ||
221 | 0x00, /* 98 DAI2 EQ3 */ | ||
222 | 0x00, /* 99 DAI2 EQ3 */ | ||
223 | 0x00, /* 9A DAI2 EQ3 */ | ||
224 | 0x00, /* 9B DAI2 EQ3 */ | ||
225 | 0x00, /* 9C DAI2 EQ3 */ | ||
226 | 0x00, /* 9D DAI2 EQ3 */ | ||
227 | 0x00, /* 9E DAI2 EQ3 */ | ||
228 | 0x00, /* 9F DAI2 EQ3 */ | ||
229 | |||
230 | 0x00, /* A0 DAI2 EQ3 */ | ||
231 | 0x00, /* A1 DAI2 EQ3 */ | ||
232 | 0x00, /* A2 DAI2 EQ4 */ | ||
233 | 0x00, /* A3 DAI2 EQ4 */ | ||
234 | 0x00, /* A4 DAI2 EQ4 */ | ||
235 | 0x00, /* A5 DAI2 EQ4 */ | ||
236 | 0x00, /* A6 DAI2 EQ4 */ | ||
237 | 0x00, /* A7 DAI2 EQ4 */ | ||
238 | 0x00, /* A8 DAI2 EQ4 */ | ||
239 | 0x00, /* A9 DAI2 EQ4 */ | ||
240 | 0x00, /* AA DAI2 EQ4 */ | ||
241 | 0x00, /* AB DAI2 EQ4 */ | ||
242 | 0x00, /* AC DAI2 EQ5 */ | ||
243 | 0x00, /* AD DAI2 EQ5 */ | ||
244 | 0x00, /* AE DAI2 EQ5 */ | ||
245 | 0x00, /* AF DAI2 EQ5 */ | ||
246 | |||
247 | 0x00, /* B0 DAI2 EQ5 */ | ||
248 | 0x00, /* B1 DAI2 EQ5 */ | ||
249 | 0x00, /* B2 DAI2 EQ5 */ | ||
250 | 0x00, /* B3 DAI2 EQ5 */ | ||
251 | 0x00, /* B4 DAI2 EQ5 */ | ||
252 | 0x00, /* B5 DAI2 EQ5 */ | ||
253 | 0x00, /* B6 DAI1 biquad */ | ||
254 | 0x00, /* B7 DAI1 biquad */ | ||
255 | 0x00, /* B8 DAI1 biquad */ | ||
256 | 0x00, /* B9 DAI1 biquad */ | ||
257 | 0x00, /* BA DAI1 biquad */ | ||
258 | 0x00, /* BB DAI1 biquad */ | ||
259 | 0x00, /* BC DAI1 biquad */ | ||
260 | 0x00, /* BD DAI1 biquad */ | ||
261 | 0x00, /* BE DAI1 biquad */ | ||
262 | 0x00, /* BF DAI1 biquad */ | ||
263 | |||
264 | 0x00, /* C0 DAI2 biquad */ | ||
265 | 0x00, /* C1 DAI2 biquad */ | ||
266 | 0x00, /* C2 DAI2 biquad */ | ||
267 | 0x00, /* C3 DAI2 biquad */ | ||
268 | 0x00, /* C4 DAI2 biquad */ | ||
269 | 0x00, /* C5 DAI2 biquad */ | ||
270 | 0x00, /* C6 DAI2 biquad */ | ||
271 | 0x00, /* C7 DAI2 biquad */ | ||
272 | 0x00, /* C8 DAI2 biquad */ | ||
273 | 0x00, /* C9 DAI2 biquad */ | ||
274 | 0x00, /* CA */ | ||
275 | 0x00, /* CB */ | ||
276 | 0x00, /* CC */ | ||
277 | 0x00, /* CD */ | ||
278 | 0x00, /* CE */ | ||
279 | 0x00, /* CF */ | ||
280 | |||
281 | 0x00, /* D0 */ | ||
282 | 0x00, /* D1 */ | ||
283 | 0x00, /* D2 */ | ||
284 | 0x00, /* D3 */ | ||
285 | 0x00, /* D4 */ | ||
286 | 0x00, /* D5 */ | ||
287 | 0x00, /* D6 */ | ||
288 | 0x00, /* D7 */ | ||
289 | 0x00, /* D8 */ | ||
290 | 0x00, /* D9 */ | ||
291 | 0x00, /* DA */ | ||
292 | 0x70, /* DB */ | ||
293 | 0x00, /* DC */ | ||
294 | 0x00, /* DD */ | ||
295 | 0x00, /* DE */ | ||
296 | 0x00, /* DF */ | ||
297 | |||
298 | 0x00, /* E0 */ | ||
299 | 0x00, /* E1 */ | ||
300 | 0x00, /* E2 */ | ||
301 | 0x00, /* E3 */ | ||
302 | 0x00, /* E4 */ | ||
303 | 0x00, /* E5 */ | ||
304 | 0x00, /* E6 */ | ||
305 | 0x00, /* E7 */ | ||
306 | 0x00, /* E8 */ | ||
307 | 0x00, /* E9 */ | ||
308 | 0x00, /* EA */ | ||
309 | 0x00, /* EB */ | ||
310 | 0x00, /* EC */ | ||
311 | 0x00, /* ED */ | ||
312 | 0x00, /* EE */ | ||
313 | 0x00, /* EF */ | ||
314 | |||
315 | 0x00, /* F0 */ | ||
316 | 0x00, /* F1 */ | ||
317 | 0x00, /* F2 */ | ||
318 | 0x00, /* F3 */ | ||
319 | 0x00, /* F4 */ | ||
320 | 0x00, /* F5 */ | ||
321 | 0x00, /* F6 */ | ||
322 | 0x00, /* F7 */ | ||
323 | 0x00, /* F8 */ | ||
324 | 0x00, /* F9 */ | ||
325 | 0x00, /* FA */ | ||
326 | 0x00, /* FB */ | ||
327 | 0x00, /* FC */ | ||
328 | 0x00, /* FD */ | ||
329 | 0x00, /* FE */ | ||
330 | 0x00, /* FF */ | ||
331 | }; | ||
332 | |||
333 | static struct { | ||
334 | int readable; | ||
335 | int writable; | ||
336 | int vol; | ||
337 | } max98088_access[M98088_REG_CNT] = { | ||
338 | { 0xFF, 0xFF, 1 }, /* 00 IRQ status */ | ||
339 | { 0xFF, 0x00, 1 }, /* 01 MIC status */ | ||
340 | { 0xFF, 0x00, 1 }, /* 02 jack status */ | ||
341 | { 0x1F, 0x1F, 1 }, /* 03 battery voltage */ | ||
342 | { 0xFF, 0xFF, 0 }, /* 04 */ | ||
343 | { 0xFF, 0xFF, 0 }, /* 05 */ | ||
344 | { 0xFF, 0xFF, 0 }, /* 06 */ | ||
345 | { 0xFF, 0xFF, 0 }, /* 07 */ | ||
346 | { 0xFF, 0xFF, 0 }, /* 08 */ | ||
347 | { 0xFF, 0xFF, 0 }, /* 09 */ | ||
348 | { 0xFF, 0xFF, 0 }, /* 0A */ | ||
349 | { 0xFF, 0xFF, 0 }, /* 0B */ | ||
350 | { 0xFF, 0xFF, 0 }, /* 0C */ | ||
351 | { 0xFF, 0xFF, 0 }, /* 0D */ | ||
352 | { 0xFF, 0xFF, 0 }, /* 0E */ | ||
353 | { 0xFF, 0xFF, 0 }, /* 0F interrupt enable */ | ||
354 | |||
355 | { 0xFF, 0xFF, 0 }, /* 10 master clock */ | ||
356 | { 0xFF, 0xFF, 0 }, /* 11 DAI1 clock mode */ | ||
357 | { 0xFF, 0xFF, 0 }, /* 12 DAI1 clock control */ | ||
358 | { 0xFF, 0xFF, 0 }, /* 13 DAI1 clock control */ | ||
359 | { 0xFF, 0xFF, 0 }, /* 14 DAI1 format */ | ||
360 | { 0xFF, 0xFF, 0 }, /* 15 DAI1 clock */ | ||
361 | { 0xFF, 0xFF, 0 }, /* 16 DAI1 config */ | ||
362 | { 0xFF, 0xFF, 0 }, /* 17 DAI1 TDM */ | ||
363 | { 0xFF, 0xFF, 0 }, /* 18 DAI1 filters */ | ||
364 | { 0xFF, 0xFF, 0 }, /* 19 DAI2 clock mode */ | ||
365 | { 0xFF, 0xFF, 0 }, /* 1A DAI2 clock control */ | ||
366 | { 0xFF, 0xFF, 0 }, /* 1B DAI2 clock control */ | ||
367 | { 0xFF, 0xFF, 0 }, /* 1C DAI2 format */ | ||
368 | { 0xFF, 0xFF, 0 }, /* 1D DAI2 clock */ | ||
369 | { 0xFF, 0xFF, 0 }, /* 1E DAI2 config */ | ||
370 | { 0xFF, 0xFF, 0 }, /* 1F DAI2 TDM */ | ||
371 | |||
372 | { 0xFF, 0xFF, 0 }, /* 20 DAI2 filters */ | ||
373 | { 0xFF, 0xFF, 0 }, /* 21 data config */ | ||
374 | { 0xFF, 0xFF, 0 }, /* 22 DAC mixer */ | ||
375 | { 0xFF, 0xFF, 0 }, /* 23 left ADC mixer */ | ||
376 | { 0xFF, 0xFF, 0 }, /* 24 right ADC mixer */ | ||
377 | { 0xFF, 0xFF, 0 }, /* 25 left HP mixer */ | ||
378 | { 0xFF, 0xFF, 0 }, /* 26 right HP mixer */ | ||
379 | { 0xFF, 0xFF, 0 }, /* 27 HP control */ | ||
380 | { 0xFF, 0xFF, 0 }, /* 28 left REC mixer */ | ||
381 | { 0xFF, 0xFF, 0 }, /* 29 right REC mixer */ | ||
382 | { 0xFF, 0xFF, 0 }, /* 2A REC control */ | ||
383 | { 0xFF, 0xFF, 0 }, /* 2B left SPK mixer */ | ||
384 | { 0xFF, 0xFF, 0 }, /* 2C right SPK mixer */ | ||
385 | { 0xFF, 0xFF, 0 }, /* 2D SPK control */ | ||
386 | { 0xFF, 0xFF, 0 }, /* 2E sidetone */ | ||
387 | { 0xFF, 0xFF, 0 }, /* 2F DAI1 playback level */ | ||
388 | |||
389 | { 0xFF, 0xFF, 0 }, /* 30 DAI1 playback level */ | ||
390 | { 0xFF, 0xFF, 0 }, /* 31 DAI2 playback level */ | ||
391 | { 0xFF, 0xFF, 0 }, /* 32 DAI2 playbakc level */ | ||
392 | { 0xFF, 0xFF, 0 }, /* 33 left ADC level */ | ||
393 | { 0xFF, 0xFF, 0 }, /* 34 right ADC level */ | ||
394 | { 0xFF, 0xFF, 0 }, /* 35 MIC1 level */ | ||
395 | { 0xFF, 0xFF, 0 }, /* 36 MIC2 level */ | ||
396 | { 0xFF, 0xFF, 0 }, /* 37 INA level */ | ||
397 | { 0xFF, 0xFF, 0 }, /* 38 INB level */ | ||
398 | { 0xFF, 0xFF, 0 }, /* 39 left HP volume */ | ||
399 | { 0xFF, 0xFF, 0 }, /* 3A right HP volume */ | ||
400 | { 0xFF, 0xFF, 0 }, /* 3B left REC volume */ | ||
401 | { 0xFF, 0xFF, 0 }, /* 3C right REC volume */ | ||
402 | { 0xFF, 0xFF, 0 }, /* 3D left SPK volume */ | ||
403 | { 0xFF, 0xFF, 0 }, /* 3E right SPK volume */ | ||
404 | { 0xFF, 0xFF, 0 }, /* 3F MIC config */ | ||
405 | |||
406 | { 0xFF, 0xFF, 0 }, /* 40 MIC threshold */ | ||
407 | { 0xFF, 0xFF, 0 }, /* 41 excursion limiter filter */ | ||
408 | { 0xFF, 0xFF, 0 }, /* 42 excursion limiter threshold */ | ||
409 | { 0xFF, 0xFF, 0 }, /* 43 ALC */ | ||
410 | { 0xFF, 0xFF, 0 }, /* 44 power limiter threshold */ | ||
411 | { 0xFF, 0xFF, 0 }, /* 45 power limiter config */ | ||
412 | { 0xFF, 0xFF, 0 }, /* 46 distortion limiter config */ | ||
413 | { 0xFF, 0xFF, 0 }, /* 47 audio input */ | ||
414 | { 0xFF, 0xFF, 0 }, /* 48 microphone */ | ||
415 | { 0xFF, 0xFF, 0 }, /* 49 level control */ | ||
416 | { 0xFF, 0xFF, 0 }, /* 4A bypass switches */ | ||
417 | { 0xFF, 0xFF, 0 }, /* 4B jack detect */ | ||
418 | { 0xFF, 0xFF, 0 }, /* 4C input enable */ | ||
419 | { 0xFF, 0xFF, 0 }, /* 4D output enable */ | ||
420 | { 0xFF, 0xFF, 0 }, /* 4E bias control */ | ||
421 | { 0xFF, 0xFF, 0 }, /* 4F DAC power */ | ||
422 | |||
423 | { 0xFF, 0xFF, 0 }, /* 50 DAC power */ | ||
424 | { 0xFF, 0xFF, 0 }, /* 51 system */ | ||
425 | { 0xFF, 0xFF, 0 }, /* 52 DAI1 EQ1 */ | ||
426 | { 0xFF, 0xFF, 0 }, /* 53 DAI1 EQ1 */ | ||
427 | { 0xFF, 0xFF, 0 }, /* 54 DAI1 EQ1 */ | ||
428 | { 0xFF, 0xFF, 0 }, /* 55 DAI1 EQ1 */ | ||
429 | { 0xFF, 0xFF, 0 }, /* 56 DAI1 EQ1 */ | ||
430 | { 0xFF, 0xFF, 0 }, /* 57 DAI1 EQ1 */ | ||
431 | { 0xFF, 0xFF, 0 }, /* 58 DAI1 EQ1 */ | ||
432 | { 0xFF, 0xFF, 0 }, /* 59 DAI1 EQ1 */ | ||
433 | { 0xFF, 0xFF, 0 }, /* 5A DAI1 EQ1 */ | ||
434 | { 0xFF, 0xFF, 0 }, /* 5B DAI1 EQ1 */ | ||
435 | { 0xFF, 0xFF, 0 }, /* 5C DAI1 EQ2 */ | ||
436 | { 0xFF, 0xFF, 0 }, /* 5D DAI1 EQ2 */ | ||
437 | { 0xFF, 0xFF, 0 }, /* 5E DAI1 EQ2 */ | ||
438 | { 0xFF, 0xFF, 0 }, /* 5F DAI1 EQ2 */ | ||
439 | |||
440 | { 0xFF, 0xFF, 0 }, /* 60 DAI1 EQ2 */ | ||
441 | { 0xFF, 0xFF, 0 }, /* 61 DAI1 EQ2 */ | ||
442 | { 0xFF, 0xFF, 0 }, /* 62 DAI1 EQ2 */ | ||
443 | { 0xFF, 0xFF, 0 }, /* 63 DAI1 EQ2 */ | ||
444 | { 0xFF, 0xFF, 0 }, /* 64 DAI1 EQ2 */ | ||
445 | { 0xFF, 0xFF, 0 }, /* 65 DAI1 EQ2 */ | ||
446 | { 0xFF, 0xFF, 0 }, /* 66 DAI1 EQ3 */ | ||
447 | { 0xFF, 0xFF, 0 }, /* 67 DAI1 EQ3 */ | ||
448 | { 0xFF, 0xFF, 0 }, /* 68 DAI1 EQ3 */ | ||
449 | { 0xFF, 0xFF, 0 }, /* 69 DAI1 EQ3 */ | ||
450 | { 0xFF, 0xFF, 0 }, /* 6A DAI1 EQ3 */ | ||
451 | { 0xFF, 0xFF, 0 }, /* 6B DAI1 EQ3 */ | ||
452 | { 0xFF, 0xFF, 0 }, /* 6C DAI1 EQ3 */ | ||
453 | { 0xFF, 0xFF, 0 }, /* 6D DAI1 EQ3 */ | ||
454 | { 0xFF, 0xFF, 0 }, /* 6E DAI1 EQ3 */ | ||
455 | { 0xFF, 0xFF, 0 }, /* 6F DAI1 EQ3 */ | ||
456 | |||
457 | { 0xFF, 0xFF, 0 }, /* 70 DAI1 EQ4 */ | ||
458 | { 0xFF, 0xFF, 0 }, /* 71 DAI1 EQ4 */ | ||
459 | { 0xFF, 0xFF, 0 }, /* 72 DAI1 EQ4 */ | ||
460 | { 0xFF, 0xFF, 0 }, /* 73 DAI1 EQ4 */ | ||
461 | { 0xFF, 0xFF, 0 }, /* 74 DAI1 EQ4 */ | ||
462 | { 0xFF, 0xFF, 0 }, /* 75 DAI1 EQ4 */ | ||
463 | { 0xFF, 0xFF, 0 }, /* 76 DAI1 EQ4 */ | ||
464 | { 0xFF, 0xFF, 0 }, /* 77 DAI1 EQ4 */ | ||
465 | { 0xFF, 0xFF, 0 }, /* 78 DAI1 EQ4 */ | ||
466 | { 0xFF, 0xFF, 0 }, /* 79 DAI1 EQ4 */ | ||
467 | { 0xFF, 0xFF, 0 }, /* 7A DAI1 EQ5 */ | ||
468 | { 0xFF, 0xFF, 0 }, /* 7B DAI1 EQ5 */ | ||
469 | { 0xFF, 0xFF, 0 }, /* 7C DAI1 EQ5 */ | ||
470 | { 0xFF, 0xFF, 0 }, /* 7D DAI1 EQ5 */ | ||
471 | { 0xFF, 0xFF, 0 }, /* 7E DAI1 EQ5 */ | ||
472 | { 0xFF, 0xFF, 0 }, /* 7F DAI1 EQ5 */ | ||
473 | |||
474 | { 0xFF, 0xFF, 0 }, /* 80 DAI1 EQ5 */ | ||
475 | { 0xFF, 0xFF, 0 }, /* 81 DAI1 EQ5 */ | ||
476 | { 0xFF, 0xFF, 0 }, /* 82 DAI1 EQ5 */ | ||
477 | { 0xFF, 0xFF, 0 }, /* 83 DAI1 EQ5 */ | ||
478 | { 0xFF, 0xFF, 0 }, /* 84 DAI2 EQ1 */ | ||
479 | { 0xFF, 0xFF, 0 }, /* 85 DAI2 EQ1 */ | ||
480 | { 0xFF, 0xFF, 0 }, /* 86 DAI2 EQ1 */ | ||
481 | { 0xFF, 0xFF, 0 }, /* 87 DAI2 EQ1 */ | ||
482 | { 0xFF, 0xFF, 0 }, /* 88 DAI2 EQ1 */ | ||
483 | { 0xFF, 0xFF, 0 }, /* 89 DAI2 EQ1 */ | ||
484 | { 0xFF, 0xFF, 0 }, /* 8A DAI2 EQ1 */ | ||
485 | { 0xFF, 0xFF, 0 }, /* 8B DAI2 EQ1 */ | ||
486 | { 0xFF, 0xFF, 0 }, /* 8C DAI2 EQ1 */ | ||
487 | { 0xFF, 0xFF, 0 }, /* 8D DAI2 EQ1 */ | ||
488 | { 0xFF, 0xFF, 0 }, /* 8E DAI2 EQ2 */ | ||
489 | { 0xFF, 0xFF, 0 }, /* 8F DAI2 EQ2 */ | ||
490 | |||
491 | { 0xFF, 0xFF, 0 }, /* 90 DAI2 EQ2 */ | ||
492 | { 0xFF, 0xFF, 0 }, /* 91 DAI2 EQ2 */ | ||
493 | { 0xFF, 0xFF, 0 }, /* 92 DAI2 EQ2 */ | ||
494 | { 0xFF, 0xFF, 0 }, /* 93 DAI2 EQ2 */ | ||
495 | { 0xFF, 0xFF, 0 }, /* 94 DAI2 EQ2 */ | ||
496 | { 0xFF, 0xFF, 0 }, /* 95 DAI2 EQ2 */ | ||
497 | { 0xFF, 0xFF, 0 }, /* 96 DAI2 EQ2 */ | ||
498 | { 0xFF, 0xFF, 0 }, /* 97 DAI2 EQ2 */ | ||
499 | { 0xFF, 0xFF, 0 }, /* 98 DAI2 EQ3 */ | ||
500 | { 0xFF, 0xFF, 0 }, /* 99 DAI2 EQ3 */ | ||
501 | { 0xFF, 0xFF, 0 }, /* 9A DAI2 EQ3 */ | ||
502 | { 0xFF, 0xFF, 0 }, /* 9B DAI2 EQ3 */ | ||
503 | { 0xFF, 0xFF, 0 }, /* 9C DAI2 EQ3 */ | ||
504 | { 0xFF, 0xFF, 0 }, /* 9D DAI2 EQ3 */ | ||
505 | { 0xFF, 0xFF, 0 }, /* 9E DAI2 EQ3 */ | ||
506 | { 0xFF, 0xFF, 0 }, /* 9F DAI2 EQ3 */ | ||
507 | |||
508 | { 0xFF, 0xFF, 0 }, /* A0 DAI2 EQ3 */ | ||
509 | { 0xFF, 0xFF, 0 }, /* A1 DAI2 EQ3 */ | ||
510 | { 0xFF, 0xFF, 0 }, /* A2 DAI2 EQ4 */ | ||
511 | { 0xFF, 0xFF, 0 }, /* A3 DAI2 EQ4 */ | ||
512 | { 0xFF, 0xFF, 0 }, /* A4 DAI2 EQ4 */ | ||
513 | { 0xFF, 0xFF, 0 }, /* A5 DAI2 EQ4 */ | ||
514 | { 0xFF, 0xFF, 0 }, /* A6 DAI2 EQ4 */ | ||
515 | { 0xFF, 0xFF, 0 }, /* A7 DAI2 EQ4 */ | ||
516 | { 0xFF, 0xFF, 0 }, /* A8 DAI2 EQ4 */ | ||
517 | { 0xFF, 0xFF, 0 }, /* A9 DAI2 EQ4 */ | ||
518 | { 0xFF, 0xFF, 0 }, /* AA DAI2 EQ4 */ | ||
519 | { 0xFF, 0xFF, 0 }, /* AB DAI2 EQ4 */ | ||
520 | { 0xFF, 0xFF, 0 }, /* AC DAI2 EQ5 */ | ||
521 | { 0xFF, 0xFF, 0 }, /* AD DAI2 EQ5 */ | ||
522 | { 0xFF, 0xFF, 0 }, /* AE DAI2 EQ5 */ | ||
523 | { 0xFF, 0xFF, 0 }, /* AF DAI2 EQ5 */ | ||
524 | |||
525 | { 0xFF, 0xFF, 0 }, /* B0 DAI2 EQ5 */ | ||
526 | { 0xFF, 0xFF, 0 }, /* B1 DAI2 EQ5 */ | ||
527 | { 0xFF, 0xFF, 0 }, /* B2 DAI2 EQ5 */ | ||
528 | { 0xFF, 0xFF, 0 }, /* B3 DAI2 EQ5 */ | ||
529 | { 0xFF, 0xFF, 0 }, /* B4 DAI2 EQ5 */ | ||
530 | { 0xFF, 0xFF, 0 }, /* B5 DAI2 EQ5 */ | ||
531 | { 0xFF, 0xFF, 0 }, /* B6 DAI1 biquad */ | ||
532 | { 0xFF, 0xFF, 0 }, /* B7 DAI1 biquad */ | ||
533 | { 0xFF, 0xFF, 0 }, /* B8 DAI1 biquad */ | ||
534 | { 0xFF, 0xFF, 0 }, /* B9 DAI1 biquad */ | ||
535 | { 0xFF, 0xFF, 0 }, /* BA DAI1 biquad */ | ||
536 | { 0xFF, 0xFF, 0 }, /* BB DAI1 biquad */ | ||
537 | { 0xFF, 0xFF, 0 }, /* BC DAI1 biquad */ | ||
538 | { 0xFF, 0xFF, 0 }, /* BD DAI1 biquad */ | ||
539 | { 0xFF, 0xFF, 0 }, /* BE DAI1 biquad */ | ||
540 | { 0xFF, 0xFF, 0 }, /* BF DAI1 biquad */ | ||
541 | |||
542 | { 0xFF, 0xFF, 0 }, /* C0 DAI2 biquad */ | ||
543 | { 0xFF, 0xFF, 0 }, /* C1 DAI2 biquad */ | ||
544 | { 0xFF, 0xFF, 0 }, /* C2 DAI2 biquad */ | ||
545 | { 0xFF, 0xFF, 0 }, /* C3 DAI2 biquad */ | ||
546 | { 0xFF, 0xFF, 0 }, /* C4 DAI2 biquad */ | ||
547 | { 0xFF, 0xFF, 0 }, /* C5 DAI2 biquad */ | ||
548 | { 0xFF, 0xFF, 0 }, /* C6 DAI2 biquad */ | ||
549 | { 0xFF, 0xFF, 0 }, /* C7 DAI2 biquad */ | ||
550 | { 0xFF, 0xFF, 0 }, /* C8 DAI2 biquad */ | ||
551 | { 0xFF, 0xFF, 0 }, /* C9 DAI2 biquad */ | ||
552 | { 0x00, 0x00, 0 }, /* CA */ | ||
553 | { 0x00, 0x00, 0 }, /* CB */ | ||
554 | { 0x00, 0x00, 0 }, /* CC */ | ||
555 | { 0x00, 0x00, 0 }, /* CD */ | ||
556 | { 0x00, 0x00, 0 }, /* CE */ | ||
557 | { 0x00, 0x00, 0 }, /* CF */ | ||
558 | |||
559 | { 0x00, 0x00, 0 }, /* D0 */ | ||
560 | { 0x00, 0x00, 0 }, /* D1 */ | ||
561 | { 0x00, 0x00, 0 }, /* D2 */ | ||
562 | { 0x00, 0x00, 0 }, /* D3 */ | ||
563 | { 0x00, 0x00, 0 }, /* D4 */ | ||
564 | { 0x00, 0x00, 0 }, /* D5 */ | ||
565 | { 0x00, 0x00, 0 }, /* D6 */ | ||
566 | { 0x00, 0x00, 0 }, /* D7 */ | ||
567 | { 0x00, 0x00, 0 }, /* D8 */ | ||
568 | { 0x00, 0x00, 0 }, /* D9 */ | ||
569 | { 0x00, 0x00, 0 }, /* DA */ | ||
570 | { 0x00, 0x00, 0 }, /* DB */ | ||
571 | { 0x00, 0x00, 0 }, /* DC */ | ||
572 | { 0x00, 0x00, 0 }, /* DD */ | ||
573 | { 0x00, 0x00, 0 }, /* DE */ | ||
574 | { 0x00, 0x00, 0 }, /* DF */ | ||
575 | |||
576 | { 0x00, 0x00, 0 }, /* E0 */ | ||
577 | { 0x00, 0x00, 0 }, /* E1 */ | ||
578 | { 0x00, 0x00, 0 }, /* E2 */ | ||
579 | { 0x00, 0x00, 0 }, /* E3 */ | ||
580 | { 0x00, 0x00, 0 }, /* E4 */ | ||
581 | { 0x00, 0x00, 0 }, /* E5 */ | ||
582 | { 0x00, 0x00, 0 }, /* E6 */ | ||
583 | { 0x00, 0x00, 0 }, /* E7 */ | ||
584 | { 0x00, 0x00, 0 }, /* E8 */ | ||
585 | { 0x00, 0x00, 0 }, /* E9 */ | ||
586 | { 0x00, 0x00, 0 }, /* EA */ | ||
587 | { 0x00, 0x00, 0 }, /* EB */ | ||
588 | { 0x00, 0x00, 0 }, /* EC */ | ||
589 | { 0x00, 0x00, 0 }, /* ED */ | ||
590 | { 0x00, 0x00, 0 }, /* EE */ | ||
591 | { 0x00, 0x00, 0 }, /* EF */ | ||
592 | |||
593 | { 0x00, 0x00, 0 }, /* F0 */ | ||
594 | { 0x00, 0x00, 0 }, /* F1 */ | ||
595 | { 0x00, 0x00, 0 }, /* F2 */ | ||
596 | { 0x00, 0x00, 0 }, /* F3 */ | ||
597 | { 0x00, 0x00, 0 }, /* F4 */ | ||
598 | { 0x00, 0x00, 0 }, /* F5 */ | ||
599 | { 0x00, 0x00, 0 }, /* F6 */ | ||
600 | { 0x00, 0x00, 0 }, /* F7 */ | ||
601 | { 0x00, 0x00, 0 }, /* F8 */ | ||
602 | { 0x00, 0x00, 0 }, /* F9 */ | ||
603 | { 0x00, 0x00, 0 }, /* FA */ | ||
604 | { 0x00, 0x00, 0 }, /* FB */ | ||
605 | { 0x00, 0x00, 0 }, /* FC */ | ||
606 | { 0x00, 0x00, 0 }, /* FD */ | ||
607 | { 0x00, 0x00, 0 }, /* FE */ | ||
608 | { 0xFF, 0x00, 1 }, /* FF */ | ||
609 | }; | ||
610 | |||
611 | static int max98088_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | ||
612 | { | ||
613 | return max98088_access[reg].vol; | ||
614 | } | ||
615 | |||
616 | |||
617 | /* | ||
618 | * Load equalizer DSP coefficient configurations registers | ||
619 | */ | ||
620 | static void m98088_eq_band(struct snd_soc_codec *codec, unsigned int dai, | ||
621 | unsigned int band, u16 *coefs) | ||
622 | { | ||
623 | unsigned int eq_reg; | ||
624 | unsigned int i; | ||
625 | |||
626 | BUG_ON(band > 4); | ||
627 | BUG_ON(dai > 1); | ||
628 | |||
629 | /* Load the base register address */ | ||
630 | eq_reg = dai ? M98088_REG_84_DAI2_EQ_BASE : M98088_REG_52_DAI1_EQ_BASE; | ||
631 | |||
632 | /* Add the band address offset, note adjustment for word address */ | ||
633 | eq_reg += band * (M98088_COEFS_PER_BAND << 1); | ||
634 | |||
635 | /* Step through the registers and coefs */ | ||
636 | for (i = 0; i < M98088_COEFS_PER_BAND; i++) { | ||
637 | snd_soc_write(codec, eq_reg++, M98088_BYTE1(coefs[i])); | ||
638 | snd_soc_write(codec, eq_reg++, M98088_BYTE0(coefs[i])); | ||
639 | } | ||
640 | } | ||
641 | |||
642 | /* | ||
643 | * Excursion limiter modes | ||
644 | */ | ||
645 | static const char *max98088_exmode_texts[] = { | ||
646 | "Off", "100Hz", "400Hz", "600Hz", "800Hz", "1000Hz", "200-400Hz", | ||
647 | "400-600Hz", "400-800Hz", | ||
648 | }; | ||
649 | |||
650 | static const unsigned int max98088_exmode_values[] = { | ||
651 | 0x00, 0x43, 0x10, 0x20, 0x30, 0x40, 0x11, 0x22, 0x32 | ||
652 | }; | ||
653 | |||
654 | static const struct soc_enum max98088_exmode_enum = | ||
655 | SOC_VALUE_ENUM_SINGLE(M98088_REG_41_SPKDHP, 0, 127, | ||
656 | ARRAY_SIZE(max98088_exmode_texts), | ||
657 | max98088_exmode_texts, | ||
658 | max98088_exmode_values); | ||
659 | |||
660 | static const char *max98088_ex_thresh[] = { /* volts PP */ | ||
661 | "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"}; | ||
662 | static const struct soc_enum max98088_ex_thresh_enum[] = { | ||
663 | SOC_ENUM_SINGLE(M98088_REG_42_SPKDHP_THRESH, 0, 8, | ||
664 | max98088_ex_thresh), | ||
665 | }; | ||
666 | |||
667 | static const char *max98088_fltr_mode[] = {"Voice", "Music" }; | ||
668 | static const struct soc_enum max98088_filter_mode_enum[] = { | ||
669 | SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 7, 2, max98088_fltr_mode), | ||
670 | }; | ||
671 | |||
672 | static const char *max98088_extmic_text[] = { "None", "MIC1", "MIC2" }; | ||
673 | |||
674 | static const struct soc_enum max98088_extmic_enum = | ||
675 | SOC_ENUM_SINGLE(M98088_REG_48_CFG_MIC, 0, 3, max98088_extmic_text); | ||
676 | |||
677 | static const struct snd_kcontrol_new max98088_extmic_mux = | ||
678 | SOC_DAPM_ENUM("External MIC Mux", max98088_extmic_enum); | ||
679 | |||
680 | static const char *max98088_dai1_fltr[] = { | ||
681 | "Off", "fc=258/fs=16k", "fc=500/fs=16k", | ||
682 | "fc=258/fs=8k", "fc=500/fs=8k", "fc=200"}; | ||
683 | static const struct soc_enum max98088_dai1_dac_filter_enum[] = { | ||
684 | SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 0, 6, max98088_dai1_fltr), | ||
685 | }; | ||
686 | static const struct soc_enum max98088_dai1_adc_filter_enum[] = { | ||
687 | SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 4, 6, max98088_dai1_fltr), | ||
688 | }; | ||
689 | |||
690 | static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, | ||
691 | struct snd_ctl_elem_value *ucontrol) | ||
692 | { | ||
693 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
694 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
695 | unsigned int sel = ucontrol->value.integer.value[0]; | ||
696 | |||
697 | max98088->mic1pre = sel; | ||
698 | snd_soc_update_bits(codec, M98088_REG_35_LVL_MIC1, M98088_MICPRE_MASK, | ||
699 | (1+sel)<<M98088_MICPRE_SHIFT); | ||
700 | |||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol, | ||
705 | struct snd_ctl_elem_value *ucontrol) | ||
706 | { | ||
707 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
708 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
709 | |||
710 | ucontrol->value.integer.value[0] = max98088->mic1pre; | ||
711 | return 0; | ||
712 | } | ||
713 | |||
714 | static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol, | ||
715 | struct snd_ctl_elem_value *ucontrol) | ||
716 | { | ||
717 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
718 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
719 | unsigned int sel = ucontrol->value.integer.value[0]; | ||
720 | |||
721 | max98088->mic2pre = sel; | ||
722 | snd_soc_update_bits(codec, M98088_REG_36_LVL_MIC2, M98088_MICPRE_MASK, | ||
723 | (1+sel)<<M98088_MICPRE_SHIFT); | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol, | ||
729 | struct snd_ctl_elem_value *ucontrol) | ||
730 | { | ||
731 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
732 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
733 | |||
734 | ucontrol->value.integer.value[0] = max98088->mic2pre; | ||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | static const unsigned int max98088_micboost_tlv[] = { | ||
739 | TLV_DB_RANGE_HEAD(2), | ||
740 | 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), | ||
741 | 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), | ||
742 | }; | ||
743 | |||
744 | static const struct snd_kcontrol_new max98088_snd_controls[] = { | ||
745 | |||
746 | SOC_DOUBLE_R("Headphone Volume", M98088_REG_39_LVL_HP_L, | ||
747 | M98088_REG_3A_LVL_HP_R, 0, 31, 0), | ||
748 | SOC_DOUBLE_R("Speaker Volume", M98088_REG_3D_LVL_SPK_L, | ||
749 | M98088_REG_3E_LVL_SPK_R, 0, 31, 0), | ||
750 | SOC_DOUBLE_R("Receiver Volume", M98088_REG_3B_LVL_REC_L, | ||
751 | M98088_REG_3C_LVL_REC_R, 0, 31, 0), | ||
752 | |||
753 | SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L, | ||
754 | M98088_REG_3A_LVL_HP_R, 7, 1, 1), | ||
755 | SOC_DOUBLE_R("Speaker Switch", M98088_REG_3D_LVL_SPK_L, | ||
756 | M98088_REG_3E_LVL_SPK_R, 7, 1, 1), | ||
757 | SOC_DOUBLE_R("Receiver Switch", M98088_REG_3B_LVL_REC_L, | ||
758 | M98088_REG_3C_LVL_REC_R, 7, 1, 1), | ||
759 | |||
760 | SOC_SINGLE("MIC1 Volume", M98088_REG_35_LVL_MIC1, 0, 31, 1), | ||
761 | SOC_SINGLE("MIC2 Volume", M98088_REG_36_LVL_MIC2, 0, 31, 1), | ||
762 | |||
763 | SOC_SINGLE_EXT_TLV("MIC1 Boost Volume", | ||
764 | M98088_REG_35_LVL_MIC1, 5, 2, 0, | ||
765 | max98088_mic1pre_get, max98088_mic1pre_set, | ||
766 | max98088_micboost_tlv), | ||
767 | SOC_SINGLE_EXT_TLV("MIC2 Boost Volume", | ||
768 | M98088_REG_36_LVL_MIC2, 5, 2, 0, | ||
769 | max98088_mic2pre_get, max98088_mic2pre_set, | ||
770 | max98088_micboost_tlv), | ||
771 | |||
772 | SOC_SINGLE("INA Volume", M98088_REG_37_LVL_INA, 0, 7, 1), | ||
773 | SOC_SINGLE("INB Volume", M98088_REG_38_LVL_INB, 0, 7, 1), | ||
774 | |||
775 | SOC_SINGLE("ADCL Volume", M98088_REG_33_LVL_ADC_L, 0, 15, 0), | ||
776 | SOC_SINGLE("ADCR Volume", M98088_REG_34_LVL_ADC_R, 0, 15, 0), | ||
777 | |||
778 | SOC_SINGLE("ADCL Boost Volume", M98088_REG_33_LVL_ADC_L, 4, 3, 0), | ||
779 | SOC_SINGLE("ADCR Boost Volume", M98088_REG_34_LVL_ADC_R, 4, 3, 0), | ||
780 | |||
781 | SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0), | ||
782 | SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0), | ||
783 | |||
784 | SOC_ENUM("EX Limiter Mode", max98088_exmode_enum), | ||
785 | SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum), | ||
786 | |||
787 | SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum), | ||
788 | SOC_ENUM("DAI1 DAC Filter", max98088_dai1_dac_filter_enum), | ||
789 | SOC_ENUM("DAI1 ADC Filter", max98088_dai1_adc_filter_enum), | ||
790 | SOC_SINGLE("DAI2 DC Block Switch", M98088_REG_20_DAI2_FILTERS, | ||
791 | 0, 1, 0), | ||
792 | |||
793 | SOC_SINGLE("ALC Switch", M98088_REG_43_SPKALC_COMP, 7, 1, 0), | ||
794 | SOC_SINGLE("ALC Threshold", M98088_REG_43_SPKALC_COMP, 0, 7, 0), | ||
795 | SOC_SINGLE("ALC Multiband", M98088_REG_43_SPKALC_COMP, 3, 1, 0), | ||
796 | SOC_SINGLE("ALC Release Time", M98088_REG_43_SPKALC_COMP, 4, 7, 0), | ||
797 | |||
798 | SOC_SINGLE("PWR Limiter Threshold", M98088_REG_44_PWRLMT_CFG, | ||
799 | 4, 15, 0), | ||
800 | SOC_SINGLE("PWR Limiter Weight", M98088_REG_44_PWRLMT_CFG, 0, 7, 0), | ||
801 | SOC_SINGLE("PWR Limiter Time1", M98088_REG_45_PWRLMT_TIME, 0, 15, 0), | ||
802 | SOC_SINGLE("PWR Limiter Time2", M98088_REG_45_PWRLMT_TIME, 4, 15, 0), | ||
803 | |||
804 | SOC_SINGLE("THD Limiter Threshold", M98088_REG_46_THDLMT_CFG, 4, 15, 0), | ||
805 | SOC_SINGLE("THD Limiter Time", M98088_REG_46_THDLMT_CFG, 0, 7, 0), | ||
806 | }; | ||
807 | |||
808 | /* Left speaker mixer switch */ | ||
809 | static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = { | ||
810 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), | ||
811 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), | ||
812 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0), | ||
813 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0), | ||
814 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0), | ||
815 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0), | ||
816 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0), | ||
817 | SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 2, 1, 0), | ||
818 | SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 3, 1, 0), | ||
819 | SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 4, 1, 0), | ||
820 | }; | ||
821 | |||
822 | /* Right speaker mixer switch */ | ||
823 | static const struct snd_kcontrol_new max98088_right_speaker_mixer_controls[] = { | ||
824 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 7, 1, 0), | ||
825 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 0, 1, 0), | ||
826 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 7, 1, 0), | ||
827 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 0, 1, 0), | ||
828 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 5, 1, 0), | ||
829 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 6, 1, 0), | ||
830 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 1, 1, 0), | ||
831 | SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 2, 1, 0), | ||
832 | SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 3, 1, 0), | ||
833 | SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 4, 1, 0), | ||
834 | }; | ||
835 | |||
836 | /* Left headphone mixer switch */ | ||
837 | static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = { | ||
838 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), | ||
839 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), | ||
840 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0), | ||
841 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0), | ||
842 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0), | ||
843 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0), | ||
844 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0), | ||
845 | SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_25_MIX_HP_LEFT, 2, 1, 0), | ||
846 | SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_25_MIX_HP_LEFT, 3, 1, 0), | ||
847 | SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_25_MIX_HP_LEFT, 4, 1, 0), | ||
848 | }; | ||
849 | |||
850 | /* Right headphone mixer switch */ | ||
851 | static const struct snd_kcontrol_new max98088_right_hp_mixer_controls[] = { | ||
852 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 7, 1, 0), | ||
853 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 0, 1, 0), | ||
854 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 7, 1, 0), | ||
855 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 0, 1, 0), | ||
856 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 5, 1, 0), | ||
857 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 6, 1, 0), | ||
858 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_26_MIX_HP_RIGHT, 1, 1, 0), | ||
859 | SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_26_MIX_HP_RIGHT, 2, 1, 0), | ||
860 | SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_26_MIX_HP_RIGHT, 3, 1, 0), | ||
861 | SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_26_MIX_HP_RIGHT, 4, 1, 0), | ||
862 | }; | ||
863 | |||
864 | /* Left earpiece/receiver mixer switch */ | ||
865 | static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = { | ||
866 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), | ||
867 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), | ||
868 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0), | ||
869 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0), | ||
870 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0), | ||
871 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0), | ||
872 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0), | ||
873 | SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_28_MIX_REC_LEFT, 2, 1, 0), | ||
874 | SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_28_MIX_REC_LEFT, 3, 1, 0), | ||
875 | SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_28_MIX_REC_LEFT, 4, 1, 0), | ||
876 | }; | ||
877 | |||
878 | /* Right earpiece/receiver mixer switch */ | ||
879 | static const struct snd_kcontrol_new max98088_right_rec_mixer_controls[] = { | ||
880 | SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 7, 1, 0), | ||
881 | SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 0, 1, 0), | ||
882 | SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 7, 1, 0), | ||
883 | SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 0, 1, 0), | ||
884 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 5, 1, 0), | ||
885 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 6, 1, 0), | ||
886 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_29_MIX_REC_RIGHT, 1, 1, 0), | ||
887 | SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_29_MIX_REC_RIGHT, 2, 1, 0), | ||
888 | SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_29_MIX_REC_RIGHT, 3, 1, 0), | ||
889 | SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_29_MIX_REC_RIGHT, 4, 1, 0), | ||
890 | }; | ||
891 | |||
892 | /* Left ADC mixer switch */ | ||
893 | static const struct snd_kcontrol_new max98088_left_ADC_mixer_controls[] = { | ||
894 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_23_MIX_ADC_LEFT, 7, 1, 0), | ||
895 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_23_MIX_ADC_LEFT, 6, 1, 0), | ||
896 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_23_MIX_ADC_LEFT, 3, 1, 0), | ||
897 | SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_23_MIX_ADC_LEFT, 2, 1, 0), | ||
898 | SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_23_MIX_ADC_LEFT, 1, 1, 0), | ||
899 | SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_23_MIX_ADC_LEFT, 0, 1, 0), | ||
900 | }; | ||
901 | |||
902 | /* Right ADC mixer switch */ | ||
903 | static const struct snd_kcontrol_new max98088_right_ADC_mixer_controls[] = { | ||
904 | SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 7, 1, 0), | ||
905 | SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 6, 1, 0), | ||
906 | SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 3, 1, 0), | ||
907 | SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 2, 1, 0), | ||
908 | SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 1, 1, 0), | ||
909 | SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 0, 1, 0), | ||
910 | }; | ||
911 | |||
912 | static int max98088_mic_event(struct snd_soc_dapm_widget *w, | ||
913 | struct snd_kcontrol *kcontrol, int event) | ||
914 | { | ||
915 | struct snd_soc_codec *codec = w->codec; | ||
916 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
917 | |||
918 | switch (event) { | ||
919 | case SND_SOC_DAPM_POST_PMU: | ||
920 | if (w->reg == M98088_REG_35_LVL_MIC1) { | ||
921 | snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK, | ||
922 | (1+max98088->mic1pre)<<M98088_MICPRE_SHIFT); | ||
923 | } else { | ||
924 | snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK, | ||
925 | (1+max98088->mic2pre)<<M98088_MICPRE_SHIFT); | ||
926 | } | ||
927 | break; | ||
928 | case SND_SOC_DAPM_POST_PMD: | ||
929 | snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK, 0); | ||
930 | break; | ||
931 | default: | ||
932 | return -EINVAL; | ||
933 | } | ||
934 | |||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | /* | ||
939 | * The line inputs are 2-channel stereo inputs with the left | ||
940 | * and right channels sharing a common PGA power control signal. | ||
941 | */ | ||
942 | static int max98088_line_pga(struct snd_soc_dapm_widget *w, | ||
943 | int event, int line, u8 channel) | ||
944 | { | ||
945 | struct snd_soc_codec *codec = w->codec; | ||
946 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
947 | u8 *state; | ||
948 | |||
949 | BUG_ON(!((channel == 1) || (channel == 2))); | ||
950 | |||
951 | switch (line) { | ||
952 | case LINE_INA: | ||
953 | state = &max98088->ina_state; | ||
954 | break; | ||
955 | case LINE_INB: | ||
956 | state = &max98088->inb_state; | ||
957 | break; | ||
958 | default: | ||
959 | return -EINVAL; | ||
960 | } | ||
961 | |||
962 | switch (event) { | ||
963 | case SND_SOC_DAPM_POST_PMU: | ||
964 | *state |= channel; | ||
965 | snd_soc_update_bits(codec, w->reg, | ||
966 | (1 << w->shift), (1 << w->shift)); | ||
967 | break; | ||
968 | case SND_SOC_DAPM_POST_PMD: | ||
969 | *state &= ~channel; | ||
970 | if (*state == 0) { | ||
971 | snd_soc_update_bits(codec, w->reg, | ||
972 | (1 << w->shift), 0); | ||
973 | } | ||
974 | break; | ||
975 | default: | ||
976 | return -EINVAL; | ||
977 | } | ||
978 | |||
979 | return 0; | ||
980 | } | ||
981 | |||
982 | static int max98088_pga_ina1_event(struct snd_soc_dapm_widget *w, | ||
983 | struct snd_kcontrol *k, int event) | ||
984 | { | ||
985 | return max98088_line_pga(w, event, LINE_INA, 1); | ||
986 | } | ||
987 | |||
988 | static int max98088_pga_ina2_event(struct snd_soc_dapm_widget *w, | ||
989 | struct snd_kcontrol *k, int event) | ||
990 | { | ||
991 | return max98088_line_pga(w, event, LINE_INA, 2); | ||
992 | } | ||
993 | |||
994 | static int max98088_pga_inb1_event(struct snd_soc_dapm_widget *w, | ||
995 | struct snd_kcontrol *k, int event) | ||
996 | { | ||
997 | return max98088_line_pga(w, event, LINE_INB, 1); | ||
998 | } | ||
999 | |||
1000 | static int max98088_pga_inb2_event(struct snd_soc_dapm_widget *w, | ||
1001 | struct snd_kcontrol *k, int event) | ||
1002 | { | ||
1003 | return max98088_line_pga(w, event, LINE_INB, 2); | ||
1004 | } | ||
1005 | |||
1006 | static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = { | ||
1007 | |||
1008 | SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98088_REG_4C_PWR_EN_IN, 1, 0), | ||
1009 | SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98088_REG_4C_PWR_EN_IN, 0, 0), | ||
1010 | |||
1011 | SND_SOC_DAPM_DAC("DACL1", "HiFi Playback", | ||
1012 | M98088_REG_4D_PWR_EN_OUT, 1, 0), | ||
1013 | SND_SOC_DAPM_DAC("DACR1", "HiFi Playback", | ||
1014 | M98088_REG_4D_PWR_EN_OUT, 0, 0), | ||
1015 | SND_SOC_DAPM_DAC("DACL2", "Aux Playback", | ||
1016 | M98088_REG_4D_PWR_EN_OUT, 1, 0), | ||
1017 | SND_SOC_DAPM_DAC("DACR2", "Aux Playback", | ||
1018 | M98088_REG_4D_PWR_EN_OUT, 0, 0), | ||
1019 | |||
1020 | SND_SOC_DAPM_PGA("HP Left Out", M98088_REG_4D_PWR_EN_OUT, | ||
1021 | 7, 0, NULL, 0), | ||
1022 | SND_SOC_DAPM_PGA("HP Right Out", M98088_REG_4D_PWR_EN_OUT, | ||
1023 | 6, 0, NULL, 0), | ||
1024 | |||
1025 | SND_SOC_DAPM_PGA("SPK Left Out", M98088_REG_4D_PWR_EN_OUT, | ||
1026 | 5, 0, NULL, 0), | ||
1027 | SND_SOC_DAPM_PGA("SPK Right Out", M98088_REG_4D_PWR_EN_OUT, | ||
1028 | 4, 0, NULL, 0), | ||
1029 | |||
1030 | SND_SOC_DAPM_PGA("REC Left Out", M98088_REG_4D_PWR_EN_OUT, | ||
1031 | 3, 0, NULL, 0), | ||
1032 | SND_SOC_DAPM_PGA("REC Right Out", M98088_REG_4D_PWR_EN_OUT, | ||
1033 | 2, 0, NULL, 0), | ||
1034 | |||
1035 | SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0, | ||
1036 | &max98088_extmic_mux), | ||
1037 | |||
1038 | SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0, | ||
1039 | &max98088_left_hp_mixer_controls[0], | ||
1040 | ARRAY_SIZE(max98088_left_hp_mixer_controls)), | ||
1041 | |||
1042 | SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0, | ||
1043 | &max98088_right_hp_mixer_controls[0], | ||
1044 | ARRAY_SIZE(max98088_right_hp_mixer_controls)), | ||
1045 | |||
1046 | SND_SOC_DAPM_MIXER("Left SPK Mixer", SND_SOC_NOPM, 0, 0, | ||
1047 | &max98088_left_speaker_mixer_controls[0], | ||
1048 | ARRAY_SIZE(max98088_left_speaker_mixer_controls)), | ||
1049 | |||
1050 | SND_SOC_DAPM_MIXER("Right SPK Mixer", SND_SOC_NOPM, 0, 0, | ||
1051 | &max98088_right_speaker_mixer_controls[0], | ||
1052 | ARRAY_SIZE(max98088_right_speaker_mixer_controls)), | ||
1053 | |||
1054 | SND_SOC_DAPM_MIXER("Left REC Mixer", SND_SOC_NOPM, 0, 0, | ||
1055 | &max98088_left_rec_mixer_controls[0], | ||
1056 | ARRAY_SIZE(max98088_left_rec_mixer_controls)), | ||
1057 | |||
1058 | SND_SOC_DAPM_MIXER("Right REC Mixer", SND_SOC_NOPM, 0, 0, | ||
1059 | &max98088_right_rec_mixer_controls[0], | ||
1060 | ARRAY_SIZE(max98088_right_rec_mixer_controls)), | ||
1061 | |||
1062 | SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0, | ||
1063 | &max98088_left_ADC_mixer_controls[0], | ||
1064 | ARRAY_SIZE(max98088_left_ADC_mixer_controls)), | ||
1065 | |||
1066 | SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0, | ||
1067 | &max98088_right_ADC_mixer_controls[0], | ||
1068 | ARRAY_SIZE(max98088_right_ADC_mixer_controls)), | ||
1069 | |||
1070 | SND_SOC_DAPM_PGA_E("MIC1 Input", M98088_REG_35_LVL_MIC1, | ||
1071 | 5, 0, NULL, 0, max98088_mic_event, | ||
1072 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1073 | |||
1074 | SND_SOC_DAPM_PGA_E("MIC2 Input", M98088_REG_36_LVL_MIC2, | ||
1075 | 5, 0, NULL, 0, max98088_mic_event, | ||
1076 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1077 | |||
1078 | SND_SOC_DAPM_PGA_E("INA1 Input", M98088_REG_4C_PWR_EN_IN, | ||
1079 | 7, 0, NULL, 0, max98088_pga_ina1_event, | ||
1080 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1081 | |||
1082 | SND_SOC_DAPM_PGA_E("INA2 Input", M98088_REG_4C_PWR_EN_IN, | ||
1083 | 7, 0, NULL, 0, max98088_pga_ina2_event, | ||
1084 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1085 | |||
1086 | SND_SOC_DAPM_PGA_E("INB1 Input", M98088_REG_4C_PWR_EN_IN, | ||
1087 | 6, 0, NULL, 0, max98088_pga_inb1_event, | ||
1088 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1089 | |||
1090 | SND_SOC_DAPM_PGA_E("INB2 Input", M98088_REG_4C_PWR_EN_IN, | ||
1091 | 6, 0, NULL, 0, max98088_pga_inb2_event, | ||
1092 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
1093 | |||
1094 | SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0), | ||
1095 | |||
1096 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
1097 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
1098 | SND_SOC_DAPM_OUTPUT("SPKL"), | ||
1099 | SND_SOC_DAPM_OUTPUT("SPKR"), | ||
1100 | SND_SOC_DAPM_OUTPUT("RECL"), | ||
1101 | SND_SOC_DAPM_OUTPUT("RECR"), | ||
1102 | |||
1103 | SND_SOC_DAPM_INPUT("MIC1"), | ||
1104 | SND_SOC_DAPM_INPUT("MIC2"), | ||
1105 | SND_SOC_DAPM_INPUT("INA1"), | ||
1106 | SND_SOC_DAPM_INPUT("INA2"), | ||
1107 | SND_SOC_DAPM_INPUT("INB1"), | ||
1108 | SND_SOC_DAPM_INPUT("INB2"), | ||
1109 | }; | ||
1110 | |||
1111 | static const struct snd_soc_dapm_route max98088_audio_map[] = { | ||
1112 | /* Left headphone output mixer */ | ||
1113 | {"Left HP Mixer", "Left DAC1 Switch", "DACL1"}, | ||
1114 | {"Left HP Mixer", "Left DAC2 Switch", "DACL2"}, | ||
1115 | {"Left HP Mixer", "Right DAC1 Switch", "DACR1"}, | ||
1116 | {"Left HP Mixer", "Right DAC2 Switch", "DACR2"}, | ||
1117 | {"Left HP Mixer", "MIC1 Switch", "MIC1 Input"}, | ||
1118 | {"Left HP Mixer", "MIC2 Switch", "MIC2 Input"}, | ||
1119 | {"Left HP Mixer", "INA1 Switch", "INA1 Input"}, | ||
1120 | {"Left HP Mixer", "INA2 Switch", "INA2 Input"}, | ||
1121 | {"Left HP Mixer", "INB1 Switch", "INB1 Input"}, | ||
1122 | {"Left HP Mixer", "INB2 Switch", "INB2 Input"}, | ||
1123 | |||
1124 | /* Right headphone output mixer */ | ||
1125 | {"Right HP Mixer", "Left DAC1 Switch", "DACL1"}, | ||
1126 | {"Right HP Mixer", "Left DAC2 Switch", "DACL2" }, | ||
1127 | {"Right HP Mixer", "Right DAC1 Switch", "DACR1"}, | ||
1128 | {"Right HP Mixer", "Right DAC2 Switch", "DACR2"}, | ||
1129 | {"Right HP Mixer", "MIC1 Switch", "MIC1 Input"}, | ||
1130 | {"Right HP Mixer", "MIC2 Switch", "MIC2 Input"}, | ||
1131 | {"Right HP Mixer", "INA1 Switch", "INA1 Input"}, | ||
1132 | {"Right HP Mixer", "INA2 Switch", "INA2 Input"}, | ||
1133 | {"Right HP Mixer", "INB1 Switch", "INB1 Input"}, | ||
1134 | {"Right HP Mixer", "INB2 Switch", "INB2 Input"}, | ||
1135 | |||
1136 | /* Left speaker output mixer */ | ||
1137 | {"Left SPK Mixer", "Left DAC1 Switch", "DACL1"}, | ||
1138 | {"Left SPK Mixer", "Left DAC2 Switch", "DACL2"}, | ||
1139 | {"Left SPK Mixer", "Right DAC1 Switch", "DACR1"}, | ||
1140 | {"Left SPK Mixer", "Right DAC2 Switch", "DACR2"}, | ||
1141 | {"Left SPK Mixer", "MIC1 Switch", "MIC1 Input"}, | ||
1142 | {"Left SPK Mixer", "MIC2 Switch", "MIC2 Input"}, | ||
1143 | {"Left SPK Mixer", "INA1 Switch", "INA1 Input"}, | ||
1144 | {"Left SPK Mixer", "INA2 Switch", "INA2 Input"}, | ||
1145 | {"Left SPK Mixer", "INB1 Switch", "INB1 Input"}, | ||
1146 | {"Left SPK Mixer", "INB2 Switch", "INB2 Input"}, | ||
1147 | |||
1148 | /* Right speaker output mixer */ | ||
1149 | {"Right SPK Mixer", "Left DAC1 Switch", "DACL1"}, | ||
1150 | {"Right SPK Mixer", "Left DAC2 Switch", "DACL2"}, | ||
1151 | {"Right SPK Mixer", "Right DAC1 Switch", "DACR1"}, | ||
1152 | {"Right SPK Mixer", "Right DAC2 Switch", "DACR2"}, | ||
1153 | {"Right SPK Mixer", "MIC1 Switch", "MIC1 Input"}, | ||
1154 | {"Right SPK Mixer", "MIC2 Switch", "MIC2 Input"}, | ||
1155 | {"Right SPK Mixer", "INA1 Switch", "INA1 Input"}, | ||
1156 | {"Right SPK Mixer", "INA2 Switch", "INA2 Input"}, | ||
1157 | {"Right SPK Mixer", "INB1 Switch", "INB1 Input"}, | ||
1158 | {"Right SPK Mixer", "INB2 Switch", "INB2 Input"}, | ||
1159 | |||
1160 | /* Earpiece/Receiver output mixer */ | ||
1161 | {"Left REC Mixer", "Left DAC1 Switch", "DACL1"}, | ||
1162 | {"Left REC Mixer", "Left DAC2 Switch", "DACL2"}, | ||
1163 | {"Left REC Mixer", "Right DAC1 Switch", "DACR1"}, | ||
1164 | {"Left REC Mixer", "Right DAC2 Switch", "DACR2"}, | ||
1165 | {"Left REC Mixer", "MIC1 Switch", "MIC1 Input"}, | ||
1166 | {"Left REC Mixer", "MIC2 Switch", "MIC2 Input"}, | ||
1167 | {"Left REC Mixer", "INA1 Switch", "INA1 Input"}, | ||
1168 | {"Left REC Mixer", "INA2 Switch", "INA2 Input"}, | ||
1169 | {"Left REC Mixer", "INB1 Switch", "INB1 Input"}, | ||
1170 | {"Left REC Mixer", "INB2 Switch", "INB2 Input"}, | ||
1171 | |||
1172 | /* Earpiece/Receiver output mixer */ | ||
1173 | {"Right REC Mixer", "Left DAC1 Switch", "DACL1"}, | ||
1174 | {"Right REC Mixer", "Left DAC2 Switch", "DACL2"}, | ||
1175 | {"Right REC Mixer", "Right DAC1 Switch", "DACR1"}, | ||
1176 | {"Right REC Mixer", "Right DAC2 Switch", "DACR2"}, | ||
1177 | {"Right REC Mixer", "MIC1 Switch", "MIC1 Input"}, | ||
1178 | {"Right REC Mixer", "MIC2 Switch", "MIC2 Input"}, | ||
1179 | {"Right REC Mixer", "INA1 Switch", "INA1 Input"}, | ||
1180 | {"Right REC Mixer", "INA2 Switch", "INA2 Input"}, | ||
1181 | {"Right REC Mixer", "INB1 Switch", "INB1 Input"}, | ||
1182 | {"Right REC Mixer", "INB2 Switch", "INB2 Input"}, | ||
1183 | |||
1184 | {"HP Left Out", NULL, "Left HP Mixer"}, | ||
1185 | {"HP Right Out", NULL, "Right HP Mixer"}, | ||
1186 | {"SPK Left Out", NULL, "Left SPK Mixer"}, | ||
1187 | {"SPK Right Out", NULL, "Right SPK Mixer"}, | ||
1188 | {"REC Left Out", NULL, "Left REC Mixer"}, | ||
1189 | {"REC Right Out", NULL, "Right REC Mixer"}, | ||
1190 | |||
1191 | {"HPL", NULL, "HP Left Out"}, | ||
1192 | {"HPR", NULL, "HP Right Out"}, | ||
1193 | {"SPKL", NULL, "SPK Left Out"}, | ||
1194 | {"SPKR", NULL, "SPK Right Out"}, | ||
1195 | {"RECL", NULL, "REC Left Out"}, | ||
1196 | {"RECR", NULL, "REC Right Out"}, | ||
1197 | |||
1198 | /* Left ADC input mixer */ | ||
1199 | {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"}, | ||
1200 | {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"}, | ||
1201 | {"Left ADC Mixer", "INA1 Switch", "INA1 Input"}, | ||
1202 | {"Left ADC Mixer", "INA2 Switch", "INA2 Input"}, | ||
1203 | {"Left ADC Mixer", "INB1 Switch", "INB1 Input"}, | ||
1204 | {"Left ADC Mixer", "INB2 Switch", "INB2 Input"}, | ||
1205 | |||
1206 | /* Right ADC input mixer */ | ||
1207 | {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"}, | ||
1208 | {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"}, | ||
1209 | {"Right ADC Mixer", "INA1 Switch", "INA1 Input"}, | ||
1210 | {"Right ADC Mixer", "INA2 Switch", "INA2 Input"}, | ||
1211 | {"Right ADC Mixer", "INB1 Switch", "INB1 Input"}, | ||
1212 | {"Right ADC Mixer", "INB2 Switch", "INB2 Input"}, | ||
1213 | |||
1214 | /* Inputs */ | ||
1215 | {"ADCL", NULL, "Left ADC Mixer"}, | ||
1216 | {"ADCR", NULL, "Right ADC Mixer"}, | ||
1217 | {"INA1 Input", NULL, "INA1"}, | ||
1218 | {"INA2 Input", NULL, "INA2"}, | ||
1219 | {"INB1 Input", NULL, "INB1"}, | ||
1220 | {"INB2 Input", NULL, "INB2"}, | ||
1221 | {"MIC1 Input", NULL, "MIC1"}, | ||
1222 | {"MIC2 Input", NULL, "MIC2"}, | ||
1223 | }; | ||
1224 | |||
1225 | /* codec mclk clock divider coefficients */ | ||
1226 | static const struct { | ||
1227 | u32 rate; | ||
1228 | u8 sr; | ||
1229 | } rate_table[] = { | ||
1230 | {8000, 0x10}, | ||
1231 | {11025, 0x20}, | ||
1232 | {16000, 0x30}, | ||
1233 | {22050, 0x40}, | ||
1234 | {24000, 0x50}, | ||
1235 | {32000, 0x60}, | ||
1236 | {44100, 0x70}, | ||
1237 | {48000, 0x80}, | ||
1238 | {88200, 0x90}, | ||
1239 | {96000, 0xA0}, | ||
1240 | }; | ||
1241 | |||
1242 | static inline int rate_value(int rate, u8 *value) | ||
1243 | { | ||
1244 | int i; | ||
1245 | |||
1246 | for (i = 0; i < ARRAY_SIZE(rate_table); i++) { | ||
1247 | if (rate_table[i].rate >= rate) { | ||
1248 | *value = rate_table[i].sr; | ||
1249 | return 0; | ||
1250 | } | ||
1251 | } | ||
1252 | *value = rate_table[0].sr; | ||
1253 | return -EINVAL; | ||
1254 | } | ||
1255 | |||
1256 | static int max98088_dai1_hw_params(struct snd_pcm_substream *substream, | ||
1257 | struct snd_pcm_hw_params *params, | ||
1258 | struct snd_soc_dai *dai) | ||
1259 | { | ||
1260 | struct snd_soc_codec *codec = dai->codec; | ||
1261 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1262 | struct max98088_cdata *cdata; | ||
1263 | unsigned long long ni; | ||
1264 | unsigned int rate; | ||
1265 | u8 regval; | ||
1266 | |||
1267 | cdata = &max98088->dai[0]; | ||
1268 | |||
1269 | rate = params_rate(params); | ||
1270 | |||
1271 | switch (params_format(params)) { | ||
1272 | case SNDRV_PCM_FORMAT_S16_LE: | ||
1273 | snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, | ||
1274 | M98088_DAI_WS, 0); | ||
1275 | break; | ||
1276 | case SNDRV_PCM_FORMAT_S24_LE: | ||
1277 | snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, | ||
1278 | M98088_DAI_WS, M98088_DAI_WS); | ||
1279 | break; | ||
1280 | default: | ||
1281 | return -EINVAL; | ||
1282 | } | ||
1283 | |||
1284 | snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0); | ||
1285 | |||
1286 | if (rate_value(rate, ®val)) | ||
1287 | return -EINVAL; | ||
1288 | |||
1289 | snd_soc_update_bits(codec, M98088_REG_11_DAI1_CLKMODE, | ||
1290 | M98088_CLKMODE_MASK, regval); | ||
1291 | cdata->rate = rate; | ||
1292 | |||
1293 | /* Configure NI when operating as master */ | ||
1294 | if (snd_soc_read(codec, M98088_REG_14_DAI1_FORMAT) | ||
1295 | & M98088_DAI_MAS) { | ||
1296 | if (max98088->sysclk == 0) { | ||
1297 | dev_err(codec->dev, "Invalid system clock frequency\n"); | ||
1298 | return -EINVAL; | ||
1299 | } | ||
1300 | ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) | ||
1301 | * (unsigned long long int)rate; | ||
1302 | do_div(ni, (unsigned long long int)max98088->sysclk); | ||
1303 | snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI, | ||
1304 | (ni >> 8) & 0x7F); | ||
1305 | snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO, | ||
1306 | ni & 0xFF); | ||
1307 | } | ||
1308 | |||
1309 | /* Update sample rate mode */ | ||
1310 | if (rate < 50000) | ||
1311 | snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS, | ||
1312 | M98088_DAI_DHF, 0); | ||
1313 | else | ||
1314 | snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS, | ||
1315 | M98088_DAI_DHF, M98088_DAI_DHF); | ||
1316 | |||
1317 | snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, | ||
1318 | M98088_SHDNRUN); | ||
1319 | |||
1320 | return 0; | ||
1321 | } | ||
1322 | |||
1323 | static int max98088_dai2_hw_params(struct snd_pcm_substream *substream, | ||
1324 | struct snd_pcm_hw_params *params, | ||
1325 | struct snd_soc_dai *dai) | ||
1326 | { | ||
1327 | struct snd_soc_codec *codec = dai->codec; | ||
1328 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1329 | struct max98088_cdata *cdata; | ||
1330 | unsigned long long ni; | ||
1331 | unsigned int rate; | ||
1332 | u8 regval; | ||
1333 | |||
1334 | cdata = &max98088->dai[1]; | ||
1335 | |||
1336 | rate = params_rate(params); | ||
1337 | |||
1338 | switch (params_format(params)) { | ||
1339 | case SNDRV_PCM_FORMAT_S16_LE: | ||
1340 | snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT, | ||
1341 | M98088_DAI_WS, 0); | ||
1342 | break; | ||
1343 | case SNDRV_PCM_FORMAT_S24_LE: | ||
1344 | snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT, | ||
1345 | M98088_DAI_WS, M98088_DAI_WS); | ||
1346 | break; | ||
1347 | default: | ||
1348 | return -EINVAL; | ||
1349 | } | ||
1350 | |||
1351 | snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0); | ||
1352 | |||
1353 | if (rate_value(rate, ®val)) | ||
1354 | return -EINVAL; | ||
1355 | |||
1356 | snd_soc_update_bits(codec, M98088_REG_19_DAI2_CLKMODE, | ||
1357 | M98088_CLKMODE_MASK, regval); | ||
1358 | cdata->rate = rate; | ||
1359 | |||
1360 | /* Configure NI when operating as master */ | ||
1361 | if (snd_soc_read(codec, M98088_REG_1C_DAI2_FORMAT) | ||
1362 | & M98088_DAI_MAS) { | ||
1363 | if (max98088->sysclk == 0) { | ||
1364 | dev_err(codec->dev, "Invalid system clock frequency\n"); | ||
1365 | return -EINVAL; | ||
1366 | } | ||
1367 | ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) | ||
1368 | * (unsigned long long int)rate; | ||
1369 | do_div(ni, (unsigned long long int)max98088->sysclk); | ||
1370 | snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI, | ||
1371 | (ni >> 8) & 0x7F); | ||
1372 | snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO, | ||
1373 | ni & 0xFF); | ||
1374 | } | ||
1375 | |||
1376 | /* Update sample rate mode */ | ||
1377 | if (rate < 50000) | ||
1378 | snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS, | ||
1379 | M98088_DAI_DHF, 0); | ||
1380 | else | ||
1381 | snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS, | ||
1382 | M98088_DAI_DHF, M98088_DAI_DHF); | ||
1383 | |||
1384 | snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, | ||
1385 | M98088_SHDNRUN); | ||
1386 | |||
1387 | return 0; | ||
1388 | } | ||
1389 | |||
1390 | static int max98088_dai_set_sysclk(struct snd_soc_dai *dai, | ||
1391 | int clk_id, unsigned int freq, int dir) | ||
1392 | { | ||
1393 | struct snd_soc_codec *codec = dai->codec; | ||
1394 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1395 | |||
1396 | /* Requested clock frequency is already setup */ | ||
1397 | if (freq == max98088->sysclk) | ||
1398 | return 0; | ||
1399 | |||
1400 | max98088->sysclk = freq; /* remember current sysclk */ | ||
1401 | |||
1402 | /* Setup clocks for slave mode, and using the PLL | ||
1403 | * PSCLK = 0x01 (when master clk is 10MHz to 20MHz) | ||
1404 | * 0x02 (when master clk is 20MHz to 30MHz).. | ||
1405 | */ | ||
1406 | if ((freq >= 10000000) && (freq < 20000000)) { | ||
1407 | snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x10); | ||
1408 | } else if ((freq >= 20000000) && (freq < 30000000)) { | ||
1409 | snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x20); | ||
1410 | } else { | ||
1411 | dev_err(codec->dev, "Invalid master clock frequency\n"); | ||
1412 | return -EINVAL; | ||
1413 | } | ||
1414 | |||
1415 | if (snd_soc_read(codec, M98088_REG_51_PWR_SYS) & M98088_SHDNRUN) { | ||
1416 | snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, | ||
1417 | M98088_SHDNRUN, 0); | ||
1418 | snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, | ||
1419 | M98088_SHDNRUN, M98088_SHDNRUN); | ||
1420 | } | ||
1421 | |||
1422 | dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq); | ||
1423 | |||
1424 | max98088->sysclk = freq; | ||
1425 | return 0; | ||
1426 | } | ||
1427 | |||
1428 | static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai, | ||
1429 | unsigned int fmt) | ||
1430 | { | ||
1431 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1432 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1433 | struct max98088_cdata *cdata; | ||
1434 | u8 reg15val; | ||
1435 | u8 reg14val = 0; | ||
1436 | |||
1437 | cdata = &max98088->dai[0]; | ||
1438 | |||
1439 | if (fmt != cdata->fmt) { | ||
1440 | cdata->fmt = fmt; | ||
1441 | |||
1442 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1443 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1444 | /* Slave mode PLL */ | ||
1445 | snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI, | ||
1446 | 0x80); | ||
1447 | snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO, | ||
1448 | 0x00); | ||
1449 | break; | ||
1450 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1451 | /* Set to master mode */ | ||
1452 | reg14val |= M98088_DAI_MAS; | ||
1453 | break; | ||
1454 | case SND_SOC_DAIFMT_CBS_CFM: | ||
1455 | case SND_SOC_DAIFMT_CBM_CFS: | ||
1456 | default: | ||
1457 | dev_err(codec->dev, "Clock mode unsupported"); | ||
1458 | return -EINVAL; | ||
1459 | } | ||
1460 | |||
1461 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1462 | case SND_SOC_DAIFMT_I2S: | ||
1463 | reg14val |= M98088_DAI_DLY; | ||
1464 | break; | ||
1465 | case SND_SOC_DAIFMT_LEFT_J: | ||
1466 | break; | ||
1467 | default: | ||
1468 | return -EINVAL; | ||
1469 | } | ||
1470 | |||
1471 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1472 | case SND_SOC_DAIFMT_NB_NF: | ||
1473 | break; | ||
1474 | case SND_SOC_DAIFMT_NB_IF: | ||
1475 | reg14val |= M98088_DAI_WCI; | ||
1476 | break; | ||
1477 | case SND_SOC_DAIFMT_IB_NF: | ||
1478 | reg14val |= M98088_DAI_BCI; | ||
1479 | break; | ||
1480 | case SND_SOC_DAIFMT_IB_IF: | ||
1481 | reg14val |= M98088_DAI_BCI|M98088_DAI_WCI; | ||
1482 | break; | ||
1483 | default: | ||
1484 | return -EINVAL; | ||
1485 | } | ||
1486 | |||
1487 | snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, | ||
1488 | M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI | | ||
1489 | M98088_DAI_WCI, reg14val); | ||
1490 | |||
1491 | reg15val = M98088_DAI_BSEL64; | ||
1492 | if (max98088->digmic) | ||
1493 | reg15val |= M98088_DAI_OSR64; | ||
1494 | snd_soc_write(codec, M98088_REG_15_DAI1_CLOCK, reg15val); | ||
1495 | } | ||
1496 | |||
1497 | return 0; | ||
1498 | } | ||
1499 | |||
1500 | static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai, | ||
1501 | unsigned int fmt) | ||
1502 | { | ||
1503 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1504 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1505 | struct max98088_cdata *cdata; | ||
1506 | u8 reg1Cval = 0; | ||
1507 | |||
1508 | cdata = &max98088->dai[1]; | ||
1509 | |||
1510 | if (fmt != cdata->fmt) { | ||
1511 | cdata->fmt = fmt; | ||
1512 | |||
1513 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1514 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1515 | /* Slave mode PLL */ | ||
1516 | snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI, | ||
1517 | 0x80); | ||
1518 | snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO, | ||
1519 | 0x00); | ||
1520 | break; | ||
1521 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1522 | /* Set to master mode */ | ||
1523 | reg1Cval |= M98088_DAI_MAS; | ||
1524 | break; | ||
1525 | case SND_SOC_DAIFMT_CBS_CFM: | ||
1526 | case SND_SOC_DAIFMT_CBM_CFS: | ||
1527 | default: | ||
1528 | dev_err(codec->dev, "Clock mode unsupported"); | ||
1529 | return -EINVAL; | ||
1530 | } | ||
1531 | |||
1532 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1533 | case SND_SOC_DAIFMT_I2S: | ||
1534 | reg1Cval |= M98088_DAI_DLY; | ||
1535 | break; | ||
1536 | case SND_SOC_DAIFMT_LEFT_J: | ||
1537 | break; | ||
1538 | default: | ||
1539 | return -EINVAL; | ||
1540 | } | ||
1541 | |||
1542 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1543 | case SND_SOC_DAIFMT_NB_NF: | ||
1544 | break; | ||
1545 | case SND_SOC_DAIFMT_NB_IF: | ||
1546 | reg1Cval |= M98088_DAI_WCI; | ||
1547 | break; | ||
1548 | case SND_SOC_DAIFMT_IB_NF: | ||
1549 | reg1Cval |= M98088_DAI_BCI; | ||
1550 | break; | ||
1551 | case SND_SOC_DAIFMT_IB_IF: | ||
1552 | reg1Cval |= M98088_DAI_BCI|M98088_DAI_WCI; | ||
1553 | break; | ||
1554 | default: | ||
1555 | return -EINVAL; | ||
1556 | } | ||
1557 | |||
1558 | snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT, | ||
1559 | M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI | | ||
1560 | M98088_DAI_WCI, reg1Cval); | ||
1561 | |||
1562 | snd_soc_write(codec, M98088_REG_1D_DAI2_CLOCK, | ||
1563 | M98088_DAI_BSEL64); | ||
1564 | } | ||
1565 | |||
1566 | return 0; | ||
1567 | } | ||
1568 | |||
1569 | static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute) | ||
1570 | { | ||
1571 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1572 | int reg; | ||
1573 | |||
1574 | if (mute) | ||
1575 | reg = M98088_DAI_MUTE; | ||
1576 | else | ||
1577 | reg = 0; | ||
1578 | |||
1579 | snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY, | ||
1580 | M98088_DAI_MUTE_MASK, reg); | ||
1581 | return 0; | ||
1582 | } | ||
1583 | |||
1584 | static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute) | ||
1585 | { | ||
1586 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1587 | int reg; | ||
1588 | |||
1589 | if (mute) | ||
1590 | reg = M98088_DAI_MUTE; | ||
1591 | else | ||
1592 | reg = 0; | ||
1593 | |||
1594 | snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY, | ||
1595 | M98088_DAI_MUTE_MASK, reg); | ||
1596 | return 0; | ||
1597 | } | ||
1598 | |||
1599 | static void max98088_sync_cache(struct snd_soc_codec *codec) | ||
1600 | { | ||
1601 | u16 *reg_cache = codec->reg_cache; | ||
1602 | int i; | ||
1603 | |||
1604 | if (!codec->cache_sync) | ||
1605 | return; | ||
1606 | |||
1607 | codec->cache_only = 0; | ||
1608 | |||
1609 | /* write back cached values if they're writeable and | ||
1610 | * different from the hardware default. | ||
1611 | */ | ||
1612 | for (i = 1; i < codec->driver->reg_cache_size; i++) { | ||
1613 | if (!max98088_access[i].writable) | ||
1614 | continue; | ||
1615 | |||
1616 | if (reg_cache[i] == max98088_reg[i]) | ||
1617 | continue; | ||
1618 | |||
1619 | snd_soc_write(codec, i, reg_cache[i]); | ||
1620 | } | ||
1621 | |||
1622 | codec->cache_sync = 0; | ||
1623 | } | ||
1624 | |||
1625 | static int max98088_set_bias_level(struct snd_soc_codec *codec, | ||
1626 | enum snd_soc_bias_level level) | ||
1627 | { | ||
1628 | switch (level) { | ||
1629 | case SND_SOC_BIAS_ON: | ||
1630 | break; | ||
1631 | |||
1632 | case SND_SOC_BIAS_PREPARE: | ||
1633 | break; | ||
1634 | |||
1635 | case SND_SOC_BIAS_STANDBY: | ||
1636 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
1637 | max98088_sync_cache(codec); | ||
1638 | |||
1639 | snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN, | ||
1640 | M98088_MBEN, M98088_MBEN); | ||
1641 | break; | ||
1642 | |||
1643 | case SND_SOC_BIAS_OFF: | ||
1644 | snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN, | ||
1645 | M98088_MBEN, 0); | ||
1646 | codec->cache_sync = 1; | ||
1647 | break; | ||
1648 | } | ||
1649 | codec->dapm.bias_level = level; | ||
1650 | return 0; | ||
1651 | } | ||
1652 | |||
1653 | #define MAX98088_RATES SNDRV_PCM_RATE_8000_96000 | ||
1654 | #define MAX98088_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | ||
1655 | |||
1656 | static struct snd_soc_dai_ops max98088_dai1_ops = { | ||
1657 | .set_sysclk = max98088_dai_set_sysclk, | ||
1658 | .set_fmt = max98088_dai1_set_fmt, | ||
1659 | .hw_params = max98088_dai1_hw_params, | ||
1660 | .digital_mute = max98088_dai1_digital_mute, | ||
1661 | }; | ||
1662 | |||
1663 | static struct snd_soc_dai_ops max98088_dai2_ops = { | ||
1664 | .set_sysclk = max98088_dai_set_sysclk, | ||
1665 | .set_fmt = max98088_dai2_set_fmt, | ||
1666 | .hw_params = max98088_dai2_hw_params, | ||
1667 | .digital_mute = max98088_dai2_digital_mute, | ||
1668 | }; | ||
1669 | |||
1670 | static struct snd_soc_dai_driver max98088_dai[] = { | ||
1671 | { | ||
1672 | .name = "HiFi", | ||
1673 | .playback = { | ||
1674 | .stream_name = "HiFi Playback", | ||
1675 | .channels_min = 1, | ||
1676 | .channels_max = 2, | ||
1677 | .rates = MAX98088_RATES, | ||
1678 | .formats = MAX98088_FORMATS, | ||
1679 | }, | ||
1680 | .capture = { | ||
1681 | .stream_name = "HiFi Capture", | ||
1682 | .channels_min = 1, | ||
1683 | .channels_max = 2, | ||
1684 | .rates = MAX98088_RATES, | ||
1685 | .formats = MAX98088_FORMATS, | ||
1686 | }, | ||
1687 | .ops = &max98088_dai1_ops, | ||
1688 | }, | ||
1689 | { | ||
1690 | .name = "Aux", | ||
1691 | .playback = { | ||
1692 | .stream_name = "Aux Playback", | ||
1693 | .channels_min = 1, | ||
1694 | .channels_max = 2, | ||
1695 | .rates = MAX98088_RATES, | ||
1696 | .formats = MAX98088_FORMATS, | ||
1697 | }, | ||
1698 | .ops = &max98088_dai2_ops, | ||
1699 | } | ||
1700 | }; | ||
1701 | |||
1702 | static int max98088_get_channel(const char *name) | ||
1703 | { | ||
1704 | if (strcmp(name, "EQ1 Mode") == 0) | ||
1705 | return 0; | ||
1706 | if (strcmp(name, "EQ2 Mode") == 0) | ||
1707 | return 1; | ||
1708 | return -EINVAL; | ||
1709 | } | ||
1710 | |||
1711 | static void max98088_setup_eq1(struct snd_soc_codec *codec) | ||
1712 | { | ||
1713 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1714 | struct max98088_pdata *pdata = max98088->pdata; | ||
1715 | struct max98088_eq_cfg *coef_set; | ||
1716 | int best, best_val, save, i, sel, fs; | ||
1717 | struct max98088_cdata *cdata; | ||
1718 | |||
1719 | cdata = &max98088->dai[0]; | ||
1720 | |||
1721 | if (!pdata || !max98088->eq_textcnt) | ||
1722 | return; | ||
1723 | |||
1724 | /* Find the selected configuration with nearest sample rate */ | ||
1725 | fs = cdata->rate; | ||
1726 | sel = cdata->eq_sel; | ||
1727 | |||
1728 | best = 0; | ||
1729 | best_val = INT_MAX; | ||
1730 | for (i = 0; i < pdata->eq_cfgcnt; i++) { | ||
1731 | if (strcmp(pdata->eq_cfg[i].name, max98088->eq_texts[sel]) == 0 && | ||
1732 | abs(pdata->eq_cfg[i].rate - fs) < best_val) { | ||
1733 | best = i; | ||
1734 | best_val = abs(pdata->eq_cfg[i].rate - fs); | ||
1735 | } | ||
1736 | } | ||
1737 | |||
1738 | dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n", | ||
1739 | pdata->eq_cfg[best].name, | ||
1740 | pdata->eq_cfg[best].rate, fs); | ||
1741 | |||
1742 | /* Disable EQ while configuring, and save current on/off state */ | ||
1743 | save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL); | ||
1744 | snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0); | ||
1745 | |||
1746 | coef_set = &pdata->eq_cfg[sel]; | ||
1747 | |||
1748 | m98088_eq_band(codec, 0, 0, coef_set->band1); | ||
1749 | m98088_eq_band(codec, 0, 1, coef_set->band2); | ||
1750 | m98088_eq_band(codec, 0, 2, coef_set->band3); | ||
1751 | m98088_eq_band(codec, 0, 3, coef_set->band4); | ||
1752 | m98088_eq_band(codec, 0, 4, coef_set->band5); | ||
1753 | |||
1754 | /* Restore the original on/off state */ | ||
1755 | snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, save); | ||
1756 | } | ||
1757 | |||
1758 | static void max98088_setup_eq2(struct snd_soc_codec *codec) | ||
1759 | { | ||
1760 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1761 | struct max98088_pdata *pdata = max98088->pdata; | ||
1762 | struct max98088_eq_cfg *coef_set; | ||
1763 | int best, best_val, save, i, sel, fs; | ||
1764 | struct max98088_cdata *cdata; | ||
1765 | |||
1766 | cdata = &max98088->dai[1]; | ||
1767 | |||
1768 | if (!pdata || !max98088->eq_textcnt) | ||
1769 | return; | ||
1770 | |||
1771 | /* Find the selected configuration with nearest sample rate */ | ||
1772 | fs = cdata->rate; | ||
1773 | |||
1774 | sel = cdata->eq_sel; | ||
1775 | best = 0; | ||
1776 | best_val = INT_MAX; | ||
1777 | for (i = 0; i < pdata->eq_cfgcnt; i++) { | ||
1778 | if (strcmp(pdata->eq_cfg[i].name, max98088->eq_texts[sel]) == 0 && | ||
1779 | abs(pdata->eq_cfg[i].rate - fs) < best_val) { | ||
1780 | best = i; | ||
1781 | best_val = abs(pdata->eq_cfg[i].rate - fs); | ||
1782 | } | ||
1783 | } | ||
1784 | |||
1785 | dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n", | ||
1786 | pdata->eq_cfg[best].name, | ||
1787 | pdata->eq_cfg[best].rate, fs); | ||
1788 | |||
1789 | /* Disable EQ while configuring, and save current on/off state */ | ||
1790 | save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL); | ||
1791 | snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0); | ||
1792 | |||
1793 | coef_set = &pdata->eq_cfg[sel]; | ||
1794 | |||
1795 | m98088_eq_band(codec, 1, 0, coef_set->band1); | ||
1796 | m98088_eq_band(codec, 1, 1, coef_set->band2); | ||
1797 | m98088_eq_band(codec, 1, 2, coef_set->band3); | ||
1798 | m98088_eq_band(codec, 1, 3, coef_set->band4); | ||
1799 | m98088_eq_band(codec, 1, 4, coef_set->band5); | ||
1800 | |||
1801 | /* Restore the original on/off state */ | ||
1802 | snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, | ||
1803 | save); | ||
1804 | } | ||
1805 | |||
1806 | static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, | ||
1807 | struct snd_ctl_elem_value *ucontrol) | ||
1808 | { | ||
1809 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1810 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1811 | struct max98088_pdata *pdata = max98088->pdata; | ||
1812 | int channel = max98088_get_channel(kcontrol->id.name); | ||
1813 | struct max98088_cdata *cdata; | ||
1814 | int sel = ucontrol->value.integer.value[0]; | ||
1815 | |||
1816 | cdata = &max98088->dai[channel]; | ||
1817 | |||
1818 | if (sel >= pdata->eq_cfgcnt) | ||
1819 | return -EINVAL; | ||
1820 | |||
1821 | cdata->eq_sel = sel; | ||
1822 | |||
1823 | switch (channel) { | ||
1824 | case 0: | ||
1825 | max98088_setup_eq1(codec); | ||
1826 | break; | ||
1827 | case 1: | ||
1828 | max98088_setup_eq2(codec); | ||
1829 | break; | ||
1830 | } | ||
1831 | |||
1832 | return 0; | ||
1833 | } | ||
1834 | |||
1835 | static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol, | ||
1836 | struct snd_ctl_elem_value *ucontrol) | ||
1837 | { | ||
1838 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1839 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1840 | int channel = max98088_get_channel(kcontrol->id.name); | ||
1841 | struct max98088_cdata *cdata; | ||
1842 | |||
1843 | cdata = &max98088->dai[channel]; | ||
1844 | ucontrol->value.enumerated.item[0] = cdata->eq_sel; | ||
1845 | return 0; | ||
1846 | } | ||
1847 | |||
1848 | static void max98088_handle_eq_pdata(struct snd_soc_codec *codec) | ||
1849 | { | ||
1850 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1851 | struct max98088_pdata *pdata = max98088->pdata; | ||
1852 | struct max98088_eq_cfg *cfg; | ||
1853 | unsigned int cfgcnt; | ||
1854 | int i, j; | ||
1855 | const char **t; | ||
1856 | int ret; | ||
1857 | |||
1858 | struct snd_kcontrol_new controls[] = { | ||
1859 | SOC_ENUM_EXT("EQ1 Mode", | ||
1860 | max98088->eq_enum, | ||
1861 | max98088_get_eq_enum, | ||
1862 | max98088_put_eq_enum), | ||
1863 | SOC_ENUM_EXT("EQ2 Mode", | ||
1864 | max98088->eq_enum, | ||
1865 | max98088_get_eq_enum, | ||
1866 | max98088_put_eq_enum), | ||
1867 | }; | ||
1868 | |||
1869 | cfg = pdata->eq_cfg; | ||
1870 | cfgcnt = pdata->eq_cfgcnt; | ||
1871 | |||
1872 | /* Setup an array of texts for the equalizer enum. | ||
1873 | * This is based on Mark Brown's equalizer driver code. | ||
1874 | */ | ||
1875 | max98088->eq_textcnt = 0; | ||
1876 | max98088->eq_texts = NULL; | ||
1877 | for (i = 0; i < cfgcnt; i++) { | ||
1878 | for (j = 0; j < max98088->eq_textcnt; j++) { | ||
1879 | if (strcmp(cfg[i].name, max98088->eq_texts[j]) == 0) | ||
1880 | break; | ||
1881 | } | ||
1882 | |||
1883 | if (j != max98088->eq_textcnt) | ||
1884 | continue; | ||
1885 | |||
1886 | /* Expand the array */ | ||
1887 | t = krealloc(max98088->eq_texts, | ||
1888 | sizeof(char *) * (max98088->eq_textcnt + 1), | ||
1889 | GFP_KERNEL); | ||
1890 | if (t == NULL) | ||
1891 | continue; | ||
1892 | |||
1893 | /* Store the new entry */ | ||
1894 | t[max98088->eq_textcnt] = cfg[i].name; | ||
1895 | max98088->eq_textcnt++; | ||
1896 | max98088->eq_texts = t; | ||
1897 | } | ||
1898 | |||
1899 | /* Now point the soc_enum to .texts array items */ | ||
1900 | max98088->eq_enum.texts = max98088->eq_texts; | ||
1901 | max98088->eq_enum.max = max98088->eq_textcnt; | ||
1902 | |||
1903 | ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); | ||
1904 | if (ret != 0) | ||
1905 | dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); | ||
1906 | } | ||
1907 | |||
1908 | static void max98088_handle_pdata(struct snd_soc_codec *codec) | ||
1909 | { | ||
1910 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1911 | struct max98088_pdata *pdata = max98088->pdata; | ||
1912 | u8 regval = 0; | ||
1913 | |||
1914 | if (!pdata) { | ||
1915 | dev_dbg(codec->dev, "No platform data\n"); | ||
1916 | return; | ||
1917 | } | ||
1918 | |||
1919 | /* Configure mic for analog/digital mic mode */ | ||
1920 | if (pdata->digmic_left_mode) | ||
1921 | regval |= M98088_DIGMIC_L; | ||
1922 | |||
1923 | if (pdata->digmic_right_mode) | ||
1924 | regval |= M98088_DIGMIC_R; | ||
1925 | |||
1926 | max98088->digmic = (regval ? 1 : 0); | ||
1927 | |||
1928 | snd_soc_write(codec, M98088_REG_48_CFG_MIC, regval); | ||
1929 | |||
1930 | /* Configure receiver output */ | ||
1931 | regval = ((pdata->receiver_mode) ? M98088_REC_LINEMODE : 0); | ||
1932 | snd_soc_update_bits(codec, M98088_REG_2A_MIC_REC_CNTL, | ||
1933 | M98088_REC_LINEMODE_MASK, regval); | ||
1934 | |||
1935 | /* Configure equalizers */ | ||
1936 | if (pdata->eq_cfgcnt) | ||
1937 | max98088_handle_eq_pdata(codec); | ||
1938 | } | ||
1939 | |||
1940 | #ifdef CONFIG_PM | ||
1941 | static int max98088_suspend(struct snd_soc_codec *codec, pm_message_t state) | ||
1942 | { | ||
1943 | max98088_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1944 | |||
1945 | return 0; | ||
1946 | } | ||
1947 | |||
1948 | static int max98088_resume(struct snd_soc_codec *codec) | ||
1949 | { | ||
1950 | max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1951 | |||
1952 | return 0; | ||
1953 | } | ||
1954 | #else | ||
1955 | #define max98088_suspend NULL | ||
1956 | #define max98088_resume NULL | ||
1957 | #endif | ||
1958 | |||
1959 | static int max98088_probe(struct snd_soc_codec *codec) | ||
1960 | { | ||
1961 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
1962 | struct max98088_cdata *cdata; | ||
1963 | int ret = 0; | ||
1964 | |||
1965 | codec->cache_sync = 1; | ||
1966 | |||
1967 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); | ||
1968 | if (ret != 0) { | ||
1969 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1970 | return ret; | ||
1971 | } | ||
1972 | |||
1973 | /* initialize private data */ | ||
1974 | |||
1975 | max98088->sysclk = (unsigned)-1; | ||
1976 | max98088->eq_textcnt = 0; | ||
1977 | |||
1978 | cdata = &max98088->dai[0]; | ||
1979 | cdata->rate = (unsigned)-1; | ||
1980 | cdata->fmt = (unsigned)-1; | ||
1981 | cdata->eq_sel = 0; | ||
1982 | |||
1983 | cdata = &max98088->dai[1]; | ||
1984 | cdata->rate = (unsigned)-1; | ||
1985 | cdata->fmt = (unsigned)-1; | ||
1986 | cdata->eq_sel = 0; | ||
1987 | |||
1988 | max98088->ina_state = 0; | ||
1989 | max98088->inb_state = 0; | ||
1990 | max98088->ex_mode = 0; | ||
1991 | max98088->digmic = 0; | ||
1992 | max98088->mic1pre = 0; | ||
1993 | max98088->mic2pre = 0; | ||
1994 | |||
1995 | ret = snd_soc_read(codec, M98088_REG_FF_REV_ID); | ||
1996 | if (ret < 0) { | ||
1997 | dev_err(codec->dev, "Failed to read device revision: %d\n", | ||
1998 | ret); | ||
1999 | goto err_access; | ||
2000 | } | ||
2001 | dev_info(codec->dev, "revision %c\n", ret + 'A'); | ||
2002 | |||
2003 | snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV); | ||
2004 | |||
2005 | /* initialize registers cache to hardware default */ | ||
2006 | max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
2007 | |||
2008 | snd_soc_write(codec, M98088_REG_0F_IRQ_ENABLE, 0x00); | ||
2009 | |||
2010 | snd_soc_write(codec, M98088_REG_22_MIX_DAC, | ||
2011 | M98088_DAI1L_TO_DACL|M98088_DAI2L_TO_DACL| | ||
2012 | M98088_DAI1R_TO_DACR|M98088_DAI2R_TO_DACR); | ||
2013 | |||
2014 | snd_soc_write(codec, M98088_REG_4E_BIAS_CNTL, 0xF0); | ||
2015 | snd_soc_write(codec, M98088_REG_50_DAC_BIAS2, 0x0F); | ||
2016 | |||
2017 | snd_soc_write(codec, M98088_REG_16_DAI1_IOCFG, | ||
2018 | M98088_S1NORMAL|M98088_SDATA); | ||
2019 | |||
2020 | snd_soc_write(codec, M98088_REG_1E_DAI2_IOCFG, | ||
2021 | M98088_S2NORMAL|M98088_SDATA); | ||
2022 | |||
2023 | max98088_handle_pdata(codec); | ||
2024 | |||
2025 | snd_soc_add_controls(codec, max98088_snd_controls, | ||
2026 | ARRAY_SIZE(max98088_snd_controls)); | ||
2027 | |||
2028 | err_access: | ||
2029 | return ret; | ||
2030 | } | ||
2031 | |||
2032 | static int max98088_remove(struct snd_soc_codec *codec) | ||
2033 | { | ||
2034 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | ||
2035 | |||
2036 | max98088_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
2037 | kfree(max98088->eq_texts); | ||
2038 | |||
2039 | return 0; | ||
2040 | } | ||
2041 | |||
2042 | static struct snd_soc_codec_driver soc_codec_dev_max98088 = { | ||
2043 | .probe = max98088_probe, | ||
2044 | .remove = max98088_remove, | ||
2045 | .suspend = max98088_suspend, | ||
2046 | .resume = max98088_resume, | ||
2047 | .set_bias_level = max98088_set_bias_level, | ||
2048 | .reg_cache_size = ARRAY_SIZE(max98088_reg), | ||
2049 | .reg_word_size = sizeof(u8), | ||
2050 | .reg_cache_default = max98088_reg, | ||
2051 | .volatile_register = max98088_volatile_register, | ||
2052 | .dapm_widgets = max98088_dapm_widgets, | ||
2053 | .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets), | ||
2054 | .dapm_routes = max98088_audio_map, | ||
2055 | .num_dapm_routes = ARRAY_SIZE(max98088_audio_map), | ||
2056 | }; | ||
2057 | |||
2058 | static int max98088_i2c_probe(struct i2c_client *i2c, | ||
2059 | const struct i2c_device_id *id) | ||
2060 | { | ||
2061 | struct max98088_priv *max98088; | ||
2062 | int ret; | ||
2063 | |||
2064 | max98088 = kzalloc(sizeof(struct max98088_priv), GFP_KERNEL); | ||
2065 | if (max98088 == NULL) | ||
2066 | return -ENOMEM; | ||
2067 | |||
2068 | max98088->devtype = id->driver_data; | ||
2069 | |||
2070 | i2c_set_clientdata(i2c, max98088); | ||
2071 | max98088->control_data = i2c; | ||
2072 | max98088->pdata = i2c->dev.platform_data; | ||
2073 | |||
2074 | ret = snd_soc_register_codec(&i2c->dev, | ||
2075 | &soc_codec_dev_max98088, &max98088_dai[0], 2); | ||
2076 | if (ret < 0) | ||
2077 | kfree(max98088); | ||
2078 | return ret; | ||
2079 | } | ||
2080 | |||
2081 | static int __devexit max98088_i2c_remove(struct i2c_client *client) | ||
2082 | { | ||
2083 | snd_soc_unregister_codec(&client->dev); | ||
2084 | kfree(i2c_get_clientdata(client)); | ||
2085 | return 0; | ||
2086 | } | ||
2087 | |||
2088 | static const struct i2c_device_id max98088_i2c_id[] = { | ||
2089 | { "max98088", MAX98088 }, | ||
2090 | { "max98089", MAX98089 }, | ||
2091 | { } | ||
2092 | }; | ||
2093 | MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); | ||
2094 | |||
2095 | static struct i2c_driver max98088_i2c_driver = { | ||
2096 | .driver = { | ||
2097 | .name = "max98088", | ||
2098 | .owner = THIS_MODULE, | ||
2099 | }, | ||
2100 | .probe = max98088_i2c_probe, | ||
2101 | .remove = __devexit_p(max98088_i2c_remove), | ||
2102 | .id_table = max98088_i2c_id, | ||
2103 | }; | ||
2104 | |||
2105 | static int __init max98088_init(void) | ||
2106 | { | ||
2107 | int ret; | ||
2108 | |||
2109 | ret = i2c_add_driver(&max98088_i2c_driver); | ||
2110 | if (ret) | ||
2111 | pr_err("Failed to register max98088 I2C driver: %d\n", ret); | ||
2112 | |||
2113 | return ret; | ||
2114 | } | ||
2115 | module_init(max98088_init); | ||
2116 | |||
2117 | static void __exit max98088_exit(void) | ||
2118 | { | ||
2119 | i2c_del_driver(&max98088_i2c_driver); | ||
2120 | } | ||
2121 | module_exit(max98088_exit); | ||
2122 | |||
2123 | MODULE_DESCRIPTION("ALSA SoC MAX98088 driver"); | ||
2124 | MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin"); | ||
2125 | MODULE_LICENSE("GPL"); | ||