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