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