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