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