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