Merge remote-tracking branch 'asoc/topic/fsl' into asoc-next
[pandora-kernel.git] / sound / soc / codecs / wm2200.c
1 /*
2  * wm2200.c  --  WM2200 ALSA SoC Audio driver
3  *
4  * Copyright 2012 Wolfson Microelectronics plc
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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/firmware.h>
19 #include <linux/gcd.h>
20 #include <linux/gpio.h>
21 #include <linux/i2c.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/regulator/fixed.h>
25 #include <linux/slab.h>
26 #include <sound/core.h>
27 #include <sound/pcm.h>
28 #include <sound/pcm_params.h>
29 #include <sound/soc.h>
30 #include <sound/jack.h>
31 #include <sound/initval.h>
32 #include <sound/tlv.h>
33 #include <sound/wm2200.h>
34
35 #include "wm2200.h"
36 #include "wmfw.h"
37
38 #define WM2200_DSP_CONTROL_1                   0x00
39 #define WM2200_DSP_CONTROL_2                   0x02
40 #define WM2200_DSP_CONTROL_3                   0x03
41 #define WM2200_DSP_CONTROL_4                   0x04
42 #define WM2200_DSP_CONTROL_5                   0x06
43 #define WM2200_DSP_CONTROL_6                   0x07
44 #define WM2200_DSP_CONTROL_7                   0x08
45 #define WM2200_DSP_CONTROL_8                   0x09
46 #define WM2200_DSP_CONTROL_9                   0x0A
47 #define WM2200_DSP_CONTROL_10                  0x0B
48 #define WM2200_DSP_CONTROL_11                  0x0C
49 #define WM2200_DSP_CONTROL_12                  0x0D
50 #define WM2200_DSP_CONTROL_13                  0x0F
51 #define WM2200_DSP_CONTROL_14                  0x10
52 #define WM2200_DSP_CONTROL_15                  0x11
53 #define WM2200_DSP_CONTROL_16                  0x12
54 #define WM2200_DSP_CONTROL_17                  0x13
55 #define WM2200_DSP_CONTROL_18                  0x14
56 #define WM2200_DSP_CONTROL_19                  0x16
57 #define WM2200_DSP_CONTROL_20                  0x17
58 #define WM2200_DSP_CONTROL_21                  0x18
59 #define WM2200_DSP_CONTROL_22                  0x1A
60 #define WM2200_DSP_CONTROL_23                  0x1B
61 #define WM2200_DSP_CONTROL_24                  0x1C
62 #define WM2200_DSP_CONTROL_25                  0x1E
63 #define WM2200_DSP_CONTROL_26                  0x20
64 #define WM2200_DSP_CONTROL_27                  0x21
65 #define WM2200_DSP_CONTROL_28                  0x22
66 #define WM2200_DSP_CONTROL_29                  0x23
67 #define WM2200_DSP_CONTROL_30                  0x24
68 #define WM2200_DSP_CONTROL_31                  0x26
69
70 /* The code assumes DCVDD is generated internally */
71 #define WM2200_NUM_CORE_SUPPLIES 2
72 static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = {
73         "DBVDD",
74         "LDOVDD",
75 };
76
77 struct wm2200_fll {
78         int fref;
79         int fout;
80         int src;
81         struct completion lock;
82 };
83
84 /* codec private data */
85 struct wm2200_priv {
86         struct regmap *regmap;
87         struct device *dev;
88         struct snd_soc_codec *codec;
89         struct wm2200_pdata pdata;
90         struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
91
92         struct completion fll_lock;
93         int fll_fout;
94         int fll_fref;
95         int fll_src;
96
97         int rev;
98         int sysclk;
99 };
100
101 #define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1)
102 #define WM2200_DSP_SPACING 12288
103
104 #define WM2200_DSP1_DM_BASE (WM2200_DSP_RANGE_BASE + (0 * WM2200_DSP_SPACING))
105 #define WM2200_DSP1_PM_BASE (WM2200_DSP_RANGE_BASE + (1 * WM2200_DSP_SPACING))
106 #define WM2200_DSP1_ZM_BASE (WM2200_DSP_RANGE_BASE + (2 * WM2200_DSP_SPACING))
107 #define WM2200_DSP2_DM_BASE (WM2200_DSP_RANGE_BASE + (3 * WM2200_DSP_SPACING))
108 #define WM2200_DSP2_PM_BASE (WM2200_DSP_RANGE_BASE + (4 * WM2200_DSP_SPACING))
109 #define WM2200_DSP2_ZM_BASE (WM2200_DSP_RANGE_BASE + (5 * WM2200_DSP_SPACING))
110
111 static const struct regmap_range_cfg wm2200_ranges[] = {
112         /* DSP1 DM */
113         { .range_min = WM2200_DSP1_DM_BASE,
114           .range_max = WM2200_DSP1_DM_BASE + 12287,
115           .selector_reg = WM2200_DSP1_CONTROL_3,
116           .selector_mask = WM2200_DSP1_PAGE_BASE_DM_0_MASK,
117           .selector_shift = WM2200_DSP1_PAGE_BASE_DM_0_SHIFT,
118           .window_start = WM2200_DSP1_DM_0, .window_len = 2048, },
119
120         /* DSP1 PM */
121         { .range_min = WM2200_DSP1_PM_BASE,
122           .range_max = WM2200_DSP1_PM_BASE + 12287,
123           .selector_reg = WM2200_DSP1_CONTROL_2,
124           .selector_mask = WM2200_DSP1_PAGE_BASE_PM_0_MASK,
125           .selector_shift = WM2200_DSP1_PAGE_BASE_PM_0_SHIFT,
126           .window_start = WM2200_DSP1_PM_0, .window_len = 768, },
127
128         /* DSP1 ZM */
129         { .range_min = WM2200_DSP1_ZM_BASE,
130           .range_max = WM2200_DSP1_ZM_BASE + 2047,
131           .selector_reg = WM2200_DSP1_CONTROL_4,
132           .selector_mask = WM2200_DSP1_PAGE_BASE_ZM_0_MASK,
133           .selector_shift = WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT,
134           .window_start = WM2200_DSP1_ZM_0, .window_len = 1024, },
135
136         /* DSP2 DM */
137         { .range_min = WM2200_DSP2_DM_BASE,
138           .range_max = WM2200_DSP2_DM_BASE + 4095,
139           .selector_reg = WM2200_DSP2_CONTROL_3,
140           .selector_mask = WM2200_DSP2_PAGE_BASE_DM_0_MASK,
141           .selector_shift = WM2200_DSP2_PAGE_BASE_DM_0_SHIFT,
142           .window_start = WM2200_DSP2_DM_0, .window_len = 2048, },
143
144         /* DSP2 PM */
145         { .range_min = WM2200_DSP2_PM_BASE,
146           .range_max = WM2200_DSP2_PM_BASE + 11287,
147           .selector_reg = WM2200_DSP2_CONTROL_2,
148           .selector_mask = WM2200_DSP2_PAGE_BASE_PM_0_MASK,
149           .selector_shift = WM2200_DSP2_PAGE_BASE_PM_0_SHIFT,
150           .window_start = WM2200_DSP2_PM_0, .window_len = 768, },
151
152         /* DSP2 ZM */
153         { .range_min = WM2200_DSP2_ZM_BASE,
154           .range_max = WM2200_DSP2_ZM_BASE + 2047,
155           .selector_reg = WM2200_DSP2_CONTROL_4,
156           .selector_mask = WM2200_DSP2_PAGE_BASE_ZM_0_MASK,
157           .selector_shift = WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT,
158           .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, },
159 };
160
161 static struct reg_default wm2200_reg_defaults[] = {
162         { 0x000B, 0x0000 },   /* R11    - Tone Generator 1 */
163         { 0x0102, 0x0000 },   /* R258   - Clocking 3 */
164         { 0x0103, 0x0011 },   /* R259   - Clocking 4 */
165         { 0x0111, 0x0000 },   /* R273   - FLL Control 1 */
166         { 0x0112, 0x0000 },   /* R274   - FLL Control 2 */
167         { 0x0113, 0x0000 },   /* R275   - FLL Control 3 */
168         { 0x0114, 0x0000 },   /* R276   - FLL Control 4 */
169         { 0x0116, 0x0177 },   /* R278   - FLL Control 6 */
170         { 0x0117, 0x0004 },   /* R279   - FLL Control 7 */
171         { 0x0119, 0x0000 },   /* R281   - FLL EFS 1 */
172         { 0x011A, 0x0002 },   /* R282   - FLL EFS 2 */
173         { 0x0200, 0x0000 },   /* R512   - Mic Charge Pump 1 */
174         { 0x0201, 0x03FF },   /* R513   - Mic Charge Pump 2 */
175         { 0x0202, 0x9BDE },   /* R514   - DM Charge Pump 1 */
176         { 0x020C, 0x0000 },   /* R524   - Mic Bias Ctrl 1 */
177         { 0x020D, 0x0000 },   /* R525   - Mic Bias Ctrl 2 */
178         { 0x020F, 0x0000 },   /* R527   - Ear Piece Ctrl 1 */
179         { 0x0210, 0x0000 },   /* R528   - Ear Piece Ctrl 2 */
180         { 0x0301, 0x0000 },   /* R769   - Input Enables */
181         { 0x0302, 0x2240 },   /* R770   - IN1L Control */
182         { 0x0303, 0x0040 },   /* R771   - IN1R Control */
183         { 0x0304, 0x2240 },   /* R772   - IN2L Control */
184         { 0x0305, 0x0040 },   /* R773   - IN2R Control */
185         { 0x0306, 0x2240 },   /* R774   - IN3L Control */
186         { 0x0307, 0x0040 },   /* R775   - IN3R Control */
187         { 0x030A, 0x0000 },   /* R778   - RXANC_SRC */
188         { 0x030B, 0x0022 },   /* R779   - Input Volume Ramp */
189         { 0x030C, 0x0180 },   /* R780   - ADC Digital Volume 1L */
190         { 0x030D, 0x0180 },   /* R781   - ADC Digital Volume 1R */
191         { 0x030E, 0x0180 },   /* R782   - ADC Digital Volume 2L */
192         { 0x030F, 0x0180 },   /* R783   - ADC Digital Volume 2R */
193         { 0x0310, 0x0180 },   /* R784   - ADC Digital Volume 3L */
194         { 0x0311, 0x0180 },   /* R785   - ADC Digital Volume 3R */
195         { 0x0400, 0x0000 },   /* R1024  - Output Enables */
196         { 0x0401, 0x0000 },   /* R1025  - DAC Volume Limit 1L */
197         { 0x0402, 0x0000 },   /* R1026  - DAC Volume Limit 1R */
198         { 0x0403, 0x0000 },   /* R1027  - DAC Volume Limit 2L */
199         { 0x0404, 0x0000 },   /* R1028  - DAC Volume Limit 2R */
200         { 0x0409, 0x0000 },   /* R1033  - DAC AEC Control 1 */
201         { 0x040A, 0x0022 },   /* R1034  - Output Volume Ramp */
202         { 0x040B, 0x0180 },   /* R1035  - DAC Digital Volume 1L */
203         { 0x040C, 0x0180 },   /* R1036  - DAC Digital Volume 1R */
204         { 0x040D, 0x0180 },   /* R1037  - DAC Digital Volume 2L */
205         { 0x040E, 0x0180 },   /* R1038  - DAC Digital Volume 2R */
206         { 0x0417, 0x0069 },   /* R1047  - PDM 1 */
207         { 0x0418, 0x0000 },   /* R1048  - PDM 2 */
208         { 0x0500, 0x0000 },   /* R1280  - Audio IF 1_1 */
209         { 0x0501, 0x0008 },   /* R1281  - Audio IF 1_2 */
210         { 0x0502, 0x0000 },   /* R1282  - Audio IF 1_3 */
211         { 0x0503, 0x0000 },   /* R1283  - Audio IF 1_4 */
212         { 0x0504, 0x0000 },   /* R1284  - Audio IF 1_5 */
213         { 0x0505, 0x0001 },   /* R1285  - Audio IF 1_6 */
214         { 0x0506, 0x0001 },   /* R1286  - Audio IF 1_7 */
215         { 0x0507, 0x0000 },   /* R1287  - Audio IF 1_8 */
216         { 0x0508, 0x0000 },   /* R1288  - Audio IF 1_9 */
217         { 0x0509, 0x0000 },   /* R1289  - Audio IF 1_10 */
218         { 0x050A, 0x0000 },   /* R1290  - Audio IF 1_11 */
219         { 0x050B, 0x0000 },   /* R1291  - Audio IF 1_12 */
220         { 0x050C, 0x0000 },   /* R1292  - Audio IF 1_13 */
221         { 0x050D, 0x0000 },   /* R1293  - Audio IF 1_14 */
222         { 0x050E, 0x0000 },   /* R1294  - Audio IF 1_15 */
223         { 0x050F, 0x0000 },   /* R1295  - Audio IF 1_16 */
224         { 0x0510, 0x0000 },   /* R1296  - Audio IF 1_17 */
225         { 0x0511, 0x0000 },   /* R1297  - Audio IF 1_18 */
226         { 0x0512, 0x0000 },   /* R1298  - Audio IF 1_19 */
227         { 0x0513, 0x0000 },   /* R1299  - Audio IF 1_20 */
228         { 0x0514, 0x0000 },   /* R1300  - Audio IF 1_21 */
229         { 0x0515, 0x0001 },   /* R1301  - Audio IF 1_22 */
230         { 0x0600, 0x0000 },   /* R1536  - OUT1LMIX Input 1 Source */
231         { 0x0601, 0x0080 },   /* R1537  - OUT1LMIX Input 1 Volume */
232         { 0x0602, 0x0000 },   /* R1538  - OUT1LMIX Input 2 Source */
233         { 0x0603, 0x0080 },   /* R1539  - OUT1LMIX Input 2 Volume */
234         { 0x0604, 0x0000 },   /* R1540  - OUT1LMIX Input 3 Source */
235         { 0x0605, 0x0080 },   /* R1541  - OUT1LMIX Input 3 Volume */
236         { 0x0606, 0x0000 },   /* R1542  - OUT1LMIX Input 4 Source */
237         { 0x0607, 0x0080 },   /* R1543  - OUT1LMIX Input 4 Volume */
238         { 0x0608, 0x0000 },   /* R1544  - OUT1RMIX Input 1 Source */
239         { 0x0609, 0x0080 },   /* R1545  - OUT1RMIX Input 1 Volume */
240         { 0x060A, 0x0000 },   /* R1546  - OUT1RMIX Input 2 Source */
241         { 0x060B, 0x0080 },   /* R1547  - OUT1RMIX Input 2 Volume */
242         { 0x060C, 0x0000 },   /* R1548  - OUT1RMIX Input 3 Source */
243         { 0x060D, 0x0080 },   /* R1549  - OUT1RMIX Input 3 Volume */
244         { 0x060E, 0x0000 },   /* R1550  - OUT1RMIX Input 4 Source */
245         { 0x060F, 0x0080 },   /* R1551  - OUT1RMIX Input 4 Volume */
246         { 0x0610, 0x0000 },   /* R1552  - OUT2LMIX Input 1 Source */
247         { 0x0611, 0x0080 },   /* R1553  - OUT2LMIX Input 1 Volume */
248         { 0x0612, 0x0000 },   /* R1554  - OUT2LMIX Input 2 Source */
249         { 0x0613, 0x0080 },   /* R1555  - OUT2LMIX Input 2 Volume */
250         { 0x0614, 0x0000 },   /* R1556  - OUT2LMIX Input 3 Source */
251         { 0x0615, 0x0080 },   /* R1557  - OUT2LMIX Input 3 Volume */
252         { 0x0616, 0x0000 },   /* R1558  - OUT2LMIX Input 4 Source */
253         { 0x0617, 0x0080 },   /* R1559  - OUT2LMIX Input 4 Volume */
254         { 0x0618, 0x0000 },   /* R1560  - OUT2RMIX Input 1 Source */
255         { 0x0619, 0x0080 },   /* R1561  - OUT2RMIX Input 1 Volume */
256         { 0x061A, 0x0000 },   /* R1562  - OUT2RMIX Input 2 Source */
257         { 0x061B, 0x0080 },   /* R1563  - OUT2RMIX Input 2 Volume */
258         { 0x061C, 0x0000 },   /* R1564  - OUT2RMIX Input 3 Source */
259         { 0x061D, 0x0080 },   /* R1565  - OUT2RMIX Input 3 Volume */
260         { 0x061E, 0x0000 },   /* R1566  - OUT2RMIX Input 4 Source */
261         { 0x061F, 0x0080 },   /* R1567  - OUT2RMIX Input 4 Volume */
262         { 0x0620, 0x0000 },   /* R1568  - AIF1TX1MIX Input 1 Source */
263         { 0x0621, 0x0080 },   /* R1569  - AIF1TX1MIX Input 1 Volume */
264         { 0x0622, 0x0000 },   /* R1570  - AIF1TX1MIX Input 2 Source */
265         { 0x0623, 0x0080 },   /* R1571  - AIF1TX1MIX Input 2 Volume */
266         { 0x0624, 0x0000 },   /* R1572  - AIF1TX1MIX Input 3 Source */
267         { 0x0625, 0x0080 },   /* R1573  - AIF1TX1MIX Input 3 Volume */
268         { 0x0626, 0x0000 },   /* R1574  - AIF1TX1MIX Input 4 Source */
269         { 0x0627, 0x0080 },   /* R1575  - AIF1TX1MIX Input 4 Volume */
270         { 0x0628, 0x0000 },   /* R1576  - AIF1TX2MIX Input 1 Source */
271         { 0x0629, 0x0080 },   /* R1577  - AIF1TX2MIX Input 1 Volume */
272         { 0x062A, 0x0000 },   /* R1578  - AIF1TX2MIX Input 2 Source */
273         { 0x062B, 0x0080 },   /* R1579  - AIF1TX2MIX Input 2 Volume */
274         { 0x062C, 0x0000 },   /* R1580  - AIF1TX2MIX Input 3 Source */
275         { 0x062D, 0x0080 },   /* R1581  - AIF1TX2MIX Input 3 Volume */
276         { 0x062E, 0x0000 },   /* R1582  - AIF1TX2MIX Input 4 Source */
277         { 0x062F, 0x0080 },   /* R1583  - AIF1TX2MIX Input 4 Volume */
278         { 0x0630, 0x0000 },   /* R1584  - AIF1TX3MIX Input 1 Source */
279         { 0x0631, 0x0080 },   /* R1585  - AIF1TX3MIX Input 1 Volume */
280         { 0x0632, 0x0000 },   /* R1586  - AIF1TX3MIX Input 2 Source */
281         { 0x0633, 0x0080 },   /* R1587  - AIF1TX3MIX Input 2 Volume */
282         { 0x0634, 0x0000 },   /* R1588  - AIF1TX3MIX Input 3 Source */
283         { 0x0635, 0x0080 },   /* R1589  - AIF1TX3MIX Input 3 Volume */
284         { 0x0636, 0x0000 },   /* R1590  - AIF1TX3MIX Input 4 Source */
285         { 0x0637, 0x0080 },   /* R1591  - AIF1TX3MIX Input 4 Volume */
286         { 0x0638, 0x0000 },   /* R1592  - AIF1TX4MIX Input 1 Source */
287         { 0x0639, 0x0080 },   /* R1593  - AIF1TX4MIX Input 1 Volume */
288         { 0x063A, 0x0000 },   /* R1594  - AIF1TX4MIX Input 2 Source */
289         { 0x063B, 0x0080 },   /* R1595  - AIF1TX4MIX Input 2 Volume */
290         { 0x063C, 0x0000 },   /* R1596  - AIF1TX4MIX Input 3 Source */
291         { 0x063D, 0x0080 },   /* R1597  - AIF1TX4MIX Input 3 Volume */
292         { 0x063E, 0x0000 },   /* R1598  - AIF1TX4MIX Input 4 Source */
293         { 0x063F, 0x0080 },   /* R1599  - AIF1TX4MIX Input 4 Volume */
294         { 0x0640, 0x0000 },   /* R1600  - AIF1TX5MIX Input 1 Source */
295         { 0x0641, 0x0080 },   /* R1601  - AIF1TX5MIX Input 1 Volume */
296         { 0x0642, 0x0000 },   /* R1602  - AIF1TX5MIX Input 2 Source */
297         { 0x0643, 0x0080 },   /* R1603  - AIF1TX5MIX Input 2 Volume */
298         { 0x0644, 0x0000 },   /* R1604  - AIF1TX5MIX Input 3 Source */
299         { 0x0645, 0x0080 },   /* R1605  - AIF1TX5MIX Input 3 Volume */
300         { 0x0646, 0x0000 },   /* R1606  - AIF1TX5MIX Input 4 Source */
301         { 0x0647, 0x0080 },   /* R1607  - AIF1TX5MIX Input 4 Volume */
302         { 0x0648, 0x0000 },   /* R1608  - AIF1TX6MIX Input 1 Source */
303         { 0x0649, 0x0080 },   /* R1609  - AIF1TX6MIX Input 1 Volume */
304         { 0x064A, 0x0000 },   /* R1610  - AIF1TX6MIX Input 2 Source */
305         { 0x064B, 0x0080 },   /* R1611  - AIF1TX6MIX Input 2 Volume */
306         { 0x064C, 0x0000 },   /* R1612  - AIF1TX6MIX Input 3 Source */
307         { 0x064D, 0x0080 },   /* R1613  - AIF1TX6MIX Input 3 Volume */
308         { 0x064E, 0x0000 },   /* R1614  - AIF1TX6MIX Input 4 Source */
309         { 0x064F, 0x0080 },   /* R1615  - AIF1TX6MIX Input 4 Volume */
310         { 0x0650, 0x0000 },   /* R1616  - EQLMIX Input 1 Source */
311         { 0x0651, 0x0080 },   /* R1617  - EQLMIX Input 1 Volume */
312         { 0x0652, 0x0000 },   /* R1618  - EQLMIX Input 2 Source */
313         { 0x0653, 0x0080 },   /* R1619  - EQLMIX Input 2 Volume */
314         { 0x0654, 0x0000 },   /* R1620  - EQLMIX Input 3 Source */
315         { 0x0655, 0x0080 },   /* R1621  - EQLMIX Input 3 Volume */
316         { 0x0656, 0x0000 },   /* R1622  - EQLMIX Input 4 Source */
317         { 0x0657, 0x0080 },   /* R1623  - EQLMIX Input 4 Volume */
318         { 0x0658, 0x0000 },   /* R1624  - EQRMIX Input 1 Source */
319         { 0x0659, 0x0080 },   /* R1625  - EQRMIX Input 1 Volume */
320         { 0x065A, 0x0000 },   /* R1626  - EQRMIX Input 2 Source */
321         { 0x065B, 0x0080 },   /* R1627  - EQRMIX Input 2 Volume */
322         { 0x065C, 0x0000 },   /* R1628  - EQRMIX Input 3 Source */
323         { 0x065D, 0x0080 },   /* R1629  - EQRMIX Input 3 Volume */
324         { 0x065E, 0x0000 },   /* R1630  - EQRMIX Input 4 Source */
325         { 0x065F, 0x0080 },   /* R1631  - EQRMIX Input 4 Volume */
326         { 0x0660, 0x0000 },   /* R1632  - LHPF1MIX Input 1 Source */
327         { 0x0661, 0x0080 },   /* R1633  - LHPF1MIX Input 1 Volume */
328         { 0x0662, 0x0000 },   /* R1634  - LHPF1MIX Input 2 Source */
329         { 0x0663, 0x0080 },   /* R1635  - LHPF1MIX Input 2 Volume */
330         { 0x0664, 0x0000 },   /* R1636  - LHPF1MIX Input 3 Source */
331         { 0x0665, 0x0080 },   /* R1637  - LHPF1MIX Input 3 Volume */
332         { 0x0666, 0x0000 },   /* R1638  - LHPF1MIX Input 4 Source */
333         { 0x0667, 0x0080 },   /* R1639  - LHPF1MIX Input 4 Volume */
334         { 0x0668, 0x0000 },   /* R1640  - LHPF2MIX Input 1 Source */
335         { 0x0669, 0x0080 },   /* R1641  - LHPF2MIX Input 1 Volume */
336         { 0x066A, 0x0000 },   /* R1642  - LHPF2MIX Input 2 Source */
337         { 0x066B, 0x0080 },   /* R1643  - LHPF2MIX Input 2 Volume */
338         { 0x066C, 0x0000 },   /* R1644  - LHPF2MIX Input 3 Source */
339         { 0x066D, 0x0080 },   /* R1645  - LHPF2MIX Input 3 Volume */
340         { 0x066E, 0x0000 },   /* R1646  - LHPF2MIX Input 4 Source */
341         { 0x066F, 0x0080 },   /* R1647  - LHPF2MIX Input 4 Volume */
342         { 0x0670, 0x0000 },   /* R1648  - DSP1LMIX Input 1 Source */
343         { 0x0671, 0x0080 },   /* R1649  - DSP1LMIX Input 1 Volume */
344         { 0x0672, 0x0000 },   /* R1650  - DSP1LMIX Input 2 Source */
345         { 0x0673, 0x0080 },   /* R1651  - DSP1LMIX Input 2 Volume */
346         { 0x0674, 0x0000 },   /* R1652  - DSP1LMIX Input 3 Source */
347         { 0x0675, 0x0080 },   /* R1653  - DSP1LMIX Input 3 Volume */
348         { 0x0676, 0x0000 },   /* R1654  - DSP1LMIX Input 4 Source */
349         { 0x0677, 0x0080 },   /* R1655  - DSP1LMIX Input 4 Volume */
350         { 0x0678, 0x0000 },   /* R1656  - DSP1RMIX Input 1 Source */
351         { 0x0679, 0x0080 },   /* R1657  - DSP1RMIX Input 1 Volume */
352         { 0x067A, 0x0000 },   /* R1658  - DSP1RMIX Input 2 Source */
353         { 0x067B, 0x0080 },   /* R1659  - DSP1RMIX Input 2 Volume */
354         { 0x067C, 0x0000 },   /* R1660  - DSP1RMIX Input 3 Source */
355         { 0x067D, 0x0080 },   /* R1661  - DSP1RMIX Input 3 Volume */
356         { 0x067E, 0x0000 },   /* R1662  - DSP1RMIX Input 4 Source */
357         { 0x067F, 0x0080 },   /* R1663  - DSP1RMIX Input 4 Volume */
358         { 0x0680, 0x0000 },   /* R1664  - DSP1AUX1MIX Input 1 Source */
359         { 0x0681, 0x0000 },   /* R1665  - DSP1AUX2MIX Input 1 Source */
360         { 0x0682, 0x0000 },   /* R1666  - DSP1AUX3MIX Input 1 Source */
361         { 0x0683, 0x0000 },   /* R1667  - DSP1AUX4MIX Input 1 Source */
362         { 0x0684, 0x0000 },   /* R1668  - DSP1AUX5MIX Input 1 Source */
363         { 0x0685, 0x0000 },   /* R1669  - DSP1AUX6MIX Input 1 Source */
364         { 0x0686, 0x0000 },   /* R1670  - DSP2LMIX Input 1 Source */
365         { 0x0687, 0x0080 },   /* R1671  - DSP2LMIX Input 1 Volume */
366         { 0x0688, 0x0000 },   /* R1672  - DSP2LMIX Input 2 Source */
367         { 0x0689, 0x0080 },   /* R1673  - DSP2LMIX Input 2 Volume */
368         { 0x068A, 0x0000 },   /* R1674  - DSP2LMIX Input 3 Source */
369         { 0x068B, 0x0080 },   /* R1675  - DSP2LMIX Input 3 Volume */
370         { 0x068C, 0x0000 },   /* R1676  - DSP2LMIX Input 4 Source */
371         { 0x068D, 0x0080 },   /* R1677  - DSP2LMIX Input 4 Volume */
372         { 0x068E, 0x0000 },   /* R1678  - DSP2RMIX Input 1 Source */
373         { 0x068F, 0x0080 },   /* R1679  - DSP2RMIX Input 1 Volume */
374         { 0x0690, 0x0000 },   /* R1680  - DSP2RMIX Input 2 Source */
375         { 0x0691, 0x0080 },   /* R1681  - DSP2RMIX Input 2 Volume */
376         { 0x0692, 0x0000 },   /* R1682  - DSP2RMIX Input 3 Source */
377         { 0x0693, 0x0080 },   /* R1683  - DSP2RMIX Input 3 Volume */
378         { 0x0694, 0x0000 },   /* R1684  - DSP2RMIX Input 4 Source */
379         { 0x0695, 0x0080 },   /* R1685  - DSP2RMIX Input 4 Volume */
380         { 0x0696, 0x0000 },   /* R1686  - DSP2AUX1MIX Input 1 Source */
381         { 0x0697, 0x0000 },   /* R1687  - DSP2AUX2MIX Input 1 Source */
382         { 0x0698, 0x0000 },   /* R1688  - DSP2AUX3MIX Input 1 Source */
383         { 0x0699, 0x0000 },   /* R1689  - DSP2AUX4MIX Input 1 Source */
384         { 0x069A, 0x0000 },   /* R1690  - DSP2AUX5MIX Input 1 Source */
385         { 0x069B, 0x0000 },   /* R1691  - DSP2AUX6MIX Input 1 Source */
386         { 0x0700, 0xA101 },   /* R1792  - GPIO CTRL 1 */
387         { 0x0701, 0xA101 },   /* R1793  - GPIO CTRL 2 */
388         { 0x0702, 0xA101 },   /* R1794  - GPIO CTRL 3 */
389         { 0x0703, 0xA101 },   /* R1795  - GPIO CTRL 4 */
390         { 0x0709, 0x0000 },   /* R1801  - Misc Pad Ctrl 1 */
391         { 0x0801, 0x00FF },   /* R2049  - Interrupt Status 1 Mask */
392         { 0x0804, 0xFFFF },   /* R2052  - Interrupt Status 2 Mask */
393         { 0x0808, 0x0000 },   /* R2056  - Interrupt Control */
394         { 0x0900, 0x0000 },   /* R2304  - EQL_1 */
395         { 0x0901, 0x0000 },   /* R2305  - EQL_2 */
396         { 0x0902, 0x0000 },   /* R2306  - EQL_3 */
397         { 0x0903, 0x0000 },   /* R2307  - EQL_4 */
398         { 0x0904, 0x0000 },   /* R2308  - EQL_5 */
399         { 0x0905, 0x0000 },   /* R2309  - EQL_6 */
400         { 0x0906, 0x0000 },   /* R2310  - EQL_7 */
401         { 0x0907, 0x0000 },   /* R2311  - EQL_8 */
402         { 0x0908, 0x0000 },   /* R2312  - EQL_9 */
403         { 0x0909, 0x0000 },   /* R2313  - EQL_10 */
404         { 0x090A, 0x0000 },   /* R2314  - EQL_11 */
405         { 0x090B, 0x0000 },   /* R2315  - EQL_12 */
406         { 0x090C, 0x0000 },   /* R2316  - EQL_13 */
407         { 0x090D, 0x0000 },   /* R2317  - EQL_14 */
408         { 0x090E, 0x0000 },   /* R2318  - EQL_15 */
409         { 0x090F, 0x0000 },   /* R2319  - EQL_16 */
410         { 0x0910, 0x0000 },   /* R2320  - EQL_17 */
411         { 0x0911, 0x0000 },   /* R2321  - EQL_18 */
412         { 0x0912, 0x0000 },   /* R2322  - EQL_19 */
413         { 0x0913, 0x0000 },   /* R2323  - EQL_20 */
414         { 0x0916, 0x0000 },   /* R2326  - EQR_1 */
415         { 0x0917, 0x0000 },   /* R2327  - EQR_2 */
416         { 0x0918, 0x0000 },   /* R2328  - EQR_3 */
417         { 0x0919, 0x0000 },   /* R2329  - EQR_4 */
418         { 0x091A, 0x0000 },   /* R2330  - EQR_5 */
419         { 0x091B, 0x0000 },   /* R2331  - EQR_6 */
420         { 0x091C, 0x0000 },   /* R2332  - EQR_7 */
421         { 0x091D, 0x0000 },   /* R2333  - EQR_8 */
422         { 0x091E, 0x0000 },   /* R2334  - EQR_9 */
423         { 0x091F, 0x0000 },   /* R2335  - EQR_10 */
424         { 0x0920, 0x0000 },   /* R2336  - EQR_11 */
425         { 0x0921, 0x0000 },   /* R2337  - EQR_12 */
426         { 0x0922, 0x0000 },   /* R2338  - EQR_13 */
427         { 0x0923, 0x0000 },   /* R2339  - EQR_14 */
428         { 0x0924, 0x0000 },   /* R2340  - EQR_15 */
429         { 0x0925, 0x0000 },   /* R2341  - EQR_16 */
430         { 0x0926, 0x0000 },   /* R2342  - EQR_17 */
431         { 0x0927, 0x0000 },   /* R2343  - EQR_18 */
432         { 0x0928, 0x0000 },   /* R2344  - EQR_19 */
433         { 0x0929, 0x0000 },   /* R2345  - EQR_20 */
434         { 0x093E, 0x0000 },   /* R2366  - HPLPF1_1 */
435         { 0x093F, 0x0000 },   /* R2367  - HPLPF1_2 */
436         { 0x0942, 0x0000 },   /* R2370  - HPLPF2_1 */
437         { 0x0943, 0x0000 },   /* R2371  - HPLPF2_2 */
438         { 0x0A00, 0x0000 },   /* R2560  - DSP1 Control 1 */
439         { 0x0A02, 0x0000 },   /* R2562  - DSP1 Control 2 */
440         { 0x0A03, 0x0000 },   /* R2563  - DSP1 Control 3 */
441         { 0x0A04, 0x0000 },   /* R2564  - DSP1 Control 4 */
442         { 0x0A06, 0x0000 },   /* R2566  - DSP1 Control 5 */
443         { 0x0A07, 0x0000 },   /* R2567  - DSP1 Control 6 */
444         { 0x0A08, 0x0000 },   /* R2568  - DSP1 Control 7 */
445         { 0x0A09, 0x0000 },   /* R2569  - DSP1 Control 8 */
446         { 0x0A0A, 0x0000 },   /* R2570  - DSP1 Control 9 */
447         { 0x0A0B, 0x0000 },   /* R2571  - DSP1 Control 10 */
448         { 0x0A0C, 0x0000 },   /* R2572  - DSP1 Control 11 */
449         { 0x0A0D, 0x0000 },   /* R2573  - DSP1 Control 12 */
450         { 0x0A0F, 0x0000 },   /* R2575  - DSP1 Control 13 */
451         { 0x0A10, 0x0000 },   /* R2576  - DSP1 Control 14 */
452         { 0x0A11, 0x0000 },   /* R2577  - DSP1 Control 15 */
453         { 0x0A12, 0x0000 },   /* R2578  - DSP1 Control 16 */
454         { 0x0A13, 0x0000 },   /* R2579  - DSP1 Control 17 */
455         { 0x0A14, 0x0000 },   /* R2580  - DSP1 Control 18 */
456         { 0x0A16, 0x0000 },   /* R2582  - DSP1 Control 19 */
457         { 0x0A17, 0x0000 },   /* R2583  - DSP1 Control 20 */
458         { 0x0A18, 0x0000 },   /* R2584  - DSP1 Control 21 */
459         { 0x0A1A, 0x1800 },   /* R2586  - DSP1 Control 22 */
460         { 0x0A1B, 0x1000 },   /* R2587  - DSP1 Control 23 */
461         { 0x0A1C, 0x0400 },   /* R2588  - DSP1 Control 24 */
462         { 0x0A1E, 0x0000 },   /* R2590  - DSP1 Control 25 */
463         { 0x0A20, 0x0000 },   /* R2592  - DSP1 Control 26 */
464         { 0x0A21, 0x0000 },   /* R2593  - DSP1 Control 27 */
465         { 0x0A22, 0x0000 },   /* R2594  - DSP1 Control 28 */
466         { 0x0A23, 0x0000 },   /* R2595  - DSP1 Control 29 */
467         { 0x0A24, 0x0000 },   /* R2596  - DSP1 Control 30 */
468         { 0x0A26, 0x0000 },   /* R2598  - DSP1 Control 31 */
469         { 0x0B00, 0x0000 },   /* R2816  - DSP2 Control 1 */
470         { 0x0B02, 0x0000 },   /* R2818  - DSP2 Control 2 */
471         { 0x0B03, 0x0000 },   /* R2819  - DSP2 Control 3 */
472         { 0x0B04, 0x0000 },   /* R2820  - DSP2 Control 4 */
473         { 0x0B06, 0x0000 },   /* R2822  - DSP2 Control 5 */
474         { 0x0B07, 0x0000 },   /* R2823  - DSP2 Control 6 */
475         { 0x0B08, 0x0000 },   /* R2824  - DSP2 Control 7 */
476         { 0x0B09, 0x0000 },   /* R2825  - DSP2 Control 8 */
477         { 0x0B0A, 0x0000 },   /* R2826  - DSP2 Control 9 */
478         { 0x0B0B, 0x0000 },   /* R2827  - DSP2 Control 10 */
479         { 0x0B0C, 0x0000 },   /* R2828  - DSP2 Control 11 */
480         { 0x0B0D, 0x0000 },   /* R2829  - DSP2 Control 12 */
481         { 0x0B0F, 0x0000 },   /* R2831  - DSP2 Control 13 */
482         { 0x0B10, 0x0000 },   /* R2832  - DSP2 Control 14 */
483         { 0x0B11, 0x0000 },   /* R2833  - DSP2 Control 15 */
484         { 0x0B12, 0x0000 },   /* R2834  - DSP2 Control 16 */
485         { 0x0B13, 0x0000 },   /* R2835  - DSP2 Control 17 */
486         { 0x0B14, 0x0000 },   /* R2836  - DSP2 Control 18 */
487         { 0x0B16, 0x0000 },   /* R2838  - DSP2 Control 19 */
488         { 0x0B17, 0x0000 },   /* R2839  - DSP2 Control 20 */
489         { 0x0B18, 0x0000 },   /* R2840  - DSP2 Control 21 */
490         { 0x0B1A, 0x0800 },   /* R2842  - DSP2 Control 22 */
491         { 0x0B1B, 0x1000 },   /* R2843  - DSP2 Control 23 */
492         { 0x0B1C, 0x0400 },   /* R2844  - DSP2 Control 24 */
493         { 0x0B1E, 0x0000 },   /* R2846  - DSP2 Control 25 */
494         { 0x0B20, 0x0000 },   /* R2848  - DSP2 Control 26 */
495         { 0x0B21, 0x0000 },   /* R2849  - DSP2 Control 27 */
496         { 0x0B22, 0x0000 },   /* R2850  - DSP2 Control 28 */
497         { 0x0B23, 0x0000 },   /* R2851  - DSP2 Control 29 */
498         { 0x0B24, 0x0000 },   /* R2852  - DSP2 Control 30 */
499         { 0x0B26, 0x0000 },   /* R2854  - DSP2 Control 31 */
500 };
501
502 static bool wm2200_volatile_register(struct device *dev, unsigned int reg)
503 {
504         int i;
505
506         for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++)
507                 if ((reg >= wm2200_ranges[i].window_start &&
508                      reg <= wm2200_ranges[i].window_start +
509                      wm2200_ranges[i].window_len) ||
510                     (reg >= wm2200_ranges[i].range_min &&
511                      reg <= wm2200_ranges[i].range_max))
512                         return true;
513
514         switch (reg) {
515         case WM2200_SOFTWARE_RESET:
516         case WM2200_DEVICE_REVISION:
517         case WM2200_ADPS1_IRQ0:
518         case WM2200_ADPS1_IRQ1:
519         case WM2200_INTERRUPT_STATUS_1:
520         case WM2200_INTERRUPT_STATUS_2:
521         case WM2200_INTERRUPT_RAW_STATUS_2:
522                 return true;
523         default:
524                 return false;
525         }
526 }
527
528 static bool wm2200_readable_register(struct device *dev, unsigned int reg)
529 {
530         int i;
531
532         for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++)
533                 if ((reg >= wm2200_ranges[i].window_start &&
534                      reg <= wm2200_ranges[i].window_start +
535                      wm2200_ranges[i].window_len) ||
536                     (reg >= wm2200_ranges[i].range_min &&
537                      reg <= wm2200_ranges[i].range_max))
538                         return true;
539
540         switch (reg) {
541         case WM2200_SOFTWARE_RESET:
542         case WM2200_DEVICE_REVISION:
543         case WM2200_TONE_GENERATOR_1:
544         case WM2200_CLOCKING_3:
545         case WM2200_CLOCKING_4:
546         case WM2200_FLL_CONTROL_1:
547         case WM2200_FLL_CONTROL_2:
548         case WM2200_FLL_CONTROL_3:
549         case WM2200_FLL_CONTROL_4:
550         case WM2200_FLL_CONTROL_6:
551         case WM2200_FLL_CONTROL_7:
552         case WM2200_FLL_EFS_1:
553         case WM2200_FLL_EFS_2:
554         case WM2200_MIC_CHARGE_PUMP_1:
555         case WM2200_MIC_CHARGE_PUMP_2:
556         case WM2200_DM_CHARGE_PUMP_1:
557         case WM2200_MIC_BIAS_CTRL_1:
558         case WM2200_MIC_BIAS_CTRL_2:
559         case WM2200_EAR_PIECE_CTRL_1:
560         case WM2200_EAR_PIECE_CTRL_2:
561         case WM2200_INPUT_ENABLES:
562         case WM2200_IN1L_CONTROL:
563         case WM2200_IN1R_CONTROL:
564         case WM2200_IN2L_CONTROL:
565         case WM2200_IN2R_CONTROL:
566         case WM2200_IN3L_CONTROL:
567         case WM2200_IN3R_CONTROL:
568         case WM2200_RXANC_SRC:
569         case WM2200_INPUT_VOLUME_RAMP:
570         case WM2200_ADC_DIGITAL_VOLUME_1L:
571         case WM2200_ADC_DIGITAL_VOLUME_1R:
572         case WM2200_ADC_DIGITAL_VOLUME_2L:
573         case WM2200_ADC_DIGITAL_VOLUME_2R:
574         case WM2200_ADC_DIGITAL_VOLUME_3L:
575         case WM2200_ADC_DIGITAL_VOLUME_3R:
576         case WM2200_OUTPUT_ENABLES:
577         case WM2200_DAC_VOLUME_LIMIT_1L:
578         case WM2200_DAC_VOLUME_LIMIT_1R:
579         case WM2200_DAC_VOLUME_LIMIT_2L:
580         case WM2200_DAC_VOLUME_LIMIT_2R:
581         case WM2200_DAC_AEC_CONTROL_1:
582         case WM2200_OUTPUT_VOLUME_RAMP:
583         case WM2200_DAC_DIGITAL_VOLUME_1L:
584         case WM2200_DAC_DIGITAL_VOLUME_1R:
585         case WM2200_DAC_DIGITAL_VOLUME_2L:
586         case WM2200_DAC_DIGITAL_VOLUME_2R:
587         case WM2200_PDM_1:
588         case WM2200_PDM_2:
589         case WM2200_AUDIO_IF_1_1:
590         case WM2200_AUDIO_IF_1_2:
591         case WM2200_AUDIO_IF_1_3:
592         case WM2200_AUDIO_IF_1_4:
593         case WM2200_AUDIO_IF_1_5:
594         case WM2200_AUDIO_IF_1_6:
595         case WM2200_AUDIO_IF_1_7:
596         case WM2200_AUDIO_IF_1_8:
597         case WM2200_AUDIO_IF_1_9:
598         case WM2200_AUDIO_IF_1_10:
599         case WM2200_AUDIO_IF_1_11:
600         case WM2200_AUDIO_IF_1_12:
601         case WM2200_AUDIO_IF_1_13:
602         case WM2200_AUDIO_IF_1_14:
603         case WM2200_AUDIO_IF_1_15:
604         case WM2200_AUDIO_IF_1_16:
605         case WM2200_AUDIO_IF_1_17:
606         case WM2200_AUDIO_IF_1_18:
607         case WM2200_AUDIO_IF_1_19:
608         case WM2200_AUDIO_IF_1_20:
609         case WM2200_AUDIO_IF_1_21:
610         case WM2200_AUDIO_IF_1_22:
611         case WM2200_OUT1LMIX_INPUT_1_SOURCE:
612         case WM2200_OUT1LMIX_INPUT_1_VOLUME:
613         case WM2200_OUT1LMIX_INPUT_2_SOURCE:
614         case WM2200_OUT1LMIX_INPUT_2_VOLUME:
615         case WM2200_OUT1LMIX_INPUT_3_SOURCE:
616         case WM2200_OUT1LMIX_INPUT_3_VOLUME:
617         case WM2200_OUT1LMIX_INPUT_4_SOURCE:
618         case WM2200_OUT1LMIX_INPUT_4_VOLUME:
619         case WM2200_OUT1RMIX_INPUT_1_SOURCE:
620         case WM2200_OUT1RMIX_INPUT_1_VOLUME:
621         case WM2200_OUT1RMIX_INPUT_2_SOURCE:
622         case WM2200_OUT1RMIX_INPUT_2_VOLUME:
623         case WM2200_OUT1RMIX_INPUT_3_SOURCE:
624         case WM2200_OUT1RMIX_INPUT_3_VOLUME:
625         case WM2200_OUT1RMIX_INPUT_4_SOURCE:
626         case WM2200_OUT1RMIX_INPUT_4_VOLUME:
627         case WM2200_OUT2LMIX_INPUT_1_SOURCE:
628         case WM2200_OUT2LMIX_INPUT_1_VOLUME:
629         case WM2200_OUT2LMIX_INPUT_2_SOURCE:
630         case WM2200_OUT2LMIX_INPUT_2_VOLUME:
631         case WM2200_OUT2LMIX_INPUT_3_SOURCE:
632         case WM2200_OUT2LMIX_INPUT_3_VOLUME:
633         case WM2200_OUT2LMIX_INPUT_4_SOURCE:
634         case WM2200_OUT2LMIX_INPUT_4_VOLUME:
635         case WM2200_OUT2RMIX_INPUT_1_SOURCE:
636         case WM2200_OUT2RMIX_INPUT_1_VOLUME:
637         case WM2200_OUT2RMIX_INPUT_2_SOURCE:
638         case WM2200_OUT2RMIX_INPUT_2_VOLUME:
639         case WM2200_OUT2RMIX_INPUT_3_SOURCE:
640         case WM2200_OUT2RMIX_INPUT_3_VOLUME:
641         case WM2200_OUT2RMIX_INPUT_4_SOURCE:
642         case WM2200_OUT2RMIX_INPUT_4_VOLUME:
643         case WM2200_AIF1TX1MIX_INPUT_1_SOURCE:
644         case WM2200_AIF1TX1MIX_INPUT_1_VOLUME:
645         case WM2200_AIF1TX1MIX_INPUT_2_SOURCE:
646         case WM2200_AIF1TX1MIX_INPUT_2_VOLUME:
647         case WM2200_AIF1TX1MIX_INPUT_3_SOURCE:
648         case WM2200_AIF1TX1MIX_INPUT_3_VOLUME:
649         case WM2200_AIF1TX1MIX_INPUT_4_SOURCE:
650         case WM2200_AIF1TX1MIX_INPUT_4_VOLUME:
651         case WM2200_AIF1TX2MIX_INPUT_1_SOURCE:
652         case WM2200_AIF1TX2MIX_INPUT_1_VOLUME:
653         case WM2200_AIF1TX2MIX_INPUT_2_SOURCE:
654         case WM2200_AIF1TX2MIX_INPUT_2_VOLUME:
655         case WM2200_AIF1TX2MIX_INPUT_3_SOURCE:
656         case WM2200_AIF1TX2MIX_INPUT_3_VOLUME:
657         case WM2200_AIF1TX2MIX_INPUT_4_SOURCE:
658         case WM2200_AIF1TX2MIX_INPUT_4_VOLUME:
659         case WM2200_AIF1TX3MIX_INPUT_1_SOURCE:
660         case WM2200_AIF1TX3MIX_INPUT_1_VOLUME:
661         case WM2200_AIF1TX3MIX_INPUT_2_SOURCE:
662         case WM2200_AIF1TX3MIX_INPUT_2_VOLUME:
663         case WM2200_AIF1TX3MIX_INPUT_3_SOURCE:
664         case WM2200_AIF1TX3MIX_INPUT_3_VOLUME:
665         case WM2200_AIF1TX3MIX_INPUT_4_SOURCE:
666         case WM2200_AIF1TX3MIX_INPUT_4_VOLUME:
667         case WM2200_AIF1TX4MIX_INPUT_1_SOURCE:
668         case WM2200_AIF1TX4MIX_INPUT_1_VOLUME:
669         case WM2200_AIF1TX4MIX_INPUT_2_SOURCE:
670         case WM2200_AIF1TX4MIX_INPUT_2_VOLUME:
671         case WM2200_AIF1TX4MIX_INPUT_3_SOURCE:
672         case WM2200_AIF1TX4MIX_INPUT_3_VOLUME:
673         case WM2200_AIF1TX4MIX_INPUT_4_SOURCE:
674         case WM2200_AIF1TX4MIX_INPUT_4_VOLUME:
675         case WM2200_AIF1TX5MIX_INPUT_1_SOURCE:
676         case WM2200_AIF1TX5MIX_INPUT_1_VOLUME:
677         case WM2200_AIF1TX5MIX_INPUT_2_SOURCE:
678         case WM2200_AIF1TX5MIX_INPUT_2_VOLUME:
679         case WM2200_AIF1TX5MIX_INPUT_3_SOURCE:
680         case WM2200_AIF1TX5MIX_INPUT_3_VOLUME:
681         case WM2200_AIF1TX5MIX_INPUT_4_SOURCE:
682         case WM2200_AIF1TX5MIX_INPUT_4_VOLUME:
683         case WM2200_AIF1TX6MIX_INPUT_1_SOURCE:
684         case WM2200_AIF1TX6MIX_INPUT_1_VOLUME:
685         case WM2200_AIF1TX6MIX_INPUT_2_SOURCE:
686         case WM2200_AIF1TX6MIX_INPUT_2_VOLUME:
687         case WM2200_AIF1TX6MIX_INPUT_3_SOURCE:
688         case WM2200_AIF1TX6MIX_INPUT_3_VOLUME:
689         case WM2200_AIF1TX6MIX_INPUT_4_SOURCE:
690         case WM2200_AIF1TX6MIX_INPUT_4_VOLUME:
691         case WM2200_EQLMIX_INPUT_1_SOURCE:
692         case WM2200_EQLMIX_INPUT_1_VOLUME:
693         case WM2200_EQLMIX_INPUT_2_SOURCE:
694         case WM2200_EQLMIX_INPUT_2_VOLUME:
695         case WM2200_EQLMIX_INPUT_3_SOURCE:
696         case WM2200_EQLMIX_INPUT_3_VOLUME:
697         case WM2200_EQLMIX_INPUT_4_SOURCE:
698         case WM2200_EQLMIX_INPUT_4_VOLUME:
699         case WM2200_EQRMIX_INPUT_1_SOURCE:
700         case WM2200_EQRMIX_INPUT_1_VOLUME:
701         case WM2200_EQRMIX_INPUT_2_SOURCE:
702         case WM2200_EQRMIX_INPUT_2_VOLUME:
703         case WM2200_EQRMIX_INPUT_3_SOURCE:
704         case WM2200_EQRMIX_INPUT_3_VOLUME:
705         case WM2200_EQRMIX_INPUT_4_SOURCE:
706         case WM2200_EQRMIX_INPUT_4_VOLUME:
707         case WM2200_LHPF1MIX_INPUT_1_SOURCE:
708         case WM2200_LHPF1MIX_INPUT_1_VOLUME:
709         case WM2200_LHPF1MIX_INPUT_2_SOURCE:
710         case WM2200_LHPF1MIX_INPUT_2_VOLUME:
711         case WM2200_LHPF1MIX_INPUT_3_SOURCE:
712         case WM2200_LHPF1MIX_INPUT_3_VOLUME:
713         case WM2200_LHPF1MIX_INPUT_4_SOURCE:
714         case WM2200_LHPF1MIX_INPUT_4_VOLUME:
715         case WM2200_LHPF2MIX_INPUT_1_SOURCE:
716         case WM2200_LHPF2MIX_INPUT_1_VOLUME:
717         case WM2200_LHPF2MIX_INPUT_2_SOURCE:
718         case WM2200_LHPF2MIX_INPUT_2_VOLUME:
719         case WM2200_LHPF2MIX_INPUT_3_SOURCE:
720         case WM2200_LHPF2MIX_INPUT_3_VOLUME:
721         case WM2200_LHPF2MIX_INPUT_4_SOURCE:
722         case WM2200_LHPF2MIX_INPUT_4_VOLUME:
723         case WM2200_DSP1LMIX_INPUT_1_SOURCE:
724         case WM2200_DSP1LMIX_INPUT_1_VOLUME:
725         case WM2200_DSP1LMIX_INPUT_2_SOURCE:
726         case WM2200_DSP1LMIX_INPUT_2_VOLUME:
727         case WM2200_DSP1LMIX_INPUT_3_SOURCE:
728         case WM2200_DSP1LMIX_INPUT_3_VOLUME:
729         case WM2200_DSP1LMIX_INPUT_4_SOURCE:
730         case WM2200_DSP1LMIX_INPUT_4_VOLUME:
731         case WM2200_DSP1RMIX_INPUT_1_SOURCE:
732         case WM2200_DSP1RMIX_INPUT_1_VOLUME:
733         case WM2200_DSP1RMIX_INPUT_2_SOURCE:
734         case WM2200_DSP1RMIX_INPUT_2_VOLUME:
735         case WM2200_DSP1RMIX_INPUT_3_SOURCE:
736         case WM2200_DSP1RMIX_INPUT_3_VOLUME:
737         case WM2200_DSP1RMIX_INPUT_4_SOURCE:
738         case WM2200_DSP1RMIX_INPUT_4_VOLUME:
739         case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE:
740         case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE:
741         case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE:
742         case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE:
743         case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE:
744         case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE:
745         case WM2200_DSP2LMIX_INPUT_1_SOURCE:
746         case WM2200_DSP2LMIX_INPUT_1_VOLUME:
747         case WM2200_DSP2LMIX_INPUT_2_SOURCE:
748         case WM2200_DSP2LMIX_INPUT_2_VOLUME:
749         case WM2200_DSP2LMIX_INPUT_3_SOURCE:
750         case WM2200_DSP2LMIX_INPUT_3_VOLUME:
751         case WM2200_DSP2LMIX_INPUT_4_SOURCE:
752         case WM2200_DSP2LMIX_INPUT_4_VOLUME:
753         case WM2200_DSP2RMIX_INPUT_1_SOURCE:
754         case WM2200_DSP2RMIX_INPUT_1_VOLUME:
755         case WM2200_DSP2RMIX_INPUT_2_SOURCE:
756         case WM2200_DSP2RMIX_INPUT_2_VOLUME:
757         case WM2200_DSP2RMIX_INPUT_3_SOURCE:
758         case WM2200_DSP2RMIX_INPUT_3_VOLUME:
759         case WM2200_DSP2RMIX_INPUT_4_SOURCE:
760         case WM2200_DSP2RMIX_INPUT_4_VOLUME:
761         case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE:
762         case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE:
763         case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE:
764         case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE:
765         case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE:
766         case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE:
767         case WM2200_GPIO_CTRL_1:
768         case WM2200_GPIO_CTRL_2:
769         case WM2200_GPIO_CTRL_3:
770         case WM2200_GPIO_CTRL_4:
771         case WM2200_ADPS1_IRQ0:
772         case WM2200_ADPS1_IRQ1:
773         case WM2200_MISC_PAD_CTRL_1:
774         case WM2200_INTERRUPT_STATUS_1:
775         case WM2200_INTERRUPT_STATUS_1_MASK:
776         case WM2200_INTERRUPT_STATUS_2:
777         case WM2200_INTERRUPT_RAW_STATUS_2:
778         case WM2200_INTERRUPT_STATUS_2_MASK:
779         case WM2200_INTERRUPT_CONTROL:
780         case WM2200_EQL_1:
781         case WM2200_EQL_2:
782         case WM2200_EQL_3:
783         case WM2200_EQL_4:
784         case WM2200_EQL_5:
785         case WM2200_EQL_6:
786         case WM2200_EQL_7:
787         case WM2200_EQL_8:
788         case WM2200_EQL_9:
789         case WM2200_EQL_10:
790         case WM2200_EQL_11:
791         case WM2200_EQL_12:
792         case WM2200_EQL_13:
793         case WM2200_EQL_14:
794         case WM2200_EQL_15:
795         case WM2200_EQL_16:
796         case WM2200_EQL_17:
797         case WM2200_EQL_18:
798         case WM2200_EQL_19:
799         case WM2200_EQL_20:
800         case WM2200_EQR_1:
801         case WM2200_EQR_2:
802         case WM2200_EQR_3:
803         case WM2200_EQR_4:
804         case WM2200_EQR_5:
805         case WM2200_EQR_6:
806         case WM2200_EQR_7:
807         case WM2200_EQR_8:
808         case WM2200_EQR_9:
809         case WM2200_EQR_10:
810         case WM2200_EQR_11:
811         case WM2200_EQR_12:
812         case WM2200_EQR_13:
813         case WM2200_EQR_14:
814         case WM2200_EQR_15:
815         case WM2200_EQR_16:
816         case WM2200_EQR_17:
817         case WM2200_EQR_18:
818         case WM2200_EQR_19:
819         case WM2200_EQR_20:
820         case WM2200_HPLPF1_1:
821         case WM2200_HPLPF1_2:
822         case WM2200_HPLPF2_1:
823         case WM2200_HPLPF2_2:
824         case WM2200_DSP1_CONTROL_1:
825         case WM2200_DSP1_CONTROL_2:
826         case WM2200_DSP1_CONTROL_3:
827         case WM2200_DSP1_CONTROL_4:
828         case WM2200_DSP1_CONTROL_5:
829         case WM2200_DSP1_CONTROL_6:
830         case WM2200_DSP1_CONTROL_7:
831         case WM2200_DSP1_CONTROL_8:
832         case WM2200_DSP1_CONTROL_9:
833         case WM2200_DSP1_CONTROL_10:
834         case WM2200_DSP1_CONTROL_11:
835         case WM2200_DSP1_CONTROL_12:
836         case WM2200_DSP1_CONTROL_13:
837         case WM2200_DSP1_CONTROL_14:
838         case WM2200_DSP1_CONTROL_15:
839         case WM2200_DSP1_CONTROL_16:
840         case WM2200_DSP1_CONTROL_17:
841         case WM2200_DSP1_CONTROL_18:
842         case WM2200_DSP1_CONTROL_19:
843         case WM2200_DSP1_CONTROL_20:
844         case WM2200_DSP1_CONTROL_21:
845         case WM2200_DSP1_CONTROL_22:
846         case WM2200_DSP1_CONTROL_23:
847         case WM2200_DSP1_CONTROL_24:
848         case WM2200_DSP1_CONTROL_25:
849         case WM2200_DSP1_CONTROL_26:
850         case WM2200_DSP1_CONTROL_27:
851         case WM2200_DSP1_CONTROL_28:
852         case WM2200_DSP1_CONTROL_29:
853         case WM2200_DSP1_CONTROL_30:
854         case WM2200_DSP1_CONTROL_31:
855         case WM2200_DSP2_CONTROL_1:
856         case WM2200_DSP2_CONTROL_2:
857         case WM2200_DSP2_CONTROL_3:
858         case WM2200_DSP2_CONTROL_4:
859         case WM2200_DSP2_CONTROL_5:
860         case WM2200_DSP2_CONTROL_6:
861         case WM2200_DSP2_CONTROL_7:
862         case WM2200_DSP2_CONTROL_8:
863         case WM2200_DSP2_CONTROL_9:
864         case WM2200_DSP2_CONTROL_10:
865         case WM2200_DSP2_CONTROL_11:
866         case WM2200_DSP2_CONTROL_12:
867         case WM2200_DSP2_CONTROL_13:
868         case WM2200_DSP2_CONTROL_14:
869         case WM2200_DSP2_CONTROL_15:
870         case WM2200_DSP2_CONTROL_16:
871         case WM2200_DSP2_CONTROL_17:
872         case WM2200_DSP2_CONTROL_18:
873         case WM2200_DSP2_CONTROL_19:
874         case WM2200_DSP2_CONTROL_20:
875         case WM2200_DSP2_CONTROL_21:
876         case WM2200_DSP2_CONTROL_22:
877         case WM2200_DSP2_CONTROL_23:
878         case WM2200_DSP2_CONTROL_24:
879         case WM2200_DSP2_CONTROL_25:
880         case WM2200_DSP2_CONTROL_26:
881         case WM2200_DSP2_CONTROL_27:
882         case WM2200_DSP2_CONTROL_28:
883         case WM2200_DSP2_CONTROL_29:
884         case WM2200_DSP2_CONTROL_30:
885         case WM2200_DSP2_CONTROL_31:
886                 return true;
887         default:
888                 return false;
889         }
890 }
891
892 static const struct reg_default wm2200_reva_patch[] = {
893         { 0x07, 0x0003 },
894         { 0x102, 0x0200 },
895         { 0x203, 0x0084 },
896         { 0x201, 0x83FF },
897         { 0x20C, 0x0062 },
898         { 0x20D, 0x0062 },
899         { 0x207, 0x2002 },
900         { 0x208, 0x20C0 },
901         { 0x21D, 0x01C0 },
902         { 0x50A, 0x0001 },
903         { 0x50B, 0x0002 },
904         { 0x50C, 0x0003 },
905         { 0x50D, 0x0004 },
906         { 0x50E, 0x0005 },
907         { 0x510, 0x0001 },
908         { 0x511, 0x0002 },
909         { 0x512, 0x0003 },
910         { 0x513, 0x0004 },
911         { 0x514, 0x0005 },
912         { 0x515, 0x0000 },
913         { 0x201, 0x8084 },
914         { 0x202, 0xBBDE },
915         { 0x203, 0x00EC },
916         { 0x500, 0x8000 },
917         { 0x507, 0x1820 },
918         { 0x508, 0x1820 },
919         { 0x505, 0x0300 },
920         { 0x506, 0x0300 },
921         { 0x302, 0x2280 },
922         { 0x303, 0x0080 },
923         { 0x304, 0x2280 },
924         { 0x305, 0x0080 },
925         { 0x306, 0x2280 },
926         { 0x307, 0x0080 },
927         { 0x401, 0x0080 },
928         { 0x402, 0x0080 },
929         { 0x417, 0x3069 },
930         { 0x900, 0x6318 },
931         { 0x901, 0x6300 },
932         { 0x902, 0x0FC8 },
933         { 0x903, 0x03FE },
934         { 0x904, 0x00E0 },
935         { 0x905, 0x1EC4 },
936         { 0x906, 0xF136 },
937         { 0x907, 0x0409 },
938         { 0x908, 0x04CC },
939         { 0x909, 0x1C9B },
940         { 0x90A, 0xF337 },
941         { 0x90B, 0x040B },
942         { 0x90C, 0x0CBB },
943         { 0x90D, 0x16F8 },
944         { 0x90E, 0xF7D9 },
945         { 0x90F, 0x040A },
946         { 0x910, 0x1F14 },
947         { 0x911, 0x058C },
948         { 0x912, 0x0563 },
949         { 0x913, 0x4000 },
950         { 0x916, 0x6318 },
951         { 0x917, 0x6300 },
952         { 0x918, 0x0FC8 },
953         { 0x919, 0x03FE },
954         { 0x91A, 0x00E0 },
955         { 0x91B, 0x1EC4 },
956         { 0x91C, 0xF136 },
957         { 0x91D, 0x0409 },
958         { 0x91E, 0x04CC },
959         { 0x91F, 0x1C9B },
960         { 0x920, 0xF337 },
961         { 0x921, 0x040B },
962         { 0x922, 0x0CBB },
963         { 0x923, 0x16F8 },
964         { 0x924, 0xF7D9 },
965         { 0x925, 0x040A },
966         { 0x926, 0x1F14 },
967         { 0x927, 0x058C },
968         { 0x928, 0x0563 },
969         { 0x929, 0x4000 },
970         { 0x709, 0x2000 },
971         { 0x207, 0x200E },
972         { 0x208, 0x20D4 },
973         { 0x20A, 0x0080 },
974         { 0x07, 0x0000 },
975 };
976
977 static int wm2200_reset(struct wm2200_priv *wm2200)
978 {
979         if (wm2200->pdata.reset) {
980                 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
981                 gpio_set_value_cansleep(wm2200->pdata.reset, 1);
982
983                 return 0;
984         } else {
985                 return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET,
986                                     0x2200);
987         }
988 }
989
990 static int wm2200_dsp_load(struct snd_soc_codec *codec, int base)
991 {
992         const struct firmware *firmware;
993         struct regmap *regmap = codec->control_data;
994         unsigned int pos = 0;
995         const struct wmfw_header *header;
996         const struct wmfw_adsp1_sizes *adsp1_sizes;
997         const struct wmfw_footer *footer;
998         const struct wmfw_region *region;
999         const char *file, *region_name;
1000         char *text;
1001         unsigned int dm, pm, zm, reg;
1002         int regions = 0;
1003         int ret, offset, type;
1004
1005         switch (base) {
1006         case WM2200_DSP1_CONTROL_1:
1007                 file = "wm2200-dsp1.wmfw";
1008                 dm = WM2200_DSP1_DM_BASE;
1009                 pm = WM2200_DSP1_PM_BASE;
1010                 zm = WM2200_DSP1_ZM_BASE;
1011                 break;
1012         case WM2200_DSP2_CONTROL_1:
1013                 file = "wm2200-dsp2.wmfw";
1014                 dm = WM2200_DSP2_DM_BASE;
1015                 pm = WM2200_DSP2_PM_BASE;
1016                 zm = WM2200_DSP2_ZM_BASE;
1017                 break;
1018         default:
1019                 dev_err(codec->dev, "BASE %x\n", base);
1020                 BUG_ON(1);
1021                 return -EINVAL;
1022         }
1023
1024         ret = request_firmware(&firmware, file, codec->dev);
1025         if (ret != 0) {
1026                 dev_err(codec->dev, "Failed to request '%s'\n", file);
1027                 return ret;
1028         }
1029
1030         pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
1031         if (pos >= firmware->size) {
1032                 dev_err(codec->dev, "%s: file too short, %d bytes\n",
1033                         file, firmware->size);
1034                 return -EINVAL;
1035         }
1036
1037         header = (void*)&firmware->data[0];
1038
1039         if (memcmp(&header->magic[0], "WMFW", 4) != 0) {
1040                 dev_err(codec->dev, "%s: invalid magic\n", file);
1041                 return -EINVAL;
1042         }
1043
1044         if (header->ver != 0) {
1045                 dev_err(codec->dev, "%s: unknown file format %d\n",
1046                         file, header->ver);
1047                 return -EINVAL;
1048         }
1049
1050         if (le32_to_cpu(header->len) != sizeof(*header) +
1051             sizeof(*adsp1_sizes) + sizeof(*footer)) {
1052                 dev_err(codec->dev, "%s: unexpected header length %d\n",
1053                         file, le32_to_cpu(header->len));
1054                 return -EINVAL;
1055         }
1056
1057         if (header->core != WMFW_ADSP1) {
1058                 dev_err(codec->dev, "%s: invalid core %d\n",
1059                         file, header->core);
1060                 return -EINVAL;
1061         }
1062
1063         adsp1_sizes = (void *)&(header[1]);
1064         footer = (void *)&(adsp1_sizes[1]);
1065
1066         dev_dbg(codec->dev, "%s: %d DM, %d PM, %d ZM\n",
1067                 file, le32_to_cpu(adsp1_sizes->dm),
1068                 le32_to_cpu(adsp1_sizes->pm), le32_to_cpu(adsp1_sizes->zm));
1069
1070         dev_dbg(codec->dev, "%s: timestamp %llu\n", file,
1071                 le64_to_cpu(footer->timestamp));
1072
1073         while (pos < firmware->size &&
1074                pos - firmware->size > sizeof(*region)) {
1075                 region = (void *)&(firmware->data[pos]);
1076                 region_name = "Unknown";
1077                 reg = 0;
1078                 text = NULL;
1079                 offset = le32_to_cpu(region->offset) & 0xffffff;
1080                 type = be32_to_cpu(region->type) & 0xff;
1081                 
1082                 switch (type) {
1083                 case WMFW_NAME_TEXT:
1084                         region_name = "Firmware name";
1085                         text = kzalloc(le32_to_cpu(region->len) + 1,
1086                                        GFP_KERNEL);
1087                         break;
1088                 case WMFW_INFO_TEXT:
1089                         region_name = "Information";
1090                         text = kzalloc(le32_to_cpu(region->len) + 1,
1091                                        GFP_KERNEL);
1092                         break;
1093                 case WMFW_ABSOLUTE:
1094                         region_name = "Absolute";
1095                         reg = offset;
1096                         break;
1097                 case WMFW_ADSP1_PM:
1098                         region_name = "PM";
1099                         reg = pm + (offset * 3);
1100                         break;
1101                 case WMFW_ADSP1_DM:
1102                         region_name = "DM";
1103                         reg = dm + (offset * 2);
1104                         break;
1105                 case WMFW_ADSP1_ZM:
1106                         region_name = "ZM";
1107                         reg = zm + (offset * 2);
1108                         break;
1109                 default:
1110                         dev_warn(codec->dev,
1111                                  "%s.%d: Unknown region type %x at %d(%x)\n",
1112                                  file, regions, type, pos, pos);
1113                         break;
1114                 }
1115
1116                 dev_dbg(codec->dev, "%s.%d: %d bytes at %d in %s\n", file,
1117                         regions, le32_to_cpu(region->len), offset,
1118                         region_name);
1119
1120                 if (text) {
1121                         memcpy(text, region->data, le32_to_cpu(region->len));
1122                         dev_info(codec->dev, "%s: %s\n", file, text);
1123                         kfree(text);
1124                 }
1125
1126                 if (reg) {
1127                         ret = regmap_raw_write(regmap, reg, region->data,
1128                                                le32_to_cpu(region->len));
1129                         if (ret != 0) {
1130                                 dev_err(codec->dev,
1131                                         "%s.%d: Failed to write %d bytes at %d in %s: %d\n",
1132                                         file, regions,
1133                                         le32_to_cpu(region->len), offset,
1134                                         region_name, ret);
1135                                 goto out;
1136                         }
1137                 }
1138
1139                 pos += le32_to_cpu(region->len) + sizeof(*region);
1140                 regions++;
1141         }
1142
1143         if (pos > firmware->size)
1144                 dev_warn(codec->dev, "%s.%d: %d bytes at end of file\n",
1145                          file, regions, pos - firmware->size);
1146
1147 out:
1148         release_firmware(firmware);
1149         
1150         return ret;
1151 }
1152
1153 static int wm2200_setup_algs(struct snd_soc_codec *codec, int base)
1154 {
1155         struct regmap *regmap = codec->control_data;
1156         struct wmfw_adsp1_id_hdr id;
1157         struct wmfw_adsp1_alg_hdr *alg;
1158         size_t algs;
1159         int zm, dm, pm, ret, i;
1160         __be32 val;
1161
1162         switch (base) {
1163         case WM2200_DSP1_CONTROL_1:
1164                 dm = WM2200_DSP1_DM_BASE;
1165                 pm = WM2200_DSP1_PM_BASE;
1166                 zm = WM2200_DSP1_ZM_BASE;
1167                 break;
1168         case WM2200_DSP2_CONTROL_1:
1169                 dm = WM2200_DSP2_DM_BASE;
1170                 pm = WM2200_DSP2_PM_BASE;
1171                 zm = WM2200_DSP2_ZM_BASE;
1172                 break;
1173         default:
1174                 dev_err(codec->dev, "BASE %x\n", base);
1175                 BUG_ON(1);
1176                 return -EINVAL;
1177         }
1178
1179         ret = regmap_raw_read(regmap, dm, &id, sizeof(id));
1180         if (ret != 0) {
1181                 dev_err(codec->dev, "Failed to read algorithm info: %d\n",
1182                         ret);
1183                 return ret;
1184         }
1185
1186         algs = be32_to_cpu(id.algs);
1187         dev_info(codec->dev, "Firmware: %x v%d.%d.%d, %d algorithms\n",
1188                  be32_to_cpu(id.fw.id),
1189                  (be32_to_cpu(id.fw.ver) & 0xff000) >> 16,
1190                  (be32_to_cpu(id.fw.ver) & 0xff00) >> 8,
1191                  be32_to_cpu(id.fw.ver) & 0xff,
1192                  algs);
1193
1194         /* Read the terminator first to validate the length */
1195         ret = regmap_raw_read(regmap, dm +
1196                               (sizeof(id) + (algs * sizeof(*alg))) / 2,
1197                               &val, sizeof(val));
1198         if (ret != 0) {
1199                 dev_err(codec->dev, "Failed to read algorithm list end: %d\n",
1200                         ret);
1201                 return ret;
1202         }
1203
1204         if (be32_to_cpu(val) != 0xbedead)
1205                 dev_warn(codec->dev, "Algorithm list end %x 0x%x != 0xbeadead\n",
1206                          (sizeof(id) + (algs * sizeof(*alg))) / 2,
1207                          be32_to_cpu(val));
1208
1209         alg = kzalloc(sizeof(*alg) * algs, GFP_KERNEL);
1210         if (!alg)
1211                 return -ENOMEM;
1212
1213         ret = regmap_raw_read(regmap, dm + (sizeof(id) / 2),
1214                               alg, algs * sizeof(*alg));
1215         if (ret != 0) {
1216                 dev_err(codec->dev, "Failed to read algorithm list: %d\n",
1217                         ret);
1218                 goto out;
1219         }
1220
1221         for (i = 0; i < algs; i++) {
1222                 dev_info(codec->dev, "%d: ID %x v%d.%d.%d\n",
1223                          i, be32_to_cpu(alg[i].alg.id),
1224                          (be32_to_cpu(alg[i].alg.ver) & 0xff000) >> 16,
1225                          (be32_to_cpu(alg[i].alg.ver) & 0xff00) >> 8,
1226                          be32_to_cpu(alg[i].alg.ver) & 0xff);
1227         }
1228
1229 out:
1230         kfree(alg);
1231         return ret;
1232 }
1233
1234 static int wm2200_load_coeff(struct snd_soc_codec *codec, int base)
1235 {
1236         struct regmap *regmap = codec->control_data;
1237         struct wmfw_coeff_hdr *hdr;
1238         struct wmfw_coeff_item *blk;
1239         const struct firmware *firmware;
1240         const char *file, *region_name;
1241         int ret, dm, pm, zm, pos, blocks, type, offset, reg;
1242
1243         switch (base) {
1244         case WM2200_DSP1_CONTROL_1:
1245                 file = "wm2200-dsp1.bin";
1246                 dm = WM2200_DSP1_DM_BASE;
1247                 pm = WM2200_DSP1_PM_BASE;
1248                 zm = WM2200_DSP1_ZM_BASE;
1249                 break;
1250         case WM2200_DSP2_CONTROL_1:
1251                 file = "wm2200-dsp2.bin";
1252                 dm = WM2200_DSP2_DM_BASE;
1253                 pm = WM2200_DSP2_PM_BASE;
1254                 zm = WM2200_DSP2_ZM_BASE;
1255                 break;
1256         default:
1257                 dev_err(codec->dev, "BASE %x\n", base);
1258                 BUG_ON(1);
1259                 return -EINVAL;
1260         }
1261
1262         ret = request_firmware(&firmware, file, codec->dev);
1263         if (ret != 0) {
1264                 dev_err(codec->dev, "Failed to request '%s'\n", file);
1265                 return ret;
1266         }
1267
1268         if (sizeof(*hdr) >= firmware->size) {
1269                 dev_err(codec->dev, "%s: file too short, %d bytes\n",
1270                         file, firmware->size);
1271                 return -EINVAL;
1272         }
1273
1274         hdr = (void*)&firmware->data[0];
1275         if (memcmp(hdr->magic, "WMDR", 4) != 0) {
1276                 dev_err(codec->dev, "%s: invalid magic\n", file);
1277                 return -EINVAL;
1278         }
1279
1280         dev_dbg(codec->dev, "%s: v%d.%d.%d\n", file,
1281                 (le32_to_cpu(hdr->ver) >> 16) & 0xff,
1282                 (le32_to_cpu(hdr->ver) >>  8) & 0xff,
1283                 le32_to_cpu(hdr->ver) & 0xff);
1284
1285         pos = le32_to_cpu(hdr->len);
1286
1287         blocks = 0;
1288         while (pos < firmware->size &&
1289                pos - firmware->size > sizeof(*blk)) {
1290                 blk = (void*)(&firmware->data[pos]);
1291
1292                 type = be32_to_cpu(blk->type) & 0xff;
1293                 offset = le32_to_cpu(blk->offset) & 0xffffff;
1294
1295                 dev_dbg(codec->dev, "%s.%d: %x v%d.%d.%d\n",
1296                         file, blocks, le32_to_cpu(blk->id),
1297                         (le32_to_cpu(blk->ver) >> 16) & 0xff,
1298                         (le32_to_cpu(blk->ver) >>  8) & 0xff,
1299                         le32_to_cpu(blk->ver) & 0xff);
1300                 dev_dbg(codec->dev, "%s.%d: %d bytes at 0x%x in %x\n",
1301                         file, blocks, le32_to_cpu(blk->len), offset, type);
1302
1303                 reg = 0;
1304                 region_name = "Unknown";
1305                 switch (type) {
1306                 case WMFW_NAME_TEXT:
1307                 case WMFW_INFO_TEXT:
1308                         break;
1309                 case WMFW_ABSOLUTE:
1310                         region_name = "register";
1311                         reg = offset;
1312                         break;
1313                 default:
1314                         dev_err(codec->dev, "Unknown region type %x\n", type);
1315                         break;
1316                 }
1317
1318                 if (reg) {
1319                         ret = regmap_raw_write(regmap, reg, blk->data,
1320                                                le32_to_cpu(blk->len));
1321                         if (ret != 0) {
1322                                 dev_err(codec->dev,
1323                                         "%s.%d: Failed to write to %x in %s\n",
1324                                         file, blocks, reg, region_name);
1325                         }
1326                 }
1327
1328                 pos += le32_to_cpu(blk->len) + sizeof(*blk);
1329                 blocks++;
1330         }
1331
1332         if (pos > firmware->size)
1333                 dev_warn(codec->dev, "%s.%d: %d bytes at end of file\n",
1334                          file, blocks, pos - firmware->size);
1335
1336         return 0;
1337 }
1338
1339 static int wm2200_dsp_ev(struct snd_soc_dapm_widget *w,
1340                          struct snd_kcontrol *kcontrol,
1341                          int event)
1342 {
1343         struct snd_soc_codec *codec = w->codec;
1344         int base = w->reg - WM2200_DSP_CONTROL_30;
1345         int ret;
1346
1347         switch (event) {
1348         case SND_SOC_DAPM_POST_PMU:
1349                 ret = wm2200_dsp_load(codec, base);
1350                 if (ret != 0)
1351                         return ret;
1352
1353                 ret = wm2200_setup_algs(codec, base);
1354                 if (ret != 0)
1355                         return ret;
1356
1357                 ret = wm2200_load_coeff(codec, base);
1358                 if (ret != 0)
1359                         return ret;
1360
1361                 /* Start the core running */
1362                 snd_soc_update_bits(codec, w->reg,
1363                                     WM2200_DSP1_CORE_ENA | WM2200_DSP1_START,
1364                                     WM2200_DSP1_CORE_ENA | WM2200_DSP1_START);
1365                 break;
1366
1367         case SND_SOC_DAPM_PRE_PMD:
1368                 /* Halt the core */
1369                 snd_soc_update_bits(codec, w->reg,
1370                                     WM2200_DSP1_CORE_ENA | WM2200_DSP1_START,
1371                                     0);
1372
1373                 snd_soc_update_bits(codec, base + WM2200_DSP_CONTROL_19,
1374                                     WM2200_DSP1_WDMA_BUFFER_LENGTH_MASK, 0);
1375                 break;
1376
1377         default:
1378                 break;
1379         }
1380
1381         return 0;
1382 }
1383
1384 static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
1385 static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
1386 static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
1387
1388 static const char *wm2200_mixer_texts[] = {
1389         "None",
1390         "Tone Generator",
1391         "AEC Loopback",
1392         "IN1L",
1393         "IN1R",
1394         "IN2L",
1395         "IN2R",
1396         "IN3L",
1397         "IN3R",
1398         "AIF1RX1",
1399         "AIF1RX2",
1400         "AIF1RX3",
1401         "AIF1RX4",
1402         "AIF1RX5",
1403         "AIF1RX6",
1404         "EQL",
1405         "EQR",
1406         "LHPF1",
1407         "LHPF2",
1408         "LHPF3",
1409         "LHPF4",
1410         "DSP1.1",
1411         "DSP1.2",
1412         "DSP1.3",
1413         "DSP1.4",
1414         "DSP1.5",
1415         "DSP1.6",
1416         "DSP2.1",
1417         "DSP2.2",
1418         "DSP2.3",
1419         "DSP2.4",
1420         "DSP2.5",
1421         "DSP2.6",
1422 };
1423
1424 static int wm2200_mixer_values[] = {
1425         0x00,
1426         0x04,   /* Tone */
1427         0x08,   /* AEC */
1428         0x10,   /* Input */
1429         0x11,
1430         0x12,
1431         0x13,
1432         0x14,
1433         0x15,
1434         0x20,   /* AIF */
1435         0x21,
1436         0x22,
1437         0x23,
1438         0x24,
1439         0x25,
1440         0x50,   /* EQ */
1441         0x51,
1442         0x52,
1443         0x60,   /* LHPF1 */
1444         0x61,   /* LHPF2 */
1445         0x68,   /* DSP1 */
1446         0x69,
1447         0x6a,
1448         0x6b,
1449         0x6c,
1450         0x6d,
1451         0x70,   /* DSP2 */
1452         0x71,
1453         0x72,
1454         0x73,
1455         0x74,
1456         0x75,
1457 };
1458
1459 #define WM2200_MIXER_CONTROLS(name, base) \
1460         SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
1461                        WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
1462         SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
1463                        WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
1464         SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
1465                        WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
1466         SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
1467                        WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
1468
1469 #define WM2200_MUX_ENUM_DECL(name, reg) \
1470         SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff,                  \
1471                                    wm2200_mixer_texts, wm2200_mixer_values)
1472
1473 #define WM2200_MUX_CTL_DECL(name) \
1474         const struct snd_kcontrol_new name##_mux =      \
1475                 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
1476
1477 #define WM2200_MIXER_ENUMS(name, base_reg) \
1478         static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg);      \
1479         static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2);  \
1480         static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4);  \
1481         static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6);  \
1482         static WM2200_MUX_CTL_DECL(name##_in1); \
1483         static WM2200_MUX_CTL_DECL(name##_in2); \
1484         static WM2200_MUX_CTL_DECL(name##_in3); \
1485         static WM2200_MUX_CTL_DECL(name##_in4)
1486
1487 #define WM2200_DSP_ENUMS(name, base_reg) \
1488         static WM2200_MUX_ENUM_DECL(name##_aux1_enum, base_reg);     \
1489         static WM2200_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 1); \
1490         static WM2200_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 2); \
1491         static WM2200_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 3); \
1492         static WM2200_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 4); \
1493         static WM2200_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 5); \
1494         static WM2200_MUX_CTL_DECL(name##_aux1); \
1495         static WM2200_MUX_CTL_DECL(name##_aux2); \
1496         static WM2200_MUX_CTL_DECL(name##_aux3); \
1497         static WM2200_MUX_CTL_DECL(name##_aux4); \
1498         static WM2200_MUX_CTL_DECL(name##_aux5); \
1499         static WM2200_MUX_CTL_DECL(name##_aux6);
1500
1501 static const struct snd_kcontrol_new wm2200_snd_controls[] = {
1502 SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
1503            WM2200_IN1_OSR_SHIFT, 1, 0),
1504 SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL,
1505            WM2200_IN2_OSR_SHIFT, 1, 0),
1506 SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL,
1507            WM2200_IN3_OSR_SHIFT, 1, 0),
1508
1509 SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL,
1510                  WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
1511 SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL,
1512                  WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
1513 SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL,
1514                  WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
1515
1516 SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
1517              WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1),
1518 SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
1519              WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1),
1520 SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
1521              WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1),
1522
1523 SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L,
1524                  WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT,
1525                  0xbf, 0, digital_tlv),
1526 SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L,
1527                  WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT,
1528                  0xbf, 0, digital_tlv),
1529 SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
1530                  WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT,
1531                  0xbf, 0, digital_tlv),
1532
1533 SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1534            WM2200_OUT1_OSR_SHIFT, 1, 0),
1535 SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1536            WM2200_OUT2_OSR_SHIFT, 1, 0),
1537
1538 SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1539              WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1),
1540 SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L,
1541                  WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0,
1542                  digital_tlv),
1543 SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L,
1544                  WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT,
1545                  0x46, 0, out_tlv),
1546
1547 SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1548              WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1),
1549 SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L,
1550                  WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0,
1551                  digital_tlv),
1552 SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
1553            WM2200_SPK1R_MUTE_SHIFT, 1, 1),
1554 };
1555
1556 WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
1557 WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE);
1558 WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE);
1559 WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE);
1560
1561 WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE);
1562 WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE);
1563 WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE);
1564 WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE);
1565 WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE);
1566 WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE);
1567
1568 WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE);
1569 WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE);
1570
1571 WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE);
1572 WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE);
1573 WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE);
1574 WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE);
1575
1576 WM2200_DSP_ENUMS(DSP1, WM2200_DSP1AUX1MIX_INPUT_1_SOURCE);
1577 WM2200_DSP_ENUMS(DSP2, WM2200_DSP2AUX1MIX_INPUT_1_SOURCE);
1578
1579 WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE);
1580 WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE);
1581
1582 #define WM2200_MUX(name, ctrl) \
1583         SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
1584
1585 #define WM2200_MIXER_WIDGETS(name, name_str)    \
1586         WM2200_MUX(name_str " Input 1", &name##_in1_mux), \
1587         WM2200_MUX(name_str " Input 2", &name##_in2_mux), \
1588         WM2200_MUX(name_str " Input 3", &name##_in3_mux), \
1589         WM2200_MUX(name_str " Input 4", &name##_in4_mux), \
1590         SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
1591
1592 #define WM2200_DSP_WIDGETS(name, name_str) \
1593         WM2200_MIXER_WIDGETS(name##L, name_str "L"), \
1594         WM2200_MIXER_WIDGETS(name##R, name_str "R"), \
1595         WM2200_MUX(name_str " Aux 1", &name##_aux1_mux), \
1596         WM2200_MUX(name_str " Aux 2", &name##_aux2_mux), \
1597         WM2200_MUX(name_str " Aux 3", &name##_aux3_mux), \
1598         WM2200_MUX(name_str " Aux 4", &name##_aux4_mux), \
1599         WM2200_MUX(name_str " Aux 5", &name##_aux5_mux), \
1600         WM2200_MUX(name_str " Aux 6", &name##_aux6_mux)
1601
1602 #define WM2200_MIXER_INPUT_ROUTES(name) \
1603         { name, "Tone Generator", "Tone Generator" }, \
1604         { name, "AEC Loopback", "AEC Loopback" }, \
1605         { name, "IN1L", "IN1L PGA" }, \
1606         { name, "IN1R", "IN1R PGA" }, \
1607         { name, "IN2L", "IN2L PGA" }, \
1608         { name, "IN2R", "IN2R PGA" }, \
1609         { name, "IN3L", "IN3L PGA" }, \
1610         { name, "IN3R", "IN3R PGA" }, \
1611         { name, "DSP1.1", "DSP1" }, \
1612         { name, "DSP1.2", "DSP1" }, \
1613         { name, "DSP1.3", "DSP1" }, \
1614         { name, "DSP1.4", "DSP1" }, \
1615         { name, "DSP1.5", "DSP1" }, \
1616         { name, "DSP1.6", "DSP1" }, \
1617         { name, "DSP2.1", "DSP2" }, \
1618         { name, "DSP2.2", "DSP2" }, \
1619         { name, "DSP2.3", "DSP2" }, \
1620         { name, "DSP2.4", "DSP2" }, \
1621         { name, "DSP2.5", "DSP2" }, \
1622         { name, "DSP2.6", "DSP2" }, \
1623         { name, "AIF1RX1", "AIF1RX1" }, \
1624         { name, "AIF1RX2", "AIF1RX2" }, \
1625         { name, "AIF1RX3", "AIF1RX3" }, \
1626         { name, "AIF1RX4", "AIF1RX4" }, \
1627         { name, "AIF1RX5", "AIF1RX5" }, \
1628         { name, "AIF1RX6", "AIF1RX6" }, \
1629         { name, "EQL", "EQL" }, \
1630         { name, "EQR", "EQR" }, \
1631         { name, "LHPF1", "LHPF1" }, \
1632         { name, "LHPF2", "LHPF2" }
1633
1634 #define WM2200_MIXER_ROUTES(widget, name) \
1635         { widget, NULL, name " Mixer" },         \
1636         { name " Mixer", NULL, name " Input 1" }, \
1637         { name " Mixer", NULL, name " Input 2" }, \
1638         { name " Mixer", NULL, name " Input 3" }, \
1639         { name " Mixer", NULL, name " Input 4" }, \
1640         WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \
1641         WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \
1642         WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \
1643         WM2200_MIXER_INPUT_ROUTES(name " Input 4")
1644
1645 #define WM2200_DSP_AUX_ROUTES(name) \
1646         { name, NULL, name " Aux 1" }, \
1647         { name, NULL, name " Aux 2" }, \
1648         { name, NULL, name " Aux 3" }, \
1649         { name, NULL, name " Aux 4" }, \
1650         { name, NULL, name " Aux 5" }, \
1651         { name, NULL, name " Aux 6" }, \
1652         WM2200_MIXER_INPUT_ROUTES(name " Aux 1"), \
1653         WM2200_MIXER_INPUT_ROUTES(name " Aux 2"), \
1654         WM2200_MIXER_INPUT_ROUTES(name " Aux 3"), \
1655         WM2200_MIXER_INPUT_ROUTES(name " Aux 4"), \
1656         WM2200_MIXER_INPUT_ROUTES(name " Aux 5"), \
1657         WM2200_MIXER_INPUT_ROUTES(name " Aux 6")
1658
1659 static const char *wm2200_aec_loopback_texts[] = {
1660         "OUT1L", "OUT1R", "OUT2L", "OUT2R",
1661 };
1662
1663 static const struct soc_enum wm2200_aec_loopback =
1664         SOC_ENUM_SINGLE(WM2200_DAC_AEC_CONTROL_1,
1665                         WM2200_AEC_LOOPBACK_SRC_SHIFT,
1666                         ARRAY_SIZE(wm2200_aec_loopback_texts),
1667                         wm2200_aec_loopback_texts);
1668
1669 static const struct snd_kcontrol_new wm2200_aec_loopback_mux =
1670         SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback);
1671
1672 static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = {
1673 SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0,
1674                     NULL, 0),
1675 SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0,
1676                     NULL, 0),
1677 SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0,
1678                     NULL, 0),
1679 SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT,
1680                     0, NULL, 0),
1681 SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
1682                     0, NULL, 0),
1683 SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
1684 SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20, 0),
1685
1686 SND_SOC_DAPM_INPUT("IN1L"),
1687 SND_SOC_DAPM_INPUT("IN1R"),
1688 SND_SOC_DAPM_INPUT("IN2L"),
1689 SND_SOC_DAPM_INPUT("IN2R"),
1690 SND_SOC_DAPM_INPUT("IN3L"),
1691 SND_SOC_DAPM_INPUT("IN3R"),
1692
1693 SND_SOC_DAPM_SIGGEN("TONE"),
1694 SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1,
1695                  WM2200_TONE_ENA_SHIFT, 0, NULL, 0),
1696
1697 SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0,
1698                  NULL, 0),
1699 SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0,
1700                  NULL, 0),
1701 SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0,
1702                  NULL, 0),
1703 SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0,
1704                  NULL, 0),
1705 SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0,
1706                  NULL, 0),
1707 SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0,
1708                  NULL, 0),
1709
1710 SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0,
1711                     WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0),
1712 SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1,
1713                     WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0),
1714 SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2,
1715                     WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0),
1716 SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3,
1717                     WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0),
1718 SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4,
1719                     WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0),
1720 SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5,
1721                     WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0),
1722
1723 SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0),
1724 SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0),
1725
1726 SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0,
1727                  NULL, 0),
1728 SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0,
1729                  NULL, 0),
1730
1731 SND_SOC_DAPM_PGA_E("DSP1", WM2200_DSP1_CONTROL_30, WM2200_DSP1_SYS_ENA_SHIFT,
1732                    0, NULL, 0, wm2200_dsp_ev,
1733                    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1734 SND_SOC_DAPM_PGA_E("DSP2", WM2200_DSP2_CONTROL_30, WM2200_DSP2_SYS_ENA_SHIFT,
1735                    0, NULL, 0, wm2200_dsp_ev,
1736                    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1737
1738 SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0,
1739                     WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0),
1740 SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1,
1741                     WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0),
1742 SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2,
1743                     WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0),
1744 SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3,
1745                     WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0),
1746 SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4,
1747                     WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0),
1748 SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5,
1749                     WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0),
1750
1751 SND_SOC_DAPM_MUX("AEC Loopback", WM2200_DAC_AEC_CONTROL_1,
1752                  WM2200_AEC_LOOPBACK_ENA_SHIFT, 0, &wm2200_aec_loopback_mux),
1753
1754 SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES,
1755                    WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0),
1756 SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES,
1757                    WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0),
1758
1759 SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1760                    WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0),
1761 SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1762                    WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0),
1763 SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1764                    WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0),
1765
1766 SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1767                    WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0),
1768 SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1769                    WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0),
1770 SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1771                    WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0),
1772
1773 SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1774                    WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0),
1775 SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1776                    WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0),
1777 SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1778                    WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0),
1779
1780 SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1781                    WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0),
1782 SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1783                    WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0),
1784 SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1785                    WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0),
1786
1787 SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT,
1788                  0, NULL, 0),
1789 SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT,
1790                  0, NULL, 0),
1791
1792 SND_SOC_DAPM_OUTPUT("EPOUTLN"),
1793 SND_SOC_DAPM_OUTPUT("EPOUTLP"),
1794 SND_SOC_DAPM_OUTPUT("EPOUTRN"),
1795 SND_SOC_DAPM_OUTPUT("EPOUTRP"),
1796 SND_SOC_DAPM_OUTPUT("SPK"),
1797
1798 WM2200_MIXER_WIDGETS(EQL, "EQL"),
1799 WM2200_MIXER_WIDGETS(EQR, "EQR"),
1800
1801 WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"),
1802 WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"),
1803
1804 WM2200_DSP_WIDGETS(DSP1, "DSP1"),
1805 WM2200_DSP_WIDGETS(DSP2, "DSP2"),
1806
1807 WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1808 WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1809 WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1810 WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1811 WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1812 WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1813
1814 WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"),
1815 WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"),
1816 WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"),
1817 WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"),
1818 };
1819
1820 static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
1821         /* Everything needs SYSCLK but only hook up things on the edge
1822          * of the chip */
1823         { "IN1L", NULL, "SYSCLK" },
1824         { "IN1R", NULL, "SYSCLK" },
1825         { "IN2L", NULL, "SYSCLK" },
1826         { "IN2R", NULL, "SYSCLK" },
1827         { "IN3L", NULL, "SYSCLK" },
1828         { "IN3R", NULL, "SYSCLK" },
1829         { "OUT1L", NULL, "SYSCLK" },
1830         { "OUT1R", NULL, "SYSCLK" },
1831         { "OUT2L", NULL, "SYSCLK" },
1832         { "OUT2R", NULL, "SYSCLK" },
1833         { "AIF1RX1", NULL, "SYSCLK" },
1834         { "AIF1RX2", NULL, "SYSCLK" },
1835         { "AIF1RX3", NULL, "SYSCLK" },
1836         { "AIF1RX4", NULL, "SYSCLK" },
1837         { "AIF1RX5", NULL, "SYSCLK" },
1838         { "AIF1RX6", NULL, "SYSCLK" },
1839         { "AIF1TX1", NULL, "SYSCLK" },
1840         { "AIF1TX2", NULL, "SYSCLK" },
1841         { "AIF1TX3", NULL, "SYSCLK" },
1842         { "AIF1TX4", NULL, "SYSCLK" },
1843         { "AIF1TX5", NULL, "SYSCLK" },
1844         { "AIF1TX6", NULL, "SYSCLK" },
1845
1846         { "IN1L", NULL, "AVDD" },
1847         { "IN1R", NULL, "AVDD" },
1848         { "IN2L", NULL, "AVDD" },
1849         { "IN2R", NULL, "AVDD" },
1850         { "IN3L", NULL, "AVDD" },
1851         { "IN3R", NULL, "AVDD" },
1852         { "OUT1L", NULL, "AVDD" },
1853         { "OUT1R", NULL, "AVDD" },
1854
1855         { "IN1L PGA", NULL, "IN1L" },
1856         { "IN1R PGA", NULL, "IN1R" },
1857         { "IN2L PGA", NULL, "IN2L" },
1858         { "IN2R PGA", NULL, "IN2R" },
1859         { "IN3L PGA", NULL, "IN3L" },
1860         { "IN3R PGA", NULL, "IN3R" },
1861
1862         { "Tone Generator", NULL, "TONE" },
1863
1864         { "CP2", NULL, "CPVDD" },
1865         { "MICBIAS1", NULL, "CP2" },
1866         { "MICBIAS2", NULL, "CP2" },
1867
1868         { "CP1", NULL, "CPVDD" },
1869         { "EPD_LN", NULL, "CP1" },
1870         { "EPD_LP", NULL, "CP1" },
1871         { "EPD_RN", NULL, "CP1" },
1872         { "EPD_RP", NULL, "CP1" },
1873
1874         { "EPD_LP", NULL, "OUT1L" },
1875         { "EPD_OUTP_LP", NULL, "EPD_LP" },
1876         { "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" },
1877         { "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" },
1878
1879         { "EPD_LN", NULL, "OUT1L" },
1880         { "EPD_OUTP_LN", NULL, "EPD_LN" },
1881         { "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" },
1882         { "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" },
1883
1884         { "EPD_RP", NULL, "OUT1R" },
1885         { "EPD_OUTP_RP", NULL, "EPD_RP" },
1886         { "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" },
1887         { "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" },
1888
1889         { "EPD_RN", NULL, "OUT1R" },
1890         { "EPD_OUTP_RN", NULL, "EPD_RN" },
1891         { "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" },
1892         { "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" },
1893
1894         { "SPK", NULL, "OUT2L" },
1895         { "SPK", NULL, "OUT2R" },
1896
1897         { "AEC Loopback", "OUT1L", "OUT1L" },
1898         { "AEC Loopback", "OUT1R", "OUT1R" },
1899         { "AEC Loopback", "OUT2L", "OUT2L" },
1900         { "AEC Loopback", "OUT2R", "OUT2R" },
1901
1902         WM2200_MIXER_ROUTES("DSP1", "DSP1L"),
1903         WM2200_MIXER_ROUTES("DSP1", "DSP1R"),
1904         WM2200_MIXER_ROUTES("DSP2", "DSP2L"),
1905         WM2200_MIXER_ROUTES("DSP2", "DSP2R"),
1906
1907         WM2200_DSP_AUX_ROUTES("DSP1"),
1908         WM2200_DSP_AUX_ROUTES("DSP2"),
1909
1910         WM2200_MIXER_ROUTES("OUT1L", "OUT1L"),
1911         WM2200_MIXER_ROUTES("OUT1R", "OUT1R"),
1912         WM2200_MIXER_ROUTES("OUT2L", "OUT2L"),
1913         WM2200_MIXER_ROUTES("OUT2R", "OUT2R"),
1914
1915         WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1916         WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1917         WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1918         WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1919         WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1920         WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1921
1922         WM2200_MIXER_ROUTES("EQL", "EQL"),
1923         WM2200_MIXER_ROUTES("EQR", "EQR"),
1924
1925         WM2200_MIXER_ROUTES("LHPF1", "LHPF1"),
1926         WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
1927 };
1928
1929 static int wm2200_probe(struct snd_soc_codec *codec)
1930 {
1931         struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev);
1932         int ret;
1933
1934         wm2200->codec = codec;
1935         codec->control_data = wm2200->regmap;
1936         codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1937
1938         ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
1939         if (ret != 0) {
1940                 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1941                 return ret;
1942         }
1943
1944         return ret;
1945 }
1946
1947 static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1948 {
1949         struct snd_soc_codec *codec = dai->codec;
1950         int lrclk, bclk, fmt_val;
1951
1952         lrclk = 0;
1953         bclk = 0;
1954
1955         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1956         case SND_SOC_DAIFMT_DSP_A:
1957                 fmt_val = 0;
1958                 break;
1959         case SND_SOC_DAIFMT_DSP_B:
1960                 fmt_val = 1;
1961                 break;
1962         case SND_SOC_DAIFMT_I2S:
1963                 fmt_val = 2;
1964                 break;
1965         case SND_SOC_DAIFMT_LEFT_J:
1966                 fmt_val = 3;
1967                 break;
1968         default:
1969                 dev_err(codec->dev, "Unsupported DAI format %d\n",
1970                         fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1971                 return -EINVAL;
1972         }
1973
1974         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1975         case SND_SOC_DAIFMT_CBS_CFS:
1976                 break;
1977         case SND_SOC_DAIFMT_CBS_CFM:
1978                 lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1979                 break;
1980         case SND_SOC_DAIFMT_CBM_CFS:
1981                 bclk |= WM2200_AIF1_BCLK_MSTR;
1982                 break;
1983         case SND_SOC_DAIFMT_CBM_CFM:
1984                 lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1985                 bclk |= WM2200_AIF1_BCLK_MSTR;
1986                 break;
1987         default:
1988                 dev_err(codec->dev, "Unsupported master mode %d\n",
1989                         fmt & SND_SOC_DAIFMT_MASTER_MASK);
1990                 return -EINVAL;
1991         }
1992
1993         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1994         case SND_SOC_DAIFMT_NB_NF:
1995                 break;
1996         case SND_SOC_DAIFMT_IB_IF:
1997                 bclk |= WM2200_AIF1_BCLK_INV;
1998                 lrclk |= WM2200_AIF1TX_LRCLK_INV;
1999                 break;
2000         case SND_SOC_DAIFMT_IB_NF:
2001                 bclk |= WM2200_AIF1_BCLK_INV;
2002                 break;
2003         case SND_SOC_DAIFMT_NB_IF:
2004                 lrclk |= WM2200_AIF1TX_LRCLK_INV;
2005                 break;
2006         default:
2007                 return -EINVAL;
2008         }
2009
2010         snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
2011                             WM2200_AIF1_BCLK_INV, bclk);
2012         snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
2013                             WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
2014                             lrclk);
2015         snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3,
2016                             WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
2017                             lrclk);
2018         snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
2019                             WM2200_AIF1_FMT_MASK << 1, fmt_val << 1);
2020
2021         return 0;
2022 }
2023
2024 static int wm2200_sr_code[] = {
2025         0,
2026         12000,
2027         24000,
2028         48000,
2029         96000,
2030         192000,
2031         384000,
2032         768000,
2033         0,
2034         11025,
2035         22050,
2036         44100,
2037         88200,
2038         176400,
2039         352800,
2040         705600,
2041         4000,
2042         8000,
2043         16000,
2044         32000,
2045         64000,
2046         128000,
2047         256000,
2048         512000,
2049 };
2050
2051 #define WM2200_NUM_BCLK_RATES 12
2052
2053 static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = {
2054         6144000,
2055         3072000,
2056         2048000,
2057         1536000,
2058         768000,
2059         512000,
2060         384000,
2061         256000,
2062         192000,
2063         128000,
2064         96000,
2065         64000,
2066 };      
2067
2068 static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = {
2069         5644800,
2070         3763200,
2071         2882400,
2072         1881600,
2073         1411200,
2074         705600,
2075         470400,
2076         352800,
2077         176400,
2078         117600,
2079         88200,
2080         58800,
2081 };
2082
2083 static int wm2200_hw_params(struct snd_pcm_substream *substream,
2084                             struct snd_pcm_hw_params *params,
2085                             struct snd_soc_dai *dai)
2086 {
2087         struct snd_soc_codec *codec = dai->codec;
2088         struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
2089         int i, bclk, lrclk, wl, fl, sr_code;
2090         int *bclk_rates;
2091
2092         /* Data sizes if not using TDM */
2093         wl = snd_pcm_format_width(params_format(params));
2094         if (wl < 0)
2095                 return wl;
2096         fl = snd_soc_params_to_frame_size(params);
2097         if (fl < 0)
2098                 return fl;
2099
2100         dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
2101                 wl, fl);
2102
2103         /* Target BCLK rate */
2104         bclk = snd_soc_params_to_bclk(params);
2105         if (bclk < 0)
2106                 return bclk;
2107
2108         if (!wm2200->sysclk) {
2109                 dev_err(codec->dev, "SYSCLK has no rate set\n");
2110                 return -EINVAL;
2111         }
2112
2113         for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++)
2114                 if (wm2200_sr_code[i] == params_rate(params))
2115                         break;
2116         if (i == ARRAY_SIZE(wm2200_sr_code)) {
2117                 dev_err(codec->dev, "Unsupported sample rate: %dHz\n",
2118                         params_rate(params));
2119                 return -EINVAL;
2120         }
2121         sr_code = i;
2122
2123         dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
2124                 bclk, wm2200->sysclk);
2125
2126         if (wm2200->sysclk % 4000)
2127                 bclk_rates = wm2200_bclk_rates_cd;
2128         else
2129                 bclk_rates = wm2200_bclk_rates_dat;
2130
2131         for (i = 0; i < WM2200_NUM_BCLK_RATES; i++)
2132                 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
2133                         break;
2134         if (i == WM2200_NUM_BCLK_RATES) {
2135                 dev_err(codec->dev,
2136                         "No valid BCLK for %dHz found from %dHz SYSCLK\n",
2137                         bclk, wm2200->sysclk);
2138                 return -EINVAL;
2139         }
2140
2141         bclk = i;
2142         dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
2143         snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1,
2144                             WM2200_AIF1_BCLK_DIV_MASK, bclk);
2145
2146         lrclk = bclk_rates[bclk] / params_rate(params);
2147         dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
2148         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
2149             dai->symmetric_rates)
2150                 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7,
2151                                     WM2200_AIF1RX_BCPF_MASK, lrclk);
2152         else
2153                 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6,
2154                                     WM2200_AIF1TX_BCPF_MASK, lrclk);
2155
2156         i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
2157         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2158                 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9,
2159                                     WM2200_AIF1RX_WL_MASK |
2160                                     WM2200_AIF1RX_SLOT_LEN_MASK, i);
2161         else
2162                 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8,
2163                                     WM2200_AIF1TX_WL_MASK |
2164                                     WM2200_AIF1TX_SLOT_LEN_MASK, i);
2165
2166         snd_soc_update_bits(codec, WM2200_CLOCKING_4,
2167                             WM2200_SAMPLE_RATE_1_MASK, sr_code);
2168
2169         return 0;
2170 }
2171
2172 static const struct snd_soc_dai_ops wm2200_dai_ops = {
2173         .set_fmt = wm2200_set_fmt,
2174         .hw_params = wm2200_hw_params,
2175 };
2176
2177 static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
2178                              int source, unsigned int freq, int dir)
2179 {
2180         struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
2181         int fval;
2182
2183         switch (clk_id) {
2184         case WM2200_CLK_SYSCLK:
2185                 break;
2186
2187         default:
2188                 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
2189                 return -EINVAL;
2190         }
2191
2192         switch (source) {
2193         case WM2200_CLKSRC_MCLK1:
2194         case WM2200_CLKSRC_MCLK2:
2195         case WM2200_CLKSRC_FLL:
2196         case WM2200_CLKSRC_BCLK1:
2197                 break;
2198         default:
2199                 dev_err(codec->dev, "Invalid source %d\n", source);
2200                 return -EINVAL;
2201         }
2202
2203         switch (freq) {
2204         case 22579200:
2205         case 24576000:
2206                 fval = 2;
2207                 break;
2208         default:
2209                 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
2210                 return -EINVAL;
2211         }
2212
2213         /* TODO: Check if MCLKs are in use and enable/disable pulls to
2214          * match.
2215          */
2216
2217         snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
2218                             WM2200_SYSCLK_SRC_MASK,
2219                             fval << WM2200_SYSCLK_FREQ_SHIFT | source);
2220
2221         wm2200->sysclk = freq;
2222
2223         return 0;
2224 }
2225
2226 struct _fll_div {
2227         u16 fll_fratio;
2228         u16 fll_outdiv;
2229         u16 fll_refclk_div;
2230         u16 n;
2231         u16 theta;
2232         u16 lambda;
2233 };
2234
2235 static struct {
2236         unsigned int min;
2237         unsigned int max;
2238         u16 fll_fratio;
2239         int ratio;
2240 } fll_fratios[] = {
2241         {       0,    64000, 4, 16 },
2242         {   64000,   128000, 3,  8 },
2243         {  128000,   256000, 2,  4 },
2244         {  256000,  1000000, 1,  2 },
2245         { 1000000, 13500000, 0,  1 },
2246 };
2247
2248 static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
2249                        unsigned int Fout)
2250 {
2251         unsigned int target;
2252         unsigned int div;
2253         unsigned int fratio, gcd_fll;
2254         int i;
2255
2256         /* Fref must be <=13.5MHz */
2257         div = 1;
2258         fll_div->fll_refclk_div = 0;
2259         while ((Fref / div) > 13500000) {
2260                 div *= 2;
2261                 fll_div->fll_refclk_div++;
2262
2263                 if (div > 8) {
2264                         pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
2265                                Fref);
2266                         return -EINVAL;
2267                 }
2268         }
2269
2270         pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
2271
2272         /* Apply the division for our remaining calculations */
2273         Fref /= div;
2274
2275         /* Fvco should be 90-100MHz; don't check the upper bound */
2276         div = 2;
2277         while (Fout * div < 90000000) {
2278                 div++;
2279                 if (div > 64) {
2280                         pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
2281                                Fout);
2282                         return -EINVAL;
2283                 }
2284         }
2285         target = Fout * div;
2286         fll_div->fll_outdiv = div - 1;
2287
2288         pr_debug("FLL Fvco=%dHz\n", target);
2289
2290         /* Find an appropraite FLL_FRATIO and factor it out of the target */
2291         for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
2292                 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
2293                         fll_div->fll_fratio = fll_fratios[i].fll_fratio;
2294                         fratio = fll_fratios[i].ratio;
2295                         break;
2296                 }
2297         }
2298         if (i == ARRAY_SIZE(fll_fratios)) {
2299                 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
2300                 return -EINVAL;
2301         }
2302
2303         fll_div->n = target / (fratio * Fref);
2304
2305         if (target % Fref == 0) {
2306                 fll_div->theta = 0;
2307                 fll_div->lambda = 0;
2308         } else {
2309                 gcd_fll = gcd(target, fratio * Fref);
2310
2311                 fll_div->theta = (target - (fll_div->n * fratio * Fref))
2312                         / gcd_fll;
2313                 fll_div->lambda = (fratio * Fref) / gcd_fll;
2314         }
2315
2316         pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
2317                  fll_div->n, fll_div->theta, fll_div->lambda);
2318         pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
2319                  fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
2320                  fll_div->fll_refclk_div);
2321
2322         return 0;
2323 }
2324
2325 static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2326                           unsigned int Fref, unsigned int Fout)
2327 {
2328         struct i2c_client *i2c = to_i2c_client(codec->dev);
2329         struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
2330         struct _fll_div factors;
2331         int ret, i, timeout;
2332
2333         if (!Fout) {
2334                 dev_dbg(codec->dev, "FLL disabled");
2335
2336                 if (wm2200->fll_fout)
2337                         pm_runtime_put(codec->dev);
2338
2339                 wm2200->fll_fout = 0;
2340                 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
2341                                     WM2200_FLL_ENA, 0);
2342                 return 0;
2343         }
2344
2345         switch (source) {
2346         case WM2200_FLL_SRC_MCLK1:
2347         case WM2200_FLL_SRC_MCLK2:
2348         case WM2200_FLL_SRC_BCLK:
2349                 break;
2350         default:
2351                 dev_err(codec->dev, "Invalid FLL source %d\n", source);
2352                 return -EINVAL;
2353         }
2354
2355         ret = fll_factors(&factors, Fref, Fout);
2356         if (ret < 0)
2357                 return ret;
2358
2359         /* Disable the FLL while we reconfigure */
2360         snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
2361
2362         snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2,
2363                             WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
2364                             (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
2365                             factors.fll_fratio);
2366         if (factors.theta) {
2367                 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
2368                                     WM2200_FLL_FRACN_ENA,
2369                                     WM2200_FLL_FRACN_ENA);
2370                 snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
2371                                     WM2200_FLL_EFS_ENA,
2372                                     WM2200_FLL_EFS_ENA);
2373         } else {
2374                 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
2375                                     WM2200_FLL_FRACN_ENA, 0);
2376                 snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
2377                                     WM2200_FLL_EFS_ENA, 0);
2378         }
2379
2380         snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
2381                             factors.theta);
2382         snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
2383                             factors.n);
2384         snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7,
2385                             WM2200_FLL_CLK_REF_DIV_MASK |
2386                             WM2200_FLL_CLK_REF_SRC_MASK,
2387                             (factors.fll_refclk_div
2388                              << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
2389         snd_soc_update_bits(codec, WM2200_FLL_EFS_1,
2390                             WM2200_FLL_LAMBDA_MASK, factors.lambda);
2391
2392         /* Clear any pending completions */
2393         try_wait_for_completion(&wm2200->fll_lock);
2394
2395         pm_runtime_get_sync(codec->dev);
2396
2397         snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
2398                             WM2200_FLL_ENA, WM2200_FLL_ENA);
2399
2400         if (i2c->irq)
2401                 timeout = 2;
2402         else
2403                 timeout = 50;
2404
2405         snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
2406                             WM2200_SYSCLK_ENA);
2407
2408         /* Poll for the lock; will use the interrupt to exit quickly */
2409         for (i = 0; i < timeout; i++) {
2410                 if (i2c->irq) {
2411                         ret = wait_for_completion_timeout(&wm2200->fll_lock,
2412                                                           msecs_to_jiffies(25));
2413                         if (ret > 0)
2414                                 break;
2415                 } else {
2416                         msleep(1);
2417                 }
2418
2419                 ret = snd_soc_read(codec,
2420                                    WM2200_INTERRUPT_RAW_STATUS_2);
2421                 if (ret < 0) {
2422                         dev_err(codec->dev,
2423                                 "Failed to read FLL status: %d\n",
2424                                 ret);
2425                         continue;
2426                 }
2427                 if (ret & WM2200_FLL_LOCK_STS)
2428                         break;
2429         }
2430         if (i == timeout) {
2431                 dev_err(codec->dev, "FLL lock timed out\n");
2432                 pm_runtime_put(codec->dev);
2433                 return -ETIMEDOUT;
2434         }
2435
2436         wm2200->fll_src = source;
2437         wm2200->fll_fref = Fref;
2438         wm2200->fll_fout = Fout;
2439
2440         dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
2441
2442         return 0;
2443 }
2444
2445 static int wm2200_dai_probe(struct snd_soc_dai *dai)
2446 {
2447         struct snd_soc_codec *codec = dai->codec;
2448         unsigned int val = 0;
2449         int ret;
2450
2451         ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1);
2452         if (ret >= 0) {
2453                 if ((ret & WM2200_GP1_FN_MASK) != 0) {
2454                         dai->symmetric_rates = true;
2455                         val = WM2200_AIF1TX_LRCLK_SRC;
2456                 }
2457         } else {
2458                 dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret);
2459         }
2460
2461         snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
2462                             WM2200_AIF1TX_LRCLK_SRC, val);
2463
2464         return 0;
2465 }
2466
2467 #define WM2200_RATES SNDRV_PCM_RATE_8000_48000
2468
2469 #define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2470                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2471
2472 static struct snd_soc_dai_driver wm2200_dai = {
2473         .name = "wm2200",
2474         .probe = wm2200_dai_probe,
2475         .playback = {
2476                 .stream_name = "Playback",
2477                 .channels_min = 2,
2478                 .channels_max = 2,
2479                 .rates = WM2200_RATES,
2480                 .formats = WM2200_FORMATS,
2481         },
2482         .capture = {
2483                  .stream_name = "Capture",
2484                  .channels_min = 2,
2485                  .channels_max = 2,
2486                  .rates = WM2200_RATES,
2487                  .formats = WM2200_FORMATS,
2488          },
2489         .ops = &wm2200_dai_ops,
2490 };
2491
2492 static struct snd_soc_codec_driver soc_codec_wm2200 = {
2493         .probe = wm2200_probe,
2494
2495         .idle_bias_off = true,
2496         .ignore_pmdown_time = true,
2497         .set_sysclk = wm2200_set_sysclk,
2498         .set_pll = wm2200_set_fll,
2499
2500         .controls = wm2200_snd_controls,
2501         .num_controls = ARRAY_SIZE(wm2200_snd_controls),
2502         .dapm_widgets = wm2200_dapm_widgets,
2503         .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets),
2504         .dapm_routes = wm2200_dapm_routes,
2505         .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes),
2506 };
2507
2508 static irqreturn_t wm2200_irq(int irq, void *data)
2509 {
2510         struct wm2200_priv *wm2200 = data;
2511         unsigned int val, mask;
2512         int ret;
2513
2514         ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val);
2515         if (ret != 0) {
2516                 dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret);
2517                 return IRQ_NONE;
2518         }
2519
2520         ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK,
2521                            &mask);
2522         if (ret != 0) {
2523                 dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret);
2524                 mask = 0;
2525         }
2526
2527         val &= ~mask;
2528
2529         if (val & WM2200_FLL_LOCK_EINT) {
2530                 dev_dbg(wm2200->dev, "FLL locked\n");
2531                 complete(&wm2200->fll_lock);
2532         }
2533
2534         if (val) {
2535                 regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val);
2536                 
2537                 return IRQ_HANDLED;
2538         } else {
2539                 return IRQ_NONE;
2540         }
2541 }
2542
2543 static const struct regmap_config wm2200_regmap = {
2544         .reg_bits = 16,
2545         .val_bits = 16,
2546
2547         .max_register = WM2200_MAX_REGISTER + (ARRAY_SIZE(wm2200_ranges) *
2548                                                WM2200_DSP_SPACING),
2549         .reg_defaults = wm2200_reg_defaults,
2550         .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults),
2551         .volatile_reg = wm2200_volatile_register,
2552         .readable_reg = wm2200_readable_register,
2553         .cache_type = REGCACHE_RBTREE,
2554         .ranges = wm2200_ranges,
2555         .num_ranges = ARRAY_SIZE(wm2200_ranges),
2556 };
2557
2558 static const unsigned int wm2200_dig_vu[] = {
2559         WM2200_DAC_DIGITAL_VOLUME_1L,
2560         WM2200_DAC_DIGITAL_VOLUME_1R,
2561         WM2200_DAC_DIGITAL_VOLUME_2L,
2562         WM2200_DAC_DIGITAL_VOLUME_2R,
2563         WM2200_ADC_DIGITAL_VOLUME_1L,
2564         WM2200_ADC_DIGITAL_VOLUME_1R,
2565         WM2200_ADC_DIGITAL_VOLUME_2L,
2566         WM2200_ADC_DIGITAL_VOLUME_2R,
2567         WM2200_ADC_DIGITAL_VOLUME_3L,
2568         WM2200_ADC_DIGITAL_VOLUME_3R,
2569 };
2570
2571 static const unsigned int wm2200_mic_ctrl_reg[] = {
2572         WM2200_IN1L_CONTROL,
2573         WM2200_IN2L_CONTROL,
2574         WM2200_IN3L_CONTROL,
2575 };
2576
2577 static __devinit int wm2200_i2c_probe(struct i2c_client *i2c,
2578                                       const struct i2c_device_id *id)
2579 {
2580         struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev);
2581         struct wm2200_priv *wm2200;
2582         unsigned int reg;
2583         int ret, i;
2584
2585         wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv),
2586                               GFP_KERNEL);
2587         if (wm2200 == NULL)
2588                 return -ENOMEM;
2589
2590         wm2200->dev = &i2c->dev;
2591         init_completion(&wm2200->fll_lock);
2592
2593         wm2200->regmap = devm_regmap_init_i2c(i2c, &wm2200_regmap);
2594         if (IS_ERR(wm2200->regmap)) {
2595                 ret = PTR_ERR(wm2200->regmap);
2596                 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2597                         ret);
2598                 goto err;
2599         }
2600
2601         if (pdata)
2602                 wm2200->pdata = *pdata;
2603
2604         i2c_set_clientdata(i2c, wm2200);
2605
2606         for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++)
2607                 wm2200->core_supplies[i].supply = wm2200_core_supply_names[i];
2608
2609         ret = devm_regulator_bulk_get(&i2c->dev,
2610                                       ARRAY_SIZE(wm2200->core_supplies),
2611                                       wm2200->core_supplies);
2612         if (ret != 0) {
2613                 dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2614                         ret);
2615                 goto err_regmap;
2616         }
2617
2618         ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2619                                     wm2200->core_supplies);
2620         if (ret != 0) {
2621                 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2622                         ret);
2623                 goto err_core;
2624         }
2625
2626         if (wm2200->pdata.ldo_ena) {
2627                 ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.ldo_ena,
2628                                             GPIOF_OUT_INIT_HIGH,
2629                                             "WM2200 LDOENA");
2630                 if (ret < 0) {
2631                         dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2632                                 wm2200->pdata.ldo_ena, ret);
2633                         goto err_enable;
2634                 }
2635                 msleep(2);
2636         }
2637
2638         if (wm2200->pdata.reset) {
2639                 ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.reset,
2640                                             GPIOF_OUT_INIT_HIGH,
2641                                             "WM2200 /RESET");
2642                 if (ret < 0) {
2643                         dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2644                                 wm2200->pdata.reset, ret);
2645                         goto err_ldo;
2646                 }
2647         }
2648
2649         ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg);
2650         if (ret < 0) {
2651                 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
2652                 goto err_reset;
2653         }
2654         switch (reg) {
2655         case 0x2200:
2656                 break;
2657
2658         default:
2659                 dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg);
2660                 ret = -EINVAL;
2661                 goto err_reset;
2662         }
2663
2664         ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, &reg);
2665         if (ret < 0) {
2666                 dev_err(&i2c->dev, "Failed to read revision register\n");
2667                 goto err_reset;
2668         }
2669
2670         wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK;
2671
2672         dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A');
2673
2674         switch (wm2200->rev) {
2675         case 0:
2676         case 1:
2677                 ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch,
2678                                             ARRAY_SIZE(wm2200_reva_patch));
2679                 if (ret != 0) {
2680                         dev_err(&i2c->dev, "Failed to register patch: %d\n",
2681                                 ret);
2682                 }
2683                 break;
2684         default:
2685                 break;
2686         }
2687
2688         ret = wm2200_reset(wm2200);
2689         if (ret < 0) {
2690                 dev_err(&i2c->dev, "Failed to issue reset\n");
2691                 goto err_reset;
2692         }
2693
2694         for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) {
2695                 if (!wm2200->pdata.gpio_defaults[i])
2696                         continue;
2697
2698                 regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i,
2699                              wm2200->pdata.gpio_defaults[i]);
2700         }
2701
2702         for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++)
2703                 regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i],
2704                                    WM2200_OUT_VU, WM2200_OUT_VU);
2705
2706         /* Assign slots 1-6 to channels 1-6 for both TX and RX */
2707         for (i = 0; i < 6; i++) {
2708                 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i);
2709                 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i);
2710         }
2711
2712         for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) {
2713                 regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i],
2714                                    WM2200_IN1_MODE_MASK |
2715                                    WM2200_IN1_DMIC_SUP_MASK,
2716                                    (wm2200->pdata.in_mode[i] <<
2717                                     WM2200_IN1_MODE_SHIFT) |
2718                                    (wm2200->pdata.dmic_sup[i] <<
2719                                     WM2200_IN1_DMIC_SUP_SHIFT));
2720         }
2721
2722         if (i2c->irq) {
2723                 ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq,
2724                                            IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
2725                                            "wm2200", wm2200);
2726                 if (ret == 0)
2727                         regmap_update_bits(wm2200->regmap,
2728                                            WM2200_INTERRUPT_STATUS_2_MASK,
2729                                            WM2200_FLL_LOCK_EINT, 0);
2730                 else
2731                         dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
2732                                 i2c->irq, ret);
2733         }
2734
2735         pm_runtime_set_active(&i2c->dev);
2736         pm_runtime_enable(&i2c->dev);
2737         pm_request_idle(&i2c->dev);
2738
2739         ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200,
2740                                      &wm2200_dai, 1);
2741         if (ret != 0) {
2742                 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
2743                 goto err_pm_runtime;
2744         }
2745
2746         return 0;
2747
2748 err_pm_runtime:
2749         pm_runtime_disable(&i2c->dev);
2750 err_reset:
2751         if (wm2200->pdata.reset)
2752                 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
2753 err_ldo:
2754         if (wm2200->pdata.ldo_ena)
2755                 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2756 err_enable:
2757         regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2758                                wm2200->core_supplies);
2759 err_core:
2760 err_regmap:
2761 err:
2762         return ret;
2763 }
2764
2765 static __devexit int wm2200_i2c_remove(struct i2c_client *i2c)
2766 {
2767         struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
2768
2769         snd_soc_unregister_codec(&i2c->dev);
2770         if (i2c->irq)
2771                 free_irq(i2c->irq, wm2200);
2772         if (wm2200->pdata.reset)
2773                 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
2774         if (wm2200->pdata.ldo_ena)
2775                 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2776
2777         return 0;
2778 }
2779
2780 #ifdef CONFIG_PM_RUNTIME
2781 static int wm2200_runtime_suspend(struct device *dev)
2782 {
2783         struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2784
2785         regcache_cache_only(wm2200->regmap, true);
2786         regcache_mark_dirty(wm2200->regmap);
2787         if (wm2200->pdata.ldo_ena)
2788                 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2789         regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2790                                wm2200->core_supplies);
2791
2792         return 0;
2793 }
2794
2795 static int wm2200_runtime_resume(struct device *dev)
2796 {
2797         struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2798         int ret;
2799
2800         ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2801                                     wm2200->core_supplies);
2802         if (ret != 0) {
2803                 dev_err(dev, "Failed to enable supplies: %d\n",
2804                         ret);
2805                 return ret;
2806         }
2807
2808         if (wm2200->pdata.ldo_ena) {
2809                 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1);
2810                 msleep(2);
2811         }
2812
2813         regcache_cache_only(wm2200->regmap, false);
2814         regcache_sync(wm2200->regmap);
2815
2816         return 0;
2817 }
2818 #endif
2819
2820 static struct dev_pm_ops wm2200_pm = {
2821         SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume,
2822                            NULL)
2823 };
2824
2825 static const struct i2c_device_id wm2200_i2c_id[] = {
2826         { "wm2200", 0 },
2827         { }
2828 };
2829 MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id);
2830
2831 static struct i2c_driver wm2200_i2c_driver = {
2832         .driver = {
2833                 .name = "wm2200",
2834                 .owner = THIS_MODULE,
2835                 .pm = &wm2200_pm,
2836         },
2837         .probe =    wm2200_i2c_probe,
2838         .remove =   __devexit_p(wm2200_i2c_remove),
2839         .id_table = wm2200_i2c_id,
2840 };
2841
2842 module_i2c_driver(wm2200_i2c_driver);
2843
2844 MODULE_DESCRIPTION("ASoC WM2200 driver");
2845 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2846 MODULE_LICENSE("GPL");