aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/wm8904.h57
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/wm8904.c2538
-rw-r--r--sound/soc/codecs/wm8904.h1681
5 files changed, 4282 insertions, 0 deletions
diff --git a/include/sound/wm8904.h b/include/sound/wm8904.h
new file mode 100644
index 000000000000..d66575a601be
--- /dev/null
+++ b/include/sound/wm8904.h
@@ -0,0 +1,57 @@
1/*
2 * Platform data for WM8904
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef __MFD_WM8994_PDATA_H__
16#define __MFD_WM8994_PDATA_H__
17
18#define WM8904_DRC_REGS 4
19#define WM8904_EQ_REGS 25
20
21/**
22 * DRC configurations are specified with a label and a set of register
23 * values to write (the enable bits will be ignored). At runtime an
24 * enumerated control will be presented for each DRC block allowing
25 * the user to choose the configration to use.
26 *
27 * Configurations may be generated by hand or by using the DRC control
28 * panel provided by the WISCE - see http://www.wolfsonmicro.com/wisce/
29 * for details.
30 */
31struct wm8904_drc_cfg {
32 const char *name;
33 u16 regs[WM8904_DRC_REGS];
34};
35
36/**
37 * ReTune Mobile configurations are specified with a label, sample
38 * rate and set of values to write (the enable bits will be ignored).
39 *
40 * Configurations are expected to be generated using the ReTune Mobile
41 * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/
42 */
43struct wm8904_retune_mobile_cfg {
44 const char *name;
45 unsigned int rate;
46 u16 regs[WM8904_EQ_REGS];
47};
48
49struct wm8904_pdata {
50 int num_drc_cfgs;
51 struct wm8904_drc_cfg *drc_cfgs;
52
53 int num_retune_mobile_cfgs;
54 struct wm8904_retune_mobile_cfg *retune_mobile_cfgs;
55};
56
57#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 52b005f8fed4..011d3ab7e64a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -49,6 +49,7 @@ config SND_SOC_ALL_CODECS
49 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 49 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
50 select SND_SOC_WM8900 if I2C 50 select SND_SOC_WM8900 if I2C
51 select SND_SOC_WM8903 if I2C 51 select SND_SOC_WM8903 if I2C
52 select SND_SOC_WM8904 if I2C
52 select SND_SOC_WM8940 if I2C 53 select SND_SOC_WM8940 if I2C
53 select SND_SOC_WM8960 if I2C 54 select SND_SOC_WM8960 if I2C
54 select SND_SOC_WM8961 if I2C 55 select SND_SOC_WM8961 if I2C
@@ -203,6 +204,9 @@ config SND_SOC_WM8900
203config SND_SOC_WM8903 204config SND_SOC_WM8903
204 tristate 205 tristate
205 206
207config SND_SOC_WM8904
208 tristate
209
206config SND_SOC_WM8940 210config SND_SOC_WM8940
207 tristate 211 tristate
208 212
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index dbaecb133ac7..0471d9044205 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -36,6 +36,7 @@ snd-soc-wm8753-objs := wm8753.o
36snd-soc-wm8776-objs := wm8776.o 36snd-soc-wm8776-objs := wm8776.o
37snd-soc-wm8900-objs := wm8900.o 37snd-soc-wm8900-objs := wm8900.o
38snd-soc-wm8903-objs := wm8903.o 38snd-soc-wm8903-objs := wm8903.o
39snd-soc-wm8904-objs := wm8904.o
39snd-soc-wm8940-objs := wm8940.o 40snd-soc-wm8940-objs := wm8940.o
40snd-soc-wm8960-objs := wm8960.o 41snd-soc-wm8960-objs := wm8960.o
41snd-soc-wm8961-objs := wm8961.o 42snd-soc-wm8961-objs := wm8961.o
@@ -92,6 +93,7 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
92obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 93obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
93obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 94obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
94obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 95obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
96obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
95obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 97obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
96obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o 98obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
97obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 99obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
new file mode 100644
index 000000000000..8310e5d14b83
--- /dev/null
+++ b/sound/soc/codecs/wm8904.c
@@ -0,0 +1,2538 @@
1/*
2 * wm8904.c -- WM8904 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <sound/wm8904.h>
30
31#include "wm8904.h"
32
33static struct snd_soc_codec *wm8904_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8904;
35
36#define WM8904_NUM_DCS_CHANNELS 4
37
38#define WM8904_NUM_SUPPLIES 5
39static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
40 "DCVDD",
41 "DBVDD",
42 "AVDD",
43 "CPVDD",
44 "MICVDD",
45};
46
47/* codec private data */
48struct wm8904_priv {
49 struct snd_soc_codec codec;
50 u16 reg_cache[WM8904_MAX_REGISTER + 1];
51
52 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
53
54 struct wm8904_pdata *pdata;
55
56 int deemph;
57
58 /* Platform provided DRC configuration */
59 const char **drc_texts;
60 int drc_cfg;
61 struct soc_enum drc_enum;
62
63 /* Platform provided ReTune mobile configuration */
64 int num_retune_mobile_texts;
65 const char **retune_mobile_texts;
66 int retune_mobile_cfg;
67 struct soc_enum retune_mobile_enum;
68
69 /* FLL setup */
70 int fll_src;
71 int fll_fref;
72 int fll_fout;
73
74 /* Clocking configuration */
75 unsigned int mclk_rate;
76 int sysclk_src;
77 unsigned int sysclk_rate;
78
79 int tdm_width;
80 int tdm_slots;
81 int bclk;
82 int fs;
83
84 /* DC servo configuration - cached offset values */
85 int dcs_state[WM8904_NUM_DCS_CHANNELS];
86};
87
88static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = {
89 0x8904, /* R0 - SW Reset and ID */
90 0x0000, /* R1 - Revision */
91 0x0000, /* R2 */
92 0x0000, /* R3 */
93 0x0018, /* R4 - Bias Control 0 */
94 0x0000, /* R5 - VMID Control 0 */
95 0x0000, /* R6 - Mic Bias Control 0 */
96 0x0000, /* R7 - Mic Bias Control 1 */
97 0x0001, /* R8 - Analogue DAC 0 */
98 0x9696, /* R9 - mic Filter Control */
99 0x0001, /* R10 - Analogue ADC 0 */
100 0x0000, /* R11 */
101 0x0000, /* R12 - Power Management 0 */
102 0x0000, /* R13 */
103 0x0000, /* R14 - Power Management 2 */
104 0x0000, /* R15 - Power Management 3 */
105 0x0000, /* R16 */
106 0x0000, /* R17 */
107 0x0000, /* R18 - Power Management 6 */
108 0x0000, /* R19 */
109 0x945E, /* R20 - Clock Rates 0 */
110 0x0C05, /* R21 - Clock Rates 1 */
111 0x0006, /* R22 - Clock Rates 2 */
112 0x0000, /* R23 */
113 0x0050, /* R24 - Audio Interface 0 */
114 0x000A, /* R25 - Audio Interface 1 */
115 0x00E4, /* R26 - Audio Interface 2 */
116 0x0040, /* R27 - Audio Interface 3 */
117 0x0000, /* R28 */
118 0x0000, /* R29 */
119 0x00C0, /* R30 - DAC Digital Volume Left */
120 0x00C0, /* R31 - DAC Digital Volume Right */
121 0x0000, /* R32 - DAC Digital 0 */
122 0x0008, /* R33 - DAC Digital 1 */
123 0x0000, /* R34 */
124 0x0000, /* R35 */
125 0x00C0, /* R36 - ADC Digital Volume Left */
126 0x00C0, /* R37 - ADC Digital Volume Right */
127 0x0010, /* R38 - ADC Digital 0 */
128 0x0000, /* R39 - Digital Microphone 0 */
129 0x01AF, /* R40 - DRC 0 */
130 0x3248, /* R41 - DRC 1 */
131 0x0000, /* R42 - DRC 2 */
132 0x0000, /* R43 - DRC 3 */
133 0x0085, /* R44 - Analogue Left Input 0 */
134 0x0085, /* R45 - Analogue Right Input 0 */
135 0x0044, /* R46 - Analogue Left Input 1 */
136 0x0044, /* R47 - Analogue Right Input 1 */
137 0x0000, /* R48 */
138 0x0000, /* R49 */
139 0x0000, /* R50 */
140 0x0000, /* R51 */
141 0x0000, /* R52 */
142 0x0000, /* R53 */
143 0x0000, /* R54 */
144 0x0000, /* R55 */
145 0x0000, /* R56 */
146 0x002D, /* R57 - Analogue OUT1 Left */
147 0x002D, /* R58 - Analogue OUT1 Right */
148 0x0039, /* R59 - Analogue OUT2 Left */
149 0x0039, /* R60 - Analogue OUT2 Right */
150 0x0000, /* R61 - Analogue OUT12 ZC */
151 0x0000, /* R62 */
152 0x0000, /* R63 */
153 0x0000, /* R64 */
154 0x0000, /* R65 */
155 0x0000, /* R66 */
156 0x0000, /* R67 - DC Servo 0 */
157 0x0000, /* R68 - DC Servo 1 */
158 0xAAAA, /* R69 - DC Servo 2 */
159 0x0000, /* R70 */
160 0xAAAA, /* R71 - DC Servo 4 */
161 0xAAAA, /* R72 - DC Servo 5 */
162 0x0000, /* R73 - DC Servo 6 */
163 0x0000, /* R74 - DC Servo 7 */
164 0x0000, /* R75 - DC Servo 8 */
165 0x0000, /* R76 - DC Servo 9 */
166 0x0000, /* R77 - DC Servo Readback 0 */
167 0x0000, /* R78 */
168 0x0000, /* R79 */
169 0x0000, /* R80 */
170 0x0000, /* R81 */
171 0x0000, /* R82 */
172 0x0000, /* R83 */
173 0x0000, /* R84 */
174 0x0000, /* R85 */
175 0x0000, /* R86 */
176 0x0000, /* R87 */
177 0x0000, /* R88 */
178 0x0000, /* R89 */
179 0x0000, /* R90 - Analogue HP 0 */
180 0x0000, /* R91 */
181 0x0000, /* R92 */
182 0x0000, /* R93 */
183 0x0000, /* R94 - Analogue Lineout 0 */
184 0x0000, /* R95 */
185 0x0000, /* R96 */
186 0x0000, /* R97 */
187 0x0000, /* R98 - Charge Pump 0 */
188 0x0000, /* R99 */
189 0x0000, /* R100 */
190 0x0000, /* R101 */
191 0x0000, /* R102 */
192 0x0000, /* R103 */
193 0x0004, /* R104 - Class W 0 */
194 0x0000, /* R105 */
195 0x0000, /* R106 */
196 0x0000, /* R107 */
197 0x0000, /* R108 - Write Sequencer 0 */
198 0x0000, /* R109 - Write Sequencer 1 */
199 0x0000, /* R110 - Write Sequencer 2 */
200 0x0000, /* R111 - Write Sequencer 3 */
201 0x0000, /* R112 - Write Sequencer 4 */
202 0x0000, /* R113 */
203 0x0000, /* R114 */
204 0x0000, /* R115 */
205 0x0000, /* R116 - FLL Control 1 */
206 0x0007, /* R117 - FLL Control 2 */
207 0x0000, /* R118 - FLL Control 3 */
208 0x2EE0, /* R119 - FLL Control 4 */
209 0x0004, /* R120 - FLL Control 5 */
210 0x0014, /* R121 - GPIO Control 1 */
211 0x0010, /* R122 - GPIO Control 2 */
212 0x0010, /* R123 - GPIO Control 3 */
213 0x0000, /* R124 - GPIO Control 4 */
214 0x0000, /* R125 */
215 0x0000, /* R126 - Digital Pulls */
216 0x0000, /* R127 - Interrupt Status */
217 0xFFFF, /* R128 - Interrupt Status Mask */
218 0x0000, /* R129 - Interrupt Polarity */
219 0x0000, /* R130 - Interrupt Debounce */
220 0x0000, /* R131 */
221 0x0000, /* R132 */
222 0x0000, /* R133 */
223 0x0000, /* R134 - EQ1 */
224 0x000C, /* R135 - EQ2 */
225 0x000C, /* R136 - EQ3 */
226 0x000C, /* R137 - EQ4 */
227 0x000C, /* R138 - EQ5 */
228 0x000C, /* R139 - EQ6 */
229 0x0FCA, /* R140 - EQ7 */
230 0x0400, /* R141 - EQ8 */
231 0x00D8, /* R142 - EQ9 */
232 0x1EB5, /* R143 - EQ10 */
233 0xF145, /* R144 - EQ11 */
234 0x0B75, /* R145 - EQ12 */
235 0x01C5, /* R146 - EQ13 */
236 0x1C58, /* R147 - EQ14 */
237 0xF373, /* R148 - EQ15 */
238 0x0A54, /* R149 - EQ16 */
239 0x0558, /* R150 - EQ17 */
240 0x168E, /* R151 - EQ18 */
241 0xF829, /* R152 - EQ19 */
242 0x07AD, /* R153 - EQ20 */
243 0x1103, /* R154 - EQ21 */
244 0x0564, /* R155 - EQ22 */
245 0x0559, /* R156 - EQ23 */
246 0x4000, /* R157 - EQ24 */
247 0x0000, /* R158 */
248 0x0000, /* R159 */
249 0x0000, /* R160 */
250 0x0000, /* R161 - Control Interface Test 1 */
251 0x0000, /* R162 */
252 0x0000, /* R163 */
253 0x0000, /* R164 */
254 0x0000, /* R165 */
255 0x0000, /* R166 */
256 0x0000, /* R167 */
257 0x0000, /* R168 */
258 0x0000, /* R169 */
259 0x0000, /* R170 */
260 0x0000, /* R171 */
261 0x0000, /* R172 */
262 0x0000, /* R173 */
263 0x0000, /* R174 */
264 0x0000, /* R175 */
265 0x0000, /* R176 */
266 0x0000, /* R177 */
267 0x0000, /* R178 */
268 0x0000, /* R179 */
269 0x0000, /* R180 */
270 0x0000, /* R181 */
271 0x0000, /* R182 */
272 0x0000, /* R183 */
273 0x0000, /* R184 */
274 0x0000, /* R185 */
275 0x0000, /* R186 */
276 0x0000, /* R187 */
277 0x0000, /* R188 */
278 0x0000, /* R189 */
279 0x0000, /* R190 */
280 0x0000, /* R191 */
281 0x0000, /* R192 */
282 0x0000, /* R193 */
283 0x0000, /* R194 */
284 0x0000, /* R195 */
285 0x0000, /* R196 */
286 0x0000, /* R197 */
287 0x0000, /* R198 */
288 0x0000, /* R199 */
289 0x0000, /* R200 */
290 0x0000, /* R201 */
291 0x0000, /* R202 */
292 0x0000, /* R203 */
293 0x0000, /* R204 - Analogue Output Bias 0 */
294 0x0000, /* R205 */
295 0x0000, /* R206 */
296 0x0000, /* R207 */
297 0x0000, /* R208 */
298 0x0000, /* R209 */
299 0x0000, /* R210 */
300 0x0000, /* R211 */
301 0x0000, /* R212 */
302 0x0000, /* R213 */
303 0x0000, /* R214 */
304 0x0000, /* R215 */
305 0x0000, /* R216 */
306 0x0000, /* R217 */
307 0x0000, /* R218 */
308 0x0000, /* R219 */
309 0x0000, /* R220 */
310 0x0000, /* R221 */
311 0x0000, /* R222 */
312 0x0000, /* R223 */
313 0x0000, /* R224 */
314 0x0000, /* R225 */
315 0x0000, /* R226 */
316 0x0000, /* R227 */
317 0x0000, /* R228 */
318 0x0000, /* R229 */
319 0x0000, /* R230 */
320 0x0000, /* R231 */
321 0x0000, /* R232 */
322 0x0000, /* R233 */
323 0x0000, /* R234 */
324 0x0000, /* R235 */
325 0x0000, /* R236 */
326 0x0000, /* R237 */
327 0x0000, /* R238 */
328 0x0000, /* R239 */
329 0x0000, /* R240 */
330 0x0000, /* R241 */
331 0x0000, /* R242 */
332 0x0000, /* R243 */
333 0x0000, /* R244 */
334 0x0000, /* R245 */
335 0x0000, /* R246 */
336 0x0000, /* R247 - FLL NCO Test 0 */
337 0x0019, /* R248 - FLL NCO Test 1 */
338};
339
340static struct {
341 int readable;
342 int writable;
343 int vol;
344} wm8904_access[] = {
345 { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */
346 { 0x0000, 0x0000, 0 }, /* R1 - Revision */
347 { 0x0000, 0x0000, 0 }, /* R2 */
348 { 0x0000, 0x0000, 0 }, /* R3 */
349 { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */
350 { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */
351 { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */
352 { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */
353 { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */
354 { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */
355 { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */
356 { 0x0000, 0x0000, 0 }, /* R11 */
357 { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */
358 { 0x0000, 0x0000, 0 }, /* R13 */
359 { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */
360 { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */
361 { 0x0000, 0x0000, 0 }, /* R16 */
362 { 0x0000, 0x0000, 0 }, /* R17 */
363 { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */
364 { 0x0000, 0x0000, 0 }, /* R19 */
365 { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */
366 { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */
367 { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */
368 { 0x0000, 0x0000, 0 }, /* R23 */
369 { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */
370 { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */
371 { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */
372 { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */
373 { 0x0000, 0x0000, 0 }, /* R28 */
374 { 0x0000, 0x0000, 0 }, /* R29 */
375 { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */
376 { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */
377 { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */
378 { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */
379 { 0x0000, 0x0000, 0 }, /* R34 */
380 { 0x0000, 0x0000, 0 }, /* R35 */
381 { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */
382 { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */
383 { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */
384 { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */
385 { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */
386 { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */
387 { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */
388 { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */
389 { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */
390 { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */
391 { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */
392 { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */
393 { 0x0000, 0x0000, 0 }, /* R48 */
394 { 0x0000, 0x0000, 0 }, /* R49 */
395 { 0x0000, 0x0000, 0 }, /* R50 */
396 { 0x0000, 0x0000, 0 }, /* R51 */
397 { 0x0000, 0x0000, 0 }, /* R52 */
398 { 0x0000, 0x0000, 0 }, /* R53 */
399 { 0x0000, 0x0000, 0 }, /* R54 */
400 { 0x0000, 0x0000, 0 }, /* R55 */
401 { 0x0000, 0x0000, 0 }, /* R56 */
402 { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */
403 { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */
404 { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */
405 { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */
406 { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */
407 { 0x0000, 0x0000, 0 }, /* R62 */
408 { 0x0000, 0x0000, 0 }, /* R63 */
409 { 0x0000, 0x0000, 0 }, /* R64 */
410 { 0x0000, 0x0000, 0 }, /* R65 */
411 { 0x0000, 0x0000, 0 }, /* R66 */
412 { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */
413 { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */
414 { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */
415 { 0x0000, 0x0000, 0 }, /* R70 */
416 { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */
417 { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */
418 { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */
419 { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */
420 { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */
421 { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */
422 { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */
423 { 0x0000, 0x0000, 0 }, /* R78 */
424 { 0x0000, 0x0000, 0 }, /* R79 */
425 { 0x0000, 0x0000, 0 }, /* R80 */
426 { 0x0000, 0x0000, 0 }, /* R81 */
427 { 0x0000, 0x0000, 0 }, /* R82 */
428 { 0x0000, 0x0000, 0 }, /* R83 */
429 { 0x0000, 0x0000, 0 }, /* R84 */
430 { 0x0000, 0x0000, 0 }, /* R85 */
431 { 0x0000, 0x0000, 0 }, /* R86 */
432 { 0x0000, 0x0000, 0 }, /* R87 */
433 { 0x0000, 0x0000, 0 }, /* R88 */
434 { 0x0000, 0x0000, 0 }, /* R89 */
435 { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */
436 { 0x0000, 0x0000, 0 }, /* R91 */
437 { 0x0000, 0x0000, 0 }, /* R92 */
438 { 0x0000, 0x0000, 0 }, /* R93 */
439 { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */
440 { 0x0000, 0x0000, 0 }, /* R95 */
441 { 0x0000, 0x0000, 0 }, /* R96 */
442 { 0x0000, 0x0000, 0 }, /* R97 */
443 { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */
444 { 0x0000, 0x0000, 0 }, /* R99 */
445 { 0x0000, 0x0000, 0 }, /* R100 */
446 { 0x0000, 0x0000, 0 }, /* R101 */
447 { 0x0000, 0x0000, 0 }, /* R102 */
448 { 0x0000, 0x0000, 0 }, /* R103 */
449 { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
450 { 0x0000, 0x0000, 0 }, /* R105 */
451 { 0x0000, 0x0000, 0 }, /* R106 */
452 { 0x0000, 0x0000, 0 }, /* R107 */
453 { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
454 { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
455 { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
456 { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
457 { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
458 { 0x0000, 0x0000, 0 }, /* R113 */
459 { 0x0000, 0x0000, 0 }, /* R114 */
460 { 0x0000, 0x0000, 0 }, /* R115 */
461 { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
462 { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
463 { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
464 { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
465 { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
466 { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
467 { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
468 { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
469 { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
470 { 0x0000, 0x0000, 0 }, /* R125 */
471 { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
472 { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
473 { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
474 { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
475 { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
476 { 0x0000, 0x0000, 0 }, /* R131 */
477 { 0x0000, 0x0000, 0 }, /* R132 */
478 { 0x0000, 0x0000, 0 }, /* R133 */
479 { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
480 { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
481 { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
482 { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
483 { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
484 { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
485 { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
486 { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
487 { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
488 { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
489 { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
490 { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
491 { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
492 { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
493 { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
494 { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
495 { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
496 { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
497 { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
498 { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
499 { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
500 { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
501 { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
502 { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
503 { 0x0000, 0x0000, 0 }, /* R158 */
504 { 0x0000, 0x0000, 0 }, /* R159 */
505 { 0x0000, 0x0000, 0 }, /* R160 */
506 { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
507 { 0x0000, 0x0000, 0 }, /* R162 */
508 { 0x0000, 0x0000, 0 }, /* R163 */
509 { 0x0000, 0x0000, 0 }, /* R164 */
510 { 0x0000, 0x0000, 0 }, /* R165 */
511 { 0x0000, 0x0000, 0 }, /* R166 */
512 { 0x0000, 0x0000, 0 }, /* R167 */
513 { 0x0000, 0x0000, 0 }, /* R168 */
514 { 0x0000, 0x0000, 0 }, /* R169 */
515 { 0x0000, 0x0000, 0 }, /* R170 */
516 { 0x0000, 0x0000, 0 }, /* R171 */
517 { 0x0000, 0x0000, 0 }, /* R172 */
518 { 0x0000, 0x0000, 0 }, /* R173 */
519 { 0x0000, 0x0000, 0 }, /* R174 */
520 { 0x0000, 0x0000, 0 }, /* R175 */
521 { 0x0000, 0x0000, 0 }, /* R176 */
522 { 0x0000, 0x0000, 0 }, /* R177 */
523 { 0x0000, 0x0000, 0 }, /* R178 */
524 { 0x0000, 0x0000, 0 }, /* R179 */
525 { 0x0000, 0x0000, 0 }, /* R180 */
526 { 0x0000, 0x0000, 0 }, /* R181 */
527 { 0x0000, 0x0000, 0 }, /* R182 */
528 { 0x0000, 0x0000, 0 }, /* R183 */
529 { 0x0000, 0x0000, 0 }, /* R184 */
530 { 0x0000, 0x0000, 0 }, /* R185 */
531 { 0x0000, 0x0000, 0 }, /* R186 */
532 { 0x0000, 0x0000, 0 }, /* R187 */
533 { 0x0000, 0x0000, 0 }, /* R188 */
534 { 0x0000, 0x0000, 0 }, /* R189 */
535 { 0x0000, 0x0000, 0 }, /* R190 */
536 { 0x0000, 0x0000, 0 }, /* R191 */
537 { 0x0000, 0x0000, 0 }, /* R192 */
538 { 0x0000, 0x0000, 0 }, /* R193 */
539 { 0x0000, 0x0000, 0 }, /* R194 */
540 { 0x0000, 0x0000, 0 }, /* R195 */
541 { 0x0000, 0x0000, 0 }, /* R196 */
542 { 0x0000, 0x0000, 0 }, /* R197 */
543 { 0x0000, 0x0000, 0 }, /* R198 */
544 { 0x0000, 0x0000, 0 }, /* R199 */
545 { 0x0000, 0x0000, 0 }, /* R200 */
546 { 0x0000, 0x0000, 0 }, /* R201 */
547 { 0x0000, 0x0000, 0 }, /* R202 */
548 { 0x0000, 0x0000, 0 }, /* R203 */
549 { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
550 { 0x0000, 0x0000, 0 }, /* R205 */
551 { 0x0000, 0x0000, 0 }, /* R206 */
552 { 0x0000, 0x0000, 0 }, /* R207 */
553 { 0x0000, 0x0000, 0 }, /* R208 */
554 { 0x0000, 0x0000, 0 }, /* R209 */
555 { 0x0000, 0x0000, 0 }, /* R210 */
556 { 0x0000, 0x0000, 0 }, /* R211 */
557 { 0x0000, 0x0000, 0 }, /* R212 */
558 { 0x0000, 0x0000, 0 }, /* R213 */
559 { 0x0000, 0x0000, 0 }, /* R214 */
560 { 0x0000, 0x0000, 0 }, /* R215 */
561 { 0x0000, 0x0000, 0 }, /* R216 */
562 { 0x0000, 0x0000, 0 }, /* R217 */
563 { 0x0000, 0x0000, 0 }, /* R218 */
564 { 0x0000, 0x0000, 0 }, /* R219 */
565 { 0x0000, 0x0000, 0 }, /* R220 */
566 { 0x0000, 0x0000, 0 }, /* R221 */
567 { 0x0000, 0x0000, 0 }, /* R222 */
568 { 0x0000, 0x0000, 0 }, /* R223 */
569 { 0x0000, 0x0000, 0 }, /* R224 */
570 { 0x0000, 0x0000, 0 }, /* R225 */
571 { 0x0000, 0x0000, 0 }, /* R226 */
572 { 0x0000, 0x0000, 0 }, /* R227 */
573 { 0x0000, 0x0000, 0 }, /* R228 */
574 { 0x0000, 0x0000, 0 }, /* R229 */
575 { 0x0000, 0x0000, 0 }, /* R230 */
576 { 0x0000, 0x0000, 0 }, /* R231 */
577 { 0x0000, 0x0000, 0 }, /* R232 */
578 { 0x0000, 0x0000, 0 }, /* R233 */
579 { 0x0000, 0x0000, 0 }, /* R234 */
580 { 0x0000, 0x0000, 0 }, /* R235 */
581 { 0x0000, 0x0000, 0 }, /* R236 */
582 { 0x0000, 0x0000, 0 }, /* R237 */
583 { 0x0000, 0x0000, 0 }, /* R238 */
584 { 0x0000, 0x0000, 0 }, /* R239 */
585 { 0x0000, 0x0000, 0 }, /* R240 */
586 { 0x0000, 0x0000, 0 }, /* R241 */
587 { 0x0000, 0x0000, 0 }, /* R242 */
588 { 0x0000, 0x0000, 0 }, /* R243 */
589 { 0x0000, 0x0000, 0 }, /* R244 */
590 { 0x0000, 0x0000, 0 }, /* R245 */
591 { 0x0000, 0x0000, 0 }, /* R246 */
592 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
593 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
594};
595
596static int wm8904_volatile_register(unsigned int reg)
597{
598 return wm8904_access[reg].vol;
599}
600
601static int wm8904_reset(struct snd_soc_codec *codec)
602{
603 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
604}
605
606static int wm8904_configure_clocking(struct snd_soc_codec *codec)
607{
608 struct wm8904_priv *wm8904 = codec->private_data;
609 unsigned int clock0, clock2, rate;
610
611 /* Gate the clock while we're updating to avoid misclocking */
612 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
613 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
614 WM8904_SYSCLK_SRC, 0);
615
616 /* This should be done on init() for bypass paths */
617 switch (wm8904->sysclk_src) {
618 case WM8904_CLK_MCLK:
619 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
620
621 clock2 &= ~WM8904_SYSCLK_SRC;
622 rate = wm8904->mclk_rate;
623
624 /* Ensure the FLL is stopped */
625 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
626 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
627 break;
628
629 case WM8904_CLK_FLL:
630 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
631 wm8904->fll_fout);
632
633 clock2 |= WM8904_SYSCLK_SRC;
634 rate = wm8904->fll_fout;
635 break;
636
637 default:
638 dev_err(codec->dev, "System clock not configured\n");
639 return -EINVAL;
640 }
641
642 /* SYSCLK shouldn't be over 13.5MHz */
643 if (rate > 13500000) {
644 clock0 = WM8904_MCLK_DIV;
645 wm8904->sysclk_rate = rate / 2;
646 } else {
647 clock0 = 0;
648 wm8904->sysclk_rate = rate;
649 }
650
651 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
652 clock0);
653
654 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
655 WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2);
656
657 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
658
659 return 0;
660}
661
662static void wm8904_set_drc(struct snd_soc_codec *codec)
663{
664 struct wm8904_priv *wm8904 = codec->private_data;
665 struct wm8904_pdata *pdata = wm8904->pdata;
666 int save, i;
667
668 /* Save any enables; the configuration should clear them. */
669 save = snd_soc_read(codec, WM8904_DRC_0);
670
671 for (i = 0; i < WM8904_DRC_REGS; i++)
672 snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff,
673 pdata->drc_cfgs[wm8904->drc_cfg].regs[i]);
674
675 /* Reenable the DRC */
676 snd_soc_update_bits(codec, WM8904_DRC_0,
677 WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save);
678}
679
680static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
681 struct snd_ctl_elem_value *ucontrol)
682{
683 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
684 struct wm8904_priv *wm8904 = codec->private_data;
685 struct wm8904_pdata *pdata = wm8904->pdata;
686 int value = ucontrol->value.integer.value[0];
687
688 if (value >= pdata->num_drc_cfgs)
689 return -EINVAL;
690
691 wm8904->drc_cfg = value;
692
693 wm8904_set_drc(codec);
694
695 return 0;
696}
697
698static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
699 struct snd_ctl_elem_value *ucontrol)
700{
701 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
702 struct wm8904_priv *wm8904 = codec->private_data;
703
704 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
705
706 return 0;
707}
708
709static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
710{
711 struct wm8904_priv *wm8904 = codec->private_data;
712 struct wm8904_pdata *pdata = wm8904->pdata;
713 int best, best_val, save, i, cfg;
714
715 if (!pdata || !wm8904->num_retune_mobile_texts)
716 return;
717
718 /* Find the version of the currently selected configuration
719 * with the nearest sample rate. */
720 cfg = wm8904->retune_mobile_cfg;
721 best = 0;
722 best_val = INT_MAX;
723 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
724 if (strcmp(pdata->retune_mobile_cfgs[i].name,
725 wm8904->retune_mobile_texts[cfg]) == 0 &&
726 abs(pdata->retune_mobile_cfgs[i].rate
727 - wm8904->fs) < best_val) {
728 best = i;
729 best_val = abs(pdata->retune_mobile_cfgs[i].rate
730 - wm8904->fs);
731 }
732 }
733
734 dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
735 pdata->retune_mobile_cfgs[best].name,
736 pdata->retune_mobile_cfgs[best].rate,
737 wm8904->fs);
738
739 /* The EQ will be disabled while reconfiguring it, remember the
740 * current configuration.
741 */
742 save = snd_soc_read(codec, WM8904_EQ1);
743
744 for (i = 0; i < WM8904_EQ_REGS; i++)
745 snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff,
746 pdata->retune_mobile_cfgs[best].regs[i]);
747
748 snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save);
749}
750
751static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
753{
754 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
755 struct wm8904_priv *wm8904 = codec->private_data;
756 struct wm8904_pdata *pdata = wm8904->pdata;
757 int value = ucontrol->value.integer.value[0];
758
759 if (value >= pdata->num_retune_mobile_cfgs)
760 return -EINVAL;
761
762 wm8904->retune_mobile_cfg = value;
763
764 wm8904_set_retune_mobile(codec);
765
766 return 0;
767}
768
769static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
770 struct snd_ctl_elem_value *ucontrol)
771{
772 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
773 struct wm8904_priv *wm8904 = codec->private_data;
774
775 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
776
777 return 0;
778}
779
780static int deemph_settings[] = { 0, 32000, 44100, 48000 };
781
782static int wm8904_set_deemph(struct snd_soc_codec *codec)
783{
784 struct wm8904_priv *wm8904 = codec->private_data;
785 int val, i, best;
786
787 /* If we're using deemphasis select the nearest available sample
788 * rate.
789 */
790 if (wm8904->deemph) {
791 best = 1;
792 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
793 if (abs(deemph_settings[i] - wm8904->fs) <
794 abs(deemph_settings[best] - wm8904->fs))
795 best = i;
796 }
797
798 val = best << WM8904_DEEMPH_SHIFT;
799 } else {
800 val = 0;
801 }
802
803 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
804
805 return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
806 WM8904_DEEMPH_MASK, val);
807}
808
809static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
810 struct snd_ctl_elem_value *ucontrol)
811{
812 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
813 struct wm8904_priv *wm8904 = codec->private_data;
814
815 return wm8904->deemph;
816}
817
818static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
819 struct snd_ctl_elem_value *ucontrol)
820{
821 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
822 struct wm8904_priv *wm8904 = codec->private_data;
823 int deemph = ucontrol->value.enumerated.item[0];
824
825 if (deemph > 1)
826 return -EINVAL;
827
828 wm8904->deemph = deemph;
829
830 return wm8904_set_deemph(codec);
831}
832
833static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
834static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
835static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
836static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
837static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
838
839static const char *input_mode_text[] = {
840 "Single-Ended", "Differential Line", "Differential Mic"
841};
842
843static const struct soc_enum lin_mode =
844 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
845
846static const struct soc_enum rin_mode =
847 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
848
849static const char *hpf_mode_text[] = {
850 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
851};
852
853static const struct soc_enum hpf_mode =
854 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
855
856static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
857SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
858 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
859
860SOC_ENUM("Left Caputure Mode", lin_mode),
861SOC_ENUM("Right Capture Mode", rin_mode),
862
863/* No TLV since it depends on mode */
864SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
865 WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
866SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
867 WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0),
868
869SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
870SOC_ENUM("High Pass Filter Mode", hpf_mode),
871
872SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0),
873};
874
875static const char *drc_path_text[] = {
876 "ADC", "DAC"
877};
878
879static const struct soc_enum drc_path =
880 SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text);
881
882static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = {
883SOC_SINGLE_TLV("Digital Playback Boost Volume",
884 WM8904_AUDIO_INTERFACE_0, 9, 3, 0, dac_boost_tlv),
885SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8904_DAC_DIGITAL_VOLUME_LEFT,
886 WM8904_DAC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
887
888SOC_DOUBLE_R_TLV("Headphone Volume", WM8904_ANALOGUE_OUT1_LEFT,
889 WM8904_ANALOGUE_OUT1_RIGHT, 0, 63, 0, out_tlv),
890SOC_DOUBLE_R("Headphone Switch", WM8904_ANALOGUE_OUT1_LEFT,
891 WM8904_ANALOGUE_OUT1_RIGHT, 8, 1, 1),
892SOC_DOUBLE_R("Headphone ZC Switch", WM8904_ANALOGUE_OUT1_LEFT,
893 WM8904_ANALOGUE_OUT1_RIGHT, 6, 1, 0),
894
895SOC_DOUBLE_R_TLV("Line Output Volume", WM8904_ANALOGUE_OUT2_LEFT,
896 WM8904_ANALOGUE_OUT2_RIGHT, 0, 63, 0, out_tlv),
897SOC_DOUBLE_R("Line Output Switch", WM8904_ANALOGUE_OUT2_LEFT,
898 WM8904_ANALOGUE_OUT2_RIGHT, 8, 1, 1),
899SOC_DOUBLE_R("Line Output ZC Switch", WM8904_ANALOGUE_OUT2_LEFT,
900 WM8904_ANALOGUE_OUT2_RIGHT, 6, 1, 0),
901
902SOC_SINGLE("EQ Switch", WM8904_EQ1, 0, 1, 0),
903SOC_SINGLE("DRC Switch", WM8904_DRC_0, 15, 1, 0),
904SOC_ENUM("DRC Path", drc_path),
905SOC_SINGLE("DAC OSRx2 Switch", WM8904_DAC_DIGITAL_1, 6, 1, 0),
906SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
907 wm8904_get_deemph, wm8904_put_deemph),
908};
909
910static const struct snd_kcontrol_new wm8904_snd_controls[] = {
911SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8904_DAC_DIGITAL_0, 4, 8, 15, 0,
912 sidetone_tlv),
913};
914
915static const struct snd_kcontrol_new wm8904_eq_controls[] = {
916SOC_SINGLE_TLV("EQ1 Volume", WM8904_EQ2, 0, 24, 0, eq_tlv),
917SOC_SINGLE_TLV("EQ2 Volume", WM8904_EQ3, 0, 24, 0, eq_tlv),
918SOC_SINGLE_TLV("EQ3 Volume", WM8904_EQ4, 0, 24, 0, eq_tlv),
919SOC_SINGLE_TLV("EQ4 Volume", WM8904_EQ5, 0, 24, 0, eq_tlv),
920SOC_SINGLE_TLV("EQ5 Volume", WM8904_EQ6, 0, 24, 0, eq_tlv),
921};
922
923static int cp_event(struct snd_soc_dapm_widget *w,
924 struct snd_kcontrol *kcontrol, int event)
925{
926 BUG_ON(event != SND_SOC_DAPM_POST_PMU);
927
928 /* Maximum startup time */
929 udelay(500);
930
931 return 0;
932}
933
934static int sysclk_event(struct snd_soc_dapm_widget *w,
935 struct snd_kcontrol *kcontrol, int event)
936{
937 struct snd_soc_codec *codec = w->codec;
938 struct wm8904_priv *wm8904 = codec->private_data;
939
940 switch (event) {
941 case SND_SOC_DAPM_PRE_PMU:
942 /* If we're using the FLL then we only start it when
943 * required; we assume that the configuration has been
944 * done previously and all we need to do is kick it
945 * off.
946 */
947 switch (wm8904->sysclk_src) {
948 case WM8904_CLK_FLL:
949 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
950 WM8904_FLL_OSC_ENA,
951 WM8904_FLL_OSC_ENA);
952
953 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
954 WM8904_FLL_ENA,
955 WM8904_FLL_ENA);
956 break;
957
958 default:
959 break;
960 }
961 break;
962
963 case SND_SOC_DAPM_POST_PMD:
964 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
965 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
966 break;
967 }
968
969 return 0;
970}
971
972static int out_pga_event(struct snd_soc_dapm_widget *w,
973 struct snd_kcontrol *kcontrol, int event)
974{
975 struct snd_soc_codec *codec = w->codec;
976 struct wm8904_priv *wm8904 = codec->private_data;
977 int reg, val;
978 int dcs_mask;
979 int dcs_l, dcs_r;
980 int dcs_l_reg, dcs_r_reg;
981 int timeout;
982
983 /* This code is shared between HP and LINEOUT; we do all our
984 * power management in stereo pairs to avoid latency issues so
985 * we reuse shift to identify which rather than strcmp() the
986 * name. */
987 reg = w->shift;
988
989 switch (reg) {
990 case WM8904_ANALOGUE_HP_0:
991 dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
992 dcs_r_reg = WM8904_DC_SERVO_8;
993 dcs_l_reg = WM8904_DC_SERVO_9;
994 dcs_l = 0;
995 dcs_r = 1;
996 break;
997 case WM8904_ANALOGUE_LINEOUT_0:
998 dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
999 dcs_r_reg = WM8904_DC_SERVO_6;
1000 dcs_l_reg = WM8904_DC_SERVO_7;
1001 dcs_l = 2;
1002 dcs_r = 3;
1003 break;
1004 default:
1005 BUG();
1006 return -EINVAL;
1007 }
1008
1009 switch (event) {
1010 case SND_SOC_DAPM_POST_PMU:
1011 /* Power on the amplifier */
1012 snd_soc_update_bits(codec, reg,
1013 WM8904_HPL_ENA | WM8904_HPR_ENA,
1014 WM8904_HPL_ENA | WM8904_HPR_ENA);
1015
1016 /* Enable the first stage */
1017 snd_soc_update_bits(codec, reg,
1018 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
1019 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);
1020
1021 /* Power up the DC servo */
1022 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1023 dcs_mask, dcs_mask);
1024
1025 /* Either calibrate the DC servo or restore cached state
1026 * if we have that.
1027 */
1028 if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
1029 dev_dbg(codec->dev, "Restoring DC servo state\n");
1030
1031 snd_soc_write(codec, dcs_l_reg,
1032 wm8904->dcs_state[dcs_l]);
1033 snd_soc_write(codec, dcs_r_reg,
1034 wm8904->dcs_state[dcs_r]);
1035
1036 snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);
1037
1038 timeout = 20;
1039 } else {
1040 dev_dbg(codec->dev, "Calibrating DC servo\n");
1041
1042 snd_soc_write(codec, WM8904_DC_SERVO_1,
1043 dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);
1044
1045 timeout = 500;
1046 }
1047
1048 /* Wait for DC servo to complete */
1049 dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
1050 do {
1051 val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
1052 if ((val & dcs_mask) == dcs_mask)
1053 break;
1054
1055 msleep(1);
1056 } while (--timeout);
1057
1058 if ((val & dcs_mask) != dcs_mask)
1059 dev_warn(codec->dev, "DC servo timed out\n");
1060 else
1061 dev_dbg(codec->dev, "DC servo ready\n");
1062
1063 /* Enable the output stage */
1064 snd_soc_update_bits(codec, reg,
1065 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1066 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
1067
1068 /* Unshort the output itself */
1069 snd_soc_update_bits(codec, reg,
1070 WM8904_HPL_RMV_SHORT |
1071 WM8904_HPR_RMV_SHORT,
1072 WM8904_HPL_RMV_SHORT |
1073 WM8904_HPR_RMV_SHORT);
1074
1075 break;
1076
1077 case SND_SOC_DAPM_PRE_PMD:
1078 /* Short the output */
1079 snd_soc_update_bits(codec, reg,
1080 WM8904_HPL_RMV_SHORT |
1081 WM8904_HPR_RMV_SHORT, 0);
1082
1083 /* Cache the DC servo configuration; this will be
1084 * invalidated if we change the configuration. */
1085 wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg);
1086 wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg);
1087
1088 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1089 dcs_mask, 0);
1090
1091 /* Disable the amplifier input and output stages */
1092 snd_soc_update_bits(codec, reg,
1093 WM8904_HPL_ENA | WM8904_HPR_ENA |
1094 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY |
1095 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1096 0);
1097 break;
1098 }
1099
1100 return 0;
1101}
1102
1103static const char *lin_text[] = {
1104 "IN1L", "IN2L", "IN3L"
1105};
1106
1107static const struct soc_enum lin_enum =
1108 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text);
1109
1110static const struct snd_kcontrol_new lin_mux =
1111 SOC_DAPM_ENUM("Left Capture Mux", lin_enum);
1112
1113static const struct soc_enum lin_inv_enum =
1114 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text);
1115
1116static const struct snd_kcontrol_new lin_inv_mux =
1117 SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
1118
1119static const char *rin_text[] = {
1120 "IN1R", "IN2R", "IN3R"
1121};
1122
1123static const struct soc_enum rin_enum =
1124 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text);
1125
1126static const struct snd_kcontrol_new rin_mux =
1127 SOC_DAPM_ENUM("Right Capture Mux", rin_enum);
1128
1129static const struct soc_enum rin_inv_enum =
1130 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text);
1131
1132static const struct snd_kcontrol_new rin_inv_mux =
1133 SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
1134
1135static const char *aif_text[] = {
1136 "Left", "Right"
1137};
1138
1139static const struct soc_enum aifoutl_enum =
1140 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text);
1141
1142static const struct snd_kcontrol_new aifoutl_mux =
1143 SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
1144
1145static const struct soc_enum aifoutr_enum =
1146 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text);
1147
1148static const struct snd_kcontrol_new aifoutr_mux =
1149 SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
1150
1151static const struct soc_enum aifinl_enum =
1152 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text);
1153
1154static const struct snd_kcontrol_new aifinl_mux =
1155 SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
1156
1157static const struct soc_enum aifinr_enum =
1158 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text);
1159
1160static const struct snd_kcontrol_new aifinr_mux =
1161 SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
1162
1163static const struct snd_soc_dapm_widget wm8904_core_dapm_widgets[] = {
1164SND_SOC_DAPM_SUPPLY("SYSCLK", WM8904_CLOCK_RATES_2, 2, 0, sysclk_event,
1165 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1166SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8904_CLOCK_RATES_2, 1, 0, NULL, 0),
1167SND_SOC_DAPM_SUPPLY("TOCLK", WM8904_CLOCK_RATES_2, 0, 0, NULL, 0),
1168};
1169
1170static const struct snd_soc_dapm_widget wm8904_adc_dapm_widgets[] = {
1171SND_SOC_DAPM_INPUT("IN1L"),
1172SND_SOC_DAPM_INPUT("IN1R"),
1173SND_SOC_DAPM_INPUT("IN2L"),
1174SND_SOC_DAPM_INPUT("IN2R"),
1175SND_SOC_DAPM_INPUT("IN3L"),
1176SND_SOC_DAPM_INPUT("IN3R"),
1177
1178SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0),
1179
1180SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
1181SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1182 &lin_inv_mux),
1183SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
1184SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1185 &rin_inv_mux),
1186
1187SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
1188 NULL, 0),
1189SND_SOC_DAPM_PGA("Right Capture PGA", WM8904_POWER_MANAGEMENT_0, 0, 0,
1190 NULL, 0),
1191
1192SND_SOC_DAPM_ADC("ADCL", NULL, WM8904_POWER_MANAGEMENT_6, 1, 0),
1193SND_SOC_DAPM_ADC("ADCR", NULL, WM8904_POWER_MANAGEMENT_6, 0, 0),
1194
1195SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
1196SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
1197
1198SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
1199SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
1200};
1201
1202static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = {
1203SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
1204SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
1205
1206SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
1207SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
1208
1209SND_SOC_DAPM_DAC("DACL", NULL, WM8904_POWER_MANAGEMENT_6, 3, 0),
1210SND_SOC_DAPM_DAC("DACR", NULL, WM8904_POWER_MANAGEMENT_6, 2, 0),
1211
1212SND_SOC_DAPM_SUPPLY("Charge pump", WM8904_CHARGE_PUMP_0, 0, 0, cp_event,
1213 SND_SOC_DAPM_POST_PMU),
1214
1215SND_SOC_DAPM_PGA("HPL PGA", WM8904_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
1216SND_SOC_DAPM_PGA("HPR PGA", WM8904_POWER_MANAGEMENT_2, 0, 0, NULL, 0),
1217
1218SND_SOC_DAPM_PGA("LINEL PGA", WM8904_POWER_MANAGEMENT_3, 1, 0, NULL, 0),
1219SND_SOC_DAPM_PGA("LINER PGA", WM8904_POWER_MANAGEMENT_3, 0, 0, NULL, 0),
1220
1221SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM, WM8904_ANALOGUE_HP_0,
1222 0, NULL, 0, out_pga_event,
1223 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1224SND_SOC_DAPM_PGA_E("Line Output", SND_SOC_NOPM, WM8904_ANALOGUE_LINEOUT_0,
1225 0, NULL, 0, out_pga_event,
1226 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1227
1228SND_SOC_DAPM_OUTPUT("HPOUTL"),
1229SND_SOC_DAPM_OUTPUT("HPOUTR"),
1230SND_SOC_DAPM_OUTPUT("LINEOUTL"),
1231SND_SOC_DAPM_OUTPUT("LINEOUTR"),
1232};
1233
1234static const char *out_mux_text[] = {
1235 "DAC", "Bypass"
1236};
1237
1238static const struct soc_enum hpl_enum =
1239 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text);
1240
1241static const struct snd_kcontrol_new hpl_mux =
1242 SOC_DAPM_ENUM("HPL Mux", hpl_enum);
1243
1244static const struct soc_enum hpr_enum =
1245 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text);
1246
1247static const struct snd_kcontrol_new hpr_mux =
1248 SOC_DAPM_ENUM("HPR Mux", hpr_enum);
1249
1250static const struct soc_enum linel_enum =
1251 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text);
1252
1253static const struct snd_kcontrol_new linel_mux =
1254 SOC_DAPM_ENUM("LINEL Mux", linel_enum);
1255
1256static const struct soc_enum liner_enum =
1257 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text);
1258
1259static const struct snd_kcontrol_new liner_mux =
1260 SOC_DAPM_ENUM("LINEL Mux", liner_enum);
1261
1262static const char *sidetone_text[] = {
1263 "None", "Left", "Right"
1264};
1265
1266static const struct soc_enum dacl_sidetone_enum =
1267 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text);
1268
1269static const struct snd_kcontrol_new dacl_sidetone_mux =
1270 SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum);
1271
1272static const struct soc_enum dacr_sidetone_enum =
1273 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text);
1274
1275static const struct snd_kcontrol_new dacr_sidetone_mux =
1276 SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum);
1277
1278static const struct snd_soc_dapm_widget wm8904_dapm_widgets[] = {
1279SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0),
1280SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1281SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1282
1283SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &dacl_sidetone_mux),
1284SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &dacr_sidetone_mux),
1285
1286SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1287SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1288SND_SOC_DAPM_MUX("LINEL Mux", SND_SOC_NOPM, 0, 0, &linel_mux),
1289SND_SOC_DAPM_MUX("LINER Mux", SND_SOC_NOPM, 0, 0, &liner_mux),
1290};
1291
1292static const struct snd_soc_dapm_route core_intercon[] = {
1293 { "CLK_DSP", NULL, "SYSCLK" },
1294 { "TOCLK", NULL, "SYSCLK" },
1295};
1296
1297static const struct snd_soc_dapm_route adc_intercon[] = {
1298 { "Left Capture Mux", "IN1L", "IN1L" },
1299 { "Left Capture Mux", "IN2L", "IN2L" },
1300 { "Left Capture Mux", "IN3L", "IN3L" },
1301
1302 { "Left Capture Inverting Mux", "IN1L", "IN1L" },
1303 { "Left Capture Inverting Mux", "IN2L", "IN2L" },
1304 { "Left Capture Inverting Mux", "IN3L", "IN3L" },
1305
1306 { "Right Capture Mux", "IN1R", "IN1R" },
1307 { "Right Capture Mux", "IN2R", "IN2R" },
1308 { "Right Capture Mux", "IN3R", "IN3R" },
1309
1310 { "Right Capture Inverting Mux", "IN1R", "IN1R" },
1311 { "Right Capture Inverting Mux", "IN2R", "IN2R" },
1312 { "Right Capture Inverting Mux", "IN3R", "IN3R" },
1313
1314 { "Left Capture PGA", NULL, "Left Capture Mux" },
1315 { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
1316
1317 { "Right Capture PGA", NULL, "Right Capture Mux" },
1318 { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
1319
1320 { "AIFOUTL", "Left", "ADCL" },
1321 { "AIFOUTL", "Right", "ADCR" },
1322 { "AIFOUTR", "Left", "ADCL" },
1323 { "AIFOUTR", "Right", "ADCR" },
1324
1325 { "ADCL", NULL, "CLK_DSP" },
1326 { "ADCL", NULL, "Left Capture PGA" },
1327
1328 { "ADCR", NULL, "CLK_DSP" },
1329 { "ADCR", NULL, "Right Capture PGA" },
1330};
1331
1332static const struct snd_soc_dapm_route dac_intercon[] = {
1333 { "DACL", "Right", "AIFINR" },
1334 { "DACL", "Left", "AIFINL" },
1335 { "DACL", NULL, "CLK_DSP" },
1336
1337 { "DACR", "Right", "AIFINR" },
1338 { "DACR", "Left", "AIFINL" },
1339 { "DACR", NULL, "CLK_DSP" },
1340
1341 { "Charge pump", NULL, "SYSCLK" },
1342
1343 { "Headphone Output", NULL, "HPL PGA" },
1344 { "Headphone Output", NULL, "HPR PGA" },
1345 { "Headphone Output", NULL, "Charge pump" },
1346 { "Headphone Output", NULL, "TOCLK" },
1347
1348 { "Line Output", NULL, "LINEL PGA" },
1349 { "Line Output", NULL, "LINER PGA" },
1350 { "Line Output", NULL, "Charge pump" },
1351 { "Line Output", NULL, "TOCLK" },
1352
1353 { "HPOUTL", NULL, "Headphone Output" },
1354 { "HPOUTR", NULL, "Headphone Output" },
1355
1356 { "LINEOUTL", NULL, "Line Output" },
1357 { "LINEOUTR", NULL, "Line Output" },
1358};
1359
1360static const struct snd_soc_dapm_route wm8904_intercon[] = {
1361 { "Left Sidetone", "Left", "ADCL" },
1362 { "Left Sidetone", "Right", "ADCR" },
1363 { "DACL", NULL, "Left Sidetone" },
1364
1365 { "Right Sidetone", "Left", "ADCL" },
1366 { "Right Sidetone", "Right", "ADCR" },
1367 { "DACR", NULL, "Right Sidetone" },
1368
1369 { "Left Bypass", NULL, "Class G" },
1370 { "Left Bypass", NULL, "Left Capture PGA" },
1371
1372 { "Right Bypass", NULL, "Class G" },
1373 { "Right Bypass", NULL, "Right Capture PGA" },
1374
1375 { "HPL Mux", "DAC", "DACL" },
1376 { "HPL Mux", "Bypass", "Left Bypass" },
1377
1378 { "HPR Mux", "DAC", "DACR" },
1379 { "HPR Mux", "Bypass", "Right Bypass" },
1380
1381 { "LINEL Mux", "DAC", "DACL" },
1382 { "LINEL Mux", "Bypass", "Left Bypass" },
1383
1384 { "LINER Mux", "DAC", "DACR" },
1385 { "LINER Mux", "Bypass", "Right Bypass" },
1386
1387 { "HPL PGA", NULL, "HPL Mux" },
1388 { "HPR PGA", NULL, "HPR Mux" },
1389
1390 { "LINEL PGA", NULL, "LINEL Mux" },
1391 { "LINER PGA", NULL, "LINER Mux" },
1392};
1393
1394static int wm8904_add_widgets(struct snd_soc_codec *codec)
1395{
1396 snd_soc_add_controls(codec, wm8904_adc_snd_controls,
1397 ARRAY_SIZE(wm8904_adc_snd_controls));
1398 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1399 ARRAY_SIZE(wm8904_dac_snd_controls));
1400 snd_soc_add_controls(codec, wm8904_snd_controls,
1401 ARRAY_SIZE(wm8904_snd_controls));
1402
1403 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1404 ARRAY_SIZE(wm8904_core_dapm_widgets));
1405 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
1406 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1407 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1408 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1409 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
1410 ARRAY_SIZE(wm8904_dapm_widgets));
1411
1412 snd_soc_dapm_add_routes(codec, core_intercon,
1413 ARRAY_SIZE(core_intercon));
1414 snd_soc_dapm_add_routes(codec, adc_intercon, ARRAY_SIZE(adc_intercon));
1415 snd_soc_dapm_add_routes(codec, dac_intercon, ARRAY_SIZE(dac_intercon));
1416 snd_soc_dapm_add_routes(codec, wm8904_intercon,
1417 ARRAY_SIZE(wm8904_intercon));
1418
1419 snd_soc_dapm_new_widgets(codec);
1420 return 0;
1421}
1422
1423static struct {
1424 int ratio;
1425 unsigned int clk_sys_rate;
1426} clk_sys_rates[] = {
1427 { 64, 0 },
1428 { 128, 1 },
1429 { 192, 2 },
1430 { 256, 3 },
1431 { 384, 4 },
1432 { 512, 5 },
1433 { 786, 6 },
1434 { 1024, 7 },
1435 { 1408, 8 },
1436 { 1536, 9 },
1437};
1438
1439static struct {
1440 int rate;
1441 int sample_rate;
1442} sample_rates[] = {
1443 { 8000, 0 },
1444 { 11025, 1 },
1445 { 12000, 1 },
1446 { 16000, 2 },
1447 { 22050, 3 },
1448 { 24000, 3 },
1449 { 32000, 4 },
1450 { 44100, 5 },
1451 { 48000, 5 },
1452};
1453
1454static struct {
1455 int div; /* *10 due to .5s */
1456 int bclk_div;
1457} bclk_divs[] = {
1458 { 10, 0 },
1459 { 15, 1 },
1460 { 20, 2 },
1461 { 30, 3 },
1462 { 40, 4 },
1463 { 50, 5 },
1464 { 55, 6 },
1465 { 60, 7 },
1466 { 80, 8 },
1467 { 100, 9 },
1468 { 110, 10 },
1469 { 120, 11 },
1470 { 160, 12 },
1471 { 200, 13 },
1472 { 220, 14 },
1473 { 240, 16 },
1474 { 200, 17 },
1475 { 320, 18 },
1476 { 440, 19 },
1477 { 480, 20 },
1478};
1479
1480
1481static int wm8904_hw_params(struct snd_pcm_substream *substream,
1482 struct snd_pcm_hw_params *params,
1483 struct snd_soc_dai *dai)
1484{
1485 struct snd_soc_codec *codec = dai->codec;
1486 struct wm8904_priv *wm8904 = codec->private_data;
1487 int ret, i, best, best_val, cur_val;
1488 unsigned int aif1 = 0;
1489 unsigned int aif2 = 0;
1490 unsigned int aif3 = 0;
1491 unsigned int clock1 = 0;
1492 unsigned int dac_digital1 = 0;
1493
1494 /* What BCLK do we need? */
1495 wm8904->fs = params_rate(params);
1496 if (wm8904->tdm_slots) {
1497 dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
1498 wm8904->tdm_slots, wm8904->tdm_width);
1499 wm8904->bclk = snd_soc_calc_bclk(wm8904->fs,
1500 wm8904->tdm_width, 2,
1501 wm8904->tdm_slots);
1502 } else {
1503 wm8904->bclk = snd_soc_params_to_bclk(params);
1504 }
1505
1506 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk);
1507
1508 ret = wm8904_configure_clocking(codec);
1509 if (ret != 0)
1510 return ret;
1511
1512 /* Select nearest CLK_SYS_RATE */
1513 best = 0;
1514 best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio)
1515 - wm8904->fs);
1516 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1517 cur_val = abs((wm8904->sysclk_rate /
1518 clk_sys_rates[i].ratio) - wm8904->fs);;
1519 if (cur_val < best_val) {
1520 best = i;
1521 best_val = cur_val;
1522 }
1523 }
1524 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1525 clk_sys_rates[best].ratio);
1526 clock1 |= (clk_sys_rates[best].clk_sys_rate
1527 << WM8904_CLK_SYS_RATE_SHIFT);
1528
1529 /* SAMPLE_RATE */
1530 best = 0;
1531 best_val = abs(wm8904->fs - sample_rates[0].rate);
1532 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1533 /* Closest match */
1534 cur_val = abs(wm8904->fs - sample_rates[i].rate);
1535 if (cur_val < best_val) {
1536 best = i;
1537 best_val = cur_val;
1538 }
1539 }
1540 dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
1541 sample_rates[best].rate);
1542 clock1 |= (sample_rates[best].sample_rate
1543 << WM8904_SAMPLE_RATE_SHIFT);
1544
1545 /* Enable sloping stopband filter for low sample rates */
1546 if (wm8904->fs <= 24000)
1547 dac_digital1 |= WM8904_DAC_SB_FILT;
1548
1549 /* BCLK_DIV */
1550 best = 0;
1551 best_val = INT_MAX;
1552 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1553 cur_val = ((wm8904->sysclk_rate * 10) / bclk_divs[i].div)
1554 - wm8904->bclk;
1555 if (cur_val < 0) /* Table is sorted */
1556 break;
1557 if (cur_val < best_val) {
1558 best = i;
1559 best_val = cur_val;
1560 }
1561 }
1562 wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div;
1563 dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
1564 bclk_divs[best].div, wm8904->bclk);
1565 aif2 |= bclk_divs[best].bclk_div;
1566
1567 /* LRCLK is a simple fraction of BCLK */
1568 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
1569 aif3 |= wm8904->bclk / wm8904->fs;
1570
1571 /* Apply the settings */
1572 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
1573 WM8904_DAC_SB_FILT, dac_digital1);
1574 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1575 WM8904_AIF_WL_MASK, aif1);
1576 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2,
1577 WM8904_BCLK_DIV_MASK, aif2);
1578 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1579 WM8904_LRCLK_RATE_MASK, aif3);
1580 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1,
1581 WM8904_SAMPLE_RATE_MASK |
1582 WM8904_CLK_SYS_RATE_MASK, clock1);
1583
1584 /* Update filters for the new settings */
1585 wm8904_set_retune_mobile(codec);
1586 wm8904_set_deemph(codec);
1587
1588 return 0;
1589}
1590
1591
1592static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1593 unsigned int freq, int dir)
1594{
1595 struct snd_soc_codec *codec = dai->codec;
1596 struct wm8904_priv *priv = codec->private_data;
1597
1598 switch (clk_id) {
1599 case WM8904_CLK_MCLK:
1600 priv->sysclk_src = clk_id;
1601 priv->mclk_rate = freq;
1602 break;
1603
1604 case WM8904_CLK_FLL:
1605 priv->sysclk_src = clk_id;
1606 break;
1607
1608 default:
1609 return -EINVAL;
1610 }
1611
1612 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1613
1614 wm8904_configure_clocking(codec);
1615
1616 return 0;
1617}
1618
1619static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1620{
1621 struct snd_soc_codec *codec = dai->codec;
1622 unsigned int aif1 = 0;
1623 unsigned int aif3 = 0;
1624
1625 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1626 case SND_SOC_DAIFMT_CBS_CFS:
1627 break;
1628 case SND_SOC_DAIFMT_CBS_CFM:
1629 aif3 |= WM8904_LRCLK_DIR;
1630 break;
1631 case SND_SOC_DAIFMT_CBM_CFS:
1632 aif1 |= WM8904_BCLK_DIR;
1633 break;
1634 case SND_SOC_DAIFMT_CBM_CFM:
1635 aif1 |= WM8904_BCLK_DIR;
1636 aif3 |= WM8904_LRCLK_DIR;
1637 break;
1638 default:
1639 return -EINVAL;
1640 }
1641
1642 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1643 case SND_SOC_DAIFMT_DSP_B:
1644 aif1 |= WM8904_AIF_LRCLK_INV;
1645 case SND_SOC_DAIFMT_DSP_A:
1646 aif1 |= 0x3;
1647 break;
1648 case SND_SOC_DAIFMT_I2S:
1649 aif1 |= 0x2;
1650 break;
1651 case SND_SOC_DAIFMT_RIGHT_J:
1652 break;
1653 case SND_SOC_DAIFMT_LEFT_J:
1654 aif1 |= 0x1;
1655 break;
1656 default:
1657 return -EINVAL;
1658 }
1659
1660 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1661 case SND_SOC_DAIFMT_DSP_A:
1662 case SND_SOC_DAIFMT_DSP_B:
1663 /* frame inversion not valid for DSP modes */
1664 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1665 case SND_SOC_DAIFMT_NB_NF:
1666 break;
1667 case SND_SOC_DAIFMT_IB_NF:
1668 aif1 |= WM8904_AIF_BCLK_INV;
1669 break;
1670 default:
1671 return -EINVAL;
1672 }
1673 break;
1674
1675 case SND_SOC_DAIFMT_I2S:
1676 case SND_SOC_DAIFMT_RIGHT_J:
1677 case SND_SOC_DAIFMT_LEFT_J:
1678 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1679 case SND_SOC_DAIFMT_NB_NF:
1680 break;
1681 case SND_SOC_DAIFMT_IB_IF:
1682 aif1 |= WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV;
1683 break;
1684 case SND_SOC_DAIFMT_IB_NF:
1685 aif1 |= WM8904_AIF_BCLK_INV;
1686 break;
1687 case SND_SOC_DAIFMT_NB_IF:
1688 aif1 |= WM8904_AIF_LRCLK_INV;
1689 break;
1690 default:
1691 return -EINVAL;
1692 }
1693 break;
1694 default:
1695 return -EINVAL;
1696 }
1697
1698 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1699 WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV |
1700 WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1);
1701 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1702 WM8904_LRCLK_DIR, aif3);
1703
1704 return 0;
1705}
1706
1707
1708static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1709 unsigned int rx_mask, int slots, int slot_width)
1710{
1711 struct snd_soc_codec *codec = dai->codec;
1712 struct wm8904_priv *wm8904 = codec->private_data;
1713 int aif1 = 0;
1714
1715 /* Don't need to validate anything if we're turning off TDM */
1716 if (slots == 0)
1717 goto out;
1718
1719 /* Note that we allow configurations we can't handle ourselves -
1720 * for example, we can generate clocks for slots 2 and up even if
1721 * we can't use those slots ourselves.
1722 */
1723 aif1 |= WM8904_AIFADC_TDM | WM8904_AIFDAC_TDM;
1724
1725 switch (rx_mask) {
1726 case 3:
1727 break;
1728 case 0xc:
1729 aif1 |= WM8904_AIFADC_TDM_CHAN;
1730 break;
1731 default:
1732 return -EINVAL;
1733 }
1734
1735
1736 switch (tx_mask) {
1737 case 3:
1738 break;
1739 case 0xc:
1740 aif1 |= WM8904_AIFDAC_TDM_CHAN;
1741 break;
1742 default:
1743 return -EINVAL;
1744 }
1745
1746out:
1747 wm8904->tdm_width = slot_width;
1748 wm8904->tdm_slots = slots / 2;
1749
1750 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1751 WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN |
1752 WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1);
1753
1754 return 0;
1755}
1756
1757struct _fll_div {
1758 u16 fll_fratio;
1759 u16 fll_outdiv;
1760 u16 fll_clk_ref_div;
1761 u16 n;
1762 u16 k;
1763};
1764
1765/* The size in bits of the FLL divide multiplied by 10
1766 * to allow rounding later */
1767#define FIXED_FLL_SIZE ((1 << 16) * 10)
1768
1769static struct {
1770 unsigned int min;
1771 unsigned int max;
1772 u16 fll_fratio;
1773 int ratio;
1774} fll_fratios[] = {
1775 { 0, 64000, 4, 16 },
1776 { 64000, 128000, 3, 8 },
1777 { 128000, 256000, 2, 4 },
1778 { 256000, 1000000, 1, 2 },
1779 { 1000000, 13500000, 0, 1 },
1780};
1781
1782static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1783 unsigned int Fout)
1784{
1785 u64 Kpart;
1786 unsigned int K, Ndiv, Nmod, target;
1787 unsigned int div;
1788 int i;
1789
1790 /* Fref must be <=13.5MHz */
1791 div = 1;
1792 fll_div->fll_clk_ref_div = 0;
1793 while ((Fref / div) > 13500000) {
1794 div *= 2;
1795 fll_div->fll_clk_ref_div++;
1796
1797 if (div > 8) {
1798 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1799 Fref);
1800 return -EINVAL;
1801 }
1802 }
1803
1804 pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
1805
1806 /* Apply the division for our remaining calculations */
1807 Fref /= div;
1808
1809 /* Fvco should be 90-100MHz; don't check the upper bound */
1810 div = 4;
1811 while (Fout * div < 90000000) {
1812 div++;
1813 if (div > 64) {
1814 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1815 Fout);
1816 return -EINVAL;
1817 }
1818 }
1819 target = Fout * div;
1820 fll_div->fll_outdiv = div - 1;
1821
1822 pr_debug("Fvco=%dHz\n", target);
1823
1824 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1825 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1826 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1827 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1828 target /= fll_fratios[i].ratio;
1829 break;
1830 }
1831 }
1832 if (i == ARRAY_SIZE(fll_fratios)) {
1833 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1834 return -EINVAL;
1835 }
1836
1837 /* Now, calculate N.K */
1838 Ndiv = target / Fref;
1839
1840 fll_div->n = Ndiv;
1841 Nmod = target % Fref;
1842 pr_debug("Nmod=%d\n", Nmod);
1843
1844 /* Calculate fractional part - scale up so we can round. */
1845 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1846
1847 do_div(Kpart, Fref);
1848
1849 K = Kpart & 0xFFFFFFFF;
1850
1851 if ((K % 10) >= 5)
1852 K += 5;
1853
1854 /* Move down to proper range now rounding is done */
1855 fll_div->k = K / 10;
1856
1857 pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
1858 fll_div->n, fll_div->k,
1859 fll_div->fll_fratio, fll_div->fll_outdiv,
1860 fll_div->fll_clk_ref_div);
1861
1862 return 0;
1863}
1864
1865static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1866 unsigned int Fref, unsigned int Fout)
1867{
1868 struct snd_soc_codec *codec = dai->codec;
1869 struct wm8904_priv *wm8904 = codec->private_data;
1870 struct _fll_div fll_div;
1871 int ret, val;
1872 int clock2, fll1;
1873
1874 /* Any change? */
1875 if (source == wm8904->fll_src && Fref == wm8904->fll_fref &&
1876 Fout == wm8904->fll_fout)
1877 return 0;
1878
1879 if (Fout == 0) {
1880 dev_dbg(codec->dev, "FLL disabled\n");
1881
1882 wm8904->fll_fref = 0;
1883 wm8904->fll_fout = 0;
1884
1885 /* Gate SYSCLK to avoid glitches */
1886 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
1887 WM8904_CLK_SYS_ENA, 0);
1888
1889 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1890 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
1891
1892 goto out;
1893 }
1894
1895 /* Validate the FLL ID */
1896 switch (source) {
1897 case WM8904_FLL_MCLK:
1898 case WM8904_FLL_LRCLK:
1899 case WM8904_FLL_BCLK:
1900 ret = fll_factors(&fll_div, Fref, Fout);
1901 if (ret != 0)
1902 return ret;
1903 break;
1904
1905 case WM8904_FLL_FREE_RUNNING:
1906 dev_dbg(codec->dev, "Using free running FLL\n");
1907 /* Force 12MHz and output/4 for now */
1908 Fout = 12000000;
1909 Fref = 12000000;
1910
1911 memset(&fll_div, 0, sizeof(fll_div));
1912 fll_div.fll_outdiv = 3;
1913 break;
1914
1915 default:
1916 dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
1917 return -EINVAL;
1918 }
1919
1920 /* Save current state then disable the FLL and SYSCLK to avoid
1921 * misclocking */
1922 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
1923 fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1);
1924 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
1925 WM8904_CLK_SYS_ENA, 0);
1926 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1927 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
1928
1929 /* Unlock forced oscilator control to switch it on/off */
1930 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
1931 WM8904_USER_KEY, WM8904_USER_KEY);
1932
1933 if (fll_id == WM8904_FLL_FREE_RUNNING) {
1934 val = WM8904_FLL_FRC_NCO;
1935 } else {
1936 val = 0;
1937 }
1938
1939 snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
1940 val);
1941 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
1942 WM8904_USER_KEY, 0);
1943
1944 switch (fll_id) {
1945 case WM8904_FLL_MCLK:
1946 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
1947 WM8904_FLL_CLK_REF_SRC_MASK, 0);
1948 break;
1949
1950 case WM8904_FLL_LRCLK:
1951 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
1952 WM8904_FLL_CLK_REF_SRC_MASK, 1);
1953 break;
1954
1955 case WM8904_FLL_BCLK:
1956 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
1957 WM8904_FLL_CLK_REF_SRC_MASK, 2);
1958 break;
1959 }
1960
1961 if (fll_div.k)
1962 val = WM8904_FLL_FRACN_ENA;
1963 else
1964 val = 0;
1965 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1966 WM8904_FLL_FRACN_ENA, val);
1967
1968 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2,
1969 WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK,
1970 (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) |
1971 (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT));
1972
1973 snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k);
1974
1975 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
1976 fll_div.n << WM8904_FLL_N_SHIFT);
1977
1978 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
1979 WM8904_FLL_CLK_REF_DIV_MASK,
1980 fll_div.fll_clk_ref_div
1981 << WM8904_FLL_CLK_REF_DIV_SHIFT);
1982
1983 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
1984
1985 wm8904->fll_fref = Fref;
1986 wm8904->fll_fout = Fout;
1987 wm8904->fll_src = source;
1988
1989 /* Enable the FLL if it was previously active */
1990 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1991 WM8904_FLL_OSC_ENA, fll1);
1992 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1993 WM8904_FLL_ENA, fll1);
1994
1995out:
1996 /* Reenable SYSCLK if it was previously active */
1997 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
1998 WM8904_CLK_SYS_ENA, clock2);
1999
2000 return 0;
2001}
2002
2003static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2004{
2005 struct snd_soc_codec *codec = codec_dai->codec;
2006 int val;
2007
2008 if (mute)
2009 val = WM8904_DAC_MUTE;
2010 else
2011 val = 0;
2012
2013 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
2014
2015 return 0;
2016}
2017
2018static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2019 enum snd_soc_bias_level level)
2020{
2021 struct wm8904_priv *wm8904 = codec->private_data;
2022 int ret, i;
2023
2024 switch (level) {
2025 case SND_SOC_BIAS_ON:
2026 break;
2027
2028 case SND_SOC_BIAS_PREPARE:
2029 /* VMID resistance 2*50k */
2030 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2031 WM8904_VMID_RES_MASK,
2032 0x1 << WM8904_VMID_RES_SHIFT);
2033
2034 /* Normal bias current */
2035 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2036 WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT);
2037 break;
2038
2039 case SND_SOC_BIAS_STANDBY:
2040 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2041 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2042 wm8904->supplies);
2043 if (ret != 0) {
2044 dev_err(codec->dev,
2045 "Failed to enable supplies: %d\n",
2046 ret);
2047 return ret;
2048 }
2049
2050 /* Sync back cached values if they're
2051 * different from the hardware default.
2052 */
2053 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
2054 if (!wm8904_access[i].writable)
2055 continue;
2056
2057 if (wm8904->reg_cache[i] == wm8904_reg[i])
2058 continue;
2059
2060 snd_soc_write(codec, i, wm8904->reg_cache[i]);
2061 }
2062
2063 /* Enable bias */
2064 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2065 WM8904_BIAS_ENA, WM8904_BIAS_ENA);
2066
2067 /* Enable VMID, VMID buffering, 2*5k resistance */
2068 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2069 WM8904_VMID_ENA |
2070 WM8904_VMID_RES_MASK,
2071 WM8904_VMID_ENA |
2072 0x3 << WM8904_VMID_RES_SHIFT);
2073
2074 /* Let VMID ramp */
2075 msleep(1);
2076 }
2077
2078 /* Maintain VMID with 2*250k */
2079 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2080 WM8904_VMID_RES_MASK,
2081 0x2 << WM8904_VMID_RES_SHIFT);
2082
2083 /* Bias current *0.5 */
2084 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2085 WM8904_ISEL_MASK, 0);
2086 break;
2087
2088 case SND_SOC_BIAS_OFF:
2089 /* Turn off VMID */
2090 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2091 WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0);
2092
2093 /* Stop bias generation */
2094 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2095 WM8904_BIAS_ENA, 0);
2096
2097 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
2098 wm8904->supplies);
2099 break;
2100 }
2101 codec->bias_level = level;
2102 return 0;
2103}
2104
2105#define WM8904_RATES SNDRV_PCM_RATE_8000_96000
2106
2107#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2108 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2109
2110static struct snd_soc_dai_ops wm8904_dai_ops = {
2111 .set_sysclk = wm8904_set_sysclk,
2112 .set_fmt = wm8904_set_fmt,
2113 .set_tdm_slot = wm8904_set_tdm_slot,
2114 .set_pll = wm8904_set_fll,
2115 .hw_params = wm8904_hw_params,
2116 .digital_mute = wm8904_digital_mute,
2117};
2118
2119struct snd_soc_dai wm8904_dai = {
2120 .name = "WM8904",
2121 .playback = {
2122 .stream_name = "Playback",
2123 .channels_min = 2,
2124 .channels_max = 2,
2125 .rates = WM8904_RATES,
2126 .formats = WM8904_FORMATS,
2127 },
2128 .capture = {
2129 .stream_name = "Capture",
2130 .channels_min = 2,
2131 .channels_max = 2,
2132 .rates = WM8904_RATES,
2133 .formats = WM8904_FORMATS,
2134 },
2135 .ops = &wm8904_dai_ops,
2136 .symmetric_rates = 1,
2137};
2138EXPORT_SYMBOL_GPL(wm8904_dai);
2139
2140#ifdef CONFIG_PM
2141static int wm8904_suspend(struct platform_device *pdev, pm_message_t state)
2142{
2143 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2144 struct snd_soc_codec *codec = socdev->card->codec;
2145
2146 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2147
2148 return 0;
2149}
2150
2151static int wm8904_resume(struct platform_device *pdev)
2152{
2153 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2154 struct snd_soc_codec *codec = socdev->card->codec;
2155
2156 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2157
2158 return 0;
2159}
2160#else
2161#define wm8904_suspend NULL
2162#define wm8904_resume NULL
2163#endif
2164
2165static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2166{
2167 struct snd_soc_codec *codec = &wm8904->codec;
2168 struct wm8904_pdata *pdata = wm8904->pdata;
2169 struct snd_kcontrol_new control =
2170 SOC_ENUM_EXT("EQ Mode",
2171 wm8904->retune_mobile_enum,
2172 wm8904_get_retune_mobile_enum,
2173 wm8904_put_retune_mobile_enum);
2174 int ret, i, j;
2175 const char **t;
2176
2177 /* We need an array of texts for the enum API but the number
2178 * of texts is likely to be less than the number of
2179 * configurations due to the sample rate dependency of the
2180 * configurations. */
2181 wm8904->num_retune_mobile_texts = 0;
2182 wm8904->retune_mobile_texts = NULL;
2183 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2184 for (j = 0; j < wm8904->num_retune_mobile_texts; j++) {
2185 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2186 wm8904->retune_mobile_texts[j]) == 0)
2187 break;
2188 }
2189
2190 if (j != wm8904->num_retune_mobile_texts)
2191 continue;
2192
2193 /* Expand the array... */
2194 t = krealloc(wm8904->retune_mobile_texts,
2195 sizeof(char *) *
2196 (wm8904->num_retune_mobile_texts + 1),
2197 GFP_KERNEL);
2198 if (t == NULL)
2199 continue;
2200
2201 /* ...store the new entry... */
2202 t[wm8904->num_retune_mobile_texts] =
2203 pdata->retune_mobile_cfgs[i].name;
2204
2205 /* ...and remember the new version. */
2206 wm8904->num_retune_mobile_texts++;
2207 wm8904->retune_mobile_texts = t;
2208 }
2209
2210 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2211 wm8904->num_retune_mobile_texts);
2212
2213 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2214 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2215
2216 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2217 if (ret != 0)
2218 dev_err(wm8904->codec.dev,
2219 "Failed to add ReTune Mobile control: %d\n", ret);
2220}
2221
2222static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2223{
2224 struct snd_soc_codec *codec = &wm8904->codec;
2225 struct wm8904_pdata *pdata = wm8904->pdata;
2226 int ret, i;
2227
2228 if (!pdata) {
2229 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2230 ARRAY_SIZE(wm8904_eq_controls));
2231 return;
2232 }
2233
2234 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
2235
2236 if (pdata->num_drc_cfgs) {
2237 struct snd_kcontrol_new control =
2238 SOC_ENUM_EXT("DRC Mode", wm8904->drc_enum,
2239 wm8904_get_drc_enum, wm8904_put_drc_enum);
2240
2241 /* We need an array of texts for the enum API */
2242 wm8904->drc_texts = kmalloc(sizeof(char *)
2243 * pdata->num_drc_cfgs, GFP_KERNEL);
2244 if (!wm8904->drc_texts) {
2245 dev_err(wm8904->codec.dev,
2246 "Failed to allocate %d DRC config texts\n",
2247 pdata->num_drc_cfgs);
2248 return;
2249 }
2250
2251 for (i = 0; i < pdata->num_drc_cfgs; i++)
2252 wm8904->drc_texts[i] = pdata->drc_cfgs[i].name;
2253
2254 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2255 wm8904->drc_enum.texts = wm8904->drc_texts;
2256
2257 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2258 if (ret != 0)
2259 dev_err(wm8904->codec.dev,
2260 "Failed to add DRC mode control: %d\n", ret);
2261
2262 wm8904_set_drc(codec);
2263 }
2264
2265 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2266 pdata->num_retune_mobile_cfgs);
2267
2268 if (pdata->num_retune_mobile_cfgs)
2269 wm8904_handle_retune_mobile_pdata(wm8904);
2270 else
2271 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2272 ARRAY_SIZE(wm8904_eq_controls));
2273}
2274
2275static int wm8904_probe(struct platform_device *pdev)
2276{
2277 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2278 struct snd_soc_codec *codec;
2279 int ret = 0;
2280
2281 if (wm8904_codec == NULL) {
2282 dev_err(&pdev->dev, "Codec device not registered\n");
2283 return -ENODEV;
2284 }
2285
2286 socdev->card->codec = wm8904_codec;
2287 codec = wm8904_codec;
2288
2289 /* register pcms */
2290 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2291 if (ret < 0) {
2292 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2293 goto pcm_err;
2294 }
2295
2296 wm8904_handle_pdata(codec->private_data);
2297
2298 wm8904_add_widgets(codec);
2299
2300 return ret;
2301
2302pcm_err:
2303 return ret;
2304}
2305
2306static int wm8904_remove(struct platform_device *pdev)
2307{
2308 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2309
2310 snd_soc_free_pcms(socdev);
2311 snd_soc_dapm_free(socdev);
2312
2313 return 0;
2314}
2315
2316struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2317 .probe = wm8904_probe,
2318 .remove = wm8904_remove,
2319 .suspend = wm8904_suspend,
2320 .resume = wm8904_resume,
2321};
2322EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2323
2324static int wm8904_register(struct wm8904_priv *wm8904,
2325 enum snd_soc_control_type control)
2326{
2327 int ret;
2328 struct snd_soc_codec *codec = &wm8904->codec;
2329 int i;
2330
2331 if (wm8904_codec) {
2332 dev_err(codec->dev, "Another WM8904 is registered\n");
2333 return -EINVAL;
2334 }
2335
2336 mutex_init(&codec->mutex);
2337 INIT_LIST_HEAD(&codec->dapm_widgets);
2338 INIT_LIST_HEAD(&codec->dapm_paths);
2339
2340 codec->private_data = wm8904;
2341 codec->name = "WM8904";
2342 codec->owner = THIS_MODULE;
2343 codec->bias_level = SND_SOC_BIAS_OFF;
2344 codec->set_bias_level = wm8904_set_bias_level;
2345 codec->dai = &wm8904_dai;
2346 codec->num_dai = 1;
2347 codec->reg_cache_size = WM8904_MAX_REGISTER;
2348 codec->reg_cache = &wm8904->reg_cache;
2349 codec->volatile_register = wm8904_volatile_register;
2350
2351 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
2352
2353 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2354 if (ret != 0) {
2355 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2356 goto err;
2357 }
2358
2359 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2360 wm8904->supplies[i].supply = wm8904_supply_names[i];
2361
2362 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
2363 wm8904->supplies);
2364 if (ret != 0) {
2365 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2366 goto err;
2367 }
2368
2369 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2370 wm8904->supplies);
2371 if (ret != 0) {
2372 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2373 goto err_get;
2374 }
2375
2376 ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
2377 if (ret < 0) {
2378 dev_err(codec->dev, "Failed to read ID register\n");
2379 goto err_enable;
2380 }
2381 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) {
2382 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2383 ret = -EINVAL;
2384 goto err_enable;
2385 }
2386
2387 ret = snd_soc_read(codec, WM8904_REVISION);
2388 if (ret < 0) {
2389 dev_err(codec->dev, "Failed to read device revision: %d\n",
2390 ret);
2391 goto err_enable;
2392 }
2393 dev_info(codec->dev, "revision %c\n", ret + 'A');
2394
2395 ret = wm8904_reset(codec);
2396 if (ret < 0) {
2397 dev_err(codec->dev, "Failed to issue reset\n");
2398 goto err_enable;
2399 }
2400
2401 wm8904_dai.dev = codec->dev;
2402
2403 /* Change some default settings - latch VU and enable ZC */
2404 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
2405 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
2406 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
2407 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
2408 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
2409 WM8904_HPOUTLZC;
2410 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
2411 WM8904_HPOUTRZC;
2412 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
2413 WM8904_LINEOUTLZC;
2414 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
2415 WM8904_LINEOUTRZC;
2416 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
2417
2418 /* Set Class W by default - this will be managed by the Class
2419 * G widget at runtime where bypass paths are available.
2420 */
2421 wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
2422
2423 /* Use normal bias source */
2424 wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
2425
2426 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2427
2428 /* Bias level configuration will have done an extra enable */
2429 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2430
2431 wm8904_codec = codec;
2432
2433 ret = snd_soc_register_codec(codec);
2434 if (ret != 0) {
2435 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2436 return ret;
2437 }
2438
2439 ret = snd_soc_register_dai(&wm8904_dai);
2440 if (ret != 0) {
2441 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2442 snd_soc_unregister_codec(codec);
2443 return ret;
2444 }
2445
2446 return 0;
2447
2448err_enable:
2449 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2450err_get:
2451 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2452err:
2453 kfree(wm8904);
2454 return ret;
2455}
2456
2457static void wm8904_unregister(struct wm8904_priv *wm8904)
2458{
2459 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF);
2460 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2461 snd_soc_unregister_dai(&wm8904_dai);
2462 snd_soc_unregister_codec(&wm8904->codec);
2463 kfree(wm8904);
2464 wm8904_codec = NULL;
2465}
2466
2467#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2468static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2469 const struct i2c_device_id *id)
2470{
2471 struct wm8904_priv *wm8904;
2472 struct snd_soc_codec *codec;
2473
2474 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2475 if (wm8904 == NULL)
2476 return -ENOMEM;
2477
2478 codec = &wm8904->codec;
2479 codec->hw_write = (hw_write_t)i2c_master_send;
2480
2481 i2c_set_clientdata(i2c, wm8904);
2482 codec->control_data = i2c;
2483 wm8904->pdata = i2c->dev.platform_data;
2484
2485 codec->dev = &i2c->dev;
2486
2487 return wm8904_register(wm8904, SND_SOC_I2C);
2488}
2489
2490static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2491{
2492 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2493 wm8904_unregister(wm8904);
2494 return 0;
2495}
2496
2497static const struct i2c_device_id wm8904_i2c_id[] = {
2498 { "wm8904", 0 },
2499 { }
2500};
2501MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2502
2503static struct i2c_driver wm8904_i2c_driver = {
2504 .driver = {
2505 .name = "WM8904",
2506 .owner = THIS_MODULE,
2507 },
2508 .probe = wm8904_i2c_probe,
2509 .remove = __devexit_p(wm8904_i2c_remove),
2510 .id_table = wm8904_i2c_id,
2511};
2512#endif
2513
2514static int __init wm8904_modinit(void)
2515{
2516 int ret;
2517#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2518 ret = i2c_add_driver(&wm8904_i2c_driver);
2519 if (ret != 0) {
2520 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n",
2521 ret);
2522 }
2523#endif
2524 return 0;
2525}
2526module_init(wm8904_modinit);
2527
2528static void __exit wm8904_exit(void)
2529{
2530#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2531 i2c_del_driver(&wm8904_i2c_driver);
2532#endif
2533}
2534module_exit(wm8904_exit);
2535
2536MODULE_DESCRIPTION("ASoC WM8904 driver");
2537MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2538MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
new file mode 100644
index 000000000000..b68886df34e4
--- /dev/null
+++ b/sound/soc/codecs/wm8904.h
@@ -0,0 +1,1681 @@
1/*
2 * wm8904.h -- WM8904 ASoC driver
3 *
4 * Copyright 2009 Wolfson Microelectronics, plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8904_H
14#define _WM8904_H
15
16#define WM8904_CLK_MCLK 1
17#define WM8904_CLK_FLL 2
18
19#define WM8904_FLL_MCLK 1
20#define WM8904_FLL_BCLK 2
21#define WM8904_FLL_LRCLK 3
22#define WM8904_FLL_FREE_RUNNING 4
23
24extern struct snd_soc_dai wm8904_dai;
25extern struct snd_soc_codec_device soc_codec_dev_wm8904;
26
27/*
28 * Register values.
29 */
30#define WM8904_SW_RESET_AND_ID 0x00
31#define WM8904_REVISION 0x01
32#define WM8904_BIAS_CONTROL_0 0x04
33#define WM8904_VMID_CONTROL_0 0x05
34#define WM8904_MIC_BIAS_CONTROL_0 0x06
35#define WM8904_MIC_BIAS_CONTROL_1 0x07
36#define WM8904_ANALOGUE_DAC_0 0x08
37#define WM8904_MIC_FILTER_CONTROL 0x09
38#define WM8904_ANALOGUE_ADC_0 0x0A
39#define WM8904_POWER_MANAGEMENT_0 0x0C
40#define WM8904_POWER_MANAGEMENT_2 0x0E
41#define WM8904_POWER_MANAGEMENT_3 0x0F
42#define WM8904_POWER_MANAGEMENT_6 0x12
43#define WM8904_CLOCK_RATES_0 0x14
44#define WM8904_CLOCK_RATES_1 0x15
45#define WM8904_CLOCK_RATES_2 0x16
46#define WM8904_AUDIO_INTERFACE_0 0x18
47#define WM8904_AUDIO_INTERFACE_1 0x19
48#define WM8904_AUDIO_INTERFACE_2 0x1A
49#define WM8904_AUDIO_INTERFACE_3 0x1B
50#define WM8904_DAC_DIGITAL_VOLUME_LEFT 0x1E
51#define WM8904_DAC_DIGITAL_VOLUME_RIGHT 0x1F
52#define WM8904_DAC_DIGITAL_0 0x20
53#define WM8904_DAC_DIGITAL_1 0x21
54#define WM8904_ADC_DIGITAL_VOLUME_LEFT 0x24
55#define WM8904_ADC_DIGITAL_VOLUME_RIGHT 0x25
56#define WM8904_ADC_DIGITAL_0 0x26
57#define WM8904_DIGITAL_MICROPHONE_0 0x27
58#define WM8904_DRC_0 0x28
59#define WM8904_DRC_1 0x29
60#define WM8904_DRC_2 0x2A
61#define WM8904_DRC_3 0x2B
62#define WM8904_ANALOGUE_LEFT_INPUT_0 0x2C
63#define WM8904_ANALOGUE_RIGHT_INPUT_0 0x2D
64#define WM8904_ANALOGUE_LEFT_INPUT_1 0x2E
65#define WM8904_ANALOGUE_RIGHT_INPUT_1 0x2F
66#define WM8904_ANALOGUE_OUT1_LEFT 0x39
67#define WM8904_ANALOGUE_OUT1_RIGHT 0x3A
68#define WM8904_ANALOGUE_OUT2_LEFT 0x3B
69#define WM8904_ANALOGUE_OUT2_RIGHT 0x3C
70#define WM8904_ANALOGUE_OUT12_ZC 0x3D
71#define WM8904_DC_SERVO_0 0x43
72#define WM8904_DC_SERVO_1 0x44
73#define WM8904_DC_SERVO_2 0x45
74#define WM8904_DC_SERVO_4 0x47
75#define WM8904_DC_SERVO_5 0x48
76#define WM8904_DC_SERVO_6 0x49
77#define WM8904_DC_SERVO_7 0x4A
78#define WM8904_DC_SERVO_8 0x4B
79#define WM8904_DC_SERVO_9 0x4C
80#define WM8904_DC_SERVO_READBACK_0 0x4D
81#define WM8904_ANALOGUE_HP_0 0x5A
82#define WM8904_ANALOGUE_LINEOUT_0 0x5E
83#define WM8904_CHARGE_PUMP_0 0x62
84#define WM8904_CLASS_W_0 0x68
85#define WM8904_WRITE_SEQUENCER_0 0x6C
86#define WM8904_WRITE_SEQUENCER_1 0x6D
87#define WM8904_WRITE_SEQUENCER_2 0x6E
88#define WM8904_WRITE_SEQUENCER_3 0x6F
89#define WM8904_WRITE_SEQUENCER_4 0x70
90#define WM8904_FLL_CONTROL_1 0x74
91#define WM8904_FLL_CONTROL_2 0x75
92#define WM8904_FLL_CONTROL_3 0x76
93#define WM8904_FLL_CONTROL_4 0x77
94#define WM8904_FLL_CONTROL_5 0x78
95#define WM8904_GPIO_CONTROL_1 0x79
96#define WM8904_GPIO_CONTROL_2 0x7A
97#define WM8904_GPIO_CONTROL_3 0x7B
98#define WM8904_GPIO_CONTROL_4 0x7C
99#define WM8904_DIGITAL_PULLS 0x7E
100#define WM8904_INTERRUPT_STATUS 0x7F
101#define WM8904_INTERRUPT_STATUS_MASK 0x80
102#define WM8904_INTERRUPT_POLARITY 0x81
103#define WM8904_INTERRUPT_DEBOUNCE 0x82
104#define WM8904_EQ1 0x86
105#define WM8904_EQ2 0x87
106#define WM8904_EQ3 0x88
107#define WM8904_EQ4 0x89
108#define WM8904_EQ5 0x8A
109#define WM8904_EQ6 0x8B
110#define WM8904_EQ7 0x8C
111#define WM8904_EQ8 0x8D
112#define WM8904_EQ9 0x8E
113#define WM8904_EQ10 0x8F
114#define WM8904_EQ11 0x90
115#define WM8904_EQ12 0x91
116#define WM8904_EQ13 0x92
117#define WM8904_EQ14 0x93
118#define WM8904_EQ15 0x94
119#define WM8904_EQ16 0x95
120#define WM8904_EQ17 0x96
121#define WM8904_EQ18 0x97
122#define WM8904_EQ19 0x98
123#define WM8904_EQ20 0x99
124#define WM8904_EQ21 0x9A
125#define WM8904_EQ22 0x9B
126#define WM8904_EQ23 0x9C
127#define WM8904_EQ24 0x9D
128#define WM8904_CONTROL_INTERFACE_TEST_1 0xA1
129#define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC
130#define WM8904_FLL_NCO_TEST_0 0xF7
131#define WM8904_FLL_NCO_TEST_1 0xF8
132
133#define WM8904_REGISTER_COUNT 101
134#define WM8904_MAX_REGISTER 0xF8
135
136/*
137 * Field Definitions.
138 */
139
140/*
141 * R0 (0x00) - SW Reset and ID
142 */
143#define WM8904_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
144#define WM8904_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
145#define WM8904_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
146
147/*
148 * R1 (0x01) - Revision
149 */
150#define WM8904_REVISION_MASK 0x000F /* REVISION - [3:0] */
151#define WM8904_REVISION_SHIFT 0 /* REVISION - [3:0] */
152#define WM8904_REVISION_WIDTH 16 /* REVISION - [3:0] */
153
154/*
155 * R4 (0x04) - Bias Control 0
156 */
157#define WM8904_POBCTRL 0x0010 /* POBCTRL */
158#define WM8904_POBCTRL_MASK 0x0010 /* POBCTRL */
159#define WM8904_POBCTRL_SHIFT 4 /* POBCTRL */
160#define WM8904_POBCTRL_WIDTH 1 /* POBCTRL */
161#define WM8904_ISEL_MASK 0x000C /* ISEL - [3:2] */
162#define WM8904_ISEL_SHIFT 2 /* ISEL - [3:2] */
163#define WM8904_ISEL_WIDTH 2 /* ISEL - [3:2] */
164#define WM8904_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
165#define WM8904_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
166#define WM8904_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
167#define WM8904_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
168#define WM8904_BIAS_ENA 0x0001 /* BIAS_ENA */
169#define WM8904_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
170#define WM8904_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
171#define WM8904_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
172
173/*
174 * R5 (0x05) - VMID Control 0
175 */
176#define WM8904_VMID_BUF_ENA 0x0040 /* VMID_BUF_ENA */
177#define WM8904_VMID_BUF_ENA_MASK 0x0040 /* VMID_BUF_ENA */
178#define WM8904_VMID_BUF_ENA_SHIFT 6 /* VMID_BUF_ENA */
179#define WM8904_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
180#define WM8904_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
181#define WM8904_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
182#define WM8904_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
183#define WM8904_VMID_ENA 0x0001 /* VMID_ENA */
184#define WM8904_VMID_ENA_MASK 0x0001 /* VMID_ENA */
185#define WM8904_VMID_ENA_SHIFT 0 /* VMID_ENA */
186#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */
187
188/*
189 * R6 (0x06) - Mic Bias Control 0
190 */
191#define WM8904_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
192#define WM8904_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
193#define WM8904_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
194#define WM8904_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
195#define WM8904_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
196#define WM8904_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
197#define WM8904_MICDET_ENA 0x0002 /* MICDET_ENA */
198#define WM8904_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
199#define WM8904_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
200#define WM8904_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
201#define WM8904_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
202#define WM8904_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
203#define WM8904_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
204#define WM8904_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
205
206/*
207 * R7 (0x07) - Mic Bias Control 1
208 */
209#define WM8904_MIC_DET_FILTER_ENA 0x8000 /* MIC_DET_FILTER_ENA */
210#define WM8904_MIC_DET_FILTER_ENA_MASK 0x8000 /* MIC_DET_FILTER_ENA */
211#define WM8904_MIC_DET_FILTER_ENA_SHIFT 15 /* MIC_DET_FILTER_ENA */
212#define WM8904_MIC_DET_FILTER_ENA_WIDTH 1 /* MIC_DET_FILTER_ENA */
213#define WM8904_MIC_SHORT_FILTER_ENA 0x4000 /* MIC_SHORT_FILTER_ENA */
214#define WM8904_MIC_SHORT_FILTER_ENA_MASK 0x4000 /* MIC_SHORT_FILTER_ENA */
215#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT 14 /* MIC_SHORT_FILTER_ENA */
216#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH 1 /* MIC_SHORT_FILTER_ENA */
217#define WM8904_MICBIAS_SEL_MASK 0x0007 /* MICBIAS_SEL - [2:0] */
218#define WM8904_MICBIAS_SEL_SHIFT 0 /* MICBIAS_SEL - [2:0] */
219#define WM8904_MICBIAS_SEL_WIDTH 3 /* MICBIAS_SEL - [2:0] */
220
221/*
222 * R8 (0x08) - Analogue DAC 0
223 */
224#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */
225#define WM8904_DAC_BIAS_SEL_SHIFT 3 /* DAC_BIAS_SEL - [4:3] */
226#define WM8904_DAC_BIAS_SEL_WIDTH 2 /* DAC_BIAS_SEL - [4:3] */
227#define WM8904_DAC_VMID_BIAS_SEL_MASK 0x0006 /* DAC_VMID_BIAS_SEL - [2:1] */
228#define WM8904_DAC_VMID_BIAS_SEL_SHIFT 1 /* DAC_VMID_BIAS_SEL - [2:1] */
229#define WM8904_DAC_VMID_BIAS_SEL_WIDTH 2 /* DAC_VMID_BIAS_SEL - [2:1] */
230
231/*
232 * R9 (0x09) - mic Filter Control
233 */
234#define WM8904_MIC_DET_SET_THRESHOLD_MASK 0xF000 /* MIC_DET_SET_THRESHOLD - [15:12] */
235#define WM8904_MIC_DET_SET_THRESHOLD_SHIFT 12 /* MIC_DET_SET_THRESHOLD - [15:12] */
236#define WM8904_MIC_DET_SET_THRESHOLD_WIDTH 4 /* MIC_DET_SET_THRESHOLD - [15:12] */
237#define WM8904_MIC_DET_RESET_THRESHOLD_MASK 0x0F00 /* MIC_DET_RESET_THRESHOLD - [11:8] */
238#define WM8904_MIC_DET_RESET_THRESHOLD_SHIFT 8 /* MIC_DET_RESET_THRESHOLD - [11:8] */
239#define WM8904_MIC_DET_RESET_THRESHOLD_WIDTH 4 /* MIC_DET_RESET_THRESHOLD - [11:8] */
240#define WM8904_MIC_SHORT_SET_THRESHOLD_MASK 0x00F0 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
241#define WM8904_MIC_SHORT_SET_THRESHOLD_SHIFT 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
242#define WM8904_MIC_SHORT_SET_THRESHOLD_WIDTH 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
243#define WM8904_MIC_SHORT_RESET_THRESHOLD_MASK 0x000F /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
244#define WM8904_MIC_SHORT_RESET_THRESHOLD_SHIFT 0 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
245#define WM8904_MIC_SHORT_RESET_THRESHOLD_WIDTH 4 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
246
247/*
248 * R10 (0x0A) - Analogue ADC 0
249 */
250#define WM8904_ADC_OSR128 0x0001 /* ADC_OSR128 */
251#define WM8904_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
252#define WM8904_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
253#define WM8904_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
254
255/*
256 * R12 (0x0C) - Power Management 0
257 */
258#define WM8904_INL_ENA 0x0002 /* INL_ENA */
259#define WM8904_INL_ENA_MASK 0x0002 /* INL_ENA */
260#define WM8904_INL_ENA_SHIFT 1 /* INL_ENA */
261#define WM8904_INL_ENA_WIDTH 1 /* INL_ENA */
262#define WM8904_INR_ENA 0x0001 /* INR_ENA */
263#define WM8904_INR_ENA_MASK 0x0001 /* INR_ENA */
264#define WM8904_INR_ENA_SHIFT 0 /* INR_ENA */
265#define WM8904_INR_ENA_WIDTH 1 /* INR_ENA */
266
267/*
268 * R14 (0x0E) - Power Management 2
269 */
270#define WM8904_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
271#define WM8904_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
272#define WM8904_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
273#define WM8904_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
274#define WM8904_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
275#define WM8904_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
276#define WM8904_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
277#define WM8904_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
278
279/*
280 * R15 (0x0F) - Power Management 3
281 */
282#define WM8904_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
283#define WM8904_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
284#define WM8904_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
285#define WM8904_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
286#define WM8904_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
287#define WM8904_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
288#define WM8904_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
289#define WM8904_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
290
291/*
292 * R18 (0x12) - Power Management 6
293 */
294#define WM8904_DACL_ENA 0x0008 /* DACL_ENA */
295#define WM8904_DACL_ENA_MASK 0x0008 /* DACL_ENA */
296#define WM8904_DACL_ENA_SHIFT 3 /* DACL_ENA */
297#define WM8904_DACL_ENA_WIDTH 1 /* DACL_ENA */
298#define WM8904_DACR_ENA 0x0004 /* DACR_ENA */
299#define WM8904_DACR_ENA_MASK 0x0004 /* DACR_ENA */
300#define WM8904_DACR_ENA_SHIFT 2 /* DACR_ENA */
301#define WM8904_DACR_ENA_WIDTH 1 /* DACR_ENA */
302#define WM8904_ADCL_ENA 0x0002 /* ADCL_ENA */
303#define WM8904_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
304#define WM8904_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
305#define WM8904_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
306#define WM8904_ADCR_ENA 0x0001 /* ADCR_ENA */
307#define WM8904_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
308#define WM8904_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
309#define WM8904_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
310
311/*
312 * R20 (0x14) - Clock Rates 0
313 */
314#define WM8904_TOCLK_RATE_DIV16 0x4000 /* TOCLK_RATE_DIV16 */
315#define WM8904_TOCLK_RATE_DIV16_MASK 0x4000 /* TOCLK_RATE_DIV16 */
316#define WM8904_TOCLK_RATE_DIV16_SHIFT 14 /* TOCLK_RATE_DIV16 */
317#define WM8904_TOCLK_RATE_DIV16_WIDTH 1 /* TOCLK_RATE_DIV16 */
318#define WM8904_TOCLK_RATE_X4 0x2000 /* TOCLK_RATE_X4 */
319#define WM8904_TOCLK_RATE_X4_MASK 0x2000 /* TOCLK_RATE_X4 */
320#define WM8904_TOCLK_RATE_X4_SHIFT 13 /* TOCLK_RATE_X4 */
321#define WM8904_TOCLK_RATE_X4_WIDTH 1 /* TOCLK_RATE_X4 */
322#define WM8904_SR_MODE 0x1000 /* SR_MODE */
323#define WM8904_SR_MODE_MASK 0x1000 /* SR_MODE */
324#define WM8904_SR_MODE_SHIFT 12 /* SR_MODE */
325#define WM8904_SR_MODE_WIDTH 1 /* SR_MODE */
326#define WM8904_MCLK_DIV 0x0001 /* MCLK_DIV */
327#define WM8904_MCLK_DIV_MASK 0x0001 /* MCLK_DIV */
328#define WM8904_MCLK_DIV_SHIFT 0 /* MCLK_DIV */
329#define WM8904_MCLK_DIV_WIDTH 1 /* MCLK_DIV */
330
331/*
332 * R21 (0x15) - Clock Rates 1
333 */
334#define WM8904_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
335#define WM8904_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
336#define WM8904_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
337#define WM8904_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
338#define WM8904_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
339#define WM8904_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
340
341/*
342 * R22 (0x16) - Clock Rates 2
343 */
344#define WM8904_MCLK_INV 0x8000 /* MCLK_INV */
345#define WM8904_MCLK_INV_MASK 0x8000 /* MCLK_INV */
346#define WM8904_MCLK_INV_SHIFT 15 /* MCLK_INV */
347#define WM8904_MCLK_INV_WIDTH 1 /* MCLK_INV */
348#define WM8904_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
349#define WM8904_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
350#define WM8904_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
351#define WM8904_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
352#define WM8904_TOCLK_RATE 0x1000 /* TOCLK_RATE */
353#define WM8904_TOCLK_RATE_MASK 0x1000 /* TOCLK_RATE */
354#define WM8904_TOCLK_RATE_SHIFT 12 /* TOCLK_RATE */
355#define WM8904_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
356#define WM8904_OPCLK_ENA 0x0008 /* OPCLK_ENA */
357#define WM8904_OPCLK_ENA_MASK 0x0008 /* OPCLK_ENA */
358#define WM8904_OPCLK_ENA_SHIFT 3 /* OPCLK_ENA */
359#define WM8904_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
360#define WM8904_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
361#define WM8904_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
362#define WM8904_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
363#define WM8904_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
364#define WM8904_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
365#define WM8904_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
366#define WM8904_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
367#define WM8904_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
368#define WM8904_TOCLK_ENA 0x0001 /* TOCLK_ENA */
369#define WM8904_TOCLK_ENA_MASK 0x0001 /* TOCLK_ENA */
370#define WM8904_TOCLK_ENA_SHIFT 0 /* TOCLK_ENA */
371#define WM8904_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
372
373/*
374 * R24 (0x18) - Audio Interface 0
375 */
376#define WM8904_DACL_DATINV 0x1000 /* DACL_DATINV */
377#define WM8904_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
378#define WM8904_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
379#define WM8904_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
380#define WM8904_DACR_DATINV 0x0800 /* DACR_DATINV */
381#define WM8904_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
382#define WM8904_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
383#define WM8904_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
384#define WM8904_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
385#define WM8904_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
386#define WM8904_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
387#define WM8904_LOOPBACK 0x0100 /* LOOPBACK */
388#define WM8904_LOOPBACK_MASK 0x0100 /* LOOPBACK */
389#define WM8904_LOOPBACK_SHIFT 8 /* LOOPBACK */
390#define WM8904_LOOPBACK_WIDTH 1 /* LOOPBACK */
391#define WM8904_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
392#define WM8904_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
393#define WM8904_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
394#define WM8904_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
395#define WM8904_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
396#define WM8904_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
397#define WM8904_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
398#define WM8904_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
399#define WM8904_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
400#define WM8904_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
401#define WM8904_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
402#define WM8904_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
403#define WM8904_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
404#define WM8904_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
405#define WM8904_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
406#define WM8904_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
407#define WM8904_ADC_COMP 0x0008 /* ADC_COMP */
408#define WM8904_ADC_COMP_MASK 0x0008 /* ADC_COMP */
409#define WM8904_ADC_COMP_SHIFT 3 /* ADC_COMP */
410#define WM8904_ADC_COMP_WIDTH 1 /* ADC_COMP */
411#define WM8904_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
412#define WM8904_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
413#define WM8904_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
414#define WM8904_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
415#define WM8904_DAC_COMP 0x0002 /* DAC_COMP */
416#define WM8904_DAC_COMP_MASK 0x0002 /* DAC_COMP */
417#define WM8904_DAC_COMP_SHIFT 1 /* DAC_COMP */
418#define WM8904_DAC_COMP_WIDTH 1 /* DAC_COMP */
419#define WM8904_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
420#define WM8904_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
421#define WM8904_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
422#define WM8904_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
423
424/*
425 * R25 (0x19) - Audio Interface 1
426 */
427#define WM8904_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
428#define WM8904_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
429#define WM8904_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
430#define WM8904_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
431#define WM8904_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
432#define WM8904_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
433#define WM8904_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
434#define WM8904_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
435#define WM8904_AIFADC_TDM 0x0800 /* AIFADC_TDM */
436#define WM8904_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
437#define WM8904_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
438#define WM8904_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
439#define WM8904_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
440#define WM8904_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
441#define WM8904_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
442#define WM8904_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
443#define WM8904_AIF_TRIS 0x0100 /* AIF_TRIS */
444#define WM8904_AIF_TRIS_MASK 0x0100 /* AIF_TRIS */
445#define WM8904_AIF_TRIS_SHIFT 8 /* AIF_TRIS */
446#define WM8904_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
447#define WM8904_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
448#define WM8904_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
449#define WM8904_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
450#define WM8904_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
451#define WM8904_BCLK_DIR 0x0040 /* BCLK_DIR */
452#define WM8904_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
453#define WM8904_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
454#define WM8904_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
455#define WM8904_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
456#define WM8904_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
457#define WM8904_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
458#define WM8904_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
459#define WM8904_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
460#define WM8904_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
461#define WM8904_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
462#define WM8904_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
463#define WM8904_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
464#define WM8904_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
465
466/*
467 * R26 (0x1A) - Audio Interface 2
468 */
469#define WM8904_OPCLK_DIV_MASK 0x0F00 /* OPCLK_DIV - [11:8] */
470#define WM8904_OPCLK_DIV_SHIFT 8 /* OPCLK_DIV - [11:8] */
471#define WM8904_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [11:8] */
472#define WM8904_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
473#define WM8904_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
474#define WM8904_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
475
476/*
477 * R27 (0x1B) - Audio Interface 3
478 */
479#define WM8904_LRCLK_DIR 0x0800 /* LRCLK_DIR */
480#define WM8904_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */
481#define WM8904_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */
482#define WM8904_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
483#define WM8904_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
484#define WM8904_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
485#define WM8904_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
486
487/*
488 * R30 (0x1E) - DAC Digital Volume Left
489 */
490#define WM8904_DAC_VU 0x0100 /* DAC_VU */
491#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
492#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
493#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
494#define WM8904_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
495#define WM8904_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
496#define WM8904_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
497
498/*
499 * R31 (0x1F) - DAC Digital Volume Right
500 */
501#define WM8904_DAC_VU 0x0100 /* DAC_VU */
502#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
503#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
504#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
505#define WM8904_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
506#define WM8904_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
507#define WM8904_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
508
509/*
510 * R32 (0x20) - DAC Digital 0
511 */
512#define WM8904_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
513#define WM8904_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
514#define WM8904_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
515#define WM8904_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
516#define WM8904_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
517#define WM8904_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
518#define WM8904_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
519#define WM8904_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
520#define WM8904_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
521#define WM8904_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
522#define WM8904_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
523#define WM8904_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
524
525/*
526 * R33 (0x21) - DAC Digital 1
527 */
528#define WM8904_DAC_MONO 0x1000 /* DAC_MONO */
529#define WM8904_DAC_MONO_MASK 0x1000 /* DAC_MONO */
530#define WM8904_DAC_MONO_SHIFT 12 /* DAC_MONO */
531#define WM8904_DAC_MONO_WIDTH 1 /* DAC_MONO */
532#define WM8904_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
533#define WM8904_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
534#define WM8904_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
535#define WM8904_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
536#define WM8904_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
537#define WM8904_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
538#define WM8904_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
539#define WM8904_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
540#define WM8904_DAC_UNMUTE_RAMP 0x0200 /* DAC_UNMUTE_RAMP */
541#define WM8904_DAC_UNMUTE_RAMP_MASK 0x0200 /* DAC_UNMUTE_RAMP */
542#define WM8904_DAC_UNMUTE_RAMP_SHIFT 9 /* DAC_UNMUTE_RAMP */
543#define WM8904_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
544#define WM8904_DAC_OSR128 0x0040 /* DAC_OSR128 */
545#define WM8904_DAC_OSR128_MASK 0x0040 /* DAC_OSR128 */
546#define WM8904_DAC_OSR128_SHIFT 6 /* DAC_OSR128 */
547#define WM8904_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
548#define WM8904_DAC_MUTE 0x0008 /* DAC_MUTE */
549#define WM8904_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
550#define WM8904_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
551#define WM8904_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
552#define WM8904_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
553#define WM8904_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
554#define WM8904_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
555
556/*
557 * R36 (0x24) - ADC Digital Volume Left
558 */
559#define WM8904_ADC_VU 0x0100 /* ADC_VU */
560#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
561#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
562#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
563#define WM8904_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
564#define WM8904_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
565#define WM8904_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
566
567/*
568 * R37 (0x25) - ADC Digital Volume Right
569 */
570#define WM8904_ADC_VU 0x0100 /* ADC_VU */
571#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
572#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
573#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
574#define WM8904_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
575#define WM8904_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
576#define WM8904_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
577
578/*
579 * R38 (0x26) - ADC Digital 0
580 */
581#define WM8904_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
582#define WM8904_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
583#define WM8904_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
584#define WM8904_ADC_HPF 0x0010 /* ADC_HPF */
585#define WM8904_ADC_HPF_MASK 0x0010 /* ADC_HPF */
586#define WM8904_ADC_HPF_SHIFT 4 /* ADC_HPF */
587#define WM8904_ADC_HPF_WIDTH 1 /* ADC_HPF */
588#define WM8904_ADCL_DATINV 0x0002 /* ADCL_DATINV */
589#define WM8904_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
590#define WM8904_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
591#define WM8904_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
592#define WM8904_ADCR_DATINV 0x0001 /* ADCR_DATINV */
593#define WM8904_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
594#define WM8904_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
595#define WM8904_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
596
597/*
598 * R39 (0x27) - Digital Microphone 0
599 */
600#define WM8904_DMIC_ENA 0x1000 /* DMIC_ENA */
601#define WM8904_DMIC_ENA_MASK 0x1000 /* DMIC_ENA */
602#define WM8904_DMIC_ENA_SHIFT 12 /* DMIC_ENA */
603#define WM8904_DMIC_ENA_WIDTH 1 /* DMIC_ENA */
604#define WM8904_DMIC_SRC 0x0800 /* DMIC_SRC */
605#define WM8904_DMIC_SRC_MASK 0x0800 /* DMIC_SRC */
606#define WM8904_DMIC_SRC_SHIFT 11 /* DMIC_SRC */
607#define WM8904_DMIC_SRC_WIDTH 1 /* DMIC_SRC */
608
609/*
610 * R40 (0x28) - DRC 0
611 */
612#define WM8904_DRC_ENA 0x8000 /* DRC_ENA */
613#define WM8904_DRC_ENA_MASK 0x8000 /* DRC_ENA */
614#define WM8904_DRC_ENA_SHIFT 15 /* DRC_ENA */
615#define WM8904_DRC_ENA_WIDTH 1 /* DRC_ENA */
616#define WM8904_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */
617#define WM8904_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */
618#define WM8904_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */
619#define WM8904_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */
620#define WM8904_DRC_GS_HYST_LVL_MASK 0x1800 /* DRC_GS_HYST_LVL - [12:11] */
621#define WM8904_DRC_GS_HYST_LVL_SHIFT 11 /* DRC_GS_HYST_LVL - [12:11] */
622#define WM8904_DRC_GS_HYST_LVL_WIDTH 2 /* DRC_GS_HYST_LVL - [12:11] */
623#define WM8904_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
624#define WM8904_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
625#define WM8904_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
626#define WM8904_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
627#define WM8904_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
628#define WM8904_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
629#define WM8904_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
630#define WM8904_DRC_GS_ENA 0x0008 /* DRC_GS_ENA */
631#define WM8904_DRC_GS_ENA_MASK 0x0008 /* DRC_GS_ENA */
632#define WM8904_DRC_GS_ENA_SHIFT 3 /* DRC_GS_ENA */
633#define WM8904_DRC_GS_ENA_WIDTH 1 /* DRC_GS_ENA */
634#define WM8904_DRC_QR 0x0004 /* DRC_QR */
635#define WM8904_DRC_QR_MASK 0x0004 /* DRC_QR */
636#define WM8904_DRC_QR_SHIFT 2 /* DRC_QR */
637#define WM8904_DRC_QR_WIDTH 1 /* DRC_QR */
638#define WM8904_DRC_ANTICLIP 0x0002 /* DRC_ANTICLIP */
639#define WM8904_DRC_ANTICLIP_MASK 0x0002 /* DRC_ANTICLIP */
640#define WM8904_DRC_ANTICLIP_SHIFT 1 /* DRC_ANTICLIP */
641#define WM8904_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
642#define WM8904_DRC_GS_HYST 0x0001 /* DRC_GS_HYST */
643#define WM8904_DRC_GS_HYST_MASK 0x0001 /* DRC_GS_HYST */
644#define WM8904_DRC_GS_HYST_SHIFT 0 /* DRC_GS_HYST */
645#define WM8904_DRC_GS_HYST_WIDTH 1 /* DRC_GS_HYST */
646
647/*
648 * R41 (0x29) - DRC 1
649 */
650#define WM8904_DRC_ATK_MASK 0xF000 /* DRC_ATK - [15:12] */
651#define WM8904_DRC_ATK_SHIFT 12 /* DRC_ATK - [15:12] */
652#define WM8904_DRC_ATK_WIDTH 4 /* DRC_ATK - [15:12] */
653#define WM8904_DRC_DCY_MASK 0x0F00 /* DRC_DCY - [11:8] */
654#define WM8904_DRC_DCY_SHIFT 8 /* DRC_DCY - [11:8] */
655#define WM8904_DRC_DCY_WIDTH 4 /* DRC_DCY - [11:8] */
656#define WM8904_DRC_QR_THR_MASK 0x00C0 /* DRC_QR_THR - [7:6] */
657#define WM8904_DRC_QR_THR_SHIFT 6 /* DRC_QR_THR - [7:6] */
658#define WM8904_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [7:6] */
659#define WM8904_DRC_QR_DCY_MASK 0x0030 /* DRC_QR_DCY - [5:4] */
660#define WM8904_DRC_QR_DCY_SHIFT 4 /* DRC_QR_DCY - [5:4] */
661#define WM8904_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [5:4] */
662#define WM8904_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
663#define WM8904_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
664#define WM8904_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
665#define WM8904_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
666#define WM8904_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
667#define WM8904_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
668
669/*
670 * R42 (0x2A) - DRC 2
671 */
672#define WM8904_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
673#define WM8904_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
674#define WM8904_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
675#define WM8904_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
676#define WM8904_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
677#define WM8904_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
678
679/*
680 * R43 (0x2B) - DRC 3
681 */
682#define WM8904_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
683#define WM8904_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
684#define WM8904_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
685#define WM8904_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
686#define WM8904_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
687#define WM8904_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
688
689/*
690 * R44 (0x2C) - Analogue Left Input 0
691 */
692#define WM8904_LINMUTE 0x0080 /* LINMUTE */
693#define WM8904_LINMUTE_MASK 0x0080 /* LINMUTE */
694#define WM8904_LINMUTE_SHIFT 7 /* LINMUTE */
695#define WM8904_LINMUTE_WIDTH 1 /* LINMUTE */
696#define WM8904_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
697#define WM8904_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
698#define WM8904_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
699
700/*
701 * R45 (0x2D) - Analogue Right Input 0
702 */
703#define WM8904_RINMUTE 0x0080 /* RINMUTE */
704#define WM8904_RINMUTE_MASK 0x0080 /* RINMUTE */
705#define WM8904_RINMUTE_SHIFT 7 /* RINMUTE */
706#define WM8904_RINMUTE_WIDTH 1 /* RINMUTE */
707#define WM8904_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
708#define WM8904_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
709#define WM8904_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
710
711/*
712 * R46 (0x2E) - Analogue Left Input 1
713 */
714#define WM8904_INL_CM_ENA 0x0040 /* INL_CM_ENA */
715#define WM8904_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
716#define WM8904_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
717#define WM8904_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
718#define WM8904_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
719#define WM8904_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
720#define WM8904_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
721#define WM8904_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
722#define WM8904_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
723#define WM8904_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
724#define WM8904_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
725#define WM8904_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
726#define WM8904_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
727
728/*
729 * R47 (0x2F) - Analogue Right Input 1
730 */
731#define WM8904_INR_CM_ENA 0x0040 /* INR_CM_ENA */
732#define WM8904_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
733#define WM8904_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
734#define WM8904_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
735#define WM8904_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
736#define WM8904_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
737#define WM8904_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
738#define WM8904_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
739#define WM8904_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
740#define WM8904_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
741#define WM8904_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
742#define WM8904_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
743#define WM8904_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
744
745/*
746 * R57 (0x39) - Analogue OUT1 Left
747 */
748#define WM8904_HPOUTL_MUTE 0x0100 /* HPOUTL_MUTE */
749#define WM8904_HPOUTL_MUTE_MASK 0x0100 /* HPOUTL_MUTE */
750#define WM8904_HPOUTL_MUTE_SHIFT 8 /* HPOUTL_MUTE */
751#define WM8904_HPOUTL_MUTE_WIDTH 1 /* HPOUTL_MUTE */
752#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
753#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
754#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
755#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
756#define WM8904_HPOUTLZC 0x0040 /* HPOUTLZC */
757#define WM8904_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
758#define WM8904_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
759#define WM8904_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
760#define WM8904_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
761#define WM8904_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
762#define WM8904_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
763
764/*
765 * R58 (0x3A) - Analogue OUT1 Right
766 */
767#define WM8904_HPOUTR_MUTE 0x0100 /* HPOUTR_MUTE */
768#define WM8904_HPOUTR_MUTE_MASK 0x0100 /* HPOUTR_MUTE */
769#define WM8904_HPOUTR_MUTE_SHIFT 8 /* HPOUTR_MUTE */
770#define WM8904_HPOUTR_MUTE_WIDTH 1 /* HPOUTR_MUTE */
771#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
772#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
773#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
774#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
775#define WM8904_HPOUTRZC 0x0040 /* HPOUTRZC */
776#define WM8904_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
777#define WM8904_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
778#define WM8904_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
779#define WM8904_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
780#define WM8904_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
781#define WM8904_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
782
783/*
784 * R59 (0x3B) - Analogue OUT2 Left
785 */
786#define WM8904_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
787#define WM8904_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
788#define WM8904_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
789#define WM8904_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
790#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
791#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
792#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
793#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
794#define WM8904_LINEOUTLZC 0x0040 /* LINEOUTLZC */
795#define WM8904_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
796#define WM8904_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
797#define WM8904_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
798#define WM8904_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
799#define WM8904_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
800#define WM8904_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
801
802/*
803 * R60 (0x3C) - Analogue OUT2 Right
804 */
805#define WM8904_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
806#define WM8904_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
807#define WM8904_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
808#define WM8904_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
809#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
810#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
811#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
812#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
813#define WM8904_LINEOUTRZC 0x0040 /* LINEOUTRZC */
814#define WM8904_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
815#define WM8904_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
816#define WM8904_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
817#define WM8904_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
818#define WM8904_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
819#define WM8904_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
820
821/*
822 * R61 (0x3D) - Analogue OUT12 ZC
823 */
824#define WM8904_HPL_BYP_ENA 0x0008 /* HPL_BYP_ENA */
825#define WM8904_HPL_BYP_ENA_MASK 0x0008 /* HPL_BYP_ENA */
826#define WM8904_HPL_BYP_ENA_SHIFT 3 /* HPL_BYP_ENA */
827#define WM8904_HPL_BYP_ENA_WIDTH 1 /* HPL_BYP_ENA */
828#define WM8904_HPR_BYP_ENA 0x0004 /* HPR_BYP_ENA */
829#define WM8904_HPR_BYP_ENA_MASK 0x0004 /* HPR_BYP_ENA */
830#define WM8904_HPR_BYP_ENA_SHIFT 2 /* HPR_BYP_ENA */
831#define WM8904_HPR_BYP_ENA_WIDTH 1 /* HPR_BYP_ENA */
832#define WM8904_LINEOUTL_BYP_ENA 0x0002 /* LINEOUTL_BYP_ENA */
833#define WM8904_LINEOUTL_BYP_ENA_MASK 0x0002 /* LINEOUTL_BYP_ENA */
834#define WM8904_LINEOUTL_BYP_ENA_SHIFT 1 /* LINEOUTL_BYP_ENA */
835#define WM8904_LINEOUTL_BYP_ENA_WIDTH 1 /* LINEOUTL_BYP_ENA */
836#define WM8904_LINEOUTR_BYP_ENA 0x0001 /* LINEOUTR_BYP_ENA */
837#define WM8904_LINEOUTR_BYP_ENA_MASK 0x0001 /* LINEOUTR_BYP_ENA */
838#define WM8904_LINEOUTR_BYP_ENA_SHIFT 0 /* LINEOUTR_BYP_ENA */
839#define WM8904_LINEOUTR_BYP_ENA_WIDTH 1 /* LINEOUTR_BYP_ENA */
840
841/*
842 * R67 (0x43) - DC Servo 0
843 */
844#define WM8904_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
845#define WM8904_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
846#define WM8904_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
847#define WM8904_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
848#define WM8904_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
849#define WM8904_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
850#define WM8904_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
851#define WM8904_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
852#define WM8904_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
853#define WM8904_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
854#define WM8904_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
855#define WM8904_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
856#define WM8904_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
857#define WM8904_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
858#define WM8904_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
859#define WM8904_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
860
861/*
862 * R68 (0x44) - DC Servo 1
863 */
864#define WM8904_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
865#define WM8904_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
866#define WM8904_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
867#define WM8904_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
868#define WM8904_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
869#define WM8904_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
870#define WM8904_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
871#define WM8904_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
872#define WM8904_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
873#define WM8904_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
874#define WM8904_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
875#define WM8904_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
876#define WM8904_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
877#define WM8904_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
878#define WM8904_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
879#define WM8904_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
880#define WM8904_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
881#define WM8904_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
882#define WM8904_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
883#define WM8904_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
884#define WM8904_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
885#define WM8904_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
886#define WM8904_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
887#define WM8904_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
888#define WM8904_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
889#define WM8904_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
890#define WM8904_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
891#define WM8904_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
892#define WM8904_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
893#define WM8904_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
894#define WM8904_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
895#define WM8904_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
896#define WM8904_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
897#define WM8904_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
898#define WM8904_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
899#define WM8904_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
900#define WM8904_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
901#define WM8904_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
902#define WM8904_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
903#define WM8904_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
904#define WM8904_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
905#define WM8904_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
906#define WM8904_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
907#define WM8904_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
908#define WM8904_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
909#define WM8904_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
910#define WM8904_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
911#define WM8904_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
912#define WM8904_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
913#define WM8904_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
914#define WM8904_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
915#define WM8904_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
916#define WM8904_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
917#define WM8904_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
918#define WM8904_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
919#define WM8904_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
920#define WM8904_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
921#define WM8904_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
922#define WM8904_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
923#define WM8904_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
924#define WM8904_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
925#define WM8904_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
926#define WM8904_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
927#define WM8904_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
928
929/*
930 * R69 (0x45) - DC Servo 2
931 */
932#define WM8904_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
933#define WM8904_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
934#define WM8904_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
935#define WM8904_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
936#define WM8904_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
937#define WM8904_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
938
939/*
940 * R71 (0x47) - DC Servo 4
941 */
942#define WM8904_DCS_SERIES_NO_23_MASK 0x007F /* DCS_SERIES_NO_23 - [6:0] */
943#define WM8904_DCS_SERIES_NO_23_SHIFT 0 /* DCS_SERIES_NO_23 - [6:0] */
944#define WM8904_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [6:0] */
945
946/*
947 * R72 (0x48) - DC Servo 5
948 */
949#define WM8904_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
950#define WM8904_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
951#define WM8904_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
952
953/*
954 * R73 (0x49) - DC Servo 6
955 */
956#define WM8904_DCS_DAC_WR_VAL_3_MASK 0x00FF /* DCS_DAC_WR_VAL_3 - [7:0] */
957#define WM8904_DCS_DAC_WR_VAL_3_SHIFT 0 /* DCS_DAC_WR_VAL_3 - [7:0] */
958#define WM8904_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [7:0] */
959
960/*
961 * R74 (0x4A) - DC Servo 7
962 */
963#define WM8904_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
964#define WM8904_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
965#define WM8904_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
966
967/*
968 * R75 (0x4B) - DC Servo 8
969 */
970#define WM8904_DCS_DAC_WR_VAL_1_MASK 0x00FF /* DCS_DAC_WR_VAL_1 - [7:0] */
971#define WM8904_DCS_DAC_WR_VAL_1_SHIFT 0 /* DCS_DAC_WR_VAL_1 - [7:0] */
972#define WM8904_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [7:0] */
973
974/*
975 * R76 (0x4C) - DC Servo 9
976 */
977#define WM8904_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
978#define WM8904_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
979#define WM8904_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
980
981/*
982 * R77 (0x4D) - DC Servo Readback 0
983 */
984#define WM8904_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
985#define WM8904_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
986#define WM8904_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
987#define WM8904_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
988#define WM8904_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
989#define WM8904_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
990#define WM8904_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
991#define WM8904_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
992#define WM8904_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
993
994/*
995 * R90 (0x5A) - Analogue HP 0
996 */
997#define WM8904_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
998#define WM8904_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
999#define WM8904_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
1000#define WM8904_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
1001#define WM8904_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
1002#define WM8904_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
1003#define WM8904_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
1004#define WM8904_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
1005#define WM8904_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
1006#define WM8904_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
1007#define WM8904_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
1008#define WM8904_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
1009#define WM8904_HPL_ENA 0x0010 /* HPL_ENA */
1010#define WM8904_HPL_ENA_MASK 0x0010 /* HPL_ENA */
1011#define WM8904_HPL_ENA_SHIFT 4 /* HPL_ENA */
1012#define WM8904_HPL_ENA_WIDTH 1 /* HPL_ENA */
1013#define WM8904_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
1014#define WM8904_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
1015#define WM8904_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
1016#define WM8904_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
1017#define WM8904_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
1018#define WM8904_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
1019#define WM8904_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
1020#define WM8904_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
1021#define WM8904_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
1022#define WM8904_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
1023#define WM8904_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
1024#define WM8904_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
1025#define WM8904_HPR_ENA 0x0001 /* HPR_ENA */
1026#define WM8904_HPR_ENA_MASK 0x0001 /* HPR_ENA */
1027#define WM8904_HPR_ENA_SHIFT 0 /* HPR_ENA */
1028#define WM8904_HPR_ENA_WIDTH 1 /* HPR_ENA */
1029
1030/*
1031 * R94 (0x5E) - Analogue Lineout 0
1032 */
1033#define WM8904_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
1034#define WM8904_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
1035#define WM8904_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
1036#define WM8904_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
1037#define WM8904_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
1038#define WM8904_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
1039#define WM8904_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
1040#define WM8904_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
1041#define WM8904_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
1042#define WM8904_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
1043#define WM8904_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
1044#define WM8904_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
1045#define WM8904_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
1046#define WM8904_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
1047#define WM8904_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
1048#define WM8904_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
1049#define WM8904_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
1050#define WM8904_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
1051#define WM8904_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
1052#define WM8904_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
1053#define WM8904_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
1054#define WM8904_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
1055#define WM8904_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
1056#define WM8904_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
1057#define WM8904_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
1058#define WM8904_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
1059#define WM8904_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
1060#define WM8904_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
1061#define WM8904_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
1062#define WM8904_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
1063#define WM8904_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
1064#define WM8904_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
1065
1066/*
1067 * R98 (0x62) - Charge Pump 0
1068 */
1069#define WM8904_CP_ENA 0x0001 /* CP_ENA */
1070#define WM8904_CP_ENA_MASK 0x0001 /* CP_ENA */
1071#define WM8904_CP_ENA_SHIFT 0 /* CP_ENA */
1072#define WM8904_CP_ENA_WIDTH 1 /* CP_ENA */
1073
1074/*
1075 * R104 (0x68) - Class W 0
1076 */
1077#define WM8904_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
1078#define WM8904_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
1079#define WM8904_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
1080#define WM8904_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
1081
1082/*
1083 * R108 (0x6C) - Write Sequencer 0
1084 */
1085#define WM8904_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1086#define WM8904_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1087#define WM8904_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1088#define WM8904_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1089#define WM8904_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1090#define WM8904_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1091#define WM8904_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1092
1093/*
1094 * R109 (0x6D) - Write Sequencer 1
1095 */
1096#define WM8904_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1097#define WM8904_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1098#define WM8904_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1099#define WM8904_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1100#define WM8904_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1101#define WM8904_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1102#define WM8904_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1103#define WM8904_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1104#define WM8904_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1105
1106/*
1107 * R110 (0x6E) - Write Sequencer 2
1108 */
1109#define WM8904_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1110#define WM8904_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1111#define WM8904_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1112#define WM8904_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1113#define WM8904_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1114#define WM8904_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1115#define WM8904_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1116#define WM8904_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1117#define WM8904_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1118#define WM8904_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1119
1120/*
1121 * R111 (0x6F) - Write Sequencer 3
1122 */
1123#define WM8904_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1124#define WM8904_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1125#define WM8904_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1126#define WM8904_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1127#define WM8904_WSEQ_START 0x0100 /* WSEQ_START */
1128#define WM8904_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1129#define WM8904_WSEQ_START_SHIFT 8 /* WSEQ_START */
1130#define WM8904_WSEQ_START_WIDTH 1 /* WSEQ_START */
1131#define WM8904_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1132#define WM8904_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1133#define WM8904_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1134
1135/*
1136 * R112 (0x70) - Write Sequencer 4
1137 */
1138#define WM8904_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
1139#define WM8904_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
1140#define WM8904_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
1141#define WM8904_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1142#define WM8904_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1143#define WM8904_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1144#define WM8904_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1145
1146/*
1147 * R116 (0x74) - FLL Control 1
1148 */
1149#define WM8904_FLL_FRACN_ENA 0x0004 /* FLL_FRACN_ENA */
1150#define WM8904_FLL_FRACN_ENA_MASK 0x0004 /* FLL_FRACN_ENA */
1151#define WM8904_FLL_FRACN_ENA_SHIFT 2 /* FLL_FRACN_ENA */
1152#define WM8904_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */
1153#define WM8904_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1154#define WM8904_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1155#define WM8904_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1156#define WM8904_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1157#define WM8904_FLL_ENA 0x0001 /* FLL_ENA */
1158#define WM8904_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1159#define WM8904_FLL_ENA_SHIFT 0 /* FLL_ENA */
1160#define WM8904_FLL_ENA_WIDTH 1 /* FLL_ENA */
1161
1162/*
1163 * R117 (0x75) - FLL Control 2
1164 */
1165#define WM8904_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
1166#define WM8904_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
1167#define WM8904_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
1168#define WM8904_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
1169#define WM8904_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
1170#define WM8904_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
1171#define WM8904_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1172#define WM8904_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1173#define WM8904_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1174
1175/*
1176 * R118 (0x76) - FLL Control 3
1177 */
1178#define WM8904_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
1179#define WM8904_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
1180#define WM8904_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
1181
1182/*
1183 * R119 (0x77) - FLL Control 4
1184 */
1185#define WM8904_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1186#define WM8904_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1187#define WM8904_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1188#define WM8904_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
1189#define WM8904_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
1190#define WM8904_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
1191
1192/*
1193 * R120 (0x78) - FLL Control 5
1194 */
1195#define WM8904_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
1196#define WM8904_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
1197#define WM8904_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
1198#define WM8904_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */
1199#define WM8904_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */
1200#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
1201
1202/*
1203 * R121 (0x79) - GPIO Control 1
1204 */
1205#define WM8904_GPIO1_PU 0x0020 /* GPIO1_PU */
1206#define WM8904_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
1207#define WM8904_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
1208#define WM8904_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
1209#define WM8904_GPIO1_PD 0x0010 /* GPIO1_PD */
1210#define WM8904_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
1211#define WM8904_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
1212#define WM8904_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
1213#define WM8904_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
1214#define WM8904_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
1215#define WM8904_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
1216
1217/*
1218 * R122 (0x7A) - GPIO Control 2
1219 */
1220#define WM8904_GPIO2_PU 0x0020 /* GPIO2_PU */
1221#define WM8904_GPIO2_PU_MASK 0x0020 /* GPIO2_PU */
1222#define WM8904_GPIO2_PU_SHIFT 5 /* GPIO2_PU */
1223#define WM8904_GPIO2_PU_WIDTH 1 /* GPIO2_PU */
1224#define WM8904_GPIO2_PD 0x0010 /* GPIO2_PD */
1225#define WM8904_GPIO2_PD_MASK 0x0010 /* GPIO2_PD */
1226#define WM8904_GPIO2_PD_SHIFT 4 /* GPIO2_PD */
1227#define WM8904_GPIO2_PD_WIDTH 1 /* GPIO2_PD */
1228#define WM8904_GPIO2_SEL_MASK 0x000F /* GPIO2_SEL - [3:0] */
1229#define WM8904_GPIO2_SEL_SHIFT 0 /* GPIO2_SEL - [3:0] */
1230#define WM8904_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [3:0] */
1231
1232/*
1233 * R123 (0x7B) - GPIO Control 3
1234 */
1235#define WM8904_GPIO3_PU 0x0020 /* GPIO3_PU */
1236#define WM8904_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */
1237#define WM8904_GPIO3_PU_SHIFT 5 /* GPIO3_PU */
1238#define WM8904_GPIO3_PU_WIDTH 1 /* GPIO3_PU */
1239#define WM8904_GPIO3_PD 0x0010 /* GPIO3_PD */
1240#define WM8904_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */
1241#define WM8904_GPIO3_PD_SHIFT 4 /* GPIO3_PD */
1242#define WM8904_GPIO3_PD_WIDTH 1 /* GPIO3_PD */
1243#define WM8904_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
1244#define WM8904_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */
1245#define WM8904_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */
1246
1247/*
1248 * R124 (0x7C) - GPIO Control 4
1249 */
1250#define WM8904_GPI7_ENA 0x0200 /* GPI7_ENA */
1251#define WM8904_GPI7_ENA_MASK 0x0200 /* GPI7_ENA */
1252#define WM8904_GPI7_ENA_SHIFT 9 /* GPI7_ENA */
1253#define WM8904_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
1254#define WM8904_GPI8_ENA 0x0100 /* GPI8_ENA */
1255#define WM8904_GPI8_ENA_MASK 0x0100 /* GPI8_ENA */
1256#define WM8904_GPI8_ENA_SHIFT 8 /* GPI8_ENA */
1257#define WM8904_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
1258#define WM8904_GPIO_BCLK_MODE_ENA 0x0080 /* GPIO_BCLK_MODE_ENA */
1259#define WM8904_GPIO_BCLK_MODE_ENA_MASK 0x0080 /* GPIO_BCLK_MODE_ENA */
1260#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT 7 /* GPIO_BCLK_MODE_ENA */
1261#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH 1 /* GPIO_BCLK_MODE_ENA */
1262#define WM8904_GPIO_BCLK_SEL_MASK 0x000F /* GPIO_BCLK_SEL - [3:0] */
1263#define WM8904_GPIO_BCLK_SEL_SHIFT 0 /* GPIO_BCLK_SEL - [3:0] */
1264#define WM8904_GPIO_BCLK_SEL_WIDTH 4 /* GPIO_BCLK_SEL - [3:0] */
1265
1266/*
1267 * R126 (0x7E) - Digital Pulls
1268 */
1269#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */
1270#define WM8904_MCLK_PU_MASK 0x0080 /* MCLK_PU */
1271#define WM8904_MCLK_PU_SHIFT 7 /* MCLK_PU */
1272#define WM8904_MCLK_PU_WIDTH 1 /* MCLK_PU */
1273#define WM8904_MCLK_PD 0x0040 /* MCLK_PD */
1274#define WM8904_MCLK_PD_MASK 0x0040 /* MCLK_PD */
1275#define WM8904_MCLK_PD_SHIFT 6 /* MCLK_PD */
1276#define WM8904_MCLK_PD_WIDTH 1 /* MCLK_PD */
1277#define WM8904_DACDAT_PU 0x0020 /* DACDAT_PU */
1278#define WM8904_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */
1279#define WM8904_DACDAT_PU_SHIFT 5 /* DACDAT_PU */
1280#define WM8904_DACDAT_PU_WIDTH 1 /* DACDAT_PU */
1281#define WM8904_DACDAT_PD 0x0010 /* DACDAT_PD */
1282#define WM8904_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */
1283#define WM8904_DACDAT_PD_SHIFT 4 /* DACDAT_PD */
1284#define WM8904_DACDAT_PD_WIDTH 1 /* DACDAT_PD */
1285#define WM8904_LRCLK_PU 0x0008 /* LRCLK_PU */
1286#define WM8904_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */
1287#define WM8904_LRCLK_PU_SHIFT 3 /* LRCLK_PU */
1288#define WM8904_LRCLK_PU_WIDTH 1 /* LRCLK_PU */
1289#define WM8904_LRCLK_PD 0x0004 /* LRCLK_PD */
1290#define WM8904_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */
1291#define WM8904_LRCLK_PD_SHIFT 2 /* LRCLK_PD */
1292#define WM8904_LRCLK_PD_WIDTH 1 /* LRCLK_PD */
1293#define WM8904_BCLK_PU 0x0002 /* BCLK_PU */
1294#define WM8904_BCLK_PU_MASK 0x0002 /* BCLK_PU */
1295#define WM8904_BCLK_PU_SHIFT 1 /* BCLK_PU */
1296#define WM8904_BCLK_PU_WIDTH 1 /* BCLK_PU */
1297#define WM8904_BCLK_PD 0x0001 /* BCLK_PD */
1298#define WM8904_BCLK_PD_MASK 0x0001 /* BCLK_PD */
1299#define WM8904_BCLK_PD_SHIFT 0 /* BCLK_PD */
1300#define WM8904_BCLK_PD_WIDTH 1 /* BCLK_PD */
1301
1302/*
1303 * R127 (0x7F) - Interrupt Status
1304 */
1305#define WM8904_IRQ 0x0400 /* IRQ */
1306#define WM8904_IRQ_MASK 0x0400 /* IRQ */
1307#define WM8904_IRQ_SHIFT 10 /* IRQ */
1308#define WM8904_IRQ_WIDTH 1 /* IRQ */
1309#define WM8904_GPIO_BCLK_EINT 0x0200 /* GPIO_BCLK_EINT */
1310#define WM8904_GPIO_BCLK_EINT_MASK 0x0200 /* GPIO_BCLK_EINT */
1311#define WM8904_GPIO_BCLK_EINT_SHIFT 9 /* GPIO_BCLK_EINT */
1312#define WM8904_GPIO_BCLK_EINT_WIDTH 1 /* GPIO_BCLK_EINT */
1313#define WM8904_WSEQ_EINT 0x0100 /* WSEQ_EINT */
1314#define WM8904_WSEQ_EINT_MASK 0x0100 /* WSEQ_EINT */
1315#define WM8904_WSEQ_EINT_SHIFT 8 /* WSEQ_EINT */
1316#define WM8904_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */
1317#define WM8904_GPIO3_EINT 0x0080 /* GPIO3_EINT */
1318#define WM8904_GPIO3_EINT_MASK 0x0080 /* GPIO3_EINT */
1319#define WM8904_GPIO3_EINT_SHIFT 7 /* GPIO3_EINT */
1320#define WM8904_GPIO3_EINT_WIDTH 1 /* GPIO3_EINT */
1321#define WM8904_GPIO2_EINT 0x0040 /* GPIO2_EINT */
1322#define WM8904_GPIO2_EINT_MASK 0x0040 /* GPIO2_EINT */
1323#define WM8904_GPIO2_EINT_SHIFT 6 /* GPIO2_EINT */
1324#define WM8904_GPIO2_EINT_WIDTH 1 /* GPIO2_EINT */
1325#define WM8904_GPIO1_EINT 0x0020 /* GPIO1_EINT */
1326#define WM8904_GPIO1_EINT_MASK 0x0020 /* GPIO1_EINT */
1327#define WM8904_GPIO1_EINT_SHIFT 5 /* GPIO1_EINT */
1328#define WM8904_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */
1329#define WM8904_GPI8_EINT 0x0010 /* GPI8_EINT */
1330#define WM8904_GPI8_EINT_MASK 0x0010 /* GPI8_EINT */
1331#define WM8904_GPI8_EINT_SHIFT 4 /* GPI8_EINT */
1332#define WM8904_GPI8_EINT_WIDTH 1 /* GPI8_EINT */
1333#define WM8904_GPI7_EINT 0x0008 /* GPI7_EINT */
1334#define WM8904_GPI7_EINT_MASK 0x0008 /* GPI7_EINT */
1335#define WM8904_GPI7_EINT_SHIFT 3 /* GPI7_EINT */
1336#define WM8904_GPI7_EINT_WIDTH 1 /* GPI7_EINT */
1337#define WM8904_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
1338#define WM8904_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
1339#define WM8904_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
1340#define WM8904_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
1341#define WM8904_MIC_SHRT_EINT 0x0002 /* MIC_SHRT_EINT */
1342#define WM8904_MIC_SHRT_EINT_MASK 0x0002 /* MIC_SHRT_EINT */
1343#define WM8904_MIC_SHRT_EINT_SHIFT 1 /* MIC_SHRT_EINT */
1344#define WM8904_MIC_SHRT_EINT_WIDTH 1 /* MIC_SHRT_EINT */
1345#define WM8904_MIC_DET_EINT 0x0001 /* MIC_DET_EINT */
1346#define WM8904_MIC_DET_EINT_MASK 0x0001 /* MIC_DET_EINT */
1347#define WM8904_MIC_DET_EINT_SHIFT 0 /* MIC_DET_EINT */
1348#define WM8904_MIC_DET_EINT_WIDTH 1 /* MIC_DET_EINT */
1349
1350/*
1351 * R128 (0x80) - Interrupt Status Mask
1352 */
1353#define WM8904_IM_GPIO_BCLK_EINT 0x0200 /* IM_GPIO_BCLK_EINT */
1354#define WM8904_IM_GPIO_BCLK_EINT_MASK 0x0200 /* IM_GPIO_BCLK_EINT */
1355#define WM8904_IM_GPIO_BCLK_EINT_SHIFT 9 /* IM_GPIO_BCLK_EINT */
1356#define WM8904_IM_GPIO_BCLK_EINT_WIDTH 1 /* IM_GPIO_BCLK_EINT */
1357#define WM8904_IM_WSEQ_EINT 0x0100 /* IM_WSEQ_EINT */
1358#define WM8904_IM_WSEQ_EINT_MASK 0x0100 /* IM_WSEQ_EINT */
1359#define WM8904_IM_WSEQ_EINT_SHIFT 8 /* IM_WSEQ_EINT */
1360#define WM8904_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */
1361#define WM8904_IM_GPIO3_EINT 0x0080 /* IM_GPIO3_EINT */
1362#define WM8904_IM_GPIO3_EINT_MASK 0x0080 /* IM_GPIO3_EINT */
1363#define WM8904_IM_GPIO3_EINT_SHIFT 7 /* IM_GPIO3_EINT */
1364#define WM8904_IM_GPIO3_EINT_WIDTH 1 /* IM_GPIO3_EINT */
1365#define WM8904_IM_GPIO2_EINT 0x0040 /* IM_GPIO2_EINT */
1366#define WM8904_IM_GPIO2_EINT_MASK 0x0040 /* IM_GPIO2_EINT */
1367#define WM8904_IM_GPIO2_EINT_SHIFT 6 /* IM_GPIO2_EINT */
1368#define WM8904_IM_GPIO2_EINT_WIDTH 1 /* IM_GPIO2_EINT */
1369#define WM8904_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */
1370#define WM8904_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */
1371#define WM8904_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */
1372#define WM8904_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */
1373#define WM8904_IM_GPI8_EINT 0x0010 /* IM_GPI8_EINT */
1374#define WM8904_IM_GPI8_EINT_MASK 0x0010 /* IM_GPI8_EINT */
1375#define WM8904_IM_GPI8_EINT_SHIFT 4 /* IM_GPI8_EINT */
1376#define WM8904_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */
1377#define WM8904_IM_GPI7_EINT 0x0008 /* IM_GPI7_EINT */
1378#define WM8904_IM_GPI7_EINT_MASK 0x0008 /* IM_GPI7_EINT */
1379#define WM8904_IM_GPI7_EINT_SHIFT 3 /* IM_GPI7_EINT */
1380#define WM8904_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */
1381#define WM8904_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
1382#define WM8904_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
1383#define WM8904_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
1384#define WM8904_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
1385#define WM8904_IM_MIC_SHRT_EINT 0x0002 /* IM_MIC_SHRT_EINT */
1386#define WM8904_IM_MIC_SHRT_EINT_MASK 0x0002 /* IM_MIC_SHRT_EINT */
1387#define WM8904_IM_MIC_SHRT_EINT_SHIFT 1 /* IM_MIC_SHRT_EINT */
1388#define WM8904_IM_MIC_SHRT_EINT_WIDTH 1 /* IM_MIC_SHRT_EINT */
1389#define WM8904_IM_MIC_DET_EINT 0x0001 /* IM_MIC_DET_EINT */
1390#define WM8904_IM_MIC_DET_EINT_MASK 0x0001 /* IM_MIC_DET_EINT */
1391#define WM8904_IM_MIC_DET_EINT_SHIFT 0 /* IM_MIC_DET_EINT */
1392#define WM8904_IM_MIC_DET_EINT_WIDTH 1 /* IM_MIC_DET_EINT */
1393
1394/*
1395 * R129 (0x81) - Interrupt Polarity
1396 */
1397#define WM8904_GPIO_BCLK_EINT_POL 0x0200 /* GPIO_BCLK_EINT_POL */
1398#define WM8904_GPIO_BCLK_EINT_POL_MASK 0x0200 /* GPIO_BCLK_EINT_POL */
1399#define WM8904_GPIO_BCLK_EINT_POL_SHIFT 9 /* GPIO_BCLK_EINT_POL */
1400#define WM8904_GPIO_BCLK_EINT_POL_WIDTH 1 /* GPIO_BCLK_EINT_POL */
1401#define WM8904_WSEQ_EINT_POL 0x0100 /* WSEQ_EINT_POL */
1402#define WM8904_WSEQ_EINT_POL_MASK 0x0100 /* WSEQ_EINT_POL */
1403#define WM8904_WSEQ_EINT_POL_SHIFT 8 /* WSEQ_EINT_POL */
1404#define WM8904_WSEQ_EINT_POL_WIDTH 1 /* WSEQ_EINT_POL */
1405#define WM8904_GPIO3_EINT_POL 0x0080 /* GPIO3_EINT_POL */
1406#define WM8904_GPIO3_EINT_POL_MASK 0x0080 /* GPIO3_EINT_POL */
1407#define WM8904_GPIO3_EINT_POL_SHIFT 7 /* GPIO3_EINT_POL */
1408#define WM8904_GPIO3_EINT_POL_WIDTH 1 /* GPIO3_EINT_POL */
1409#define WM8904_GPIO2_EINT_POL 0x0040 /* GPIO2_EINT_POL */
1410#define WM8904_GPIO2_EINT_POL_MASK 0x0040 /* GPIO2_EINT_POL */
1411#define WM8904_GPIO2_EINT_POL_SHIFT 6 /* GPIO2_EINT_POL */
1412#define WM8904_GPIO2_EINT_POL_WIDTH 1 /* GPIO2_EINT_POL */
1413#define WM8904_GPIO1_EINT_POL 0x0020 /* GPIO1_EINT_POL */
1414#define WM8904_GPIO1_EINT_POL_MASK 0x0020 /* GPIO1_EINT_POL */
1415#define WM8904_GPIO1_EINT_POL_SHIFT 5 /* GPIO1_EINT_POL */
1416#define WM8904_GPIO1_EINT_POL_WIDTH 1 /* GPIO1_EINT_POL */
1417#define WM8904_GPI8_EINT_POL 0x0010 /* GPI8_EINT_POL */
1418#define WM8904_GPI8_EINT_POL_MASK 0x0010 /* GPI8_EINT_POL */
1419#define WM8904_GPI8_EINT_POL_SHIFT 4 /* GPI8_EINT_POL */
1420#define WM8904_GPI8_EINT_POL_WIDTH 1 /* GPI8_EINT_POL */
1421#define WM8904_GPI7_EINT_POL 0x0008 /* GPI7_EINT_POL */
1422#define WM8904_GPI7_EINT_POL_MASK 0x0008 /* GPI7_EINT_POL */
1423#define WM8904_GPI7_EINT_POL_SHIFT 3 /* GPI7_EINT_POL */
1424#define WM8904_GPI7_EINT_POL_WIDTH 1 /* GPI7_EINT_POL */
1425#define WM8904_FLL_LOCK_EINT_POL 0x0004 /* FLL_LOCK_EINT_POL */
1426#define WM8904_FLL_LOCK_EINT_POL_MASK 0x0004 /* FLL_LOCK_EINT_POL */
1427#define WM8904_FLL_LOCK_EINT_POL_SHIFT 2 /* FLL_LOCK_EINT_POL */
1428#define WM8904_FLL_LOCK_EINT_POL_WIDTH 1 /* FLL_LOCK_EINT_POL */
1429#define WM8904_MIC_SHRT_EINT_POL 0x0002 /* MIC_SHRT_EINT_POL */
1430#define WM8904_MIC_SHRT_EINT_POL_MASK 0x0002 /* MIC_SHRT_EINT_POL */
1431#define WM8904_MIC_SHRT_EINT_POL_SHIFT 1 /* MIC_SHRT_EINT_POL */
1432#define WM8904_MIC_SHRT_EINT_POL_WIDTH 1 /* MIC_SHRT_EINT_POL */
1433#define WM8904_MIC_DET_EINT_POL 0x0001 /* MIC_DET_EINT_POL */
1434#define WM8904_MIC_DET_EINT_POL_MASK 0x0001 /* MIC_DET_EINT_POL */
1435#define WM8904_MIC_DET_EINT_POL_SHIFT 0 /* MIC_DET_EINT_POL */
1436#define WM8904_MIC_DET_EINT_POL_WIDTH 1 /* MIC_DET_EINT_POL */
1437
1438/*
1439 * R130 (0x82) - Interrupt Debounce
1440 */
1441#define WM8904_GPIO_BCLK_EINT_DB 0x0200 /* GPIO_BCLK_EINT_DB */
1442#define WM8904_GPIO_BCLK_EINT_DB_MASK 0x0200 /* GPIO_BCLK_EINT_DB */
1443#define WM8904_GPIO_BCLK_EINT_DB_SHIFT 9 /* GPIO_BCLK_EINT_DB */
1444#define WM8904_GPIO_BCLK_EINT_DB_WIDTH 1 /* GPIO_BCLK_EINT_DB */
1445#define WM8904_WSEQ_EINT_DB 0x0100 /* WSEQ_EINT_DB */
1446#define WM8904_WSEQ_EINT_DB_MASK 0x0100 /* WSEQ_EINT_DB */
1447#define WM8904_WSEQ_EINT_DB_SHIFT 8 /* WSEQ_EINT_DB */
1448#define WM8904_WSEQ_EINT_DB_WIDTH 1 /* WSEQ_EINT_DB */
1449#define WM8904_GPIO3_EINT_DB 0x0080 /* GPIO3_EINT_DB */
1450#define WM8904_GPIO3_EINT_DB_MASK 0x0080 /* GPIO3_EINT_DB */
1451#define WM8904_GPIO3_EINT_DB_SHIFT 7 /* GPIO3_EINT_DB */
1452#define WM8904_GPIO3_EINT_DB_WIDTH 1 /* GPIO3_EINT_DB */
1453#define WM8904_GPIO2_EINT_DB 0x0040 /* GPIO2_EINT_DB */
1454#define WM8904_GPIO2_EINT_DB_MASK 0x0040 /* GPIO2_EINT_DB */
1455#define WM8904_GPIO2_EINT_DB_SHIFT 6 /* GPIO2_EINT_DB */
1456#define WM8904_GPIO2_EINT_DB_WIDTH 1 /* GPIO2_EINT_DB */
1457#define WM8904_GPIO1_EINT_DB 0x0020 /* GPIO1_EINT_DB */
1458#define WM8904_GPIO1_EINT_DB_MASK 0x0020 /* GPIO1_EINT_DB */
1459#define WM8904_GPIO1_EINT_DB_SHIFT 5 /* GPIO1_EINT_DB */
1460#define WM8904_GPIO1_EINT_DB_WIDTH 1 /* GPIO1_EINT_DB */
1461#define WM8904_GPI8_EINT_DB 0x0010 /* GPI8_EINT_DB */
1462#define WM8904_GPI8_EINT_DB_MASK 0x0010 /* GPI8_EINT_DB */
1463#define WM8904_GPI8_EINT_DB_SHIFT 4 /* GPI8_EINT_DB */
1464#define WM8904_GPI8_EINT_DB_WIDTH 1 /* GPI8_EINT_DB */
1465#define WM8904_GPI7_EINT_DB 0x0008 /* GPI7_EINT_DB */
1466#define WM8904_GPI7_EINT_DB_MASK 0x0008 /* GPI7_EINT_DB */
1467#define WM8904_GPI7_EINT_DB_SHIFT 3 /* GPI7_EINT_DB */
1468#define WM8904_GPI7_EINT_DB_WIDTH 1 /* GPI7_EINT_DB */
1469#define WM8904_FLL_LOCK_EINT_DB 0x0004 /* FLL_LOCK_EINT_DB */
1470#define WM8904_FLL_LOCK_EINT_DB_MASK 0x0004 /* FLL_LOCK_EINT_DB */
1471#define WM8904_FLL_LOCK_EINT_DB_SHIFT 2 /* FLL_LOCK_EINT_DB */
1472#define WM8904_FLL_LOCK_EINT_DB_WIDTH 1 /* FLL_LOCK_EINT_DB */
1473#define WM8904_MIC_SHRT_EINT_DB 0x0002 /* MIC_SHRT_EINT_DB */
1474#define WM8904_MIC_SHRT_EINT_DB_MASK 0x0002 /* MIC_SHRT_EINT_DB */
1475#define WM8904_MIC_SHRT_EINT_DB_SHIFT 1 /* MIC_SHRT_EINT_DB */
1476#define WM8904_MIC_SHRT_EINT_DB_WIDTH 1 /* MIC_SHRT_EINT_DB */
1477#define WM8904_MIC_DET_EINT_DB 0x0001 /* MIC_DET_EINT_DB */
1478#define WM8904_MIC_DET_EINT_DB_MASK 0x0001 /* MIC_DET_EINT_DB */
1479#define WM8904_MIC_DET_EINT_DB_SHIFT 0 /* MIC_DET_EINT_DB */
1480#define WM8904_MIC_DET_EINT_DB_WIDTH 1 /* MIC_DET_EINT_DB */
1481
1482/*
1483 * R134 (0x86) - EQ1
1484 */
1485#define WM8904_EQ_ENA 0x0001 /* EQ_ENA */
1486#define WM8904_EQ_ENA_MASK 0x0001 /* EQ_ENA */
1487#define WM8904_EQ_ENA_SHIFT 0 /* EQ_ENA */
1488#define WM8904_EQ_ENA_WIDTH 1 /* EQ_ENA */
1489
1490/*
1491 * R135 (0x87) - EQ2
1492 */
1493#define WM8904_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */
1494#define WM8904_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */
1495#define WM8904_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */
1496
1497/*
1498 * R136 (0x88) - EQ3
1499 */
1500#define WM8904_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */
1501#define WM8904_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */
1502#define WM8904_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */
1503
1504/*
1505 * R137 (0x89) - EQ4
1506 */
1507#define WM8904_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */
1508#define WM8904_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */
1509#define WM8904_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */
1510
1511/*
1512 * R138 (0x8A) - EQ5
1513 */
1514#define WM8904_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */
1515#define WM8904_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */
1516#define WM8904_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */
1517
1518/*
1519 * R139 (0x8B) - EQ6
1520 */
1521#define WM8904_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */
1522#define WM8904_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */
1523#define WM8904_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */
1524
1525/*
1526 * R140 (0x8C) - EQ7
1527 */
1528#define WM8904_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
1529#define WM8904_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
1530#define WM8904_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
1531
1532/*
1533 * R141 (0x8D) - EQ8
1534 */
1535#define WM8904_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
1536#define WM8904_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
1537#define WM8904_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
1538
1539/*
1540 * R142 (0x8E) - EQ9
1541 */
1542#define WM8904_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
1543#define WM8904_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
1544#define WM8904_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
1545
1546/*
1547 * R143 (0x8F) - EQ10
1548 */
1549#define WM8904_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
1550#define WM8904_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
1551#define WM8904_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
1552
1553/*
1554 * R144 (0x90) - EQ11
1555 */
1556#define WM8904_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
1557#define WM8904_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
1558#define WM8904_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
1559
1560/*
1561 * R145 (0x91) - EQ12
1562 */
1563#define WM8904_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
1564#define WM8904_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
1565#define WM8904_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
1566
1567/*
1568 * R146 (0x92) - EQ13
1569 */
1570#define WM8904_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
1571#define WM8904_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
1572#define WM8904_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
1573
1574/*
1575 * R147 (0x93) - EQ14
1576 */
1577#define WM8904_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
1578#define WM8904_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
1579#define WM8904_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
1580
1581/*
1582 * R148 (0x94) - EQ15
1583 */
1584#define WM8904_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
1585#define WM8904_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
1586#define WM8904_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
1587
1588/*
1589 * R149 (0x95) - EQ16
1590 */
1591#define WM8904_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
1592#define WM8904_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
1593#define WM8904_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
1594
1595/*
1596 * R150 (0x96) - EQ17
1597 */
1598#define WM8904_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
1599#define WM8904_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
1600#define WM8904_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
1601
1602/*
1603 * R151 (0x97) - EQ18
1604 */
1605#define WM8904_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
1606#define WM8904_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
1607#define WM8904_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
1608
1609/*
1610 * R152 (0x98) - EQ19
1611 */
1612#define WM8904_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
1613#define WM8904_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
1614#define WM8904_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
1615
1616/*
1617 * R153 (0x99) - EQ20
1618 */
1619#define WM8904_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
1620#define WM8904_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
1621#define WM8904_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
1622
1623/*
1624 * R154 (0x9A) - EQ21
1625 */
1626#define WM8904_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
1627#define WM8904_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
1628#define WM8904_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
1629
1630/*
1631 * R155 (0x9B) - EQ22
1632 */
1633#define WM8904_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
1634#define WM8904_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
1635#define WM8904_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
1636
1637/*
1638 * R156 (0x9C) - EQ23
1639 */
1640#define WM8904_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
1641#define WM8904_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
1642#define WM8904_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
1643
1644/*
1645 * R157 (0x9D) - EQ24
1646 */
1647#define WM8904_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
1648#define WM8904_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
1649#define WM8904_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
1650
1651/*
1652 * R161 (0xA1) - Control Interface Test 1
1653 */
1654#define WM8904_USER_KEY 0x0002 /* USER_KEY */
1655#define WM8904_USER_KEY_MASK 0x0002 /* USER_KEY */
1656#define WM8904_USER_KEY_SHIFT 1 /* USER_KEY */
1657#define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */
1658
1659/*
1660 * R204 (0xCC) - Analogue Output Bias 0
1661 */
1662#define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
1663#define WM8904_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
1664#define WM8904_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
1665
1666/*
1667 * R247 (0xF7) - FLL NCO Test 0
1668 */
1669#define WM8904_FLL_FRC_NCO 0x0001 /* FLL_FRC_NCO */
1670#define WM8904_FLL_FRC_NCO_MASK 0x0001 /* FLL_FRC_NCO */
1671#define WM8904_FLL_FRC_NCO_SHIFT 0 /* FLL_FRC_NCO */
1672#define WM8904_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1673
1674/*
1675 * R248 (0xF8) - FLL NCO Test 1
1676 */
1677#define WM8904_FLL_FRC_NCO_VAL_MASK 0x003F /* FLL_FRC_NCO_VAL - [5:0] */
1678#define WM8904_FLL_FRC_NCO_VAL_SHIFT 0 /* FLL_FRC_NCO_VAL - [5:0] */
1679#define WM8904_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [5:0] */
1680
1681#endif