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