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