Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wm5102.c
Go to the documentation of this file.
1 /*
2  * wm5102.c -- WM5102 ALSA SoC Audio driver
3  *
4  * Copyright 2012 Wolfson Microelectronics plc
5  *
6  * Author: Mark Brown <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/pm.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/regmap.h>
20 #include <linux/slab.h>
21 #include <sound/core.h>
22 #include <sound/pcm.h>
23 #include <sound/pcm_params.h>
24 #include <sound/soc.h>
25 #include <sound/jack.h>
26 #include <sound/initval.h>
27 #include <sound/tlv.h>
28 
29 #include <linux/mfd/arizona/core.h>
31 
32 #include "arizona.h"
33 #include "wm5102.h"
34 
35 struct wm5102_priv {
37  struct arizona_fll fll[2];
38 };
39 
40 static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
41 static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
42 static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
43 static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
44 
45 static const struct reg_default wm5102_sysclk_reva_patch[] = {
46  { 0x3000, 0x2225 },
47  { 0x3001, 0x3a03 },
48  { 0x3002, 0x0225 },
49  { 0x3003, 0x0801 },
50  { 0x3004, 0x6249 },
51  { 0x3005, 0x0c04 },
52  { 0x3006, 0x0225 },
53  { 0x3007, 0x5901 },
54  { 0x3008, 0xe249 },
55  { 0x3009, 0x030d },
56  { 0x300a, 0x0249 },
57  { 0x300b, 0x2c01 },
58  { 0x300c, 0xe249 },
59  { 0x300d, 0x4342 },
60  { 0x300e, 0xe249 },
61  { 0x300f, 0x73c0 },
62  { 0x3010, 0x4249 },
63  { 0x3011, 0x0c00 },
64  { 0x3012, 0x0225 },
65  { 0x3013, 0x1f01 },
66  { 0x3014, 0x0225 },
67  { 0x3015, 0x1e01 },
68  { 0x3016, 0x0225 },
69  { 0x3017, 0xfa00 },
70  { 0x3018, 0x0000 },
71  { 0x3019, 0xf000 },
72  { 0x301a, 0x0000 },
73  { 0x301b, 0xf000 },
74  { 0x301c, 0x0000 },
75  { 0x301d, 0xf000 },
76  { 0x301e, 0x0000 },
77  { 0x301f, 0xf000 },
78  { 0x3020, 0x0000 },
79  { 0x3021, 0xf000 },
80  { 0x3022, 0x0000 },
81  { 0x3023, 0xf000 },
82  { 0x3024, 0x0000 },
83  { 0x3025, 0xf000 },
84  { 0x3026, 0x0000 },
85  { 0x3027, 0xf000 },
86  { 0x3028, 0x0000 },
87  { 0x3029, 0xf000 },
88  { 0x302a, 0x0000 },
89  { 0x302b, 0xf000 },
90  { 0x302c, 0x0000 },
91  { 0x302d, 0xf000 },
92  { 0x302e, 0x0000 },
93  { 0x302f, 0xf000 },
94  { 0x3030, 0x0225 },
95  { 0x3031, 0x1a01 },
96  { 0x3032, 0x0225 },
97  { 0x3033, 0x1e00 },
98  { 0x3034, 0x0225 },
99  { 0x3035, 0x1f00 },
100  { 0x3036, 0x6225 },
101  { 0x3037, 0xf800 },
102  { 0x3038, 0x0000 },
103  { 0x3039, 0xf000 },
104  { 0x303a, 0x0000 },
105  { 0x303b, 0xf000 },
106  { 0x303c, 0x0000 },
107  { 0x303d, 0xf000 },
108  { 0x303e, 0x0000 },
109  { 0x303f, 0xf000 },
110  { 0x3040, 0x2226 },
111  { 0x3041, 0x3a03 },
112  { 0x3042, 0x0226 },
113  { 0x3043, 0x0801 },
114  { 0x3044, 0x6249 },
115  { 0x3045, 0x0c06 },
116  { 0x3046, 0x0226 },
117  { 0x3047, 0x5901 },
118  { 0x3048, 0xe249 },
119  { 0x3049, 0x030d },
120  { 0x304a, 0x0249 },
121  { 0x304b, 0x2c01 },
122  { 0x304c, 0xe249 },
123  { 0x304d, 0x4342 },
124  { 0x304e, 0xe249 },
125  { 0x304f, 0x73c0 },
126  { 0x3050, 0x4249 },
127  { 0x3051, 0x0c00 },
128  { 0x3052, 0x0226 },
129  { 0x3053, 0x1f01 },
130  { 0x3054, 0x0226 },
131  { 0x3055, 0x1e01 },
132  { 0x3056, 0x0226 },
133  { 0x3057, 0xfa00 },
134  { 0x3058, 0x0000 },
135  { 0x3059, 0xf000 },
136  { 0x305a, 0x0000 },
137  { 0x305b, 0xf000 },
138  { 0x305c, 0x0000 },
139  { 0x305d, 0xf000 },
140  { 0x305e, 0x0000 },
141  { 0x305f, 0xf000 },
142  { 0x3060, 0x0000 },
143  { 0x3061, 0xf000 },
144  { 0x3062, 0x0000 },
145  { 0x3063, 0xf000 },
146  { 0x3064, 0x0000 },
147  { 0x3065, 0xf000 },
148  { 0x3066, 0x0000 },
149  { 0x3067, 0xf000 },
150  { 0x3068, 0x0000 },
151  { 0x3069, 0xf000 },
152  { 0x306a, 0x0000 },
153  { 0x306b, 0xf000 },
154  { 0x306c, 0x0000 },
155  { 0x306d, 0xf000 },
156  { 0x306e, 0x0000 },
157  { 0x306f, 0xf000 },
158  { 0x3070, 0x0226 },
159  { 0x3071, 0x1a01 },
160  { 0x3072, 0x0226 },
161  { 0x3073, 0x1e00 },
162  { 0x3074, 0x0226 },
163  { 0x3075, 0x1f00 },
164  { 0x3076, 0x6226 },
165  { 0x3077, 0xf800 },
166  { 0x3078, 0x0000 },
167  { 0x3079, 0xf000 },
168  { 0x307a, 0x0000 },
169  { 0x307b, 0xf000 },
170  { 0x307c, 0x0000 },
171  { 0x307d, 0xf000 },
172  { 0x307e, 0x0000 },
173  { 0x307f, 0xf000 },
174  { 0x3080, 0x2227 },
175  { 0x3081, 0x3a03 },
176  { 0x3082, 0x0227 },
177  { 0x3083, 0x0801 },
178  { 0x3084, 0x6255 },
179  { 0x3085, 0x0c04 },
180  { 0x3086, 0x0227 },
181  { 0x3087, 0x5901 },
182  { 0x3088, 0xe255 },
183  { 0x3089, 0x030d },
184  { 0x308a, 0x0255 },
185  { 0x308b, 0x2c01 },
186  { 0x308c, 0xe255 },
187  { 0x308d, 0x4342 },
188  { 0x308e, 0xe255 },
189  { 0x308f, 0x73c0 },
190  { 0x3090, 0x4255 },
191  { 0x3091, 0x0c00 },
192  { 0x3092, 0x0227 },
193  { 0x3093, 0x1f01 },
194  { 0x3094, 0x0227 },
195  { 0x3095, 0x1e01 },
196  { 0x3096, 0x0227 },
197  { 0x3097, 0xfa00 },
198  { 0x3098, 0x0000 },
199  { 0x3099, 0xf000 },
200  { 0x309a, 0x0000 },
201  { 0x309b, 0xf000 },
202  { 0x309c, 0x0000 },
203  { 0x309d, 0xf000 },
204  { 0x309e, 0x0000 },
205  { 0x309f, 0xf000 },
206  { 0x30a0, 0x0000 },
207  { 0x30a1, 0xf000 },
208  { 0x30a2, 0x0000 },
209  { 0x30a3, 0xf000 },
210  { 0x30a4, 0x0000 },
211  { 0x30a5, 0xf000 },
212  { 0x30a6, 0x0000 },
213  { 0x30a7, 0xf000 },
214  { 0x30a8, 0x0000 },
215  { 0x30a9, 0xf000 },
216  { 0x30aa, 0x0000 },
217  { 0x30ab, 0xf000 },
218  { 0x30ac, 0x0000 },
219  { 0x30ad, 0xf000 },
220  { 0x30ae, 0x0000 },
221  { 0x30af, 0xf000 },
222  { 0x30b0, 0x0227 },
223  { 0x30b1, 0x1a01 },
224  { 0x30b2, 0x0227 },
225  { 0x30b3, 0x1e00 },
226  { 0x30b4, 0x0227 },
227  { 0x30b5, 0x1f00 },
228  { 0x30b6, 0x6227 },
229  { 0x30b7, 0xf800 },
230  { 0x30b8, 0x0000 },
231  { 0x30b9, 0xf000 },
232  { 0x30ba, 0x0000 },
233  { 0x30bb, 0xf000 },
234  { 0x30bc, 0x0000 },
235  { 0x30bd, 0xf000 },
236  { 0x30be, 0x0000 },
237  { 0x30bf, 0xf000 },
238  { 0x30c0, 0x2228 },
239  { 0x30c1, 0x3a03 },
240  { 0x30c2, 0x0228 },
241  { 0x30c3, 0x0801 },
242  { 0x30c4, 0x6255 },
243  { 0x30c5, 0x0c06 },
244  { 0x30c6, 0x0228 },
245  { 0x30c7, 0x5901 },
246  { 0x30c8, 0xe255 },
247  { 0x30c9, 0x030d },
248  { 0x30ca, 0x0255 },
249  { 0x30cb, 0x2c01 },
250  { 0x30cc, 0xe255 },
251  { 0x30cd, 0x4342 },
252  { 0x30ce, 0xe255 },
253  { 0x30cf, 0x73c0 },
254  { 0x30d0, 0x4255 },
255  { 0x30d1, 0x0c00 },
256  { 0x30d2, 0x0228 },
257  { 0x30d3, 0x1f01 },
258  { 0x30d4, 0x0228 },
259  { 0x30d5, 0x1e01 },
260  { 0x30d6, 0x0228 },
261  { 0x30d7, 0xfa00 },
262  { 0x30d8, 0x0000 },
263  { 0x30d9, 0xf000 },
264  { 0x30da, 0x0000 },
265  { 0x30db, 0xf000 },
266  { 0x30dc, 0x0000 },
267  { 0x30dd, 0xf000 },
268  { 0x30de, 0x0000 },
269  { 0x30df, 0xf000 },
270  { 0x30e0, 0x0000 },
271  { 0x30e1, 0xf000 },
272  { 0x30e2, 0x0000 },
273  { 0x30e3, 0xf000 },
274  { 0x30e4, 0x0000 },
275  { 0x30e5, 0xf000 },
276  { 0x30e6, 0x0000 },
277  { 0x30e7, 0xf000 },
278  { 0x30e8, 0x0000 },
279  { 0x30e9, 0xf000 },
280  { 0x30ea, 0x0000 },
281  { 0x30eb, 0xf000 },
282  { 0x30ec, 0x0000 },
283  { 0x30ed, 0xf000 },
284  { 0x30ee, 0x0000 },
285  { 0x30ef, 0xf000 },
286  { 0x30f0, 0x0228 },
287  { 0x30f1, 0x1a01 },
288  { 0x30f2, 0x0228 },
289  { 0x30f3, 0x1e00 },
290  { 0x30f4, 0x0228 },
291  { 0x30f5, 0x1f00 },
292  { 0x30f6, 0x6228 },
293  { 0x30f7, 0xf800 },
294  { 0x30f8, 0x0000 },
295  { 0x30f9, 0xf000 },
296  { 0x30fa, 0x0000 },
297  { 0x30fb, 0xf000 },
298  { 0x30fc, 0x0000 },
299  { 0x30fd, 0xf000 },
300  { 0x30fe, 0x0000 },
301  { 0x30ff, 0xf000 },
302  { 0x3100, 0x222b },
303  { 0x3101, 0x3a03 },
304  { 0x3102, 0x222b },
305  { 0x3103, 0x5803 },
306  { 0x3104, 0xe26f },
307  { 0x3105, 0x030d },
308  { 0x3106, 0x626f },
309  { 0x3107, 0x2c01 },
310  { 0x3108, 0xe26f },
311  { 0x3109, 0x4342 },
312  { 0x310a, 0xe26f },
313  { 0x310b, 0x73c0 },
314  { 0x310c, 0x026f },
315  { 0x310d, 0x0c00 },
316  { 0x310e, 0x022b },
317  { 0x310f, 0x1f01 },
318  { 0x3110, 0x022b },
319  { 0x3111, 0x1e01 },
320  { 0x3112, 0x022b },
321  { 0x3113, 0xfa00 },
322  { 0x3114, 0x0000 },
323  { 0x3115, 0xf000 },
324  { 0x3116, 0x0000 },
325  { 0x3117, 0xf000 },
326  { 0x3118, 0x0000 },
327  { 0x3119, 0xf000 },
328  { 0x311a, 0x0000 },
329  { 0x311b, 0xf000 },
330  { 0x311c, 0x0000 },
331  { 0x311d, 0xf000 },
332  { 0x311e, 0x0000 },
333  { 0x311f, 0xf000 },
334  { 0x3120, 0x022b },
335  { 0x3121, 0x0a01 },
336  { 0x3122, 0x022b },
337  { 0x3123, 0x1e00 },
338  { 0x3124, 0x022b },
339  { 0x3125, 0x1f00 },
340  { 0x3126, 0x622b },
341  { 0x3127, 0xf800 },
342  { 0x3128, 0x0000 },
343  { 0x3129, 0xf000 },
344  { 0x312a, 0x0000 },
345  { 0x312b, 0xf000 },
346  { 0x312c, 0x0000 },
347  { 0x312d, 0xf000 },
348  { 0x312e, 0x0000 },
349  { 0x312f, 0xf000 },
350  { 0x3130, 0x0000 },
351  { 0x3131, 0xf000 },
352  { 0x3132, 0x0000 },
353  { 0x3133, 0xf000 },
354  { 0x3134, 0x0000 },
355  { 0x3135, 0xf000 },
356  { 0x3136, 0x0000 },
357  { 0x3137, 0xf000 },
358  { 0x3138, 0x0000 },
359  { 0x3139, 0xf000 },
360  { 0x313a, 0x0000 },
361  { 0x313b, 0xf000 },
362  { 0x313c, 0x0000 },
363  { 0x313d, 0xf000 },
364  { 0x313e, 0x0000 },
365  { 0x313f, 0xf000 },
366  { 0x3140, 0x0000 },
367  { 0x3141, 0xf000 },
368  { 0x3142, 0x0000 },
369  { 0x3143, 0xf000 },
370  { 0x3144, 0x0000 },
371  { 0x3145, 0xf000 },
372  { 0x3146, 0x0000 },
373  { 0x3147, 0xf000 },
374  { 0x3148, 0x0000 },
375  { 0x3149, 0xf000 },
376  { 0x314a, 0x0000 },
377  { 0x314b, 0xf000 },
378  { 0x314c, 0x0000 },
379  { 0x314d, 0xf000 },
380  { 0x314e, 0x0000 },
381  { 0x314f, 0xf000 },
382  { 0x3150, 0x0000 },
383  { 0x3151, 0xf000 },
384  { 0x3152, 0x0000 },
385  { 0x3153, 0xf000 },
386  { 0x3154, 0x0000 },
387  { 0x3155, 0xf000 },
388  { 0x3156, 0x0000 },
389  { 0x3157, 0xf000 },
390  { 0x3158, 0x0000 },
391  { 0x3159, 0xf000 },
392  { 0x315a, 0x0000 },
393  { 0x315b, 0xf000 },
394  { 0x315c, 0x0000 },
395  { 0x315d, 0xf000 },
396  { 0x315e, 0x0000 },
397  { 0x315f, 0xf000 },
398  { 0x3160, 0x0000 },
399  { 0x3161, 0xf000 },
400  { 0x3162, 0x0000 },
401  { 0x3163, 0xf000 },
402  { 0x3164, 0x0000 },
403  { 0x3165, 0xf000 },
404  { 0x3166, 0x0000 },
405  { 0x3167, 0xf000 },
406  { 0x3168, 0x0000 },
407  { 0x3169, 0xf000 },
408  { 0x316a, 0x0000 },
409  { 0x316b, 0xf000 },
410  { 0x316c, 0x0000 },
411  { 0x316d, 0xf000 },
412  { 0x316e, 0x0000 },
413  { 0x316f, 0xf000 },
414  { 0x3170, 0x0000 },
415  { 0x3171, 0xf000 },
416  { 0x3172, 0x0000 },
417  { 0x3173, 0xf000 },
418  { 0x3174, 0x0000 },
419  { 0x3175, 0xf000 },
420  { 0x3176, 0x0000 },
421  { 0x3177, 0xf000 },
422  { 0x3178, 0x0000 },
423  { 0x3179, 0xf000 },
424  { 0x317a, 0x0000 },
425  { 0x317b, 0xf000 },
426  { 0x317c, 0x0000 },
427  { 0x317d, 0xf000 },
428  { 0x317e, 0x0000 },
429  { 0x317f, 0xf000 },
430  { 0x3180, 0x2001 },
431  { 0x3181, 0xf101 },
432  { 0x3182, 0x0000 },
433  { 0x3183, 0xf000 },
434  { 0x3184, 0x0000 },
435  { 0x3185, 0xf000 },
436  { 0x3186, 0x0000 },
437  { 0x3187, 0xf000 },
438  { 0x3188, 0x0000 },
439  { 0x3189, 0xf000 },
440  { 0x318a, 0x0000 },
441  { 0x318b, 0xf000 },
442  { 0x318c, 0x0000 },
443  { 0x318d, 0xf000 },
444  { 0x318e, 0x0000 },
445  { 0x318f, 0xf000 },
446  { 0x3190, 0x0000 },
447  { 0x3191, 0xf000 },
448  { 0x3192, 0x0000 },
449  { 0x3193, 0xf000 },
450  { 0x3194, 0x0000 },
451  { 0x3195, 0xf000 },
452  { 0x3196, 0x0000 },
453  { 0x3197, 0xf000 },
454  { 0x3198, 0x0000 },
455  { 0x3199, 0xf000 },
456  { 0x319a, 0x0000 },
457  { 0x319b, 0xf000 },
458  { 0x319c, 0x0000 },
459  { 0x319d, 0xf000 },
460  { 0x319e, 0x0000 },
461  { 0x319f, 0xf000 },
462  { 0x31a0, 0x0000 },
463  { 0x31a1, 0xf000 },
464  { 0x31a2, 0x0000 },
465  { 0x31a3, 0xf000 },
466  { 0x31a4, 0x0000 },
467  { 0x31a5, 0xf000 },
468  { 0x31a6, 0x0000 },
469  { 0x31a7, 0xf000 },
470  { 0x31a8, 0x0000 },
471  { 0x31a9, 0xf000 },
472  { 0x31aa, 0x0000 },
473  { 0x31ab, 0xf000 },
474  { 0x31ac, 0x0000 },
475  { 0x31ad, 0xf000 },
476  { 0x31ae, 0x0000 },
477  { 0x31af, 0xf000 },
478  { 0x31b0, 0x0000 },
479  { 0x31b1, 0xf000 },
480  { 0x31b2, 0x0000 },
481  { 0x31b3, 0xf000 },
482  { 0x31b4, 0x0000 },
483  { 0x31b5, 0xf000 },
484  { 0x31b6, 0x0000 },
485  { 0x31b7, 0xf000 },
486  { 0x31b8, 0x0000 },
487  { 0x31b9, 0xf000 },
488  { 0x31ba, 0x0000 },
489  { 0x31bb, 0xf000 },
490  { 0x31bc, 0x0000 },
491  { 0x31bd, 0xf000 },
492  { 0x31be, 0x0000 },
493  { 0x31bf, 0xf000 },
494  { 0x31c0, 0x0000 },
495  { 0x31c1, 0xf000 },
496  { 0x31c2, 0x0000 },
497  { 0x31c3, 0xf000 },
498  { 0x31c4, 0x0000 },
499  { 0x31c5, 0xf000 },
500  { 0x31c6, 0x0000 },
501  { 0x31c7, 0xf000 },
502  { 0x31c8, 0x0000 },
503  { 0x31c9, 0xf000 },
504  { 0x31ca, 0x0000 },
505  { 0x31cb, 0xf000 },
506  { 0x31cc, 0x0000 },
507  { 0x31cd, 0xf000 },
508  { 0x31ce, 0x0000 },
509  { 0x31cf, 0xf000 },
510  { 0x31d0, 0x0000 },
511  { 0x31d1, 0xf000 },
512  { 0x31d2, 0x0000 },
513  { 0x31d3, 0xf000 },
514  { 0x31d4, 0x0000 },
515  { 0x31d5, 0xf000 },
516  { 0x31d6, 0x0000 },
517  { 0x31d7, 0xf000 },
518  { 0x31d8, 0x0000 },
519  { 0x31d9, 0xf000 },
520  { 0x31da, 0x0000 },
521  { 0x31db, 0xf000 },
522  { 0x31dc, 0x0000 },
523  { 0x31dd, 0xf000 },
524  { 0x31de, 0x0000 },
525  { 0x31df, 0xf000 },
526  { 0x31e0, 0x0000 },
527  { 0x31e1, 0xf000 },
528  { 0x31e2, 0x0000 },
529  { 0x31e3, 0xf000 },
530  { 0x31e4, 0x0000 },
531  { 0x31e5, 0xf000 },
532  { 0x31e6, 0x0000 },
533  { 0x31e7, 0xf000 },
534  { 0x31e8, 0x0000 },
535  { 0x31e9, 0xf000 },
536  { 0x31ea, 0x0000 },
537  { 0x31eb, 0xf000 },
538  { 0x31ec, 0x0000 },
539  { 0x31ed, 0xf000 },
540  { 0x31ee, 0x0000 },
541  { 0x31ef, 0xf000 },
542  { 0x31f0, 0x0000 },
543  { 0x31f1, 0xf000 },
544  { 0x31f2, 0x0000 },
545  { 0x31f3, 0xf000 },
546  { 0x31f4, 0x0000 },
547  { 0x31f5, 0xf000 },
548  { 0x31f6, 0x0000 },
549  { 0x31f7, 0xf000 },
550  { 0x31f8, 0x0000 },
551  { 0x31f9, 0xf000 },
552  { 0x31fa, 0x0000 },
553  { 0x31fb, 0xf000 },
554  { 0x31fc, 0x0000 },
555  { 0x31fd, 0xf000 },
556  { 0x31fe, 0x0000 },
557  { 0x31ff, 0xf000 },
558  { 0x024d, 0xff50 },
559  { 0x0252, 0xff50 },
560  { 0x0259, 0x0112 },
561  { 0x025e, 0x0112 },
562 };
563 
564 static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
565  struct snd_kcontrol *kcontrol, int event)
566 {
567  struct snd_soc_codec *codec = w->codec;
568  struct arizona *arizona = dev_get_drvdata(codec->dev);
569  struct regmap *regmap = codec->control_data;
570  const struct reg_default *patch = NULL;
571  int i, patch_size;
572 
573  switch (arizona->rev) {
574  case 0:
575  patch = wm5102_sysclk_reva_patch;
576  patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch);
577  break;
578  }
579 
580  switch (event) {
582  if (patch)
583  for (i = 0; i < patch_size; i++)
584  regmap_write(regmap, patch[i].reg,
585  patch[i].def);
586  break;
587 
588  default:
589  break;
590  }
591 
592  return 0;
593 }
594 
595 static const struct snd_kcontrol_new wm5102_snd_controls[] = {
596 SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
597  ARIZONA_IN1_OSR_SHIFT, 1, 0),
598 SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL,
599  ARIZONA_IN2_OSR_SHIFT, 1, 0),
600 SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL,
601  ARIZONA_IN3_OSR_SHIFT, 1, 0),
602 
605  ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
608  ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
611  ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
612 
613 SOC_DOUBLE_R("IN1 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_1L,
615 SOC_DOUBLE_R("IN2 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_2L,
617 SOC_DOUBLE_R("IN3 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_3L,
619 
620 SOC_DOUBLE_R_TLV("IN1 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
622  0xbf, 0, digital_tlv),
623 SOC_DOUBLE_R_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
625  0xbf, 0, digital_tlv),
626 SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L,
628  0xbf, 0, digital_tlv),
629 
634 
636  24, 0, eq_tlv),
638  24, 0, eq_tlv),
640  24, 0, eq_tlv),
642  24, 0, eq_tlv),
644  24, 0, eq_tlv),
645 
647  24, 0, eq_tlv),
649  24, 0, eq_tlv),
651  24, 0, eq_tlv),
653  24, 0, eq_tlv),
655  24, 0, eq_tlv),
656 
658  24, 0, eq_tlv),
660  24, 0, eq_tlv),
662  24, 0, eq_tlv),
664  24, 0, eq_tlv),
666  24, 0, eq_tlv),
667 
669  24, 0, eq_tlv),
671  24, 0, eq_tlv),
673  24, 0, eq_tlv),
675  24, 0, eq_tlv),
677  24, 0, eq_tlv),
678 
681 
684 
689 
690 SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
691 SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
692 SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
693 SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
694 
697 
698 SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR,
699  ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv),
700 
710 
711 SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
712  ARIZONA_OUT1_OSR_SHIFT, 1, 0),
713 SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
714  ARIZONA_OUT2_OSR_SHIFT, 1, 0),
715 SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
716  ARIZONA_OUT3_OSR_SHIFT, 1, 0),
717 SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
718  ARIZONA_OUT4_OSR_SHIFT, 1, 0),
719 SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
720  ARIZONA_OUT5_OSR_SHIFT, 1, 0),
721 
722 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
724 SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
726 SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
728 SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
730 SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
732 
733 SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
735  0xbf, 0, digital_tlv),
736 SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
738  0xbf, 0, digital_tlv),
739 SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
740  ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
741 SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
743  0xbf, 0, digital_tlv),
744 SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
746  0xbf, 0, digital_tlv),
747 
751  0x34, 0x40, 0, ana_tlv),
755  0x34, 0x40, 0, ana_tlv),
757  ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
758 
761 
770 
773 
776 };
777 
782 
785 
790 
793 
796 
806 
815 
818 
821 
826 
827 
828 static const char *wm5102_aec_loopback_texts[] = {
829  "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
830  "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R",
831 };
832 
833 static const unsigned int wm5102_aec_loopback_values[] = {
834  0, 1, 2, 3, 4, 6, 7, 8, 9,
835 };
836 
837 static const struct soc_enum wm5102_aec_loopback =
841  ARRAY_SIZE(wm5102_aec_loopback_texts),
842  wm5102_aec_loopback_texts,
843  wm5102_aec_loopback_values);
844 
845 static const struct snd_kcontrol_new wm5102_aec_loopback_mux =
846  SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback);
847 
848 static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
850  0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU),
857 
858 SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
859 SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
860 SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
862 SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0),
863 SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
864 
865 SND_SOC_DAPM_SIGGEN("TONE"),
866 SND_SOC_DAPM_SIGGEN("NOISE"),
867 
868 SND_SOC_DAPM_INPUT("IN1L"),
869 SND_SOC_DAPM_INPUT("IN1R"),
870 SND_SOC_DAPM_INPUT("IN2L"),
871 SND_SOC_DAPM_INPUT("IN2R"),
872 SND_SOC_DAPM_INPUT("IN3L"),
873 SND_SOC_DAPM_INPUT("IN3R"),
874 
876  0, NULL, 0, arizona_in_ev,
879  0, NULL, 0, arizona_in_ev,
882  0, NULL, 0, arizona_in_ev,
885  0, NULL, 0, arizona_in_ev,
888  0, NULL, 0, arizona_in_ev,
891  0, NULL, 0, arizona_in_ev,
893 
900 
903 
904 SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
906 SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
908 
911 
916 
918  NULL, 0),
920  NULL, 0),
921 
923  NULL, 0),
925  NULL, 0),
927  NULL, 0),
929  NULL, 0),
930 
932  0, NULL, 0),
934  0, NULL, 0),
935 
937  NULL, 0),
939  NULL, 0),
941  NULL, 0),
943  NULL, 0),
944 
945 SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
947 SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
949 SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
951 SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
953 SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
955 SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
957 SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
959 SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
961 
962 SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
964 SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
966 SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
968 SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
970 SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
972 SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
974 SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
976 SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
978 
979 SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
981 SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
983 
984 SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
986 SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
988 
989 SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
991 SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
993 
994 SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
996 SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
998 
1000  ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
1001 
1029 
1030 ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"),
1031 ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"),
1032 ARIZONA_MIXER_WIDGETS(EQ3, "EQ3"),
1033 ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"),
1034 
1035 ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
1036 ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
1037 
1038 ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
1039 ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
1040 ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
1041 ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
1042 
1043 ARIZONA_MIXER_WIDGETS(Mic, "Mic"),
1044 ARIZONA_MIXER_WIDGETS(Noise, "Noise"),
1045 
1046 ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
1047 ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
1048 
1049 ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
1050 ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
1051 ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
1052 ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
1053 ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
1054 ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
1055 ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
1056 ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
1057 ARIZONA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
1058 
1059 ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1060 ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1061 ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1062 ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1063 ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1064 ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1065 ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
1066 ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
1067 
1068 ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
1069 ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
1070 
1071 ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
1072 ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
1073 
1074 ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
1075 ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
1076 ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
1077 ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
1078 
1079 SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1080 SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1081 SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1082 SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1083 SND_SOC_DAPM_OUTPUT("EPOUTN"),
1084 SND_SOC_DAPM_OUTPUT("EPOUTP"),
1085 SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
1086 SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
1087 SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
1088 SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
1089 SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
1090 SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
1091 };
1092 
1093 #define ARIZONA_MIXER_INPUT_ROUTES(name) \
1094  { name, "Noise Generator", "Noise Generator" }, \
1095  { name, "Tone Generator 1", "Tone Generator 1" }, \
1096  { name, "Tone Generator 2", "Tone Generator 2" }, \
1097  { name, "AEC", "AEC Loopback" }, \
1098  { name, "IN1L", "IN1L PGA" }, \
1099  { name, "IN1R", "IN1R PGA" }, \
1100  { name, "IN2L", "IN2L PGA" }, \
1101  { name, "IN2R", "IN2R PGA" }, \
1102  { name, "IN3L", "IN3L PGA" }, \
1103  { name, "IN3R", "IN3R PGA" }, \
1104  { name, "Mic Mute Mixer", "Mic Mute Mixer" }, \
1105  { name, "AIF1RX1", "AIF1RX1" }, \
1106  { name, "AIF1RX2", "AIF1RX2" }, \
1107  { name, "AIF1RX3", "AIF1RX3" }, \
1108  { name, "AIF1RX4", "AIF1RX4" }, \
1109  { name, "AIF1RX5", "AIF1RX5" }, \
1110  { name, "AIF1RX6", "AIF1RX6" }, \
1111  { name, "AIF1RX7", "AIF1RX7" }, \
1112  { name, "AIF1RX8", "AIF1RX8" }, \
1113  { name, "AIF2RX1", "AIF2RX1" }, \
1114  { name, "AIF2RX2", "AIF2RX2" }, \
1115  { name, "AIF3RX1", "AIF3RX1" }, \
1116  { name, "AIF3RX2", "AIF3RX2" }, \
1117  { name, "EQ1", "EQ1" }, \
1118  { name, "EQ2", "EQ2" }, \
1119  { name, "EQ3", "EQ3" }, \
1120  { name, "EQ4", "EQ4" }, \
1121  { name, "DRC1L", "DRC1L" }, \
1122  { name, "DRC1R", "DRC1R" }, \
1123  { name, "LHPF1", "LHPF1" }, \
1124  { name, "LHPF2", "LHPF2" }, \
1125  { name, "LHPF3", "LHPF3" }, \
1126  { name, "LHPF4", "LHPF4" }, \
1127  { name, "ASRC1L", "ASRC1L" }, \
1128  { name, "ASRC1R", "ASRC1R" }, \
1129  { name, "ASRC2L", "ASRC2L" }, \
1130  { name, "ASRC2R", "ASRC2R" }
1131 
1132 static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1133  { "AIF2 Capture", NULL, "DBVDD2" },
1134  { "AIF2 Playback", NULL, "DBVDD2" },
1135 
1136  { "AIF3 Capture", NULL, "DBVDD3" },
1137  { "AIF3 Playback", NULL, "DBVDD3" },
1138 
1139  { "OUT1L", NULL, "CPVDD" },
1140  { "OUT1R", NULL, "CPVDD" },
1141  { "OUT2L", NULL, "CPVDD" },
1142  { "OUT2R", NULL, "CPVDD" },
1143  { "OUT3L", NULL, "CPVDD" },
1144 
1145  { "OUT4L", NULL, "SPKVDDL" },
1146  { "OUT4R", NULL, "SPKVDDR" },
1147 
1148  { "OUT1L", NULL, "SYSCLK" },
1149  { "OUT1R", NULL, "SYSCLK" },
1150  { "OUT2L", NULL, "SYSCLK" },
1151  { "OUT2R", NULL, "SYSCLK" },
1152  { "OUT3L", NULL, "SYSCLK" },
1153  { "OUT4L", NULL, "SYSCLK" },
1154  { "OUT4R", NULL, "SYSCLK" },
1155  { "OUT5L", NULL, "SYSCLK" },
1156  { "OUT5R", NULL, "SYSCLK" },
1157 
1158  { "MICBIAS1", NULL, "MICVDD" },
1159  { "MICBIAS2", NULL, "MICVDD" },
1160  { "MICBIAS3", NULL, "MICVDD" },
1161 
1162  { "Noise Generator", NULL, "NOISE" },
1163  { "Tone Generator 1", NULL, "TONE" },
1164  { "Tone Generator 2", NULL, "TONE" },
1165 
1166  { "Mic Mute Mixer", NULL, "Noise Mixer" },
1167  { "Mic Mute Mixer", NULL, "Mic Mixer" },
1168 
1169  { "AIF1 Capture", NULL, "AIF1TX1" },
1170  { "AIF1 Capture", NULL, "AIF1TX2" },
1171  { "AIF1 Capture", NULL, "AIF1TX3" },
1172  { "AIF1 Capture", NULL, "AIF1TX4" },
1173  { "AIF1 Capture", NULL, "AIF1TX5" },
1174  { "AIF1 Capture", NULL, "AIF1TX6" },
1175  { "AIF1 Capture", NULL, "AIF1TX7" },
1176  { "AIF1 Capture", NULL, "AIF1TX8" },
1177 
1178  { "AIF1RX1", NULL, "AIF1 Playback" },
1179  { "AIF1RX2", NULL, "AIF1 Playback" },
1180  { "AIF1RX3", NULL, "AIF1 Playback" },
1181  { "AIF1RX4", NULL, "AIF1 Playback" },
1182  { "AIF1RX5", NULL, "AIF1 Playback" },
1183  { "AIF1RX6", NULL, "AIF1 Playback" },
1184  { "AIF1RX7", NULL, "AIF1 Playback" },
1185  { "AIF1RX8", NULL, "AIF1 Playback" },
1186 
1187  { "AIF2 Capture", NULL, "AIF2TX1" },
1188  { "AIF2 Capture", NULL, "AIF2TX2" },
1189 
1190  { "AIF2RX1", NULL, "AIF2 Playback" },
1191  { "AIF2RX2", NULL, "AIF2 Playback" },
1192 
1193  { "AIF3 Capture", NULL, "AIF3TX1" },
1194  { "AIF3 Capture", NULL, "AIF3TX2" },
1195 
1196  { "AIF3RX1", NULL, "AIF3 Playback" },
1197  { "AIF3RX2", NULL, "AIF3 Playback" },
1198 
1199  { "AIF1 Playback", NULL, "SYSCLK" },
1200  { "AIF2 Playback", NULL, "SYSCLK" },
1201  { "AIF3 Playback", NULL, "SYSCLK" },
1202 
1203  { "AIF1 Capture", NULL, "SYSCLK" },
1204  { "AIF2 Capture", NULL, "SYSCLK" },
1205  { "AIF3 Capture", NULL, "SYSCLK" },
1206 
1207  { "IN1L PGA", NULL, "IN1L" },
1208  { "IN1R PGA", NULL, "IN1R" },
1209 
1210  { "IN2L PGA", NULL, "IN2L" },
1211  { "IN2R PGA", NULL, "IN2R" },
1212 
1213  { "IN3L PGA", NULL, "IN3L" },
1214  { "IN3R PGA", NULL, "IN3R" },
1215 
1216  ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1217  ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1218  ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
1219  ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
1220  ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"),
1221 
1222  ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
1223  ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
1224  ARIZONA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
1225  ARIZONA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
1226 
1227  ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1228  ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1229 
1230  ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1231  ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1232  ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1233  ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1234  ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1235  ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1236  ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
1237  ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
1238 
1239  ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1240  ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1241 
1242  ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1243  ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1244 
1245  ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
1246  ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
1247  ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
1248  ARIZONA_MIXER_ROUTES("EQ4", "EQ4"),
1249 
1250  ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
1251  ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
1252 
1253  ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
1254  ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
1255  ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
1256  ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
1257 
1258  ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
1259  ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
1260  ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
1261  ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
1262 
1263  { "AEC Loopback", "HPOUT1L", "OUT1L" },
1264  { "AEC Loopback", "HPOUT1R", "OUT1R" },
1265  { "HPOUT1L", NULL, "OUT1L" },
1266  { "HPOUT1R", NULL, "OUT1R" },
1267 
1268  { "AEC Loopback", "HPOUT2L", "OUT2L" },
1269  { "AEC Loopback", "HPOUT2R", "OUT2R" },
1270  { "HPOUT2L", NULL, "OUT2L" },
1271  { "HPOUT2R", NULL, "OUT2R" },
1272 
1273  { "AEC Loopback", "EPOUT", "OUT3L" },
1274  { "EPOUTN", NULL, "OUT3L" },
1275  { "EPOUTP", NULL, "OUT3L" },
1276 
1277  { "AEC Loopback", "SPKOUTL", "OUT4L" },
1278  { "SPKOUTLN", NULL, "OUT4L" },
1279  { "SPKOUTLP", NULL, "OUT4L" },
1280 
1281  { "AEC Loopback", "SPKOUTR", "OUT4R" },
1282  { "SPKOUTRN", NULL, "OUT4R" },
1283  { "SPKOUTRP", NULL, "OUT4R" },
1284 
1285  { "AEC Loopback", "SPKDAT1L", "OUT5L" },
1286  { "AEC Loopback", "SPKDAT1R", "OUT5R" },
1287  { "SPKDAT1L", NULL, "OUT5L" },
1288  { "SPKDAT1R", NULL, "OUT5R" },
1289 };
1290 
1291 static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1292  unsigned int Fref, unsigned int Fout)
1293 {
1294  struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
1295 
1296  switch (fll_id) {
1297  case WM5102_FLL1:
1298  return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout);
1299  case WM5102_FLL2:
1300  return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout);
1301  default:
1302  return -EINVAL;
1303  }
1304 }
1305 
1306 #define WM5102_RATES SNDRV_PCM_RATE_8000_192000
1307 
1308 #define WM5102_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1309  SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1310 
1311 static struct snd_soc_dai_driver wm5102_dai[] = {
1312  {
1313  .name = "wm5102-aif1",
1314  .id = 1,
1315  .base = ARIZONA_AIF1_BCLK_CTRL,
1316  .playback = {
1317  .stream_name = "AIF1 Playback",
1318  .channels_min = 1,
1319  .channels_max = 8,
1320  .rates = WM5102_RATES,
1321  .formats = WM5102_FORMATS,
1322  },
1323  .capture = {
1324  .stream_name = "AIF1 Capture",
1325  .channels_min = 1,
1326  .channels_max = 8,
1327  .rates = WM5102_RATES,
1328  .formats = WM5102_FORMATS,
1329  },
1330  .ops = &arizona_dai_ops,
1331  .symmetric_rates = 1,
1332  },
1333  {
1334  .name = "wm5102-aif2",
1335  .id = 2,
1336  .base = ARIZONA_AIF2_BCLK_CTRL,
1337  .playback = {
1338  .stream_name = "AIF2 Playback",
1339  .channels_min = 1,
1340  .channels_max = 2,
1341  .rates = WM5102_RATES,
1342  .formats = WM5102_FORMATS,
1343  },
1344  .capture = {
1345  .stream_name = "AIF2 Capture",
1346  .channels_min = 1,
1347  .channels_max = 2,
1348  .rates = WM5102_RATES,
1349  .formats = WM5102_FORMATS,
1350  },
1351  .ops = &arizona_dai_ops,
1352  .symmetric_rates = 1,
1353  },
1354  {
1355  .name = "wm5102-aif3",
1356  .id = 3,
1357  .base = ARIZONA_AIF3_BCLK_CTRL,
1358  .playback = {
1359  .stream_name = "AIF3 Playback",
1360  .channels_min = 1,
1361  .channels_max = 2,
1362  .rates = WM5102_RATES,
1363  .formats = WM5102_FORMATS,
1364  },
1365  .capture = {
1366  .stream_name = "AIF3 Capture",
1367  .channels_min = 1,
1368  .channels_max = 2,
1369  .rates = WM5102_RATES,
1370  .formats = WM5102_FORMATS,
1371  },
1372  .ops = &arizona_dai_ops,
1373  .symmetric_rates = 1,
1374  },
1375 };
1376 
1377 static int wm5102_codec_probe(struct snd_soc_codec *codec)
1378 {
1379  struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
1380 
1381  codec->control_data = priv->core.arizona->regmap;
1382  return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
1383 }
1384 
1385 #define WM5102_DIG_VU 0x0200
1386 
1387 static unsigned int wm5102_digital_vu[] = {
1394 
1405 };
1406 
1407 static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
1408  .probe = wm5102_codec_probe,
1409 
1410  .idle_bias_off = true,
1411 
1412  .set_sysclk = arizona_set_sysclk,
1413  .set_pll = wm5102_set_fll,
1414 
1415  .controls = wm5102_snd_controls,
1416  .num_controls = ARRAY_SIZE(wm5102_snd_controls),
1417  .dapm_widgets = wm5102_dapm_widgets,
1418  .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets),
1419  .dapm_routes = wm5102_dapm_routes,
1420  .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),
1421 };
1422 
1423 static int __devinit wm5102_probe(struct platform_device *pdev)
1424 {
1425  struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1426  struct wm5102_priv *wm5102;
1427  int i;
1428 
1429  wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv),
1430  GFP_KERNEL);
1431  if (wm5102 == NULL)
1432  return -ENOMEM;
1433  platform_set_drvdata(pdev, wm5102);
1434 
1435  wm5102->core.arizona = arizona;
1436 
1437  for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++)
1438  wm5102->fll[i].vco_mult = 1;
1439 
1440  arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
1442  &wm5102->fll[0]);
1443  arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
1445  &wm5102->fll[1]);
1446 
1447  for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++)
1448  arizona_init_dai(&wm5102->core, i);
1449 
1450  /* Latch volume update bits */
1451  for (i = 0; i < ARRAY_SIZE(wm5102_digital_vu); i++)
1452  regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
1454 
1455  pm_runtime_enable(&pdev->dev);
1456  pm_runtime_idle(&pdev->dev);
1457 
1458  return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
1459  wm5102_dai, ARRAY_SIZE(wm5102_dai));
1460 }
1461 
1462 static int __devexit wm5102_remove(struct platform_device *pdev)
1463 {
1464  snd_soc_unregister_codec(&pdev->dev);
1465  pm_runtime_disable(&pdev->dev);
1466 
1467  return 0;
1468 }
1469 
1470 static struct platform_driver wm5102_codec_driver = {
1471  .driver = {
1472  .name = "wm5102-codec",
1473  .owner = THIS_MODULE,
1474  },
1475  .probe = wm5102_probe,
1476  .remove = __devexit_p(wm5102_remove),
1477 };
1478 
1479 module_platform_driver(wm5102_codec_driver);
1480 
1481 MODULE_DESCRIPTION("ASoC WM5102 driver");
1482 MODULE_AUTHOR("Mark Brown <[email protected]>");
1483 MODULE_LICENSE("GPL");
1484 MODULE_ALIAS("platform:wm5102-codec");