aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig24
-rw-r--r--sound/soc/codecs/Makefile16
-rw-r--r--sound/soc/codecs/ad1836.c96
-rw-r--r--sound/soc/codecs/ad1836.h1
-rw-r--r--sound/soc/codecs/ad1938.c228
-rw-r--r--sound/soc/codecs/ak4104.c4
-rw-r--r--sound/soc/codecs/cs4270.c91
-rw-r--r--sound/soc/codecs/da7210.c589
-rw-r--r--sound/soc/codecs/da7210.h24
-rw-r--r--sound/soc/codecs/tlv320aic3x.c75
-rw-r--r--sound/soc/codecs/tlv320dac33.c311
-rw-r--r--sound/soc/codecs/tpa6130a2.c115
-rw-r--r--sound/soc/codecs/twl4030.c33
-rw-r--r--sound/soc/codecs/twl4030.h2
-rw-r--r--sound/soc/codecs/wm2000.c888
-rw-r--r--sound/soc/codecs/wm2000.h79
-rw-r--r--sound/soc/codecs/wm8727.c66
-rw-r--r--sound/soc/codecs/wm8731.c3
-rw-r--r--sound/soc/codecs/wm8753.c8
-rw-r--r--sound/soc/codecs/wm8776.c2
-rw-r--r--sound/soc/codecs/wm8904.c2656
-rw-r--r--sound/soc/codecs/wm8904.h1681
-rw-r--r--sound/soc/codecs/wm8955.c1151
-rw-r--r--sound/soc/codecs/wm8955.h489
-rw-r--r--sound/soc/codecs/wm8961.c3
-rw-r--r--sound/soc/codecs/wm8974.c12
-rw-r--r--sound/soc/codecs/wm8974.h12
-rw-r--r--sound/soc/codecs/wm8978.c1149
-rw-r--r--sound/soc/codecs/wm8978.h86
-rw-r--r--sound/soc/codecs/wm8990.c8
-rw-r--r--sound/soc/codecs/wm8993.c307
-rw-r--r--sound/soc/codecs/wm8994.c3867
-rw-r--r--sound/soc/codecs/wm8994.h26
-rw-r--r--sound/soc/codecs/wm9713.c64
-rw-r--r--sound/soc/codecs/wm_hubs.c148
-rw-r--r--sound/soc/codecs/wm_hubs.h6
36 files changed, 13727 insertions, 593 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 52b005f8fed4..1743d565e996 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -23,6 +23,7 @@ config SND_SOC_ALL_CODECS
23 select SND_SOC_AK4671 if I2C 23 select SND_SOC_AK4671 if I2C
24 select SND_SOC_CS4270 if I2C 24 select SND_SOC_CS4270 if I2C
25 select SND_SOC_MAX9877 if I2C 25 select SND_SOC_MAX9877 if I2C
26 select SND_SOC_DA7210 if I2C
26 select SND_SOC_PCM3008 27 select SND_SOC_PCM3008
27 select SND_SOC_SPDIF 28 select SND_SOC_SPDIF
28 select SND_SOC_SSM2602 if I2C 29 select SND_SOC_SSM2602 if I2C
@@ -35,6 +36,7 @@ config SND_SOC_ALL_CODECS
35 select SND_SOC_TWL4030 if TWL4030_CORE 36 select SND_SOC_TWL4030 if TWL4030_CORE
36 select SND_SOC_UDA134X 37 select SND_SOC_UDA134X
37 select SND_SOC_UDA1380 if I2C 38 select SND_SOC_UDA1380 if I2C
39 select SND_SOC_WM2000 if I2C
38 select SND_SOC_WM8350 if MFD_WM8350 40 select SND_SOC_WM8350 if MFD_WM8350
39 select SND_SOC_WM8400 if MFD_WM8400 41 select SND_SOC_WM8400 if MFD_WM8400
40 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 42 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -49,14 +51,18 @@ config SND_SOC_ALL_CODECS
49 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 51 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
50 select SND_SOC_WM8900 if I2C 52 select SND_SOC_WM8900 if I2C
51 select SND_SOC_WM8903 if I2C 53 select SND_SOC_WM8903 if I2C
54 select SND_SOC_WM8904 if I2C
52 select SND_SOC_WM8940 if I2C 55 select SND_SOC_WM8940 if I2C
56 select SND_SOC_WM8955 if I2C
53 select SND_SOC_WM8960 if I2C 57 select SND_SOC_WM8960 if I2C
54 select SND_SOC_WM8961 if I2C 58 select SND_SOC_WM8961 if I2C
55 select SND_SOC_WM8971 if I2C 59 select SND_SOC_WM8971 if I2C
56 select SND_SOC_WM8974 if I2C 60 select SND_SOC_WM8974 if I2C
61 select SND_SOC_WM8978 if I2C
57 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 62 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
58 select SND_SOC_WM8990 if I2C 63 select SND_SOC_WM8990 if I2C
59 select SND_SOC_WM8993 if I2C 64 select SND_SOC_WM8993 if I2C
65 select SND_SOC_WM8994 if MFD_WM8994
60 select SND_SOC_WM9081 if I2C 66 select SND_SOC_WM9081 if I2C
61 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 67 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
62 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 68 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -112,6 +118,9 @@ config SND_SOC_AK4671
112config SND_SOC_CS4270 118config SND_SOC_CS4270
113 tristate 119 tristate
114 120
121config SND_SOC_DA7210
122 tristate
123
115# Cirrus Logic CS4270 Codec VD = 3.3V Errata 124# Cirrus Logic CS4270 Codec VD = 3.3V Errata
116# Select if you are affected by the errata where the part will not function 125# Select if you are affected by the errata where the part will not function
117# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will 126# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
@@ -203,9 +212,15 @@ config SND_SOC_WM8900
203config SND_SOC_WM8903 212config SND_SOC_WM8903
204 tristate 213 tristate
205 214
215config SND_SOC_WM8904
216 tristate
217
206config SND_SOC_WM8940 218config SND_SOC_WM8940
207 tristate 219 tristate
208 220
221config SND_SOC_WM8955
222 tristate
223
209config SND_SOC_WM8960 224config SND_SOC_WM8960
210 tristate 225 tristate
211 226
@@ -218,6 +233,9 @@ config SND_SOC_WM8971
218config SND_SOC_WM8974 233config SND_SOC_WM8974
219 tristate 234 tristate
220 235
236config SND_SOC_WM8978
237 tristate
238
221config SND_SOC_WM8988 239config SND_SOC_WM8988
222 tristate 240 tristate
223 241
@@ -227,6 +245,9 @@ config SND_SOC_WM8990
227config SND_SOC_WM8993 245config SND_SOC_WM8993
228 tristate 246 tristate
229 247
248config SND_SOC_WM8994
249 tristate
250
230config SND_SOC_WM9081 251config SND_SOC_WM9081
231 tristate 252 tristate
232 253
@@ -245,3 +266,6 @@ config SND_SOC_MAX9877
245 266
246config SND_SOC_TPA6130A2 267config SND_SOC_TPA6130A2
247 tristate 268 tristate
269
270config SND_SOC_WM2000
271 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index dbaecb133ac7..dd5ce6df6292 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -10,6 +10,7 @@ snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o 10snd-soc-ak4671-objs := ak4671.o
11snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
12snd-soc-cx20442-objs := cx20442.o 12snd-soc-cx20442-objs := cx20442.o
13snd-soc-da7210-objs := da7210.o
13snd-soc-l3-objs := l3.o 14snd-soc-l3-objs := l3.o
14snd-soc-pcm3008-objs := pcm3008.o 15snd-soc-pcm3008-objs := pcm3008.o
15snd-soc-spdif-objs := spdif_transciever.o 16snd-soc-spdif-objs := spdif_transciever.o
@@ -36,14 +37,18 @@ snd-soc-wm8753-objs := wm8753.o
36snd-soc-wm8776-objs := wm8776.o 37snd-soc-wm8776-objs := wm8776.o
37snd-soc-wm8900-objs := wm8900.o 38snd-soc-wm8900-objs := wm8900.o
38snd-soc-wm8903-objs := wm8903.o 39snd-soc-wm8903-objs := wm8903.o
40snd-soc-wm8904-objs := wm8904.o
39snd-soc-wm8940-objs := wm8940.o 41snd-soc-wm8940-objs := wm8940.o
42snd-soc-wm8955-objs := wm8955.o
40snd-soc-wm8960-objs := wm8960.o 43snd-soc-wm8960-objs := wm8960.o
41snd-soc-wm8961-objs := wm8961.o 44snd-soc-wm8961-objs := wm8961.o
42snd-soc-wm8971-objs := wm8971.o 45snd-soc-wm8971-objs := wm8971.o
43snd-soc-wm8974-objs := wm8974.o 46snd-soc-wm8974-objs := wm8974.o
47snd-soc-wm8978-objs := wm8978.o
44snd-soc-wm8988-objs := wm8988.o 48snd-soc-wm8988-objs := wm8988.o
45snd-soc-wm8990-objs := wm8990.o 49snd-soc-wm8990-objs := wm8990.o
46snd-soc-wm8993-objs := wm8993.o 50snd-soc-wm8993-objs := wm8993.o
51snd-soc-wm8994-objs := wm8994.o
47snd-soc-wm9081-objs := wm9081.o 52snd-soc-wm9081-objs := wm9081.o
48snd-soc-wm9705-objs := wm9705.o 53snd-soc-wm9705-objs := wm9705.o
49snd-soc-wm9712-objs := wm9712.o 54snd-soc-wm9712-objs := wm9712.o
@@ -53,6 +58,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
53# Amp 58# Amp
54snd-soc-max9877-objs := max9877.o 59snd-soc-max9877-objs := max9877.o
55snd-soc-tpa6130a2-objs := tpa6130a2.o 60snd-soc-tpa6130a2-objs := tpa6130a2.o
61snd-soc-wm2000-objs := wm2000.o
56 62
57obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 63obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
58obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 64obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
@@ -66,6 +72,7 @@ obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
66obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 72obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
67obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 73obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
68obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 74obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
75obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
69obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 76obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
70obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 77obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
71obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 78obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
@@ -92,14 +99,18 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
92obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 99obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
93obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 100obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
94obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 101obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
95obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 102obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
96obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
97obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 103obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
104obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
98obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 105obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
99obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o 106obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
107obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
108obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
109obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
100obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 110obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
101obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 111obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
102obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 112obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
113obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
103obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 114obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
104obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 115obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
105obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 116obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
@@ -109,3 +120,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
109# Amp 120# Amp
110obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 121obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
111obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 122obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
123obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 2c18e3d1b71e..3c80137d5938 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -171,57 +171,35 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
171 return 0; 171 return 0;
172} 172}
173 173
174 174#ifdef CONFIG_PM
175/* 175static int ad1836_soc_suspend(struct platform_device *pdev,
176 * interface to read/write ad1836 register 176 pm_message_t state)
177 */
178#define AD1836_SPI_REG_SHFT 12
179#define AD1836_SPI_READ (1 << 11)
180#define AD1836_SPI_VAL_MSK 0x3FF
181
182/*
183 * write to the ad1836 register space
184 */
185
186static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg,
187 unsigned int value)
188{ 177{
189 u16 *reg_cache = codec->reg_cache; 178 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
190 int ret = 0; 179 struct snd_soc_codec *codec = socdev->card->codec;
191 180
192 if (value != reg_cache[reg]) { 181 /* reset clock control mode */
193 unsigned short buf; 182 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
194 struct spi_transfer t = { 183 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
195 .tx_buf = &buf,
196 .len = 2,
197 };
198 struct spi_message m;
199
200 buf = (reg << AD1836_SPI_REG_SHFT) |
201 (value & AD1836_SPI_VAL_MSK);
202 spi_message_init(&m);
203 spi_message_add_tail(&t, &m);
204 ret = spi_sync(codec->control_data, &m);
205 if (ret == 0)
206 reg_cache[reg] = value;
207 }
208 184
209 return ret; 185 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
210} 186}
211 187
212/* 188static int ad1836_soc_resume(struct platform_device *pdev)
213 * read from the ad1836 register space cache
214 */
215static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec,
216 unsigned int reg)
217{ 189{
218 u16 *reg_cache = codec->reg_cache; 190 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
191 struct snd_soc_codec *codec = socdev->card->codec;
219 192
220 if (reg >= codec->reg_cache_size) 193 /* restore clock control mode */
221 return -EINVAL; 194 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
195 adc_ctrl2 |= AD1836_ADC_AUX;
222 196
223 return reg_cache[reg]; 197 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
224} 198}
199#else
200#define ad1836_soc_suspend NULL
201#define ad1836_soc_resume NULL
202#endif
225 203
226static int __devinit ad1836_spi_probe(struct spi_device *spi) 204static int __devinit ad1836_spi_probe(struct spi_device *spi)
227{ 205{
@@ -306,32 +284,38 @@ static int ad1836_register(struct ad1836_priv *ad1836)
306 codec->owner = THIS_MODULE; 284 codec->owner = THIS_MODULE;
307 codec->dai = &ad1836_dai; 285 codec->dai = &ad1836_dai;
308 codec->num_dai = 1; 286 codec->num_dai = 1;
309 codec->write = ad1836_write_reg;
310 codec->read = ad1836_read_reg_cache;
311 INIT_LIST_HEAD(&codec->dapm_widgets); 287 INIT_LIST_HEAD(&codec->dapm_widgets);
312 INIT_LIST_HEAD(&codec->dapm_paths); 288 INIT_LIST_HEAD(&codec->dapm_paths);
313 289
314 ad1836_dai.dev = codec->dev; 290 ad1836_dai.dev = codec->dev;
315 ad1836_codec = codec; 291 ad1836_codec = codec;
316 292
293 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
294 if (ret < 0) {
295 dev_err(codec->dev, "failed to set cache I/O: %d\n",
296 ret);
297 kfree(ad1836);
298 return ret;
299 }
300
317 /* default setting for ad1836 */ 301 /* default setting for ad1836 */
318 /* de-emphasis: 48kHz, power-on dac */ 302 /* de-emphasis: 48kHz, power-on dac */
319 codec->write(codec, AD1836_DAC_CTRL1, 0x300); 303 snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
320 /* unmute dac channels */ 304 /* unmute dac channels */
321 codec->write(codec, AD1836_DAC_CTRL2, 0x0); 305 snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
322 /* high-pass filter enable, power-on adc */ 306 /* high-pass filter enable, power-on adc */
323 codec->write(codec, AD1836_ADC_CTRL1, 0x100); 307 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
324 /* unmute adc channles, adc aux mode */ 308 /* unmute adc channles, adc aux mode */
325 codec->write(codec, AD1836_ADC_CTRL2, 0x180); 309 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
326 /* left/right diff:PGA/MUX */ 310 /* left/right diff:PGA/MUX */
327 codec->write(codec, AD1836_ADC_CTRL3, 0x3A); 311 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
328 /* volume */ 312 /* volume */
329 codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); 313 snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF);
330 codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); 314 snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF);
331 codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); 315 snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF);
332 codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); 316 snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF);
333 codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); 317 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
334 codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); 318 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
335 319
336 ret = snd_soc_register_codec(codec); 320 ret = snd_soc_register_codec(codec);
337 if (ret != 0) { 321 if (ret != 0) {
@@ -404,6 +388,8 @@ static int ad1836_remove(struct platform_device *pdev)
404struct snd_soc_codec_device soc_codec_dev_ad1836 = { 388struct snd_soc_codec_device soc_codec_dev_ad1836 = {
405 .probe = ad1836_probe, 389 .probe = ad1836_probe,
406 .remove = ad1836_remove, 390 .remove = ad1836_remove,
391 .suspend = ad1836_soc_suspend,
392 .resume = ad1836_soc_resume,
407}; 393};
408EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836); 394EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
409 395
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index 7660ee6973c0..e9d90d3951c5 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -54,6 +54,7 @@
54#define AD1836_ADC_SERFMT_MASK (7 << 6) 54#define AD1836_ADC_SERFMT_MASK (7 << 6)
55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) 55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) 56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
57#define AD1836_ADC_AUX (0x6 << 6)
57 58
58#define AD1836_ADC_CTRL3 14 59#define AD1836_ADC_CTRL3 14
59 60
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index 5d489186c05b..c233810d463d 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -46,6 +46,11 @@ struct ad1938_priv {
46 u8 reg_cache[AD1938_NUM_REGS]; 46 u8 reg_cache[AD1938_NUM_REGS];
47}; 47};
48 48
49/* ad1938 register cache & default register settings */
50static const u8 ad1938_reg[AD1938_NUM_REGS] = {
51 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
52};
53
49static struct snd_soc_codec *ad1938_codec; 54static struct snd_soc_codec *ad1938_codec;
50struct snd_soc_codec_device soc_codec_dev_ad1938; 55struct snd_soc_codec_device soc_codec_dev_ad1938;
51static int ad1938_register(struct ad1938_priv *ad1938); 56static int ad1938_register(struct ad1938_priv *ad1938);
@@ -97,6 +102,7 @@ static const struct snd_kcontrol_new ad1938_snd_controls[] = {
97static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = { 102static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
98 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1), 103 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
99 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 104 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
105 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD1938_PLL_CLK_CTRL0, 0, 1, NULL, 0),
100 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0), 106 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
101 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 107 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
102 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 108 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
@@ -107,6 +113,8 @@ static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
107}; 113};
108 114
109static const struct snd_soc_dapm_route audio_paths[] = { 115static const struct snd_soc_dapm_route audio_paths[] = {
116 { "DAC", NULL, "PLL_PWR" },
117 { "ADC", NULL, "PLL_PWR" },
110 { "DAC", NULL, "ADC_PWR" }, 118 { "DAC", NULL, "ADC_PWR" },
111 { "ADC", NULL, "ADC_PWR" }, 119 { "ADC", NULL, "ADC_PWR" },
112 { "DAC1OUT", "DAC1 Switch", "DAC" }, 120 { "DAC1OUT", "DAC1 Switch", "DAC" },
@@ -126,30 +134,20 @@ static int ad1938_mute(struct snd_soc_dai *dai, int mute)
126 struct snd_soc_codec *codec = dai->codec; 134 struct snd_soc_codec *codec = dai->codec;
127 int reg; 135 int reg;
128 136
129 reg = codec->read(codec, AD1938_DAC_CTRL2); 137 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
130 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg & 138 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
131 (~AD1938_DAC_MASTER_MUTE); 139 (~AD1938_DAC_MASTER_MUTE);
132 codec->write(codec, AD1938_DAC_CTRL2, reg); 140 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
133
134 return 0;
135}
136
137static inline int ad1938_pll_powerctrl(struct snd_soc_codec *codec, int cmd)
138{
139 int reg = codec->read(codec, AD1938_PLL_CLK_CTRL0);
140 reg = (cmd > 0) ? reg & (~AD1938_PLL_POWERDOWN) : reg |
141 AD1938_PLL_POWERDOWN;
142 codec->write(codec, AD1938_PLL_CLK_CTRL0, reg);
143 141
144 return 0; 142 return 0;
145} 143}
146 144
147static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 145static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
148 unsigned int mask, int slots, int width) 146 unsigned int rx_mask, int slots, int width)
149{ 147{
150 struct snd_soc_codec *codec = dai->codec; 148 struct snd_soc_codec *codec = dai->codec;
151 int dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 149 int dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
152 int adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 150 int adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
153 151
154 dac_reg &= ~AD1938_DAC_CHAN_MASK; 152 dac_reg &= ~AD1938_DAC_CHAN_MASK;
155 adc_reg &= ~AD1938_ADC_CHAN_MASK; 153 adc_reg &= ~AD1938_ADC_CHAN_MASK;
@@ -175,8 +173,8 @@ static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
175 return -EINVAL; 173 return -EINVAL;
176 } 174 }
177 175
178 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 176 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
179 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 177 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
180 178
181 return 0; 179 return 0;
182} 180}
@@ -187,8 +185,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
187 struct snd_soc_codec *codec = codec_dai->codec; 185 struct snd_soc_codec *codec = codec_dai->codec;
188 int adc_reg, dac_reg; 186 int adc_reg, dac_reg;
189 187
190 adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 188 adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
191 dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 189 dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
192 190
193 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S 191 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
194 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) 192 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
@@ -265,8 +263,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
265 return -EINVAL; 263 return -EINVAL;
266 } 264 }
267 265
268 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 266 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
269 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 267 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
270 268
271 return 0; 269 return 0;
272} 270}
@@ -295,134 +293,13 @@ static int ad1938_hw_params(struct snd_pcm_substream *substream,
295 break; 293 break;
296 } 294 }
297 295
298 reg = codec->read(codec, AD1938_DAC_CTRL2); 296 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
299 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len; 297 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
300 codec->write(codec, AD1938_DAC_CTRL2, reg); 298 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
301 299
302 reg = codec->read(codec, AD1938_ADC_CTRL1); 300 reg = snd_soc_read(codec, AD1938_ADC_CTRL1);
303 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len; 301 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
304 codec->write(codec, AD1938_ADC_CTRL1, reg); 302 snd_soc_write(codec, AD1938_ADC_CTRL1, reg);
305
306 return 0;
307}
308
309static int ad1938_set_bias_level(struct snd_soc_codec *codec,
310 enum snd_soc_bias_level level)
311{
312 switch (level) {
313 case SND_SOC_BIAS_ON:
314 ad1938_pll_powerctrl(codec, 1);
315 break;
316 case SND_SOC_BIAS_PREPARE:
317 break;
318 case SND_SOC_BIAS_STANDBY:
319 case SND_SOC_BIAS_OFF:
320 ad1938_pll_powerctrl(codec, 0);
321 break;
322 }
323 codec->bias_level = level;
324 return 0;
325}
326
327/*
328 * interface to read/write ad1938 register
329 */
330
331#define AD1938_SPI_ADDR 0x4
332#define AD1938_SPI_READ 0x1
333#define AD1938_SPI_BUFLEN 3
334
335/*
336 * write to the ad1938 register space
337 */
338
339static int ad1938_write_reg(struct snd_soc_codec *codec, unsigned int reg,
340 unsigned int value)
341{
342 u8 *reg_cache = codec->reg_cache;
343 int ret = 0;
344
345 if (value != reg_cache[reg]) {
346 uint8_t buf[AD1938_SPI_BUFLEN];
347 struct spi_transfer t = {
348 .tx_buf = buf,
349 .len = AD1938_SPI_BUFLEN,
350 };
351 struct spi_message m;
352
353 buf[0] = AD1938_SPI_ADDR << 1;
354 buf[1] = reg;
355 buf[2] = value;
356 spi_message_init(&m);
357 spi_message_add_tail(&t, &m);
358 ret = spi_sync(codec->control_data, &m);
359 if (ret == 0)
360 reg_cache[reg] = value;
361 }
362
363 return ret;
364}
365
366/*
367 * read from the ad1938 register space cache
368 */
369
370static unsigned int ad1938_read_reg_cache(struct snd_soc_codec *codec,
371 unsigned int reg)
372{
373 u8 *reg_cache = codec->reg_cache;
374
375 if (reg >= codec->reg_cache_size)
376 return -EINVAL;
377
378 return reg_cache[reg];
379}
380
381/*
382 * read from the ad1938 register space
383 */
384
385static unsigned int ad1938_read_reg(struct snd_soc_codec *codec,
386 unsigned int reg)
387{
388 char w_buf[AD1938_SPI_BUFLEN];
389 char r_buf[AD1938_SPI_BUFLEN];
390 int ret;
391
392 struct spi_transfer t = {
393 .tx_buf = w_buf,
394 .rx_buf = r_buf,
395 .len = AD1938_SPI_BUFLEN,
396 };
397 struct spi_message m;
398
399 w_buf[0] = (AD1938_SPI_ADDR << 1) | AD1938_SPI_READ;
400 w_buf[1] = reg;
401 w_buf[2] = 0;
402
403 spi_message_init(&m);
404 spi_message_add_tail(&t, &m);
405 ret = spi_sync(codec->control_data, &m);
406 if (ret == 0)
407 return r_buf[2];
408 else
409 return -EIO;
410}
411
412static int ad1938_fill_cache(struct snd_soc_codec *codec)
413{
414 int i;
415 u8 *reg_cache = codec->reg_cache;
416 struct spi_device *spi = codec->control_data;
417
418 for (i = 0; i < codec->reg_cache_size; i++) {
419 int ret = ad1938_read_reg(codec, i);
420 if (ret == -EIO) {
421 dev_err(&spi->dev, "AD1938 SPI read failure\n");
422 return ret;
423 }
424 reg_cache[i] = ret;
425 }
426 303
427 return 0; 304 return 0;
428} 305}
@@ -512,32 +389,37 @@ static int ad1938_register(struct ad1938_priv *ad1938)
512 codec->owner = THIS_MODULE; 389 codec->owner = THIS_MODULE;
513 codec->dai = &ad1938_dai; 390 codec->dai = &ad1938_dai;
514 codec->num_dai = 1; 391 codec->num_dai = 1;
515 codec->write = ad1938_write_reg;
516 codec->read = ad1938_read_reg_cache;
517 codec->set_bias_level = ad1938_set_bias_level;
518 INIT_LIST_HEAD(&codec->dapm_widgets); 392 INIT_LIST_HEAD(&codec->dapm_widgets);
519 INIT_LIST_HEAD(&codec->dapm_paths); 393 INIT_LIST_HEAD(&codec->dapm_paths);
520 394
521 ad1938_dai.dev = codec->dev; 395 ad1938_dai.dev = codec->dev;
522 ad1938_codec = codec; 396 ad1938_codec = codec;
523 397
398 memcpy(codec->reg_cache, ad1938_reg, AD1938_NUM_REGS);
399
400 ret = snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_SPI);
401 if (ret < 0) {
402 dev_err(codec->dev, "failed to set cache I/O: %d\n",
403 ret);
404 kfree(ad1938);
405 return ret;
406 }
407
524 /* default setting for ad1938 */ 408 /* default setting for ad1938 */
525 409
526 /* unmute dac channels */ 410 /* unmute dac channels */
527 codec->write(codec, AD1938_DAC_CHNL_MUTE, 0x0); 411 snd_soc_write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
528 /* de-emphasis: 48kHz, powedown dac */ 412 /* de-emphasis: 48kHz, powedown dac */
529 codec->write(codec, AD1938_DAC_CTRL2, 0x1A); 413 snd_soc_write(codec, AD1938_DAC_CTRL2, 0x1A);
530 /* powerdown dac, dac in tdm mode */ 414 /* powerdown dac, dac in tdm mode */
531 codec->write(codec, AD1938_DAC_CTRL0, 0x41); 415 snd_soc_write(codec, AD1938_DAC_CTRL0, 0x41);
532 /* high-pass filter enable */ 416 /* high-pass filter enable */
533 codec->write(codec, AD1938_ADC_CTRL0, 0x3); 417 snd_soc_write(codec, AD1938_ADC_CTRL0, 0x3);
534 /* sata delay=1, adc aux mode */ 418 /* sata delay=1, adc aux mode */
535 codec->write(codec, AD1938_ADC_CTRL1, 0x43); 419 snd_soc_write(codec, AD1938_ADC_CTRL1, 0x43);
536 /* pll input: mclki/xi */ 420 /* pll input: mclki/xi */
537 codec->write(codec, AD1938_PLL_CLK_CTRL0, 0x9D); 421 snd_soc_write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
538 codec->write(codec, AD1938_PLL_CLK_CTRL1, 0x04); 422 snd_soc_write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
539
540 ad1938_fill_cache(codec);
541 423
542 ret = snd_soc_register_codec(codec); 424 ret = snd_soc_register_codec(codec);
543 if (ret != 0) { 425 if (ret != 0) {
@@ -559,7 +441,6 @@ static int ad1938_register(struct ad1938_priv *ad1938)
559 441
560static void ad1938_unregister(struct ad1938_priv *ad1938) 442static void ad1938_unregister(struct ad1938_priv *ad1938)
561{ 443{
562 ad1938_set_bias_level(&ad1938->codec, SND_SOC_BIAS_OFF);
563 snd_soc_unregister_dai(&ad1938_dai); 444 snd_soc_unregister_dai(&ad1938_dai);
564 snd_soc_unregister_codec(&ad1938->codec); 445 snd_soc_unregister_codec(&ad1938->codec);
565 kfree(ad1938); 446 kfree(ad1938);
@@ -593,7 +474,6 @@ static int ad1938_probe(struct platform_device *pdev)
593 ARRAY_SIZE(ad1938_dapm_widgets)); 474 ARRAY_SIZE(ad1938_dapm_widgets));
594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 475 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
595 476
596 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
597 477
598pcm_err: 478pcm_err:
599 return ret; 479 return ret;
@@ -610,37 +490,9 @@ static int ad1938_remove(struct platform_device *pdev)
610 return 0; 490 return 0;
611} 491}
612 492
613#ifdef CONFIG_PM
614static int ad1938_suspend(struct platform_device *pdev,
615 pm_message_t state)
616{
617 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
618 struct snd_soc_codec *codec = socdev->card->codec;
619
620 ad1938_set_bias_level(codec, SND_SOC_BIAS_OFF);
621 return 0;
622}
623
624static int ad1938_resume(struct platform_device *pdev)
625{
626 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
627 struct snd_soc_codec *codec = socdev->card->codec;
628
629 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
630 ad1938_set_bias_level(codec, SND_SOC_BIAS_ON);
631
632 return 0;
633}
634#else
635#define ad1938_suspend NULL
636#define ad1938_resume NULL
637#endif
638
639struct snd_soc_codec_device soc_codec_dev_ad1938 = { 493struct snd_soc_codec_device soc_codec_dev_ad1938 = {
640 .probe = ad1938_probe, 494 .probe = ad1938_probe,
641 .remove = ad1938_remove, 495 .remove = ad1938_remove,
642 .suspend = ad1938_suspend,
643 .resume = ad1938_resume,
644}; 496};
645EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938); 497EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
646 498
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 3a14c6fc4f5e..b9ef7e45891d 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -185,9 +185,7 @@ struct snd_soc_dai ak4104_dai = {
185 .stream_name = "Playback", 185 .stream_name = "Playback",
186 .channels_min = 2, 186 .channels_min = 2,
187 .channels_max = 2, 187 .channels_max = 2,
188 .rates = SNDRV_PCM_RATE_44100 | 188 .rates = SNDRV_PCM_RATE_8000_192000,
189 SNDRV_PCM_RATE_48000 |
190 SNDRV_PCM_RATE_32000,
191 .formats = SNDRV_PCM_FMTBIT_S16_LE | 189 .formats = SNDRV_PCM_FMTBIT_S16_LE |
192 SNDRV_PCM_FMTBIT_S24_3LE | 190 SNDRV_PCM_FMTBIT_S24_3LE |
193 SNDRV_PCM_FMTBIT_S24_LE 191 SNDRV_PCM_FMTBIT_S24_LE
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ffe122d1cd76..dfbeb2db61b3 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -28,6 +28,7 @@
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/regulator/consumer.h>
31 32
32#include "cs4270.h" 33#include "cs4270.h"
33 34
@@ -106,6 +107,10 @@
106#define CS4270_MUTE_DAC_A 0x01 107#define CS4270_MUTE_DAC_A 0x01
107#define CS4270_MUTE_DAC_B 0x02 108#define CS4270_MUTE_DAC_B 0x02
108 109
110static const char *supply_names[] = {
111 "va", "vd", "vlc"
112};
113
109/* Private data for the CS4270 */ 114/* Private data for the CS4270 */
110struct cs4270_private { 115struct cs4270_private {
111 struct snd_soc_codec codec; 116 struct snd_soc_codec codec;
@@ -114,6 +119,9 @@ struct cs4270_private {
114 unsigned int mode; /* The mode (I2S or left-justified) */ 119 unsigned int mode; /* The mode (I2S or left-justified) */
115 unsigned int slave_mode; 120 unsigned int slave_mode;
116 unsigned int manual_mute; 121 unsigned int manual_mute;
122
123 /* power domain regulators */
124 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
117}; 125};
118 126
119/** 127/**
@@ -192,6 +200,11 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
192 * This function must be called by the machine driver's 'startup' function, 200 * This function must be called by the machine driver's 'startup' function,
193 * otherwise the list of supported sample rates will not be available in 201 * otherwise the list of supported sample rates will not be available in
194 * time for ALSA. 202 * time for ALSA.
203 *
204 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
205 * theoretically possible sample rates to be enabled. Call it again with a
206 * proper value set one the external clock is set (most probably you would do
207 * that from a machine's driver 'hw_param' hook.
195 */ 208 */
196static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, 209static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
197 int clk_id, unsigned int freq, int dir) 210 int clk_id, unsigned int freq, int dir)
@@ -205,20 +218,27 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
205 218
206 cs4270->mclk = freq; 219 cs4270->mclk = freq;
207 220
208 for (i = 0; i < NUM_MCLK_RATIOS; i++) { 221 if (cs4270->mclk) {
209 unsigned int rate = freq / cs4270_mode_ratios[i].ratio; 222 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
210 rates |= snd_pcm_rate_to_rate_bit(rate); 223 unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
211 if (rate < rate_min) 224 rates |= snd_pcm_rate_to_rate_bit(rate);
212 rate_min = rate; 225 if (rate < rate_min)
213 if (rate > rate_max) 226 rate_min = rate;
214 rate_max = rate; 227 if (rate > rate_max)
215 } 228 rate_max = rate;
216 /* FIXME: soc should support a rate list */ 229 }
217 rates &= ~SNDRV_PCM_RATE_KNOT; 230 /* FIXME: soc should support a rate list */
231 rates &= ~SNDRV_PCM_RATE_KNOT;
218 232
219 if (!rates) { 233 if (!rates) {
220 dev_err(codec->dev, "could not find a valid sample rate\n"); 234 dev_err(codec->dev, "could not find a valid sample rate\n");
221 return -EINVAL; 235 return -EINVAL;
236 }
237 } else {
238 /* enable all possible rates */
239 rates = SNDRV_PCM_RATE_8000_192000;
240 rate_min = 8000;
241 rate_max = 192000;
222 } 242 }
223 243
224 codec_dai->playback.rates = rates; 244 codec_dai->playback.rates = rates;
@@ -579,7 +599,8 @@ static int cs4270_probe(struct platform_device *pdev)
579{ 599{
580 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 600 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
581 struct snd_soc_codec *codec = cs4270_codec; 601 struct snd_soc_codec *codec = cs4270_codec;
582 int ret; 602 struct cs4270_private *cs4270 = codec->private_data;
603 int i, ret;
583 604
584 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 605 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
585 socdev->card->codec = codec; 606 socdev->card->codec = codec;
@@ -599,8 +620,26 @@ static int cs4270_probe(struct platform_device *pdev)
599 goto error_free_pcms; 620 goto error_free_pcms;
600 } 621 }
601 622
623 /* get the power supply regulators */
624 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
625 cs4270->supplies[i].supply = supply_names[i];
626
627 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
628 cs4270->supplies);
629 if (ret < 0)
630 goto error_free_pcms;
631
632 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
633 cs4270->supplies);
634 if (ret < 0)
635 goto error_free_regulators;
636
602 return 0; 637 return 0;
603 638
639error_free_regulators:
640 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
641 cs4270->supplies);
642
604error_free_pcms: 643error_free_pcms:
605 snd_soc_free_pcms(socdev); 644 snd_soc_free_pcms(socdev);
606 645
@@ -616,8 +655,12 @@ error_free_pcms:
616static int cs4270_remove(struct platform_device *pdev) 655static int cs4270_remove(struct platform_device *pdev)
617{ 656{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 657 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
658 struct snd_soc_codec *codec = cs4270_codec;
659 struct cs4270_private *cs4270 = codec->private_data;
619 660
620 snd_soc_free_pcms(socdev); 661 snd_soc_free_pcms(socdev);
662 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
663 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
621 664
622 return 0; 665 return 0;
623}; 666};
@@ -799,17 +842,33 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
799static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 842static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
800{ 843{
801 struct snd_soc_codec *codec = cs4270_codec; 844 struct snd_soc_codec *codec = cs4270_codec;
802 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; 845 struct cs4270_private *cs4270 = codec->private_data;
846 int reg, ret;
803 847
804 return snd_soc_write(codec, CS4270_PWRCTL, reg); 848 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
849 if (reg < 0)
850 return reg;
851
852 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
853 if (ret < 0)
854 return ret;
855
856 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
857 cs4270->supplies);
858
859 return 0;
805} 860}
806 861
807static int cs4270_soc_resume(struct platform_device *pdev) 862static int cs4270_soc_resume(struct platform_device *pdev)
808{ 863{
809 struct snd_soc_codec *codec = cs4270_codec; 864 struct snd_soc_codec *codec = cs4270_codec;
865 struct cs4270_private *cs4270 = codec->private_data;
810 struct i2c_client *i2c_client = codec->control_data; 866 struct i2c_client *i2c_client = codec->control_data;
811 int reg; 867 int reg;
812 868
869 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
870 cs4270->supplies);
871
813 /* In case the device was put to hard reset during sleep, we need to 872 /* In case the device was put to hard reset during sleep, we need to
814 * wait 500ns here before any I2C communication. */ 873 * wait 500ns here before any I2C communication. */
815 ndelay(500); 874 ndelay(500);
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
new file mode 100644
index 000000000000..cf2975a7294a
--- /dev/null
+++ b/sound/soc/codecs/da7210.c
@@ -0,0 +1,589 @@
1/*
2 * DA7210 ALSA Soc codec driver
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h>
32#include <sound/initval.h>
33#include <asm/div64.h>
34
35#include "da7210.h"
36
37/* DA7210 register space */
38#define DA7210_STATUS 0x02
39#define DA7210_STARTUP1 0x03
40#define DA7210_MIC_L 0x07
41#define DA7210_MIC_R 0x08
42#define DA7210_INMIX_L 0x0D
43#define DA7210_INMIX_R 0x0E
44#define DA7210_ADC_HPF 0x0F
45#define DA7210_ADC 0x10
46#define DA7210_DAC_HPF 0x14
47#define DA7210_DAC_L 0x15
48#define DA7210_DAC_R 0x16
49#define DA7210_DAC_SEL 0x17
50#define DA7210_OUTMIX_L 0x1C
51#define DA7210_OUTMIX_R 0x1D
52#define DA7210_HP_L_VOL 0x21
53#define DA7210_HP_R_VOL 0x22
54#define DA7210_HP_CFG 0x23
55#define DA7210_DAI_SRC_SEL 0x25
56#define DA7210_DAI_CFG1 0x26
57#define DA7210_DAI_CFG3 0x28
58#define DA7210_PLL_DIV3 0x2B
59#define DA7210_PLL 0x2C
60
61/* STARTUP1 bit fields */
62#define DA7210_SC_MST_EN (1 << 0)
63
64/* MIC_L bit fields */
65#define DA7210_MICBIAS_EN (1 << 6)
66#define DA7210_MIC_L_EN (1 << 7)
67
68/* MIC_R bit fields */
69#define DA7210_MIC_R_EN (1 << 7)
70
71/* INMIX_L bit fields */
72#define DA7210_IN_L_EN (1 << 7)
73
74/* INMIX_R bit fields */
75#define DA7210_IN_R_EN (1 << 7)
76
77/* ADC_HPF bit fields */
78#define DA7210_ADC_VOICE_EN (1 << 7)
79
80/* ADC bit fields */
81#define DA7210_ADC_L_EN (1 << 3)
82#define DA7210_ADC_R_EN (1 << 7)
83
84/* DAC_HPF fields */
85#define DA7210_DAC_VOICE_EN (1 << 7)
86
87/* DAC_SEL bit fields */
88#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
89#define DA7210_DAC_L_EN (1 << 3)
90#define DA7210_DAC_R_SRC_DAI_R (5 << 4)
91#define DA7210_DAC_R_EN (1 << 7)
92
93/* OUTMIX_L bit fields */
94#define DA7210_OUT_L_EN (1 << 7)
95
96/* OUTMIX_R bit fields */
97#define DA7210_OUT_R_EN (1 << 7)
98
99/* HP_CFG bit fields */
100#define DA7210_HP_2CAP_MODE (1 << 1)
101#define DA7210_HP_SENSE_EN (1 << 2)
102#define DA7210_HP_L_EN (1 << 3)
103#define DA7210_HP_MODE (1 << 6)
104#define DA7210_HP_R_EN (1 << 7)
105
106/* DAI_SRC_SEL bit fields */
107#define DA7210_DAI_OUT_L_SRC (6 << 0)
108#define DA7210_DAI_OUT_R_SRC (7 << 4)
109
110/* DAI_CFG1 bit fields */
111#define DA7210_DAI_WORD_S16_LE (0 << 0)
112#define DA7210_DAI_WORD_S24_LE (2 << 0)
113#define DA7210_DAI_FLEN_64BIT (1 << 2)
114#define DA7210_DAI_MODE_MASTER (1 << 7)
115
116/* DAI_CFG3 bit fields */
117#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
118#define DA7210_DAI_OE (1 << 3)
119#define DA7210_DAI_EN (1 << 7)
120
121/*PLL_DIV3 bit fields */
122#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
123#define DA7210_PLL_BYP (1 << 6)
124
125/* PLL bit fields */
126#define DA7210_PLL_FS_48000 (11 << 0)
127
128#define DA7210_VERSION "0.0.1"
129
130/* Codec private data */
131struct da7210_priv {
132 struct snd_soc_codec codec;
133};
134
135static struct snd_soc_codec *da7210_codec;
136
137/*
138 * Register cache
139 */
140static const u8 da7210_reg[] = {
141 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */
143 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */
144 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */
145 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */
146 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */
147 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */
148 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */
157 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */
158 0x00, /* R88 */
159};
160
161/*
162 * Read da7210 register cache
163 */
164static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
165{
166 u8 *cache = codec->reg_cache;
167 BUG_ON(reg > ARRAY_SIZE(da7210_reg));
168 return cache[reg];
169}
170
171/*
172 * Write to the da7210 register space
173 */
174static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
175{
176 u8 *cache = codec->reg_cache;
177 u8 data[2];
178
179 BUG_ON(codec->volatile_register);
180
181 data[0] = reg & 0xff;
182 data[1] = value & 0xff;
183
184 if (reg >= codec->reg_cache_size)
185 return -EIO;
186
187 if (2 != codec->hw_write(codec->control_data, data, 2))
188 return -EIO;
189
190 cache[reg] = value;
191 return 0;
192}
193
194/*
195 * Read from the da7210 register space.
196 */
197static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg)
198{
199 if (DA7210_STATUS == reg)
200 return i2c_smbus_read_byte_data(codec->control_data, reg);
201
202 return da7210_read_reg_cache(codec, reg);
203}
204
205static int da7210_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
207{
208 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
209 struct snd_soc_codec *codec = dai->codec;
210
211 if (is_play) {
212 /* PlayBack Volume 40 */
213 snd_soc_update_bits(codec, DA7210_HP_L_VOL, 0x3F, 40);
214 snd_soc_update_bits(codec, DA7210_HP_R_VOL, 0x3F, 40);
215
216 /* Enable Out */
217 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
218 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
219
220 } else {
221 /* Volume 7 */
222 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
223 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
224
225 /* Enable Mic */
226 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
227 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
228 }
229
230 return 0;
231}
232
233/*
234 * Set PCM DAI word length.
235 */
236static int da7210_hw_params(struct snd_pcm_substream *substream,
237 struct snd_pcm_hw_params *params,
238 struct snd_soc_dai *dai)
239{
240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 struct snd_soc_device *socdev = rtd->socdev;
242 struct snd_soc_codec *codec = socdev->card->codec;
243 u32 dai_cfg1;
244 u32 reg, mask;
245
246 /* set DAI source to Left and Right ADC */
247 da7210_write(codec, DA7210_DAI_SRC_SEL,
248 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
249
250 /* Enable DAI */
251 da7210_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
252
253 dai_cfg1 = 0xFC & da7210_read(codec, DA7210_DAI_CFG1);
254
255 switch (params_format(params)) {
256 case SNDRV_PCM_FORMAT_S16_LE:
257 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
258 break;
259 case SNDRV_PCM_FORMAT_S24_LE:
260 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
261 break;
262 default:
263 return -EINVAL;
264 }
265
266 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
267
268 /* FIXME
269 *
270 * It support 48K only now
271 */
272 switch (params_rate(params)) {
273 case 48000:
274 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
275 reg = DA7210_DAC_HPF;
276 mask = DA7210_DAC_VOICE_EN;
277 } else {
278 reg = DA7210_ADC_HPF;
279 mask = DA7210_ADC_VOICE_EN;
280 }
281 break;
282 default:
283 return -EINVAL;
284 }
285
286 snd_soc_update_bits(codec, reg, mask, 0);
287
288 return 0;
289}
290
291/*
292 * Set DAI mode and Format
293 */
294static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
295{
296 struct snd_soc_codec *codec = codec_dai->codec;
297 u32 dai_cfg1;
298 u32 dai_cfg3;
299
300 dai_cfg1 = 0x7f & da7210_read(codec, DA7210_DAI_CFG1);
301 dai_cfg3 = 0xfc & da7210_read(codec, DA7210_DAI_CFG3);
302
303 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
304 case SND_SOC_DAIFMT_CBM_CFM:
305 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
306 break;
307 default:
308 return -EINVAL;
309 }
310
311 /* FIXME
312 *
313 * It support I2S only now
314 */
315 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
316 case SND_SOC_DAIFMT_I2S:
317 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
318 break;
319 default:
320 return -EINVAL;
321 }
322
323 /* FIXME
324 *
325 * It support 64bit data transmission only now
326 */
327 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
328
329 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
330 da7210_write(codec, DA7210_DAI_CFG3, dai_cfg3);
331
332 return 0;
333}
334
335#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
336
337/* DAI operations */
338static struct snd_soc_dai_ops da7210_dai_ops = {
339 .startup = da7210_startup,
340 .hw_params = da7210_hw_params,
341 .set_fmt = da7210_set_dai_fmt,
342};
343
344struct snd_soc_dai da7210_dai = {
345 .name = "DA7210 IIS",
346 .id = 0,
347 /* playback capabilities */
348 .playback = {
349 .stream_name = "Playback",
350 .channels_min = 1,
351 .channels_max = 2,
352 .rates = SNDRV_PCM_RATE_8000_96000,
353 .formats = DA7210_FORMATS,
354 },
355 /* capture capabilities */
356 .capture = {
357 .stream_name = "Capture",
358 .channels_min = 1,
359 .channels_max = 2,
360 .rates = SNDRV_PCM_RATE_8000_96000,
361 .formats = DA7210_FORMATS,
362 },
363 .ops = &da7210_dai_ops,
364};
365EXPORT_SYMBOL_GPL(da7210_dai);
366
367/*
368 * Initialize the DA7210 driver
369 * register the mixer and dsp interfaces with the kernel
370 */
371static int da7210_init(struct da7210_priv *da7210)
372{
373 struct snd_soc_codec *codec = &da7210->codec;
374 int ret = 0;
375
376 if (da7210_codec) {
377 dev_err(codec->dev, "Another da7210 is registered\n");
378 return -EINVAL;
379 }
380
381 mutex_init(&codec->mutex);
382 INIT_LIST_HEAD(&codec->dapm_widgets);
383 INIT_LIST_HEAD(&codec->dapm_paths);
384
385 codec->private_data = da7210;
386 codec->name = "DA7210";
387 codec->owner = THIS_MODULE;
388 codec->read = da7210_read;
389 codec->write = da7210_write;
390 codec->dai = &da7210_dai;
391 codec->num_dai = 1;
392 codec->hw_write = (hw_write_t)i2c_master_send;
393 codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
394 codec->reg_cache = kmemdup(da7210_reg,
395 sizeof(da7210_reg), GFP_KERNEL);
396
397 if (!codec->reg_cache)
398 return -ENOMEM;
399
400 da7210_dai.dev = codec->dev;
401 da7210_codec = codec;
402
403 ret = snd_soc_register_codec(codec);
404 if (ret) {
405 dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
406 goto init_err;
407 }
408
409 ret = snd_soc_register_dai(&da7210_dai);
410 if (ret) {
411 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
412 goto init_err;
413 }
414
415 /* FIXME
416 *
417 * This driver use fixed value here
418 */
419
420 /*
421 * ADC settings
422 */
423
424 /* Enable Left & Right MIC PGA and Mic Bias */
425 da7210_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
426 da7210_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
427
428 /* Enable Left and Right input PGA */
429 da7210_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
430 da7210_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
431
432 /* Enable Left and Right ADC */
433 da7210_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
434
435 /*
436 * DAC settings
437 */
438
439 /* Enable Left and Right DAC */
440 da7210_write(codec, DA7210_DAC_SEL,
441 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
442 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
443
444 /* Enable Left and Right out PGA */
445 da7210_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
446 da7210_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
447
448 /* Enable Left and Right HeadPhone PGA */
449 da7210_write(codec, DA7210_HP_CFG,
450 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
451 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
452
453 /* Diable PLL and bypass it */
454 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
455
456 /* Bypass PLL and set MCLK freq rang to 10-20MHz */
457 da7210_write(codec, DA7210_PLL_DIV3,
458 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
459
460 /* Activate all enabled subsystem */
461 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
462
463 return ret;
464
465init_err:
466 kfree(codec->reg_cache);
467 codec->reg_cache = NULL;
468
469 return ret;
470
471}
472
473#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
474static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
475 const struct i2c_device_id *id)
476{
477 struct da7210_priv *da7210;
478 struct snd_soc_codec *codec;
479 int ret;
480
481 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
482 if (!da7210)
483 return -ENOMEM;
484
485 codec = &da7210->codec;
486 codec->dev = &i2c->dev;
487
488 i2c_set_clientdata(i2c, da7210);
489 codec->control_data = i2c;
490
491 ret = da7210_init(da7210);
492 if (ret < 0)
493 pr_err("Failed to initialise da7210 audio codec\n");
494
495 return ret;
496}
497
498static int __devexit da7210_i2c_remove(struct i2c_client *client)
499{
500 struct da7210_priv *da7210 = i2c_get_clientdata(client);
501
502 snd_soc_unregister_dai(&da7210_dai);
503 kfree(da7210->codec.reg_cache);
504 kfree(da7210);
505 da7210_codec = NULL;
506
507 return 0;
508}
509
510static const struct i2c_device_id da7210_i2c_id[] = {
511 { "da7210", 0 },
512 { }
513};
514MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
515
516/* I2C codec control layer */
517static struct i2c_driver da7210_i2c_driver = {
518 .driver = {
519 .name = "DA7210 I2C Codec",
520 .owner = THIS_MODULE,
521 },
522 .probe = da7210_i2c_probe,
523 .remove = __devexit_p(da7210_i2c_remove),
524 .id_table = da7210_i2c_id,
525};
526#endif
527
528static int da7210_probe(struct platform_device *pdev)
529{
530 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
531 struct snd_soc_codec *codec;
532 int ret;
533
534 if (!da7210_codec) {
535 dev_err(&pdev->dev, "Codec device not registered\n");
536 return -ENODEV;
537 }
538
539 socdev->card->codec = da7210_codec;
540 codec = da7210_codec;
541
542 /* Register pcms */
543 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
544 if (ret < 0)
545 goto pcm_err;
546
547 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
548
549pcm_err:
550 return ret;
551}
552
553static int da7210_remove(struct platform_device *pdev)
554{
555 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
556
557 snd_soc_free_pcms(socdev);
558 snd_soc_dapm_free(socdev);
559
560 return 0;
561}
562
563struct snd_soc_codec_device soc_codec_dev_da7210 = {
564 .probe = da7210_probe,
565 .remove = da7210_remove,
566};
567EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
568
569static int __init da7210_modinit(void)
570{
571 int ret = 0;
572#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
573 ret = i2c_add_driver(&da7210_i2c_driver);
574#endif
575 return ret;
576}
577module_init(da7210_modinit);
578
579static void __exit da7210_exit(void)
580{
581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
582 i2c_del_driver(&da7210_i2c_driver);
583#endif
584}
585module_exit(da7210_exit);
586
587MODULE_DESCRIPTION("ASoC DA7210 driver");
588MODULE_AUTHOR("David Chen, Kuninori Morimoto");
589MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7210.h b/sound/soc/codecs/da7210.h
new file mode 100644
index 000000000000..390d621eb742
--- /dev/null
+++ b/sound/soc/codecs/da7210.h
@@ -0,0 +1,24 @@
1/*
2 * da7210.h -- audio driver for da7210
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef _DA7210_H
18#define _DA7210_H
19
20extern struct snd_soc_dai da7210_dai;
21extern struct snd_soc_codec_device soc_codec_dev_da7210;
22
23#endif
24
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 2b4dc2b0b017..e4b946a19ea3 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -765,9 +765,10 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
765 struct snd_soc_codec *codec = socdev->card->codec; 765 struct snd_soc_codec *codec = socdev->card->codec;
766 struct aic3x_priv *aic3x = codec->private_data; 766 struct aic3x_priv *aic3x = codec->private_data;
767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
768 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 768 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
769 u16 pll_d = 1; 769 u16 d, pll_d = 1;
770 u8 reg; 770 u8 reg;
771 int clk;
771 772
772 /* select data word length */ 773 /* select data word length */
773 data = 774 data =
@@ -833,48 +834,70 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
833 if (bypass_pll) 834 if (bypass_pll)
834 return 0; 835 return 0;
835 836
836 /* Use PLL 837 /* Use PLL, compute apropriate setup for j, d, r and p, the closest
837 * find an apropriate setup for j, d, r and p by iterating over 838 * one wins the game. Try with d==0 first, next with d!=0.
838 * p and r - j and d are calculated for each fraction. 839 * Constraints for j are according to the datasheet.
839 * Up to 128 values are probed, the closest one wins the game.
840 * The sysclk is divided by 1000 to prevent integer overflows. 840 * The sysclk is divided by 1000 to prevent integer overflows.
841 */ 841 */
842
842 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000); 843 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
843 844
844 for (r = 1; r <= 16; r++) 845 for (r = 1; r <= 16; r++)
845 for (p = 1; p <= 8; p++) { 846 for (p = 1; p <= 8; p++) {
846 int clk, tmp = (codec_clk * pll_r * 10) / pll_p; 847 for (j = 4; j <= 55; j++) {
847 u8 j = tmp / 10000; 848 /* This is actually 1000*((j+(d/10000))*r)/p
848 u16 d = tmp % 10000; 849 * The term had to be converted to get
850 * rid of the division by 10000; d = 0 here
851 */
852 int tmp_clk = (1000 * j * r) / p;
853
854 /* Check whether this values get closer than
855 * the best ones we had before
856 */
857 if (abs(codec_clk - tmp_clk) <
858 abs(codec_clk - last_clk)) {
859 pll_j = j; pll_d = 0;
860 pll_r = r; pll_p = p;
861 last_clk = tmp_clk;
862 }
863
864 /* Early exit for exact matches */
865 if (tmp_clk == codec_clk)
866 goto found;
867 }
868 }
849 869
850 if (j > 63) 870 /* try with d != 0 */
851 continue; 871 for (p = 1; p <= 8; p++) {
872 j = codec_clk * p / 1000;
852 873
853 if (d != 0 && aic3x->sysclk < 10000000) 874 if (j < 4 || j > 11)
854 continue; 875 continue;
855 876
856 /* This is actually 1000 * ((j + (d/10000)) * r) / p 877 /* do not use codec_clk here since we'd loose precision */
857 * The term had to be converted to get rid of the 878 d = ((2048 * p * fsref) - j * aic3x->sysclk)
858 * division by 10000 */ 879 * 100 / (aic3x->sysclk/100);
859 clk = ((10000 * j * r) + (d * r)) / (10 * p);
860 880
861 /* check whether this values get closer than the best 881 clk = (10000 * j + d) / (10 * p);
862 * ones we had before */
863 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
864 pll_j = j; pll_d = d; pll_r = r; pll_p = p;
865 last_clk = clk;
866 }
867 882
868 /* Early exit for exact matches */ 883 /* check whether this values get closer than the best
869 if (clk == codec_clk) 884 * ones we had before */
870 break; 885 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
886 pll_j = j; pll_d = d; pll_r = 1; pll_p = p;
887 last_clk = clk;
871 } 888 }
872 889
890 /* Early exit for exact matches */
891 if (clk == codec_clk)
892 goto found;
893 }
894
873 if (last_clk == 0) { 895 if (last_clk == 0) {
874 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__); 896 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
875 return -EINVAL; 897 return -EINVAL;
876 } 898 }
877 899
900found:
878 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 901 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
879 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); 902 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT));
880 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT); 903 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT);
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 9c8903dbe647..f9f367d29a90 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -30,6 +30,7 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/regulator/consumer.h>
33#include <sound/core.h> 34#include <sound/core.h>
34#include <sound/pcm.h> 35#include <sound/pcm.h>
35#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
@@ -58,11 +59,26 @@ enum dac33_state {
58 DAC33_FLUSH, 59 DAC33_FLUSH,
59}; 60};
60 61
62enum dac33_fifo_modes {
63 DAC33_FIFO_BYPASS = 0,
64 DAC33_FIFO_MODE1,
65 DAC33_FIFO_MODE7,
66 DAC33_FIFO_LAST_MODE,
67};
68
69#define DAC33_NUM_SUPPLIES 3
70static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
71 "AVDD",
72 "DVDD",
73 "IOVDD",
74};
75
61struct tlv320dac33_priv { 76struct tlv320dac33_priv {
62 struct mutex mutex; 77 struct mutex mutex;
63 struct workqueue_struct *dac33_wq; 78 struct workqueue_struct *dac33_wq;
64 struct work_struct work; 79 struct work_struct work;
65 struct snd_soc_codec codec; 80 struct snd_soc_codec codec;
81 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
66 int power_gpio; 82 int power_gpio;
67 int chip_power; 83 int chip_power;
68 int irq; 84 int irq;
@@ -73,8 +89,9 @@ struct tlv320dac33_priv {
73 * this */ 89 * this */
74 unsigned int nsample_max; /* nsample should not be higher than 90 unsigned int nsample_max; /* nsample should not be higher than
75 * this */ 91 * this */
76 unsigned int nsample_switch; /* Use FIFO or bypass FIFO switch */ 92 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
77 unsigned int nsample; /* burst read amount from host */ 93 unsigned int nsample; /* burst read amount from host */
94 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
78 95
79 enum dac33_state state; 96 enum dac33_state state;
80}; 97};
@@ -297,28 +314,49 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
297 dac33_write(codec, DAC33_PWR_CTRL, reg); 314 dac33_write(codec, DAC33_PWR_CTRL, reg);
298} 315}
299 316
300static void dac33_hard_power(struct snd_soc_codec *codec, int power) 317static int dac33_hard_power(struct snd_soc_codec *codec, int power)
301{ 318{
302 struct tlv320dac33_priv *dac33 = codec->private_data; 319 struct tlv320dac33_priv *dac33 = codec->private_data;
320 int ret;
303 321
304 mutex_lock(&dac33->mutex); 322 mutex_lock(&dac33->mutex);
305 if (power) { 323 if (power) {
306 if (dac33->power_gpio >= 0) { 324 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
307 gpio_set_value(dac33->power_gpio, 1); 325 dac33->supplies);
308 dac33->chip_power = 1; 326 if (ret != 0) {
309 /* Restore registers */ 327 dev_err(codec->dev,
310 dac33_restore_regs(codec); 328 "Failed to enable supplies: %d\n", ret);
329 goto exit;
311 } 330 }
331
332 if (dac33->power_gpio >= 0)
333 gpio_set_value(dac33->power_gpio, 1);
334
335 dac33->chip_power = 1;
336
337 /* Restore registers */
338 dac33_restore_regs(codec);
339
312 dac33_soft_power(codec, 1); 340 dac33_soft_power(codec, 1);
313 } else { 341 } else {
314 dac33_soft_power(codec, 0); 342 dac33_soft_power(codec, 0);
315 if (dac33->power_gpio >= 0) { 343 if (dac33->power_gpio >= 0)
316 gpio_set_value(dac33->power_gpio, 0); 344 gpio_set_value(dac33->power_gpio, 0);
317 dac33->chip_power = 0; 345
346 ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
347 dac33->supplies);
348 if (ret != 0) {
349 dev_err(codec->dev,
350 "Failed to disable supplies: %d\n", ret);
351 goto exit;
318 } 352 }
353
354 dac33->chip_power = 0;
319 } 355 }
320 mutex_unlock(&dac33->mutex);
321 356
357exit:
358 mutex_unlock(&dac33->mutex);
359 return ret;
322} 360}
323 361
324static int dac33_get_nsample(struct snd_kcontrol *kcontrol, 362static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
@@ -351,39 +389,48 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
351 return ret; 389 return ret;
352} 390}
353 391
354static int dac33_get_nsample_switch(struct snd_kcontrol *kcontrol, 392static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol) 393 struct snd_ctl_elem_value *ucontrol)
356{ 394{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 395 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct tlv320dac33_priv *dac33 = codec->private_data; 396 struct tlv320dac33_priv *dac33 = codec->private_data;
359 397
360 ucontrol->value.integer.value[0] = dac33->nsample_switch; 398 ucontrol->value.integer.value[0] = dac33->fifo_mode;
361 399
362 return 0; 400 return 0;
363} 401}
364 402
365static int dac33_set_nsample_switch(struct snd_kcontrol *kcontrol, 403static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol) 404 struct snd_ctl_elem_value *ucontrol)
367{ 405{
368 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 406 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct tlv320dac33_priv *dac33 = codec->private_data; 407 struct tlv320dac33_priv *dac33 = codec->private_data;
370 int ret = 0; 408 int ret = 0;
371 409
372 if (dac33->nsample_switch == ucontrol->value.integer.value[0]) 410 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
373 return 0; 411 return 0;
374 /* Do not allow changes while stream is running*/ 412 /* Do not allow changes while stream is running*/
375 if (codec->active) 413 if (codec->active)
376 return -EPERM; 414 return -EPERM;
377 415
378 if (ucontrol->value.integer.value[0] < 0 || 416 if (ucontrol->value.integer.value[0] < 0 ||
379 ucontrol->value.integer.value[0] > 1) 417 ucontrol->value.integer.value[0] >= DAC33_FIFO_LAST_MODE)
380 ret = -EINVAL; 418 ret = -EINVAL;
381 else 419 else
382 dac33->nsample_switch = ucontrol->value.integer.value[0]; 420 dac33->fifo_mode = ucontrol->value.integer.value[0];
383 421
384 return ret; 422 return ret;
385} 423}
386 424
425/* Codec operation modes */
426static const char *dac33_fifo_mode_texts[] = {
427 "Bypass", "Mode 1", "Mode 7"
428};
429
430static const struct soc_enum dac33_fifo_mode_enum =
431 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts),
432 dac33_fifo_mode_texts);
433
387/* 434/*
388 * DACL/R digital volume control: 435 * DACL/R digital volume control:
389 * from 0 dB to -63.5 in 0.5 dB steps 436 * from 0 dB to -63.5 in 0.5 dB steps
@@ -406,8 +453,8 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = {
406static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = { 453static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
407 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0, 454 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
408 dac33_get_nsample, dac33_set_nsample), 455 dac33_get_nsample, dac33_set_nsample),
409 SOC_SINGLE_EXT("nSample Switch", 0, 0, 1, 0, 456 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
410 dac33_get_nsample_switch, dac33_set_nsample_switch), 457 dac33_get_fifo_mode, dac33_set_fifo_mode),
411}; 458};
412 459
413/* Analog bypass */ 460/* Analog bypass */
@@ -469,6 +516,8 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
469static int dac33_set_bias_level(struct snd_soc_codec *codec, 516static int dac33_set_bias_level(struct snd_soc_codec *codec,
470 enum snd_soc_bias_level level) 517 enum snd_soc_bias_level level)
471{ 518{
519 int ret;
520
472 switch (level) { 521 switch (level) {
473 case SND_SOC_BIAS_ON: 522 case SND_SOC_BIAS_ON:
474 dac33_soft_power(codec, 1); 523 dac33_soft_power(codec, 1);
@@ -476,12 +525,19 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
476 case SND_SOC_BIAS_PREPARE: 525 case SND_SOC_BIAS_PREPARE:
477 break; 526 break;
478 case SND_SOC_BIAS_STANDBY: 527 case SND_SOC_BIAS_STANDBY:
479 if (codec->bias_level == SND_SOC_BIAS_OFF) 528 if (codec->bias_level == SND_SOC_BIAS_OFF) {
480 dac33_hard_power(codec, 1); 529 ret = dac33_hard_power(codec, 1);
530 if (ret != 0)
531 return ret;
532 }
533
481 dac33_soft_power(codec, 0); 534 dac33_soft_power(codec, 0);
482 break; 535 break;
483 case SND_SOC_BIAS_OFF: 536 case SND_SOC_BIAS_OFF:
484 dac33_hard_power(codec, 0); 537 ret = dac33_hard_power(codec, 0);
538 if (ret != 0)
539 return ret;
540
485 break; 541 break;
486 } 542 }
487 codec->bias_level = level; 543 codec->bias_level = level;
@@ -489,6 +545,51 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
489 return 0; 545 return 0;
490} 546}
491 547
548static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
549{
550 struct snd_soc_codec *codec;
551
552 codec = &dac33->codec;
553
554 switch (dac33->fifo_mode) {
555 case DAC33_FIFO_MODE1:
556 dac33_write16(codec, DAC33_NSAMPLE_MSB,
557 DAC33_THRREG(dac33->nsample));
558 dac33_write16(codec, DAC33_PREFILL_MSB,
559 DAC33_THRREG(dac33->alarm_threshold));
560 break;
561 case DAC33_FIFO_MODE7:
562 dac33_write16(codec, DAC33_PREFILL_MSB,
563 DAC33_THRREG(10));
564 break;
565 default:
566 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
567 dac33->fifo_mode);
568 break;
569 }
570}
571
572static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
573{
574 struct snd_soc_codec *codec;
575
576 codec = &dac33->codec;
577
578 switch (dac33->fifo_mode) {
579 case DAC33_FIFO_MODE1:
580 dac33_write16(codec, DAC33_NSAMPLE_MSB,
581 DAC33_THRREG(dac33->nsample));
582 break;
583 case DAC33_FIFO_MODE7:
584 /* At the moment we are not using interrupts in mode7 */
585 break;
586 default:
587 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
588 dac33->fifo_mode);
589 break;
590 }
591}
592
492static void dac33_work(struct work_struct *work) 593static void dac33_work(struct work_struct *work)
493{ 594{
494 struct snd_soc_codec *codec; 595 struct snd_soc_codec *codec;
@@ -502,14 +603,10 @@ static void dac33_work(struct work_struct *work)
502 switch (dac33->state) { 603 switch (dac33->state) {
503 case DAC33_PREFILL: 604 case DAC33_PREFILL:
504 dac33->state = DAC33_PLAYBACK; 605 dac33->state = DAC33_PLAYBACK;
505 dac33_write16(codec, DAC33_NSAMPLE_MSB, 606 dac33_prefill_handler(dac33);
506 DAC33_THRREG(dac33->nsample));
507 dac33_write16(codec, DAC33_PREFILL_MSB,
508 DAC33_THRREG(dac33->alarm_threshold));
509 break; 607 break;
510 case DAC33_PLAYBACK: 608 case DAC33_PLAYBACK:
511 dac33_write16(codec, DAC33_NSAMPLE_MSB, 609 dac33_playback_handler(dac33);
512 DAC33_THRREG(dac33->nsample));
513 break; 610 break;
514 case DAC33_IDLE: 611 case DAC33_IDLE:
515 break; 612 break;
@@ -547,7 +644,7 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
547 unsigned int pwr_ctrl; 644 unsigned int pwr_ctrl;
548 645
549 /* Stop pending workqueue */ 646 /* Stop pending workqueue */
550 if (dac33->nsample_switch) 647 if (dac33->fifo_mode)
551 cancel_work_sync(&dac33->work); 648 cancel_work_sync(&dac33->work);
552 649
553 mutex_lock(&dac33->mutex); 650 mutex_lock(&dac33->mutex);
@@ -603,7 +700,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
603} 700}
604 701
605#define CALC_OSCSET(rate, refclk) ( \ 702#define CALC_OSCSET(rate, refclk) ( \
606 ((((rate * 10000) / refclk) * 4096) + 5000) / 10000) 703 ((((rate * 10000) / refclk) * 4096) + 7000) / 10000)
607#define CALC_RATIOSET(rate, refclk) ( \ 704#define CALC_RATIOSET(rate, refclk) ( \
608 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000) 705 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
609 706
@@ -619,7 +716,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
619 struct snd_soc_codec *codec = socdev->card->codec; 716 struct snd_soc_codec *codec = socdev->card->codec;
620 struct tlv320dac33_priv *dac33 = codec->private_data; 717 struct tlv320dac33_priv *dac33 = codec->private_data;
621 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 718 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
622 u8 aictrl_a, fifoctrl_a; 719 u8 aictrl_a, aictrl_b, fifoctrl_a;
623 720
624 switch (substream->runtime->rate) { 721 switch (substream->runtime->rate) {
625 case 44100: 722 case 44100:
@@ -637,7 +734,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
637 734
638 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A); 735 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
639 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK); 736 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
737 /* Read FIFO control A, and clear FIFO flush bit */
640 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A); 738 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
739 fifoctrl_a &= ~DAC33_FIFOFLUSH;
740
641 fifoctrl_a &= ~DAC33_WIDTH; 741 fifoctrl_a &= ~DAC33_WIDTH;
642 switch (substream->runtime->format) { 742 switch (substream->runtime->format) {
643 case SNDRV_PCM_FORMAT_S16_LE: 743 case SNDRV_PCM_FORMAT_S16_LE:
@@ -675,7 +775,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
675 775
676 dac33_oscwait(codec); 776 dac33_oscwait(codec);
677 777
678 if (dac33->nsample_switch) { 778 if (dac33->fifo_mode) {
779 /* Generic for all FIFO modes */
679 /* 50-51 : ASRC Control registers */ 780 /* 50-51 : ASRC Control registers */
680 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */ 781 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
681 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */ 782 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
@@ -685,38 +786,101 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
685 786
686 /* Set interrupts to high active */ 787 /* Set interrupts to high active */
687 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH); 788 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
688
689 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
690 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
691 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
692 } else { 789 } else {
790 /* FIFO bypass mode */
693 /* 50-51 : ASRC Control registers */ 791 /* 50-51 : ASRC Control registers */
694 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP); 792 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
695 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */ 793 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
696 } 794 }
697 795
698 if (dac33->nsample_switch) 796 /* Interrupt behaviour configuration */
797 switch (dac33->fifo_mode) {
798 case DAC33_FIFO_MODE1:
799 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
800 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
801 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
802 break;
803 case DAC33_FIFO_MODE7:
804 /* Disable all interrupts */
805 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
806 break;
807 default:
808 /* in FIFO bypass mode, the interrupts are not used */
809 break;
810 }
811
812 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
813
814 switch (dac33->fifo_mode) {
815 case DAC33_FIFO_MODE1:
816 /*
817 * For mode1:
818 * Disable the FIFO bypass (Enable the use of FIFO)
819 * Select nSample mode
820 * BCLK is only running when data is needed by DAC33
821 */
699 fifoctrl_a &= ~DAC33_FBYPAS; 822 fifoctrl_a &= ~DAC33_FBYPAS;
700 else 823 fifoctrl_a &= ~DAC33_FAUTO;
824 aictrl_b &= ~DAC33_BCLKON;
825 break;
826 case DAC33_FIFO_MODE7:
827 /*
828 * For mode1:
829 * Disable the FIFO bypass (Enable the use of FIFO)
830 * Select Threshold mode
831 * BCLK is only running when data is needed by DAC33
832 */
833 fifoctrl_a &= ~DAC33_FBYPAS;
834 fifoctrl_a |= DAC33_FAUTO;
835 aictrl_b &= ~DAC33_BCLKON;
836 break;
837 default:
838 /*
839 * For FIFO bypass mode:
840 * Enable the FIFO bypass (Disable the FIFO use)
841 * Set the BCLK as continous
842 */
701 fifoctrl_a |= DAC33_FBYPAS; 843 fifoctrl_a |= DAC33_FBYPAS;
702 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a); 844 aictrl_b |= DAC33_BCLKON;
845 break;
846 }
703 847
848 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
704 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a); 849 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
705 reg_tmp = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B); 850 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
706 if (dac33->nsample_switch)
707 reg_tmp &= ~DAC33_BCLKON;
708 else
709 reg_tmp |= DAC33_BCLKON;
710 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg_tmp);
711 851
712 if (dac33->nsample_switch) { 852 /*
713 /* 20: BCLK divide ratio */ 853 * BCLK divide ratio
714 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 3); 854 * 0: 1.5
855 * 1: 1
856 * 2: 2
857 * ...
858 * 254: 254
859 * 255: 255
860 */
861 if (dac33->fifo_mode)
862 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
863 dac33->burst_bclkdiv);
864 else
865 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
715 866
867 switch (dac33->fifo_mode) {
868 case DAC33_FIFO_MODE1:
716 dac33_write16(codec, DAC33_ATHR_MSB, 869 dac33_write16(codec, DAC33_ATHR_MSB,
717 DAC33_THRREG(dac33->alarm_threshold)); 870 DAC33_THRREG(dac33->alarm_threshold));
718 } else { 871 break;
719 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); 872 case DAC33_FIFO_MODE7:
873 /*
874 * Configure the threshold levels, and leave 10 sample space
875 * at the bottom, and also at the top of the FIFO
876 */
877 dac33_write16(codec, DAC33_UTHR_MSB,
878 DAC33_THRREG(DAC33_BUFFER_SIZE_SAMPLES - 10));
879 dac33_write16(codec, DAC33_LTHR_MSB,
880 DAC33_THRREG(10));
881 break;
882 default:
883 break;
720 } 884 }
721 885
722 mutex_unlock(&dac33->mutex); 886 mutex_unlock(&dac33->mutex);
@@ -789,7 +953,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
789 case SNDRV_PCM_TRIGGER_START: 953 case SNDRV_PCM_TRIGGER_START:
790 case SNDRV_PCM_TRIGGER_RESUME: 954 case SNDRV_PCM_TRIGGER_RESUME:
791 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 955 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
792 if (dac33->nsample_switch) { 956 if (dac33->fifo_mode) {
793 dac33->state = DAC33_PREFILL; 957 dac33->state = DAC33_PREFILL;
794 queue_work(dac33->dac33_wq, &dac33->work); 958 queue_work(dac33->dac33_wq, &dac33->work);
795 } 959 }
@@ -797,7 +961,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
797 case SNDRV_PCM_TRIGGER_STOP: 961 case SNDRV_PCM_TRIGGER_STOP:
798 case SNDRV_PCM_TRIGGER_SUSPEND: 962 case SNDRV_PCM_TRIGGER_SUSPEND:
799 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 963 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
800 if (dac33->nsample_switch) { 964 if (dac33->fifo_mode) {
801 dac33->state = DAC33_FLUSH; 965 dac33->state = DAC33_FLUSH;
802 queue_work(dac33->dac33_wq, &dac33->work); 966 queue_work(dac33->dac33_wq, &dac33->work);
803 } 967 }
@@ -843,6 +1007,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
843 unsigned int fmt) 1007 unsigned int fmt)
844{ 1008{
845 struct snd_soc_codec *codec = codec_dai->codec; 1009 struct snd_soc_codec *codec = codec_dai->codec;
1010 struct tlv320dac33_priv *dac33 = codec->private_data;
846 u8 aictrl_a, aictrl_b; 1011 u8 aictrl_a, aictrl_b;
847 1012
848 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A); 1013 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
@@ -855,7 +1020,11 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
855 break; 1020 break;
856 case SND_SOC_DAIFMT_CBS_CFS: 1021 case SND_SOC_DAIFMT_CBS_CFS:
857 /* Codec Slave */ 1022 /* Codec Slave */
858 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK); 1023 if (dac33->fifo_mode) {
1024 dev_err(codec->dev, "FIFO mode requires master mode\n");
1025 return -EINVAL;
1026 } else
1027 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
859 break; 1028 break;
860 default: 1029 default:
861 return -EINVAL; 1030 return -EINVAL;
@@ -959,6 +1128,9 @@ static int dac33_soc_probe(struct platform_device *pdev)
959 /* power on device */ 1128 /* power on device */
960 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1129 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
961 1130
1131 /* Bias level configuration has enabled regulator an extra time */
1132 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1133
962 return 0; 1134 return 0;
963 1135
964pcm_err: 1136pcm_err:
@@ -1033,13 +1205,13 @@ struct snd_soc_dai dac33_dai = {
1033}; 1205};
1034EXPORT_SYMBOL_GPL(dac33_dai); 1206EXPORT_SYMBOL_GPL(dac33_dai);
1035 1207
1036static int dac33_i2c_probe(struct i2c_client *client, 1208static int __devinit dac33_i2c_probe(struct i2c_client *client,
1037 const struct i2c_device_id *id) 1209 const struct i2c_device_id *id)
1038{ 1210{
1039 struct tlv320dac33_platform_data *pdata; 1211 struct tlv320dac33_platform_data *pdata;
1040 struct tlv320dac33_priv *dac33; 1212 struct tlv320dac33_priv *dac33;
1041 struct snd_soc_codec *codec; 1213 struct snd_soc_codec *codec;
1042 int ret = 0; 1214 int ret, i;
1043 1215
1044 if (client->dev.platform_data == NULL) { 1216 if (client->dev.platform_data == NULL) {
1045 dev_err(&client->dev, "Platform data not set\n"); 1217 dev_err(&client->dev, "Platform data not set\n");
@@ -1080,10 +1252,11 @@ static int dac33_i2c_probe(struct i2c_client *client,
1080 i2c_set_clientdata(client, dac33); 1252 i2c_set_clientdata(client, dac33);
1081 1253
1082 dac33->power_gpio = pdata->power_gpio; 1254 dac33->power_gpio = pdata->power_gpio;
1255 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1083 dac33->irq = client->irq; 1256 dac33->irq = client->irq;
1084 dac33->nsample = NSAMPLE_MAX; 1257 dac33->nsample = NSAMPLE_MAX;
1085 /* Disable FIFO use by default */ 1258 /* Disable FIFO use by default */
1086 dac33->nsample_switch = 0; 1259 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1087 1260
1088 tlv320dac33_codec = codec; 1261 tlv320dac33_codec = codec;
1089 1262
@@ -1130,6 +1303,24 @@ static int dac33_i2c_probe(struct i2c_client *client,
1130 } 1303 }
1131 } 1304 }
1132 1305
1306 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
1307 dac33->supplies[i].supply = dac33_supply_names[i];
1308
1309 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(dac33->supplies),
1310 dac33->supplies);
1311
1312 if (ret != 0) {
1313 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1314 goto err_get;
1315 }
1316
1317 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
1318 dac33->supplies);
1319 if (ret != 0) {
1320 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1321 goto err_enable;
1322 }
1323
1133 ret = snd_soc_register_codec(codec); 1324 ret = snd_soc_register_codec(codec);
1134 if (ret != 0) { 1325 if (ret != 0) {
1135 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1326 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
@@ -1149,6 +1340,10 @@ static int dac33_i2c_probe(struct i2c_client *client,
1149 return ret; 1340 return ret;
1150 1341
1151error_codec: 1342error_codec:
1343 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1344err_enable:
1345 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1346err_get:
1152 if (dac33->irq >= 0) { 1347 if (dac33->irq >= 0) {
1153 free_irq(dac33->irq, &dac33->codec); 1348 free_irq(dac33->irq, &dac33->codec);
1154 destroy_workqueue(dac33->dac33_wq); 1349 destroy_workqueue(dac33->dac33_wq);
@@ -1165,7 +1360,7 @@ error_reg:
1165 return ret; 1360 return ret;
1166} 1361}
1167 1362
1168static int dac33_i2c_remove(struct i2c_client *client) 1363static int __devexit dac33_i2c_remove(struct i2c_client *client)
1169{ 1364{
1170 struct tlv320dac33_priv *dac33; 1365 struct tlv320dac33_priv *dac33;
1171 1366
@@ -1177,6 +1372,8 @@ static int dac33_i2c_remove(struct i2c_client *client)
1177 if (dac33->irq >= 0) 1372 if (dac33->irq >= 0)
1178 free_irq(dac33->irq, &dac33->codec); 1373 free_irq(dac33->irq, &dac33->codec);
1179 1374
1375 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1376
1180 destroy_workqueue(dac33->dac33_wq); 1377 destroy_workqueue(dac33->dac33_wq);
1181 snd_soc_unregister_dai(&dac33_dai); 1378 snd_soc_unregister_dai(&dac33_dai);
1182 snd_soc_unregister_codec(&dac33->codec); 1379 snd_soc_unregister_codec(&dac33->codec);
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 6b650c1aa3d1..958d49c969ac 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -25,6 +25,7 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/regulator/consumer.h>
28#include <sound/tpa6130a2-plat.h> 29#include <sound/tpa6130a2-plat.h>
29#include <sound/soc.h> 30#include <sound/soc.h>
30#include <sound/soc-dapm.h> 31#include <sound/soc-dapm.h>
@@ -34,10 +35,22 @@
34 35
35static struct i2c_client *tpa6130a2_client; 36static struct i2c_client *tpa6130a2_client;
36 37
38#define TPA6130A2_NUM_SUPPLIES 2
39static const char *tpa6130a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
40 "CPVSS",
41 "Vdd",
42};
43
44static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
45 "HPVdd",
46 "AVdd",
47};
48
37/* This struct is used to save the context */ 49/* This struct is used to save the context */
38struct tpa6130a2_data { 50struct tpa6130a2_data {
39 struct mutex mutex; 51 struct mutex mutex;
40 unsigned char regs[TPA6130A2_CACHEREGNUM]; 52 unsigned char regs[TPA6130A2_CACHEREGNUM];
53 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES];
41 int power_gpio; 54 int power_gpio;
42 unsigned char power_state; 55 unsigned char power_state;
43}; 56};
@@ -106,10 +119,11 @@ static void tpa6130a2_initialize(void)
106 tpa6130a2_i2c_write(i, data->regs[i]); 119 tpa6130a2_i2c_write(i, data->regs[i]);
107} 120}
108 121
109static void tpa6130a2_power(int power) 122static int tpa6130a2_power(int power)
110{ 123{
111 struct tpa6130a2_data *data; 124 struct tpa6130a2_data *data;
112 u8 val; 125 u8 val;
126 int ret;
113 127
114 BUG_ON(tpa6130a2_client == NULL); 128 BUG_ON(tpa6130a2_client == NULL);
115 data = i2c_get_clientdata(tpa6130a2_client); 129 data = i2c_get_clientdata(tpa6130a2_client);
@@ -117,11 +131,20 @@ static void tpa6130a2_power(int power)
117 mutex_lock(&data->mutex); 131 mutex_lock(&data->mutex);
118 if (power) { 132 if (power) {
119 /* Power on */ 133 /* Power on */
120 if (data->power_gpio >= 0) { 134 if (data->power_gpio >= 0)
121 gpio_set_value(data->power_gpio, 1); 135 gpio_set_value(data->power_gpio, 1);
122 data->power_state = 1; 136
123 tpa6130a2_initialize(); 137 ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies),
138 data->supplies);
139 if (ret != 0) {
140 dev_err(&tpa6130a2_client->dev,
141 "Failed to enable supplies: %d\n", ret);
142 goto exit;
124 } 143 }
144
145 data->power_state = 1;
146 tpa6130a2_initialize();
147
125 /* Clear SWS */ 148 /* Clear SWS */
126 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 149 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
127 val &= ~TPA6130A2_SWS; 150 val &= ~TPA6130A2_SWS;
@@ -131,13 +154,25 @@ static void tpa6130a2_power(int power)
131 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 154 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
132 val |= TPA6130A2_SWS; 155 val |= TPA6130A2_SWS;
133 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); 156 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
157
134 /* Power off */ 158 /* Power off */
135 if (data->power_gpio >= 0) { 159 if (data->power_gpio >= 0)
136 gpio_set_value(data->power_gpio, 0); 160 gpio_set_value(data->power_gpio, 0);
137 data->power_state = 0; 161
162 ret = regulator_bulk_disable(ARRAY_SIZE(data->supplies),
163 data->supplies);
164 if (ret != 0) {
165 dev_err(&tpa6130a2_client->dev,
166 "Failed to disable supplies: %d\n", ret);
167 goto exit;
138 } 168 }
169
170 data->power_state = 0;
139 } 171 }
172
173exit:
140 mutex_unlock(&data->mutex); 174 mutex_unlock(&data->mutex);
175 return ret;
141} 176}
142 177
143static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol, 178static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
@@ -237,12 +272,8 @@ static const struct snd_kcontrol_new tpa6130a2_controls[] = {
237 */ 272 */
238static void tpa6130a2_channel_enable(u8 channel, int enable) 273static void tpa6130a2_channel_enable(u8 channel, int enable)
239{ 274{
240 struct tpa6130a2_data *data;
241 u8 val; 275 u8 val;
242 276
243 BUG_ON(tpa6130a2_client == NULL);
244 data = i2c_get_clientdata(tpa6130a2_client);
245
246 if (enable) { 277 if (enable) {
247 /* Enable channel */ 278 /* Enable channel */
248 /* Enable amplifier */ 279 /* Enable amplifier */
@@ -299,15 +330,17 @@ static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
299static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w, 330static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
300 struct snd_kcontrol *kcontrol, int event) 331 struct snd_kcontrol *kcontrol, int event)
301{ 332{
333 int ret = 0;
334
302 switch (event) { 335 switch (event) {
303 case SND_SOC_DAPM_POST_PMU: 336 case SND_SOC_DAPM_POST_PMU:
304 tpa6130a2_power(1); 337 ret = tpa6130a2_power(1);
305 break; 338 break;
306 case SND_SOC_DAPM_POST_PMD: 339 case SND_SOC_DAPM_POST_PMD:
307 tpa6130a2_power(0); 340 ret = tpa6130a2_power(0);
308 break; 341 break;
309 } 342 }
310 return 0; 343 return ret;
311} 344}
312 345
313static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = { 346static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
@@ -346,13 +379,13 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
346} 379}
347EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 380EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
348 381
349static int tpa6130a2_probe(struct i2c_client *client, 382static int __devinit tpa6130a2_probe(struct i2c_client *client,
350 const struct i2c_device_id *id) 383 const struct i2c_device_id *id)
351{ 384{
352 struct device *dev; 385 struct device *dev;
353 struct tpa6130a2_data *data; 386 struct tpa6130a2_data *data;
354 struct tpa6130a2_platform_data *pdata; 387 struct tpa6130a2_platform_data *pdata;
355 int ret; 388 int i, ret;
356 389
357 dev = &client->dev; 390 dev = &client->dev;
358 391
@@ -387,15 +420,38 @@ static int tpa6130a2_probe(struct i2c_client *client,
387 if (ret < 0) { 420 if (ret < 0) {
388 dev_err(dev, "Failed to request power GPIO (%d)\n", 421 dev_err(dev, "Failed to request power GPIO (%d)\n",
389 data->power_gpio); 422 data->power_gpio);
390 goto fail; 423 goto err_gpio;
391 } 424 }
392 gpio_direction_output(data->power_gpio, 0); 425 gpio_direction_output(data->power_gpio, 0);
393 } else {
394 data->power_state = 1;
395 tpa6130a2_initialize();
396 } 426 }
397 427
398 tpa6130a2_power(1); 428 switch (pdata->id) {
429 case TPA6130A2:
430 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
431 data->supplies[i].supply = tpa6130a2_supply_names[i];
432 break;
433 case TPA6140A2:
434 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
435 data->supplies[i].supply = tpa6140a2_supply_names[i];;
436 break;
437 default:
438 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
439 pdata->id);
440 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
441 data->supplies[i].supply = tpa6130a2_supply_names[i];
442 }
443
444 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
445 data->supplies);
446 if (ret != 0) {
447 dev_err(dev, "Failed to request supplies: %d\n", ret);
448 goto err_regulator;
449 }
450
451 ret = tpa6130a2_power(1);
452 if (ret != 0)
453 goto err_power;
454
399 455
400 /* Read version */ 456 /* Read version */
401 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) & 457 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
@@ -404,10 +460,18 @@ static int tpa6130a2_probe(struct i2c_client *client,
404 dev_warn(dev, "UNTESTED version detected (%d)\n", ret); 460 dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
405 461
406 /* Disable the chip */ 462 /* Disable the chip */
407 tpa6130a2_power(0); 463 ret = tpa6130a2_power(0);
464 if (ret != 0)
465 goto err_power;
408 466
409 return 0; 467 return 0;
410fail: 468
469err_power:
470 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
471err_regulator:
472 if (data->power_gpio >= 0)
473 gpio_free(data->power_gpio);
474err_gpio:
411 kfree(data); 475 kfree(data);
412 i2c_set_clientdata(tpa6130a2_client, NULL); 476 i2c_set_clientdata(tpa6130a2_client, NULL);
413 tpa6130a2_client = NULL; 477 tpa6130a2_client = NULL;
@@ -415,7 +479,7 @@ fail:
415 return ret; 479 return ret;
416} 480}
417 481
418static int tpa6130a2_remove(struct i2c_client *client) 482static int __devexit tpa6130a2_remove(struct i2c_client *client)
419{ 483{
420 struct tpa6130a2_data *data = i2c_get_clientdata(client); 484 struct tpa6130a2_data *data = i2c_get_clientdata(client);
421 485
@@ -423,6 +487,9 @@ static int tpa6130a2_remove(struct i2c_client *client)
423 487
424 if (data->power_gpio >= 0) 488 if (data->power_gpio >= 0)
425 gpio_free(data->power_gpio); 489 gpio_free(data->power_gpio);
490
491 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
492
426 kfree(data); 493 kfree(data);
427 tpa6130a2_client = NULL; 494 tpa6130a2_client = NULL;
428 495
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 2a27f7b56726..6f5d4af20052 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -55,7 +55,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
55 0x0c, /* REG_ATXR1PGA (0xB) */ 55 0x0c, /* REG_ATXR1PGA (0xB) */
56 0x00, /* REG_AVTXL2PGA (0xC) */ 56 0x00, /* REG_AVTXL2PGA (0xC) */
57 0x00, /* REG_AVTXR2PGA (0xD) */ 57 0x00, /* REG_AVTXR2PGA (0xD) */
58 0x01, /* REG_AUDIO_IF (0xE) */ 58 0x00, /* REG_AUDIO_IF (0xE) */
59 0x00, /* REG_VOICE_IF (0xF) */ 59 0x00, /* REG_VOICE_IF (0xF) */
60 0x00, /* REG_ARXR1PGA (0x10) */ 60 0x00, /* REG_ARXR1PGA (0x10) */
61 0x00, /* REG_ARXL1PGA (0x11) */ 61 0x00, /* REG_ARXL1PGA (0x11) */
@@ -64,19 +64,19 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
64 0x00, /* REG_VRXPGA (0x14) */ 64 0x00, /* REG_VRXPGA (0x14) */
65 0x00, /* REG_VSTPGA (0x15) */ 65 0x00, /* REG_VSTPGA (0x15) */
66 0x00, /* REG_VRX2ARXPGA (0x16) */ 66 0x00, /* REG_VRX2ARXPGA (0x16) */
67 0x0c, /* REG_AVDAC_CTL (0x17) */ 67 0x00, /* REG_AVDAC_CTL (0x17) */
68 0x00, /* REG_ARX2VTXPGA (0x18) */ 68 0x00, /* REG_ARX2VTXPGA (0x18) */
69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ 69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ 70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
71 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */ 71 0x4a, /* REG_ARXL2_APGA_CTL (0x1B) */
72 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */ 72 0x4a, /* REG_ARXR2_APGA_CTL (0x1C) */
73 0x00, /* REG_ATX2ARXPGA (0x1D) */ 73 0x00, /* REG_ATX2ARXPGA (0x1D) */
74 0x00, /* REG_BT_IF (0x1E) */ 74 0x00, /* REG_BT_IF (0x1E) */
75 0x00, /* REG_BTPGA (0x1F) */ 75 0x00, /* REG_BTPGA (0x1F) */
76 0x00, /* REG_BTSTPGA (0x20) */ 76 0x00, /* REG_BTSTPGA (0x20) */
77 0x00, /* REG_EAR_CTL (0x21) */ 77 0x00, /* REG_EAR_CTL (0x21) */
78 0x24, /* REG_HS_SEL (0x22) */ 78 0x00, /* REG_HS_SEL (0x22) */
79 0x0a, /* REG_HS_GAIN_SET (0x23) */ 79 0x00, /* REG_HS_GAIN_SET (0x23) */
80 0x00, /* REG_HS_POPN_SET (0x24) */ 80 0x00, /* REG_HS_POPN_SET (0x24) */
81 0x00, /* REG_PREDL_CTL (0x25) */ 81 0x00, /* REG_PREDL_CTL (0x25) */
82 0x00, /* REG_PREDR_CTL (0x26) */ 82 0x00, /* REG_PREDR_CTL (0x26) */
@@ -99,7 +99,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ 99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ 100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ 101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
102 0x16, /* REG_APLL_CTL (0x3A) */ 102 0x06, /* REG_APLL_CTL (0x3A) */
103 0x00, /* REG_DTMF_CTL (0x3B) */ 103 0x00, /* REG_DTMF_CTL (0x3B) */
104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ 104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ 105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
@@ -1203,6 +1203,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1203 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event, 1203 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1204 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), 1204 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1205 1205
1206 SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0),
1207
1206 /* Output MIXER controls */ 1208 /* Output MIXER controls */
1207 /* Earpiece */ 1209 /* Earpiece */
1208 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1210 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
@@ -1337,6 +1339,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1337 {"Digital L2 Playback Mixer", NULL, "APLL Enable"}, 1339 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, 1340 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1339 1341
1342 {"Digital R1 Playback Mixer", NULL, "AIF Enable"},
1343 {"Digital L1 Playback Mixer", NULL, "AIF Enable"},
1344 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1345 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1346
1340 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, 1347 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1341 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, 1348 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1342 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, 1349 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
@@ -1455,6 +1462,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1455 {"ADC Virtual Left2", NULL, "APLL Enable"}, 1462 {"ADC Virtual Left2", NULL, "APLL Enable"},
1456 {"ADC Virtual Right2", NULL, "APLL Enable"}, 1463 {"ADC Virtual Right2", NULL, "APLL Enable"},
1457 1464
1465 {"ADC Virtual Left1", NULL, "AIF Enable"},
1466 {"ADC Virtual Right1", NULL, "AIF Enable"},
1467 {"ADC Virtual Left2", NULL, "AIF Enable"},
1468 {"ADC Virtual Right2", NULL, "AIF Enable"},
1469
1458 /* Analog bypass routes */ 1470 /* Analog bypass routes */
1459 {"Right1 Analog Loopback", "Switch", "Analog Right"}, 1471 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1460 {"Left1 Analog Loopback", "Switch", "Analog Left"}, 1472 {"Left1 Analog Loopback", "Switch", "Analog Left"},
@@ -2152,8 +2164,6 @@ static int twl4030_soc_remove(struct platform_device *pdev)
2152 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2164 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2153 snd_soc_free_pcms(socdev); 2165 snd_soc_free_pcms(socdev);
2154 snd_soc_dapm_free(socdev); 2166 snd_soc_dapm_free(socdev);
2155 kfree(codec->private_data);
2156 kfree(codec);
2157 2167
2158 return 0; 2168 return 0;
2159} 2169}
@@ -2192,7 +2202,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2192 codec->write = twl4030_write; 2202 codec->write = twl4030_write;
2193 codec->set_bias_level = twl4030_set_bias_level; 2203 codec->set_bias_level = twl4030_set_bias_level;
2194 codec->dai = twl4030_dai; 2204 codec->dai = twl4030_dai;
2195 codec->num_dai = ARRAY_SIZE(twl4030_dai), 2205 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2196 codec->reg_cache_size = sizeof(twl4030_reg); 2206 codec->reg_cache_size = sizeof(twl4030_reg);
2197 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg), 2207 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2198 GFP_KERNEL); 2208 GFP_KERNEL);
@@ -2237,6 +2247,9 @@ static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2237{ 2247{
2238 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev); 2248 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
2239 2249
2250 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2251 snd_soc_unregister_codec(&twl4030->codec);
2252 kfree(twl4030->codec.reg_cache);
2240 kfree(twl4030); 2253 kfree(twl4030);
2241 2254
2242 twl4030_codec = NULL; 2255 twl4030_codec = NULL;
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index dd6396ec9c79..f206d242ca31 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -25,7 +25,7 @@
25/* Register descriptions are here */ 25/* Register descriptions are here */
26#include <linux/mfd/twl4030-codec.h> 26#include <linux/mfd/twl4030-codec.h>
27 27
28/* Sgadow register used by the audio driver */ 28/* Shadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A 29#define TWL4030_REG_SW_SHADOW 0x4A
30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
31 31
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
new file mode 100644
index 000000000000..217b02680597
--- /dev/null
+++ b/sound/soc/codecs/wm2000.c
@@ -0,0 +1,888 @@
1/*
2 * wm2000.c -- WM2000 ALSA Soc Audio driver
3 *
4 * Copyright 2008-2010 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 * The download image for the WM2000 will be requested as
13 * 'wm2000_anc.bin' by default (overridable via platform data) at
14 * runtime and is expected to be in flat binary format. This is
15 * generated by Wolfson configuration tools and includes
16 * system-specific callibration information. If supplied as a
17 * sequence of ASCII-encoded hexidecimal bytes this can be converted
18 * into a flat binary with a command such as this on the command line:
19 *
20 * perl -e 'while (<>) { s/[\r\n]+// ; printf("%c", hex($_)); }'
21 * < file > wm2000_anc.bin
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/version.h>
27#include <linux/kernel.h>
28#include <linux/init.h>
29#include <linux/firmware.h>
30#include <linux/delay.h>
31#include <linux/pm.h>
32#include <linux/i2c.h>
33#include <linux/platform_device.h>
34#include <linux/debugfs.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h>
41#include <sound/tlv.h>
42
43#include <sound/wm2000.h>
44
45#include "wm2000.h"
46
47enum wm2000_anc_mode {
48 ANC_ACTIVE = 0,
49 ANC_BYPASS = 1,
50 ANC_STANDBY = 2,
51 ANC_OFF = 3,
52};
53
54struct wm2000_priv {
55 struct i2c_client *i2c;
56
57 enum wm2000_anc_mode anc_mode;
58
59 unsigned int anc_active:1;
60 unsigned int anc_eng_ena:1;
61 unsigned int spk_ena:1;
62
63 unsigned int mclk_div:1;
64 unsigned int speech_clarity:1;
65
66 int anc_download_size;
67 char *anc_download;
68};
69
70static struct i2c_client *wm2000_i2c;
71
72static int wm2000_write(struct i2c_client *i2c, unsigned int reg,
73 unsigned int value)
74{
75 u8 data[3];
76 int ret;
77
78 data[0] = (reg >> 8) & 0xff;
79 data[1] = reg & 0xff;
80 data[2] = value & 0xff;
81
82 dev_vdbg(&i2c->dev, "write %x = %x\n", reg, value);
83
84 ret = i2c_master_send(i2c, data, 3);
85 if (ret == 3)
86 return 0;
87 if (ret < 0)
88 return ret;
89 else
90 return -EIO;
91}
92
93static unsigned int wm2000_read(struct i2c_client *i2c, unsigned int r)
94{
95 struct i2c_msg xfer[2];
96 u8 reg[2];
97 u8 data;
98 int ret;
99
100 /* Write register */
101 reg[0] = (r >> 8) & 0xff;
102 reg[1] = r & 0xff;
103 xfer[0].addr = i2c->addr;
104 xfer[0].flags = 0;
105 xfer[0].len = sizeof(reg);
106 xfer[0].buf = &reg[0];
107
108 /* Read data */
109 xfer[1].addr = i2c->addr;
110 xfer[1].flags = I2C_M_RD;
111 xfer[1].len = 1;
112 xfer[1].buf = &data;
113
114 ret = i2c_transfer(i2c->adapter, xfer, 2);
115 if (ret != 2) {
116 dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret);
117 return 0;
118 }
119
120 dev_vdbg(&i2c->dev, "read %x from %x\n", data, r);
121
122 return data;
123}
124
125static void wm2000_reset(struct wm2000_priv *wm2000)
126{
127 struct i2c_client *i2c = wm2000->i2c;
128
129 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
130 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
131 wm2000_write(i2c, WM2000_REG_ID1, 0);
132
133 wm2000->anc_mode = ANC_OFF;
134}
135
136static int wm2000_poll_bit(struct i2c_client *i2c,
137 unsigned int reg, u8 mask, int timeout)
138{
139 int val;
140
141 val = wm2000_read(i2c, reg);
142
143 while (!(val & mask) && --timeout) {
144 msleep(1);
145 val = wm2000_read(i2c, reg);
146 }
147
148 if (timeout == 0)
149 return 0;
150 else
151 return 1;
152}
153
154static int wm2000_power_up(struct i2c_client *i2c, int analogue)
155{
156 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
157 int ret, timeout;
158
159 BUG_ON(wm2000->anc_mode != ANC_OFF);
160
161 dev_dbg(&i2c->dev, "Beginning power up\n");
162
163 if (!wm2000->mclk_div) {
164 dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
165 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
166 WM2000_MCLK_DIV2_ENA_CLR);
167 } else {
168 dev_dbg(&i2c->dev, "Enabling MCLK divider\n");
169 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
170 WM2000_MCLK_DIV2_ENA_SET);
171 }
172
173 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
174 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_SET);
175
176 /* Wait for ANC engine to become ready */
177 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
178 WM2000_ANC_ENG_IDLE, 1)) {
179 dev_err(&i2c->dev, "ANC engine failed to reset\n");
180 return -ETIMEDOUT;
181 }
182
183 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
184 WM2000_STATUS_BOOT_COMPLETE, 1)) {
185 dev_err(&i2c->dev, "ANC engine failed to initialise\n");
186 return -ETIMEDOUT;
187 }
188
189 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
190
191 /* Open code download of the data since it is the only bulk
192 * write we do. */
193 dev_dbg(&i2c->dev, "Downloading %d bytes\n",
194 wm2000->anc_download_size - 2);
195
196 ret = i2c_master_send(i2c, wm2000->anc_download,
197 wm2000->anc_download_size);
198 if (ret < 0) {
199 dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);
200 return ret;
201 }
202 if (ret != wm2000->anc_download_size) {
203 dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",
204 ret, wm2000->anc_download_size);
205 return -EIO;
206 }
207
208 dev_dbg(&i2c->dev, "Download complete\n");
209
210 if (analogue) {
211 timeout = 248;
212 wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
213
214 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
215 WM2000_MODE_ANA_SEQ_INCLUDE |
216 WM2000_MODE_MOUSE_ENABLE |
217 WM2000_MODE_THERMAL_ENABLE);
218 } else {
219 timeout = 10;
220
221 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
222 WM2000_MODE_MOUSE_ENABLE |
223 WM2000_MODE_THERMAL_ENABLE);
224 }
225
226 ret = wm2000_read(i2c, WM2000_REG_SPEECH_CLARITY);
227 if (wm2000->speech_clarity)
228 ret &= ~WM2000_SPEECH_CLARITY;
229 else
230 ret |= WM2000_SPEECH_CLARITY;
231 wm2000_write(i2c, WM2000_REG_SPEECH_CLARITY, ret);
232
233 wm2000_write(i2c, WM2000_REG_SYS_START0, 0x33);
234 wm2000_write(i2c, WM2000_REG_SYS_START1, 0x02);
235
236 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
237
238 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
239 WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
240 dev_err(&i2c->dev, "Timed out waiting for device after %dms\n",
241 timeout * 10);
242 return -ETIMEDOUT;
243 }
244
245 dev_dbg(&i2c->dev, "ANC active\n");
246 if (analogue)
247 dev_dbg(&i2c->dev, "Analogue active\n");
248 wm2000->anc_mode = ANC_ACTIVE;
249
250 return 0;
251}
252
253static int wm2000_power_down(struct i2c_client *i2c, int analogue)
254{
255 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
256 int timeout;
257
258 if (analogue) {
259 timeout = 248;
260 wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
261 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
262 WM2000_MODE_ANA_SEQ_INCLUDE |
263 WM2000_MODE_POWER_DOWN);
264 } else {
265 timeout = 10;
266 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
267 WM2000_MODE_POWER_DOWN);
268 }
269
270 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
271 WM2000_STATUS_POWER_DOWN_COMPLETE, timeout)) {
272 dev_err(&i2c->dev, "Timeout waiting for ANC power down\n");
273 return -ETIMEDOUT;
274 }
275
276 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
277 WM2000_ANC_ENG_IDLE, 1)) {
278 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
279 return -ETIMEDOUT;
280 }
281
282 dev_dbg(&i2c->dev, "powered off\n");
283 wm2000->anc_mode = ANC_OFF;
284
285 return 0;
286}
287
288static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue)
289{
290 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
291
292 BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
293
294 if (analogue) {
295 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
296 WM2000_MODE_ANA_SEQ_INCLUDE |
297 WM2000_MODE_THERMAL_ENABLE |
298 WM2000_MODE_BYPASS_ENTRY);
299 } else {
300 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
301 WM2000_MODE_THERMAL_ENABLE |
302 WM2000_MODE_BYPASS_ENTRY);
303 }
304
305 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
306 WM2000_STATUS_ANC_DISABLED, 10)) {
307 dev_err(&i2c->dev, "Timeout waiting for ANC disable\n");
308 return -ETIMEDOUT;
309 }
310
311 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
312 WM2000_ANC_ENG_IDLE, 1)) {
313 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
314 return -ETIMEDOUT;
315 }
316
317 wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
318 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
319
320 wm2000->anc_mode = ANC_BYPASS;
321 dev_dbg(&i2c->dev, "bypass enabled\n");
322
323 return 0;
324}
325
326static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue)
327{
328 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
329
330 BUG_ON(wm2000->anc_mode != ANC_BYPASS);
331
332 wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
333
334 if (analogue) {
335 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
336 WM2000_MODE_ANA_SEQ_INCLUDE |
337 WM2000_MODE_MOUSE_ENABLE |
338 WM2000_MODE_THERMAL_ENABLE);
339 } else {
340 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
341 WM2000_MODE_MOUSE_ENABLE |
342 WM2000_MODE_THERMAL_ENABLE);
343 }
344
345 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
346 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
347
348 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
349 WM2000_STATUS_MOUSE_ACTIVE, 10)) {
350 dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");
351 return -ETIMEDOUT;
352 }
353
354 wm2000->anc_mode = ANC_ACTIVE;
355 dev_dbg(&i2c->dev, "MOUSE active\n");
356
357 return 0;
358}
359
360static int wm2000_enter_standby(struct i2c_client *i2c, int analogue)
361{
362 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
363 int timeout;
364
365 BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
366
367 if (analogue) {
368 timeout = 248;
369 wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
370
371 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
372 WM2000_MODE_ANA_SEQ_INCLUDE |
373 WM2000_MODE_THERMAL_ENABLE |
374 WM2000_MODE_STANDBY_ENTRY);
375 } else {
376 timeout = 10;
377
378 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
379 WM2000_MODE_THERMAL_ENABLE |
380 WM2000_MODE_STANDBY_ENTRY);
381 }
382
383 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
384 WM2000_STATUS_ANC_DISABLED, timeout)) {
385 dev_err(&i2c->dev,
386 "Timed out waiting for ANC disable after 1ms\n");
387 return -ETIMEDOUT;
388 }
389
390 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE,
391 1)) {
392 dev_err(&i2c->dev,
393 "Timed out waiting for standby after %dms\n",
394 timeout * 10);
395 return -ETIMEDOUT;
396 }
397
398 wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
399 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
400
401 wm2000->anc_mode = ANC_STANDBY;
402 dev_dbg(&i2c->dev, "standby\n");
403 if (analogue)
404 dev_dbg(&i2c->dev, "Analogue disabled\n");
405
406 return 0;
407}
408
409static int wm2000_exit_standby(struct i2c_client *i2c, int analogue)
410{
411 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
412 int timeout;
413
414 BUG_ON(wm2000->anc_mode != ANC_STANDBY);
415
416 wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
417
418 if (analogue) {
419 timeout = 248;
420 wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
421
422 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
423 WM2000_MODE_ANA_SEQ_INCLUDE |
424 WM2000_MODE_THERMAL_ENABLE |
425 WM2000_MODE_MOUSE_ENABLE);
426 } else {
427 timeout = 10;
428
429 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
430 WM2000_MODE_THERMAL_ENABLE |
431 WM2000_MODE_MOUSE_ENABLE);
432 }
433
434 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
435 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
436
437 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
438 WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
439 dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n",
440 timeout * 10);
441 return -ETIMEDOUT;
442 }
443
444 wm2000->anc_mode = ANC_ACTIVE;
445 dev_dbg(&i2c->dev, "MOUSE active\n");
446 if (analogue)
447 dev_dbg(&i2c->dev, "Analogue enabled\n");
448
449 return 0;
450}
451
452typedef int (*wm2000_mode_fn)(struct i2c_client *i2c, int analogue);
453
454static struct {
455 enum wm2000_anc_mode source;
456 enum wm2000_anc_mode dest;
457 int analogue;
458 wm2000_mode_fn step[2];
459} anc_transitions[] = {
460 {
461 .source = ANC_OFF,
462 .dest = ANC_ACTIVE,
463 .analogue = 1,
464 .step = {
465 wm2000_power_up,
466 },
467 },
468 {
469 .source = ANC_OFF,
470 .dest = ANC_STANDBY,
471 .step = {
472 wm2000_power_up,
473 wm2000_enter_standby,
474 },
475 },
476 {
477 .source = ANC_OFF,
478 .dest = ANC_BYPASS,
479 .analogue = 1,
480 .step = {
481 wm2000_power_up,
482 wm2000_enter_bypass,
483 },
484 },
485 {
486 .source = ANC_ACTIVE,
487 .dest = ANC_BYPASS,
488 .analogue = 1,
489 .step = {
490 wm2000_enter_bypass,
491 },
492 },
493 {
494 .source = ANC_ACTIVE,
495 .dest = ANC_STANDBY,
496 .analogue = 1,
497 .step = {
498 wm2000_enter_standby,
499 },
500 },
501 {
502 .source = ANC_ACTIVE,
503 .dest = ANC_OFF,
504 .analogue = 1,
505 .step = {
506 wm2000_power_down,
507 },
508 },
509 {
510 .source = ANC_BYPASS,
511 .dest = ANC_ACTIVE,
512 .analogue = 1,
513 .step = {
514 wm2000_exit_bypass,
515 },
516 },
517 {
518 .source = ANC_BYPASS,
519 .dest = ANC_STANDBY,
520 .analogue = 1,
521 .step = {
522 wm2000_exit_bypass,
523 wm2000_enter_standby,
524 },
525 },
526 {
527 .source = ANC_BYPASS,
528 .dest = ANC_OFF,
529 .step = {
530 wm2000_exit_bypass,
531 wm2000_power_down,
532 },
533 },
534 {
535 .source = ANC_STANDBY,
536 .dest = ANC_ACTIVE,
537 .analogue = 1,
538 .step = {
539 wm2000_exit_standby,
540 },
541 },
542 {
543 .source = ANC_STANDBY,
544 .dest = ANC_BYPASS,
545 .analogue = 1,
546 .step = {
547 wm2000_exit_standby,
548 wm2000_enter_bypass,
549 },
550 },
551 {
552 .source = ANC_STANDBY,
553 .dest = ANC_OFF,
554 .step = {
555 wm2000_exit_standby,
556 wm2000_power_down,
557 },
558 },
559};
560
561static int wm2000_anc_transition(struct wm2000_priv *wm2000,
562 enum wm2000_anc_mode mode)
563{
564 struct i2c_client *i2c = wm2000->i2c;
565 int i, j;
566 int ret;
567
568 if (wm2000->anc_mode == mode)
569 return 0;
570
571 for (i = 0; i < ARRAY_SIZE(anc_transitions); i++)
572 if (anc_transitions[i].source == wm2000->anc_mode &&
573 anc_transitions[i].dest == mode)
574 break;
575 if (i == ARRAY_SIZE(anc_transitions)) {
576 dev_err(&i2c->dev, "No transition for %d->%d\n",
577 wm2000->anc_mode, mode);
578 return -EINVAL;
579 }
580
581 for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) {
582 if (!anc_transitions[i].step[j])
583 break;
584 ret = anc_transitions[i].step[j](i2c,
585 anc_transitions[i].analogue);
586 if (ret != 0)
587 return ret;
588 }
589
590 return 0;
591}
592
593static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
594{
595 struct i2c_client *i2c = wm2000->i2c;
596 enum wm2000_anc_mode mode;
597
598 if (wm2000->anc_eng_ena && wm2000->spk_ena)
599 if (wm2000->anc_active)
600 mode = ANC_ACTIVE;
601 else
602 mode = ANC_BYPASS;
603 else
604 mode = ANC_STANDBY;
605
606 dev_dbg(&i2c->dev, "Set mode %d (enabled %d, mute %d, active %d)\n",
607 mode, wm2000->anc_eng_ena, !wm2000->spk_ena,
608 wm2000->anc_active);
609
610 return wm2000_anc_transition(wm2000, mode);
611}
612
613static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
614 struct snd_ctl_elem_value *ucontrol)
615{
616 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
617
618 ucontrol->value.enumerated.item[0] = wm2000->anc_active;
619
620 return 0;
621}
622
623static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
625{
626 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
627 int anc_active = ucontrol->value.enumerated.item[0];
628
629 if (anc_active > 1)
630 return -EINVAL;
631
632 wm2000->anc_active = anc_active;
633
634 return wm2000_anc_set_mode(wm2000);
635}
636
637static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_value *ucontrol)
639{
640 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
641
642 ucontrol->value.enumerated.item[0] = wm2000->spk_ena;
643
644 return 0;
645}
646
647static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
648 struct snd_ctl_elem_value *ucontrol)
649{
650 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
651 int val = ucontrol->value.enumerated.item[0];
652
653 if (val > 1)
654 return -EINVAL;
655
656 wm2000->spk_ena = val;
657
658 return wm2000_anc_set_mode(wm2000);
659}
660
661static const struct snd_kcontrol_new wm2000_controls[] = {
662 SOC_SINGLE_BOOL_EXT("WM2000 ANC Switch", 0,
663 wm2000_anc_mode_get,
664 wm2000_anc_mode_put),
665 SOC_SINGLE_BOOL_EXT("WM2000 Switch", 0,
666 wm2000_speaker_get,
667 wm2000_speaker_put),
668};
669
670static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
671 struct snd_kcontrol *kcontrol, int event)
672{
673 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
674
675 if (SND_SOC_DAPM_EVENT_ON(event))
676 wm2000->anc_eng_ena = 1;
677
678 if (SND_SOC_DAPM_EVENT_OFF(event))
679 wm2000->anc_eng_ena = 0;
680
681 return wm2000_anc_set_mode(wm2000);
682}
683
684static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
685/* Externally visible pins */
686SND_SOC_DAPM_OUTPUT("WM2000 SPKN"),
687SND_SOC_DAPM_OUTPUT("WM2000 SPKP"),
688
689SND_SOC_DAPM_INPUT("WM2000 LINN"),
690SND_SOC_DAPM_INPUT("WM2000 LINP"),
691
692SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0,
693 wm2000_anc_power_event,
694 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
695};
696
697/* Target, Path, Source */
698static const struct snd_soc_dapm_route audio_map[] = {
699 { "WM2000 SPKN", NULL, "ANC Engine" },
700 { "WM2000 SPKP", NULL, "ANC Engine" },
701 { "ANC Engine", NULL, "WM2000 LINN" },
702 { "ANC Engine", NULL, "WM2000 LINP" },
703};
704
705/* Called from the machine driver */
706int wm2000_add_controls(struct snd_soc_codec *codec)
707{
708 int ret;
709
710 if (!wm2000_i2c) {
711 pr_err("WM2000 not yet probed\n");
712 return -ENODEV;
713 }
714
715 ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets,
716 ARRAY_SIZE(wm2000_dapm_widgets));
717 if (ret < 0)
718 return ret;
719
720 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
721 if (ret < 0)
722 return ret;
723
724 return snd_soc_add_controls(codec, wm2000_controls,
725 ARRAY_SIZE(wm2000_controls));
726}
727EXPORT_SYMBOL_GPL(wm2000_add_controls);
728
729static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
730 const struct i2c_device_id *i2c_id)
731{
732 struct wm2000_priv *wm2000;
733 struct wm2000_platform_data *pdata;
734 const char *filename;
735 const struct firmware *fw;
736 int reg, ret;
737 u16 id;
738
739 if (wm2000_i2c) {
740 dev_err(&i2c->dev, "Another WM2000 is already registered\n");
741 return -EINVAL;
742 }
743
744 wm2000 = kzalloc(sizeof(struct wm2000_priv), GFP_KERNEL);
745 if (wm2000 == NULL) {
746 dev_err(&i2c->dev, "Unable to allocate private data\n");
747 return -ENOMEM;
748 }
749
750 /* Verify that this is a WM2000 */
751 reg = wm2000_read(i2c, WM2000_REG_ID1);
752 id = reg << 8;
753 reg = wm2000_read(i2c, WM2000_REG_ID2);
754 id |= reg & 0xff;
755
756 if (id != 0x2000) {
757 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
758 ret = -ENODEV;
759 goto err;
760 }
761
762 reg = wm2000_read(i2c, WM2000_REG_REVISON);
763 dev_info(&i2c->dev, "revision %c\n", reg + 'A');
764
765 filename = "wm2000_anc.bin";
766 pdata = dev_get_platdata(&i2c->dev);
767 if (pdata) {
768 wm2000->mclk_div = pdata->mclkdiv2;
769 wm2000->speech_clarity = !pdata->speech_enh_disable;
770
771 if (pdata->download_file)
772 filename = pdata->download_file;
773 }
774
775 ret = request_firmware(&fw, filename, &i2c->dev);
776 if (ret != 0) {
777 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
778 goto err;
779 }
780
781 /* Pre-cook the concatenation of the register address onto the image */
782 wm2000->anc_download_size = fw->size + 2;
783 wm2000->anc_download = kmalloc(wm2000->anc_download_size, GFP_KERNEL);
784 if (wm2000->anc_download == NULL) {
785 dev_err(&i2c->dev, "Out of memory\n");
786 ret = -ENOMEM;
787 goto err_fw;
788 }
789
790 wm2000->anc_download[0] = 0x80;
791 wm2000->anc_download[1] = 0x00;
792 memcpy(wm2000->anc_download + 2, fw->data, fw->size);
793
794 release_firmware(fw);
795
796 dev_set_drvdata(&i2c->dev, wm2000);
797 wm2000->anc_eng_ena = 1;
798 wm2000->i2c = i2c;
799
800 wm2000_reset(wm2000);
801
802 /* This will trigger a transition to standby mode by default */
803 wm2000_anc_set_mode(wm2000);
804
805 wm2000_i2c = i2c;
806
807 return 0;
808
809err_fw:
810 release_firmware(fw);
811err:
812 kfree(wm2000);
813 return ret;
814}
815
816static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
817{
818 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
819
820 wm2000_anc_transition(wm2000, ANC_OFF);
821
822 wm2000_i2c = NULL;
823 kfree(wm2000->anc_download);
824 kfree(wm2000);
825
826 return 0;
827}
828
829static void wm2000_i2c_shutdown(struct i2c_client *i2c)
830{
831 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
832
833 wm2000_anc_transition(wm2000, ANC_OFF);
834}
835
836#ifdef CONFIG_PM
837static int wm2000_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
838{
839 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
840
841 return wm2000_anc_transition(wm2000, ANC_OFF);
842}
843
844static int wm2000_i2c_resume(struct i2c_client *i2c)
845{
846 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
847
848 return wm2000_anc_set_mode(wm2000);
849}
850#else
851#define wm2000_i2c_suspend NULL
852#define wm2000_i2c_resume NULL
853#endif
854
855static const struct i2c_device_id wm2000_i2c_id[] = {
856 { "wm2000", 0 },
857 { }
858};
859MODULE_DEVICE_TABLE(i2c, wm2000_i2c_id);
860
861static struct i2c_driver wm2000_i2c_driver = {
862 .driver = {
863 .name = "wm2000",
864 .owner = THIS_MODULE,
865 },
866 .probe = wm2000_i2c_probe,
867 .remove = __devexit_p(wm2000_i2c_remove),
868 .suspend = wm2000_i2c_suspend,
869 .resume = wm2000_i2c_resume,
870 .shutdown = wm2000_i2c_shutdown,
871 .id_table = wm2000_i2c_id,
872};
873
874static int __init wm2000_init(void)
875{
876 return i2c_add_driver(&wm2000_i2c_driver);
877}
878module_init(wm2000_init);
879
880static void __exit wm2000_exit(void)
881{
882 i2c_del_driver(&wm2000_i2c_driver);
883}
884module_exit(wm2000_exit);
885
886MODULE_DESCRIPTION("ASoC WM2000 driver");
887MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
888MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
new file mode 100644
index 000000000000..c18e261c3c7f
--- /dev/null
+++ b/sound/soc/codecs/wm2000.h
@@ -0,0 +1,79 @@
1/*
2 * wm2000.h -- WM2000 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM2000_H
10#define _WM2000_H
11
12struct wm2000_setup_data {
13 unsigned short i2c_address;
14 int mclk_div; /* Set to a non-zero value if MCLK_DIV_2 required */
15};
16
17extern int wm2000_add_controls(struct snd_soc_codec *codec);
18
19extern struct snd_soc_dai wm2000_dai;
20extern struct snd_soc_codec_device soc_codec_dev_wm2000;
21
22#define WM2000_REG_SYS_START 0x8000
23#define WM2000_REG_SPEECH_CLARITY 0x8fef
24#define WM2000_REG_SYS_WATCHDOG 0x8ff6
25#define WM2000_REG_ANA_VMID_PD_TIME 0x8ff7
26#define WM2000_REG_ANA_VMID_PU_TIME 0x8ff8
27#define WM2000_REG_CAT_FLTR_INDX 0x8ff9
28#define WM2000_REG_CAT_GAIN_0 0x8ffa
29#define WM2000_REG_SYS_STATUS 0x8ffc
30#define WM2000_REG_SYS_MODE_CNTRL 0x8ffd
31#define WM2000_REG_SYS_START0 0x8ffe
32#define WM2000_REG_SYS_START1 0x8fff
33#define WM2000_REG_ID1 0xf000
34#define WM2000_REG_ID2 0xf001
35#define WM2000_REG_REVISON 0xf002
36#define WM2000_REG_SYS_CTL1 0xf003
37#define WM2000_REG_SYS_CTL2 0xf004
38#define WM2000_REG_ANC_STAT 0xf005
39#define WM2000_REG_IF_CTL 0xf006
40
41/* SPEECH_CLARITY */
42#define WM2000_SPEECH_CLARITY 0x01
43
44/* SYS_STATUS */
45#define WM2000_STATUS_MOUSE_ACTIVE 0x40
46#define WM2000_STATUS_CAT_FREQ_COMPLETE 0x20
47#define WM2000_STATUS_CAT_GAIN_COMPLETE 0x10
48#define WM2000_STATUS_THERMAL_SHUTDOWN_COMPLETE 0x08
49#define WM2000_STATUS_ANC_DISABLED 0x04
50#define WM2000_STATUS_POWER_DOWN_COMPLETE 0x02
51#define WM2000_STATUS_BOOT_COMPLETE 0x01
52
53/* SYS_MODE_CNTRL */
54#define WM2000_MODE_ANA_SEQ_INCLUDE 0x80
55#define WM2000_MODE_MOUSE_ENABLE 0x40
56#define WM2000_MODE_CAT_FREQ_ENABLE 0x20
57#define WM2000_MODE_CAT_GAIN_ENABLE 0x10
58#define WM2000_MODE_BYPASS_ENTRY 0x08
59#define WM2000_MODE_STANDBY_ENTRY 0x04
60#define WM2000_MODE_THERMAL_ENABLE 0x02
61#define WM2000_MODE_POWER_DOWN 0x01
62
63/* SYS_CTL1 */
64#define WM2000_SYS_STBY 0x01
65
66/* SYS_CTL2 */
67#define WM2000_MCLK_DIV2_ENA_CLR 0x80
68#define WM2000_MCLK_DIV2_ENA_SET 0x40
69#define WM2000_ANC_ENG_CLR 0x20
70#define WM2000_ANC_ENG_SET 0x10
71#define WM2000_ANC_INT_N_CLR 0x08
72#define WM2000_ANC_INT_N_SET 0x04
73#define WM2000_RAM_CLR 0x02
74#define WM2000_RAM_SET 0x01
75
76/* ANC_STAT */
77#define WM2000_ANC_ENG_IDLE 0x01
78
79#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index d8ffbd641d71..63a254e293ca 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -44,23 +44,16 @@ struct snd_soc_dai wm8727_dai = {
44}; 44};
45EXPORT_SYMBOL_GPL(wm8727_dai); 45EXPORT_SYMBOL_GPL(wm8727_dai);
46 46
47static struct snd_soc_codec *wm8727_codec;
48
47static int wm8727_soc_probe(struct platform_device *pdev) 49static int wm8727_soc_probe(struct platform_device *pdev)
48{ 50{
49 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 51 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
50 struct snd_soc_codec *codec;
51 int ret = 0; 52 int ret = 0;
52 53
53 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 54 BUG_ON(!wm8727_codec);
54 if (codec == NULL) 55
55 return -ENOMEM; 56 socdev->card->codec = wm8727_codec;
56 mutex_init(&codec->mutex);
57 codec->name = "WM8727";
58 codec->owner = THIS_MODULE;
59 codec->dai = &wm8727_dai;
60 codec->num_dai = 1;
61 socdev->card->codec = codec;
62 INIT_LIST_HEAD(&codec->dapm_widgets);
63 INIT_LIST_HEAD(&codec->dapm_paths);
64 57
65 /* register pcms */ 58 /* register pcms */
66 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 59 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -80,12 +73,9 @@ pcm_err:
80static int wm8727_soc_remove(struct platform_device *pdev) 73static int wm8727_soc_remove(struct platform_device *pdev)
81{ 74{
82 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 75 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
83 struct snd_soc_codec *codec = socdev->card->codec;
84 76
85 if (codec == NULL)
86 return 0;
87 snd_soc_free_pcms(socdev); 77 snd_soc_free_pcms(socdev);
88 kfree(codec); 78
89 return 0; 79 return 0;
90} 80}
91 81
@@ -98,13 +88,55 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
98 88
99static __devinit int wm8727_platform_probe(struct platform_device *pdev) 89static __devinit int wm8727_platform_probe(struct platform_device *pdev)
100{ 90{
91 struct snd_soc_codec *codec;
92 int ret;
93
94 if (wm8727_codec) {
95 dev_err(&pdev->dev, "Another WM8727 is registered\n");
96 return -EBUSY;
97 }
98
99 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
100 if (codec == NULL)
101 return -ENOMEM;
102 wm8727_codec = codec;
103
104 platform_set_drvdata(pdev, codec);
105
106 mutex_init(&codec->mutex);
107 codec->dev = &pdev->dev;
108 codec->name = "WM8727";
109 codec->owner = THIS_MODULE;
110 codec->dai = &wm8727_dai;
111 codec->num_dai = 1;
112 INIT_LIST_HEAD(&codec->dapm_widgets);
113 INIT_LIST_HEAD(&codec->dapm_paths);
114
101 wm8727_dai.dev = &pdev->dev; 115 wm8727_dai.dev = &pdev->dev;
102 return snd_soc_register_dai(&wm8727_dai); 116
117 ret = snd_soc_register_codec(codec);
118 if (ret != 0) {
119 dev_err(&pdev->dev, "Failed to register CODEC: %d\n", ret);
120 goto err;
121 }
122
123 ret = snd_soc_register_dai(&wm8727_dai);
124 if (ret != 0) {
125 dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
126 goto err_codec;
127 }
128
129err_codec:
130 snd_soc_unregister_codec(codec);
131err:
132 kfree(codec);
133 return ret;
103} 134}
104 135
105static int __devexit wm8727_platform_remove(struct platform_device *pdev) 136static int __devexit wm8727_platform_remove(struct platform_device *pdev)
106{ 137{
107 snd_soc_unregister_dai(&wm8727_dai); 138 snd_soc_unregister_dai(&wm8727_dai);
139 snd_soc_unregister_codec(platform_get_drvdata(pdev));
108 return 0; 140 return 0;
109} 141}
110 142
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 3a497810f939..5a2619dbf283 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -456,6 +456,9 @@ static int wm8731_resume(struct platform_device *pdev)
456 456
457 /* Sync reg_cache with the hardware */ 457 /* Sync reg_cache with the hardware */
458 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 458 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
459 if (cache[i] == wm8731_reg[i])
460 continue;
461
459 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 462 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
460 data[1] = cache[i] & 0x00ff; 463 data[1] = cache[i] & 0x00ff;
461 codec->hw_write(codec->control_data, data, 2); 464 codec->hw_write(codec->control_data, data, 2);
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index d6850dacda29..c2444e7c8480 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1507,10 +1507,6 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1508 struct snd_soc_codec *codec = socdev->card->codec; 1508 struct snd_soc_codec *codec = socdev->card->codec;
1509 1509
1510 /* we only need to suspend if we are a valid card */
1511 if (!codec->card)
1512 return 0;
1513
1514 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1510 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1515 return 0; 1511 return 0;
1516} 1512}
@@ -1523,10 +1519,6 @@ static int wm8753_resume(struct platform_device *pdev)
1523 u8 data[2]; 1519 u8 data[2];
1524 u16 *cache = codec->reg_cache; 1520 u16 *cache = codec->reg_cache;
1525 1521
1526 /* we only need to resume if we are a valid card */
1527 if (!codec->card)
1528 return 0;
1529
1530 /* Sync reg_cache with the hardware */ 1522 /* Sync reg_cache with the hardware */
1531 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { 1523 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
1532 if (i + 1 == WM8753_RESET) 1524 if (i + 1 == WM8753_RESET)
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index ab2c0da18091..44e7d9d82f87 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -406,6 +406,8 @@ static int wm8776_resume(struct platform_device *pdev)
406 406
407 /* Sync reg_cache with the hardware */ 407 /* Sync reg_cache with the hardware */
408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) { 408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
409 if (cache[i] == wm8776_reg[i])
410 continue;
409 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 411 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
410 data[1] = cache[i] & 0x00ff; 412 data[1] = cache[i] & 0x00ff;
411 codec->hw_write(codec->control_data, data, 2); 413 codec->hw_write(codec->control_data, data, 2);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
new file mode 100644
index 000000000000..593e47d0e0eb
--- /dev/null
+++ b/sound/soc/codecs/wm8904.c
@@ -0,0 +1,2656 @@
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
36enum wm8904_type {
37 WM8904,
38 WM8912,
39};
40
41#define WM8904_NUM_DCS_CHANNELS 4
42
43#define WM8904_NUM_SUPPLIES 5
44static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
45 "DCVDD",
46 "DBVDD",
47 "AVDD",
48 "CPVDD",
49 "MICVDD",
50};
51
52/* codec private data */
53struct wm8904_priv {
54 struct snd_soc_codec codec;
55 u16 reg_cache[WM8904_MAX_REGISTER + 1];
56
57 enum wm8904_type devtype;
58
59 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
60
61 struct wm8904_pdata *pdata;
62
63 int deemph;
64
65 /* Platform provided DRC configuration */
66 const char **drc_texts;
67 int drc_cfg;
68 struct soc_enum drc_enum;
69
70 /* Platform provided ReTune mobile configuration */
71 int num_retune_mobile_texts;
72 const char **retune_mobile_texts;
73 int retune_mobile_cfg;
74 struct soc_enum retune_mobile_enum;
75
76 /* FLL setup */
77 int fll_src;
78 int fll_fref;
79 int fll_fout;
80
81 /* Clocking configuration */
82 unsigned int mclk_rate;
83 int sysclk_src;
84 unsigned int sysclk_rate;
85
86 int tdm_width;
87 int tdm_slots;
88 int bclk;
89 int fs;
90
91 /* DC servo configuration - cached offset values */
92 int dcs_state[WM8904_NUM_DCS_CHANNELS];
93};
94
95static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = {
96 0x8904, /* R0 - SW Reset and ID */
97 0x0000, /* R1 - Revision */
98 0x0000, /* R2 */
99 0x0000, /* R3 */
100 0x0018, /* R4 - Bias Control 0 */
101 0x0000, /* R5 - VMID Control 0 */
102 0x0000, /* R6 - Mic Bias Control 0 */
103 0x0000, /* R7 - Mic Bias Control 1 */
104 0x0001, /* R8 - Analogue DAC 0 */
105 0x9696, /* R9 - mic Filter Control */
106 0x0001, /* R10 - Analogue ADC 0 */
107 0x0000, /* R11 */
108 0x0000, /* R12 - Power Management 0 */
109 0x0000, /* R13 */
110 0x0000, /* R14 - Power Management 2 */
111 0x0000, /* R15 - Power Management 3 */
112 0x0000, /* R16 */
113 0x0000, /* R17 */
114 0x0000, /* R18 - Power Management 6 */
115 0x0000, /* R19 */
116 0x945E, /* R20 - Clock Rates 0 */
117 0x0C05, /* R21 - Clock Rates 1 */
118 0x0006, /* R22 - Clock Rates 2 */
119 0x0000, /* R23 */
120 0x0050, /* R24 - Audio Interface 0 */
121 0x000A, /* R25 - Audio Interface 1 */
122 0x00E4, /* R26 - Audio Interface 2 */
123 0x0040, /* R27 - Audio Interface 3 */
124 0x0000, /* R28 */
125 0x0000, /* R29 */
126 0x00C0, /* R30 - DAC Digital Volume Left */
127 0x00C0, /* R31 - DAC Digital Volume Right */
128 0x0000, /* R32 - DAC Digital 0 */
129 0x0008, /* R33 - DAC Digital 1 */
130 0x0000, /* R34 */
131 0x0000, /* R35 */
132 0x00C0, /* R36 - ADC Digital Volume Left */
133 0x00C0, /* R37 - ADC Digital Volume Right */
134 0x0010, /* R38 - ADC Digital 0 */
135 0x0000, /* R39 - Digital Microphone 0 */
136 0x01AF, /* R40 - DRC 0 */
137 0x3248, /* R41 - DRC 1 */
138 0x0000, /* R42 - DRC 2 */
139 0x0000, /* R43 - DRC 3 */
140 0x0085, /* R44 - Analogue Left Input 0 */
141 0x0085, /* R45 - Analogue Right Input 0 */
142 0x0044, /* R46 - Analogue Left Input 1 */
143 0x0044, /* R47 - Analogue Right Input 1 */
144 0x0000, /* R48 */
145 0x0000, /* R49 */
146 0x0000, /* R50 */
147 0x0000, /* R51 */
148 0x0000, /* R52 */
149 0x0000, /* R53 */
150 0x0000, /* R54 */
151 0x0000, /* R55 */
152 0x0000, /* R56 */
153 0x002D, /* R57 - Analogue OUT1 Left */
154 0x002D, /* R58 - Analogue OUT1 Right */
155 0x0039, /* R59 - Analogue OUT2 Left */
156 0x0039, /* R60 - Analogue OUT2 Right */
157 0x0000, /* R61 - Analogue OUT12 ZC */
158 0x0000, /* R62 */
159 0x0000, /* R63 */
160 0x0000, /* R64 */
161 0x0000, /* R65 */
162 0x0000, /* R66 */
163 0x0000, /* R67 - DC Servo 0 */
164 0x0000, /* R68 - DC Servo 1 */
165 0xAAAA, /* R69 - DC Servo 2 */
166 0x0000, /* R70 */
167 0xAAAA, /* R71 - DC Servo 4 */
168 0xAAAA, /* R72 - DC Servo 5 */
169 0x0000, /* R73 - DC Servo 6 */
170 0x0000, /* R74 - DC Servo 7 */
171 0x0000, /* R75 - DC Servo 8 */
172 0x0000, /* R76 - DC Servo 9 */
173 0x0000, /* R77 - DC Servo Readback 0 */
174 0x0000, /* R78 */
175 0x0000, /* R79 */
176 0x0000, /* R80 */
177 0x0000, /* R81 */
178 0x0000, /* R82 */
179 0x0000, /* R83 */
180 0x0000, /* R84 */
181 0x0000, /* R85 */
182 0x0000, /* R86 */
183 0x0000, /* R87 */
184 0x0000, /* R88 */
185 0x0000, /* R89 */
186 0x0000, /* R90 - Analogue HP 0 */
187 0x0000, /* R91 */
188 0x0000, /* R92 */
189 0x0000, /* R93 */
190 0x0000, /* R94 - Analogue Lineout 0 */
191 0x0000, /* R95 */
192 0x0000, /* R96 */
193 0x0000, /* R97 */
194 0x0000, /* R98 - Charge Pump 0 */
195 0x0000, /* R99 */
196 0x0000, /* R100 */
197 0x0000, /* R101 */
198 0x0000, /* R102 */
199 0x0000, /* R103 */
200 0x0004, /* R104 - Class W 0 */
201 0x0000, /* R105 */
202 0x0000, /* R106 */
203 0x0000, /* R107 */
204 0x0000, /* R108 - Write Sequencer 0 */
205 0x0000, /* R109 - Write Sequencer 1 */
206 0x0000, /* R110 - Write Sequencer 2 */
207 0x0000, /* R111 - Write Sequencer 3 */
208 0x0000, /* R112 - Write Sequencer 4 */
209 0x0000, /* R113 */
210 0x0000, /* R114 */
211 0x0000, /* R115 */
212 0x0000, /* R116 - FLL Control 1 */
213 0x0007, /* R117 - FLL Control 2 */
214 0x0000, /* R118 - FLL Control 3 */
215 0x2EE0, /* R119 - FLL Control 4 */
216 0x0004, /* R120 - FLL Control 5 */
217 0x0014, /* R121 - GPIO Control 1 */
218 0x0010, /* R122 - GPIO Control 2 */
219 0x0010, /* R123 - GPIO Control 3 */
220 0x0000, /* R124 - GPIO Control 4 */
221 0x0000, /* R125 */
222 0x0000, /* R126 - Digital Pulls */
223 0x0000, /* R127 - Interrupt Status */
224 0xFFFF, /* R128 - Interrupt Status Mask */
225 0x0000, /* R129 - Interrupt Polarity */
226 0x0000, /* R130 - Interrupt Debounce */
227 0x0000, /* R131 */
228 0x0000, /* R132 */
229 0x0000, /* R133 */
230 0x0000, /* R134 - EQ1 */
231 0x000C, /* R135 - EQ2 */
232 0x000C, /* R136 - EQ3 */
233 0x000C, /* R137 - EQ4 */
234 0x000C, /* R138 - EQ5 */
235 0x000C, /* R139 - EQ6 */
236 0x0FCA, /* R140 - EQ7 */
237 0x0400, /* R141 - EQ8 */
238 0x00D8, /* R142 - EQ9 */
239 0x1EB5, /* R143 - EQ10 */
240 0xF145, /* R144 - EQ11 */
241 0x0B75, /* R145 - EQ12 */
242 0x01C5, /* R146 - EQ13 */
243 0x1C58, /* R147 - EQ14 */
244 0xF373, /* R148 - EQ15 */
245 0x0A54, /* R149 - EQ16 */
246 0x0558, /* R150 - EQ17 */
247 0x168E, /* R151 - EQ18 */
248 0xF829, /* R152 - EQ19 */
249 0x07AD, /* R153 - EQ20 */
250 0x1103, /* R154 - EQ21 */
251 0x0564, /* R155 - EQ22 */
252 0x0559, /* R156 - EQ23 */
253 0x4000, /* R157 - EQ24 */
254 0x0000, /* R158 */
255 0x0000, /* R159 */
256 0x0000, /* R160 */
257 0x0000, /* R161 - Control Interface Test 1 */
258 0x0000, /* R162 */
259 0x0000, /* R163 */
260 0x0000, /* R164 */
261 0x0000, /* R165 */
262 0x0000, /* R166 */
263 0x0000, /* R167 */
264 0x0000, /* R168 */
265 0x0000, /* R169 */
266 0x0000, /* R170 */
267 0x0000, /* R171 */
268 0x0000, /* R172 */
269 0x0000, /* R173 */
270 0x0000, /* R174 */
271 0x0000, /* R175 */
272 0x0000, /* R176 */
273 0x0000, /* R177 */
274 0x0000, /* R178 */
275 0x0000, /* R179 */
276 0x0000, /* R180 */
277 0x0000, /* R181 */
278 0x0000, /* R182 */
279 0x0000, /* R183 */
280 0x0000, /* R184 */
281 0x0000, /* R185 */
282 0x0000, /* R186 */
283 0x0000, /* R187 */
284 0x0000, /* R188 */
285 0x0000, /* R189 */
286 0x0000, /* R190 */
287 0x0000, /* R191 */
288 0x0000, /* R192 */
289 0x0000, /* R193 */
290 0x0000, /* R194 */
291 0x0000, /* R195 */
292 0x0000, /* R196 */
293 0x0000, /* R197 */
294 0x0000, /* R198 */
295 0x0000, /* R199 */
296 0x0000, /* R200 */
297 0x0000, /* R201 */
298 0x0000, /* R202 */
299 0x0000, /* R203 */
300 0x0000, /* R204 - Analogue Output Bias 0 */
301 0x0000, /* R205 */
302 0x0000, /* R206 */
303 0x0000, /* R207 */
304 0x0000, /* R208 */
305 0x0000, /* R209 */
306 0x0000, /* R210 */
307 0x0000, /* R211 */
308 0x0000, /* R212 */
309 0x0000, /* R213 */
310 0x0000, /* R214 */
311 0x0000, /* R215 */
312 0x0000, /* R216 */
313 0x0000, /* R217 */
314 0x0000, /* R218 */
315 0x0000, /* R219 */
316 0x0000, /* R220 */
317 0x0000, /* R221 */
318 0x0000, /* R222 */
319 0x0000, /* R223 */
320 0x0000, /* R224 */
321 0x0000, /* R225 */
322 0x0000, /* R226 */
323 0x0000, /* R227 */
324 0x0000, /* R228 */
325 0x0000, /* R229 */
326 0x0000, /* R230 */
327 0x0000, /* R231 */
328 0x0000, /* R232 */
329 0x0000, /* R233 */
330 0x0000, /* R234 */
331 0x0000, /* R235 */
332 0x0000, /* R236 */
333 0x0000, /* R237 */
334 0x0000, /* R238 */
335 0x0000, /* R239 */
336 0x0000, /* R240 */
337 0x0000, /* R241 */
338 0x0000, /* R242 */
339 0x0000, /* R243 */
340 0x0000, /* R244 */
341 0x0000, /* R245 */
342 0x0000, /* R246 */
343 0x0000, /* R247 - FLL NCO Test 0 */
344 0x0019, /* R248 - FLL NCO Test 1 */
345};
346
347static struct {
348 int readable;
349 int writable;
350 int vol;
351} wm8904_access[] = {
352 { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */
353 { 0x0000, 0x0000, 0 }, /* R1 - Revision */
354 { 0x0000, 0x0000, 0 }, /* R2 */
355 { 0x0000, 0x0000, 0 }, /* R3 */
356 { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */
357 { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */
358 { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */
359 { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */
360 { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */
361 { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */
362 { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */
363 { 0x0000, 0x0000, 0 }, /* R11 */
364 { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */
365 { 0x0000, 0x0000, 0 }, /* R13 */
366 { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */
367 { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */
368 { 0x0000, 0x0000, 0 }, /* R16 */
369 { 0x0000, 0x0000, 0 }, /* R17 */
370 { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */
371 { 0x0000, 0x0000, 0 }, /* R19 */
372 { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */
373 { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */
374 { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */
375 { 0x0000, 0x0000, 0 }, /* R23 */
376 { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */
377 { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */
378 { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */
379 { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */
380 { 0x0000, 0x0000, 0 }, /* R28 */
381 { 0x0000, 0x0000, 0 }, /* R29 */
382 { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */
383 { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */
384 { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */
385 { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */
386 { 0x0000, 0x0000, 0 }, /* R34 */
387 { 0x0000, 0x0000, 0 }, /* R35 */
388 { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */
389 { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */
390 { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */
391 { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */
392 { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */
393 { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */
394 { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */
395 { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */
396 { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */
397 { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */
398 { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */
399 { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */
400 { 0x0000, 0x0000, 0 }, /* R48 */
401 { 0x0000, 0x0000, 0 }, /* R49 */
402 { 0x0000, 0x0000, 0 }, /* R50 */
403 { 0x0000, 0x0000, 0 }, /* R51 */
404 { 0x0000, 0x0000, 0 }, /* R52 */
405 { 0x0000, 0x0000, 0 }, /* R53 */
406 { 0x0000, 0x0000, 0 }, /* R54 */
407 { 0x0000, 0x0000, 0 }, /* R55 */
408 { 0x0000, 0x0000, 0 }, /* R56 */
409 { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */
410 { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */
411 { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */
412 { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */
413 { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */
414 { 0x0000, 0x0000, 0 }, /* R62 */
415 { 0x0000, 0x0000, 0 }, /* R63 */
416 { 0x0000, 0x0000, 0 }, /* R64 */
417 { 0x0000, 0x0000, 0 }, /* R65 */
418 { 0x0000, 0x0000, 0 }, /* R66 */
419 { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */
420 { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */
421 { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */
422 { 0x0000, 0x0000, 0 }, /* R70 */
423 { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */
424 { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */
425 { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */
426 { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */
427 { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */
428 { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */
429 { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */
430 { 0x0000, 0x0000, 0 }, /* R78 */
431 { 0x0000, 0x0000, 0 }, /* R79 */
432 { 0x0000, 0x0000, 0 }, /* R80 */
433 { 0x0000, 0x0000, 0 }, /* R81 */
434 { 0x0000, 0x0000, 0 }, /* R82 */
435 { 0x0000, 0x0000, 0 }, /* R83 */
436 { 0x0000, 0x0000, 0 }, /* R84 */
437 { 0x0000, 0x0000, 0 }, /* R85 */
438 { 0x0000, 0x0000, 0 }, /* R86 */
439 { 0x0000, 0x0000, 0 }, /* R87 */
440 { 0x0000, 0x0000, 0 }, /* R88 */
441 { 0x0000, 0x0000, 0 }, /* R89 */
442 { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */
443 { 0x0000, 0x0000, 0 }, /* R91 */
444 { 0x0000, 0x0000, 0 }, /* R92 */
445 { 0x0000, 0x0000, 0 }, /* R93 */
446 { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */
447 { 0x0000, 0x0000, 0 }, /* R95 */
448 { 0x0000, 0x0000, 0 }, /* R96 */
449 { 0x0000, 0x0000, 0 }, /* R97 */
450 { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */
451 { 0x0000, 0x0000, 0 }, /* R99 */
452 { 0x0000, 0x0000, 0 }, /* R100 */
453 { 0x0000, 0x0000, 0 }, /* R101 */
454 { 0x0000, 0x0000, 0 }, /* R102 */
455 { 0x0000, 0x0000, 0 }, /* R103 */
456 { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
457 { 0x0000, 0x0000, 0 }, /* R105 */
458 { 0x0000, 0x0000, 0 }, /* R106 */
459 { 0x0000, 0x0000, 0 }, /* R107 */
460 { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
461 { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
462 { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
463 { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
464 { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
465 { 0x0000, 0x0000, 0 }, /* R113 */
466 { 0x0000, 0x0000, 0 }, /* R114 */
467 { 0x0000, 0x0000, 0 }, /* R115 */
468 { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
469 { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
470 { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
471 { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
472 { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
473 { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
474 { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
475 { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
476 { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
477 { 0x0000, 0x0000, 0 }, /* R125 */
478 { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
479 { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
480 { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
481 { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
482 { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
483 { 0x0000, 0x0000, 0 }, /* R131 */
484 { 0x0000, 0x0000, 0 }, /* R132 */
485 { 0x0000, 0x0000, 0 }, /* R133 */
486 { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
487 { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
488 { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
489 { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
490 { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
491 { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
492 { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
493 { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
494 { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
495 { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
496 { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
497 { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
498 { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
499 { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
500 { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
501 { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
502 { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
503 { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
504 { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
505 { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
506 { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
507 { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
508 { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
509 { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
510 { 0x0000, 0x0000, 0 }, /* R158 */
511 { 0x0000, 0x0000, 0 }, /* R159 */
512 { 0x0000, 0x0000, 0 }, /* R160 */
513 { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
514 { 0x0000, 0x0000, 0 }, /* R162 */
515 { 0x0000, 0x0000, 0 }, /* R163 */
516 { 0x0000, 0x0000, 0 }, /* R164 */
517 { 0x0000, 0x0000, 0 }, /* R165 */
518 { 0x0000, 0x0000, 0 }, /* R166 */
519 { 0x0000, 0x0000, 0 }, /* R167 */
520 { 0x0000, 0x0000, 0 }, /* R168 */
521 { 0x0000, 0x0000, 0 }, /* R169 */
522 { 0x0000, 0x0000, 0 }, /* R170 */
523 { 0x0000, 0x0000, 0 }, /* R171 */
524 { 0x0000, 0x0000, 0 }, /* R172 */
525 { 0x0000, 0x0000, 0 }, /* R173 */
526 { 0x0000, 0x0000, 0 }, /* R174 */
527 { 0x0000, 0x0000, 0 }, /* R175 */
528 { 0x0000, 0x0000, 0 }, /* R176 */
529 { 0x0000, 0x0000, 0 }, /* R177 */
530 { 0x0000, 0x0000, 0 }, /* R178 */
531 { 0x0000, 0x0000, 0 }, /* R179 */
532 { 0x0000, 0x0000, 0 }, /* R180 */
533 { 0x0000, 0x0000, 0 }, /* R181 */
534 { 0x0000, 0x0000, 0 }, /* R182 */
535 { 0x0000, 0x0000, 0 }, /* R183 */
536 { 0x0000, 0x0000, 0 }, /* R184 */
537 { 0x0000, 0x0000, 0 }, /* R185 */
538 { 0x0000, 0x0000, 0 }, /* R186 */
539 { 0x0000, 0x0000, 0 }, /* R187 */
540 { 0x0000, 0x0000, 0 }, /* R188 */
541 { 0x0000, 0x0000, 0 }, /* R189 */
542 { 0x0000, 0x0000, 0 }, /* R190 */
543 { 0x0000, 0x0000, 0 }, /* R191 */
544 { 0x0000, 0x0000, 0 }, /* R192 */
545 { 0x0000, 0x0000, 0 }, /* R193 */
546 { 0x0000, 0x0000, 0 }, /* R194 */
547 { 0x0000, 0x0000, 0 }, /* R195 */
548 { 0x0000, 0x0000, 0 }, /* R196 */
549 { 0x0000, 0x0000, 0 }, /* R197 */
550 { 0x0000, 0x0000, 0 }, /* R198 */
551 { 0x0000, 0x0000, 0 }, /* R199 */
552 { 0x0000, 0x0000, 0 }, /* R200 */
553 { 0x0000, 0x0000, 0 }, /* R201 */
554 { 0x0000, 0x0000, 0 }, /* R202 */
555 { 0x0000, 0x0000, 0 }, /* R203 */
556 { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
557 { 0x0000, 0x0000, 0 }, /* R205 */
558 { 0x0000, 0x0000, 0 }, /* R206 */
559 { 0x0000, 0x0000, 0 }, /* R207 */
560 { 0x0000, 0x0000, 0 }, /* R208 */
561 { 0x0000, 0x0000, 0 }, /* R209 */
562 { 0x0000, 0x0000, 0 }, /* R210 */
563 { 0x0000, 0x0000, 0 }, /* R211 */
564 { 0x0000, 0x0000, 0 }, /* R212 */
565 { 0x0000, 0x0000, 0 }, /* R213 */
566 { 0x0000, 0x0000, 0 }, /* R214 */
567 { 0x0000, 0x0000, 0 }, /* R215 */
568 { 0x0000, 0x0000, 0 }, /* R216 */
569 { 0x0000, 0x0000, 0 }, /* R217 */
570 { 0x0000, 0x0000, 0 }, /* R218 */
571 { 0x0000, 0x0000, 0 }, /* R219 */
572 { 0x0000, 0x0000, 0 }, /* R220 */
573 { 0x0000, 0x0000, 0 }, /* R221 */
574 { 0x0000, 0x0000, 0 }, /* R222 */
575 { 0x0000, 0x0000, 0 }, /* R223 */
576 { 0x0000, 0x0000, 0 }, /* R224 */
577 { 0x0000, 0x0000, 0 }, /* R225 */
578 { 0x0000, 0x0000, 0 }, /* R226 */
579 { 0x0000, 0x0000, 0 }, /* R227 */
580 { 0x0000, 0x0000, 0 }, /* R228 */
581 { 0x0000, 0x0000, 0 }, /* R229 */
582 { 0x0000, 0x0000, 0 }, /* R230 */
583 { 0x0000, 0x0000, 0 }, /* R231 */
584 { 0x0000, 0x0000, 0 }, /* R232 */
585 { 0x0000, 0x0000, 0 }, /* R233 */
586 { 0x0000, 0x0000, 0 }, /* R234 */
587 { 0x0000, 0x0000, 0 }, /* R235 */
588 { 0x0000, 0x0000, 0 }, /* R236 */
589 { 0x0000, 0x0000, 0 }, /* R237 */
590 { 0x0000, 0x0000, 0 }, /* R238 */
591 { 0x0000, 0x0000, 0 }, /* R239 */
592 { 0x0000, 0x0000, 0 }, /* R240 */
593 { 0x0000, 0x0000, 0 }, /* R241 */
594 { 0x0000, 0x0000, 0 }, /* R242 */
595 { 0x0000, 0x0000, 0 }, /* R243 */
596 { 0x0000, 0x0000, 0 }, /* R244 */
597 { 0x0000, 0x0000, 0 }, /* R245 */
598 { 0x0000, 0x0000, 0 }, /* R246 */
599 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
600 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
601};
602
603static int wm8904_volatile_register(unsigned int reg)
604{
605 return wm8904_access[reg].vol;
606}
607
608static int wm8904_reset(struct snd_soc_codec *codec)
609{
610 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
611}
612
613static int wm8904_configure_clocking(struct snd_soc_codec *codec)
614{
615 struct wm8904_priv *wm8904 = codec->private_data;
616 unsigned int clock0, clock2, rate;
617
618 /* Gate the clock while we're updating to avoid misclocking */
619 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
620 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
621 WM8904_SYSCLK_SRC, 0);
622
623 /* This should be done on init() for bypass paths */
624 switch (wm8904->sysclk_src) {
625 case WM8904_CLK_MCLK:
626 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
627
628 clock2 &= ~WM8904_SYSCLK_SRC;
629 rate = wm8904->mclk_rate;
630
631 /* Ensure the FLL is stopped */
632 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
633 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
634 break;
635
636 case WM8904_CLK_FLL:
637 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
638 wm8904->fll_fout);
639
640 clock2 |= WM8904_SYSCLK_SRC;
641 rate = wm8904->fll_fout;
642 break;
643
644 default:
645 dev_err(codec->dev, "System clock not configured\n");
646 return -EINVAL;
647 }
648
649 /* SYSCLK shouldn't be over 13.5MHz */
650 if (rate > 13500000) {
651 clock0 = WM8904_MCLK_DIV;
652 wm8904->sysclk_rate = rate / 2;
653 } else {
654 clock0 = 0;
655 wm8904->sysclk_rate = rate;
656 }
657
658 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
659 clock0);
660
661 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
662 WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2);
663
664 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
665
666 return 0;
667}
668
669static void wm8904_set_drc(struct snd_soc_codec *codec)
670{
671 struct wm8904_priv *wm8904 = codec->private_data;
672 struct wm8904_pdata *pdata = wm8904->pdata;
673 int save, i;
674
675 /* Save any enables; the configuration should clear them. */
676 save = snd_soc_read(codec, WM8904_DRC_0);
677
678 for (i = 0; i < WM8904_DRC_REGS; i++)
679 snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff,
680 pdata->drc_cfgs[wm8904->drc_cfg].regs[i]);
681
682 /* Reenable the DRC */
683 snd_soc_update_bits(codec, WM8904_DRC_0,
684 WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save);
685}
686
687static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
688 struct snd_ctl_elem_value *ucontrol)
689{
690 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
691 struct wm8904_priv *wm8904 = codec->private_data;
692 struct wm8904_pdata *pdata = wm8904->pdata;
693 int value = ucontrol->value.integer.value[0];
694
695 if (value >= pdata->num_drc_cfgs)
696 return -EINVAL;
697
698 wm8904->drc_cfg = value;
699
700 wm8904_set_drc(codec);
701
702 return 0;
703}
704
705static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
706 struct snd_ctl_elem_value *ucontrol)
707{
708 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
709 struct wm8904_priv *wm8904 = codec->private_data;
710
711 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
712
713 return 0;
714}
715
716static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
717{
718 struct wm8904_priv *wm8904 = codec->private_data;
719 struct wm8904_pdata *pdata = wm8904->pdata;
720 int best, best_val, save, i, cfg;
721
722 if (!pdata || !wm8904->num_retune_mobile_texts)
723 return;
724
725 /* Find the version of the currently selected configuration
726 * with the nearest sample rate. */
727 cfg = wm8904->retune_mobile_cfg;
728 best = 0;
729 best_val = INT_MAX;
730 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
731 if (strcmp(pdata->retune_mobile_cfgs[i].name,
732 wm8904->retune_mobile_texts[cfg]) == 0 &&
733 abs(pdata->retune_mobile_cfgs[i].rate
734 - wm8904->fs) < best_val) {
735 best = i;
736 best_val = abs(pdata->retune_mobile_cfgs[i].rate
737 - wm8904->fs);
738 }
739 }
740
741 dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
742 pdata->retune_mobile_cfgs[best].name,
743 pdata->retune_mobile_cfgs[best].rate,
744 wm8904->fs);
745
746 /* The EQ will be disabled while reconfiguring it, remember the
747 * current configuration.
748 */
749 save = snd_soc_read(codec, WM8904_EQ1);
750
751 for (i = 0; i < WM8904_EQ_REGS; i++)
752 snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff,
753 pdata->retune_mobile_cfgs[best].regs[i]);
754
755 snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save);
756}
757
758static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
759 struct snd_ctl_elem_value *ucontrol)
760{
761 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
762 struct wm8904_priv *wm8904 = codec->private_data;
763 struct wm8904_pdata *pdata = wm8904->pdata;
764 int value = ucontrol->value.integer.value[0];
765
766 if (value >= pdata->num_retune_mobile_cfgs)
767 return -EINVAL;
768
769 wm8904->retune_mobile_cfg = value;
770
771 wm8904_set_retune_mobile(codec);
772
773 return 0;
774}
775
776static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
777 struct snd_ctl_elem_value *ucontrol)
778{
779 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
780 struct wm8904_priv *wm8904 = codec->private_data;
781
782 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
783
784 return 0;
785}
786
787static int deemph_settings[] = { 0, 32000, 44100, 48000 };
788
789static int wm8904_set_deemph(struct snd_soc_codec *codec)
790{
791 struct wm8904_priv *wm8904 = codec->private_data;
792 int val, i, best;
793
794 /* If we're using deemphasis select the nearest available sample
795 * rate.
796 */
797 if (wm8904->deemph) {
798 best = 1;
799 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
800 if (abs(deemph_settings[i] - wm8904->fs) <
801 abs(deemph_settings[best] - wm8904->fs))
802 best = i;
803 }
804
805 val = best << WM8904_DEEMPH_SHIFT;
806 } else {
807 val = 0;
808 }
809
810 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
811
812 return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
813 WM8904_DEEMPH_MASK, val);
814}
815
816static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
817 struct snd_ctl_elem_value *ucontrol)
818{
819 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
820 struct wm8904_priv *wm8904 = codec->private_data;
821
822 return wm8904->deemph;
823}
824
825static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
826 struct snd_ctl_elem_value *ucontrol)
827{
828 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
829 struct wm8904_priv *wm8904 = codec->private_data;
830 int deemph = ucontrol->value.enumerated.item[0];
831
832 if (deemph > 1)
833 return -EINVAL;
834
835 wm8904->deemph = deemph;
836
837 return wm8904_set_deemph(codec);
838}
839
840static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
841static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
842static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
843static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
844static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
845
846static const char *input_mode_text[] = {
847 "Single-Ended", "Differential Line", "Differential Mic"
848};
849
850static const struct soc_enum lin_mode =
851 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
852
853static const struct soc_enum rin_mode =
854 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
855
856static const char *hpf_mode_text[] = {
857 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
858};
859
860static const struct soc_enum hpf_mode =
861 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
862
863static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
864SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
865 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
866
867SOC_ENUM("Left Caputure Mode", lin_mode),
868SOC_ENUM("Right Capture Mode", rin_mode),
869
870/* No TLV since it depends on mode */
871SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
872 WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
873SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
874 WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0),
875
876SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
877SOC_ENUM("High Pass Filter Mode", hpf_mode),
878
879SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0),
880};
881
882static const char *drc_path_text[] = {
883 "ADC", "DAC"
884};
885
886static const struct soc_enum drc_path =
887 SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text);
888
889static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = {
890SOC_SINGLE_TLV("Digital Playback Boost Volume",
891 WM8904_AUDIO_INTERFACE_0, 9, 3, 0, dac_boost_tlv),
892SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8904_DAC_DIGITAL_VOLUME_LEFT,
893 WM8904_DAC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
894
895SOC_DOUBLE_R_TLV("Headphone Volume", WM8904_ANALOGUE_OUT1_LEFT,
896 WM8904_ANALOGUE_OUT1_RIGHT, 0, 63, 0, out_tlv),
897SOC_DOUBLE_R("Headphone Switch", WM8904_ANALOGUE_OUT1_LEFT,
898 WM8904_ANALOGUE_OUT1_RIGHT, 8, 1, 1),
899SOC_DOUBLE_R("Headphone ZC Switch", WM8904_ANALOGUE_OUT1_LEFT,
900 WM8904_ANALOGUE_OUT1_RIGHT, 6, 1, 0),
901
902SOC_DOUBLE_R_TLV("Line Output Volume", WM8904_ANALOGUE_OUT2_LEFT,
903 WM8904_ANALOGUE_OUT2_RIGHT, 0, 63, 0, out_tlv),
904SOC_DOUBLE_R("Line Output Switch", WM8904_ANALOGUE_OUT2_LEFT,
905 WM8904_ANALOGUE_OUT2_RIGHT, 8, 1, 1),
906SOC_DOUBLE_R("Line Output ZC Switch", WM8904_ANALOGUE_OUT2_LEFT,
907 WM8904_ANALOGUE_OUT2_RIGHT, 6, 1, 0),
908
909SOC_SINGLE("EQ Switch", WM8904_EQ1, 0, 1, 0),
910SOC_SINGLE("DRC Switch", WM8904_DRC_0, 15, 1, 0),
911SOC_ENUM("DRC Path", drc_path),
912SOC_SINGLE("DAC OSRx2 Switch", WM8904_DAC_DIGITAL_1, 6, 1, 0),
913SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
914 wm8904_get_deemph, wm8904_put_deemph),
915};
916
917static const struct snd_kcontrol_new wm8904_snd_controls[] = {
918SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8904_DAC_DIGITAL_0, 4, 8, 15, 0,
919 sidetone_tlv),
920};
921
922static const struct snd_kcontrol_new wm8904_eq_controls[] = {
923SOC_SINGLE_TLV("EQ1 Volume", WM8904_EQ2, 0, 24, 0, eq_tlv),
924SOC_SINGLE_TLV("EQ2 Volume", WM8904_EQ3, 0, 24, 0, eq_tlv),
925SOC_SINGLE_TLV("EQ3 Volume", WM8904_EQ4, 0, 24, 0, eq_tlv),
926SOC_SINGLE_TLV("EQ4 Volume", WM8904_EQ5, 0, 24, 0, eq_tlv),
927SOC_SINGLE_TLV("EQ5 Volume", WM8904_EQ6, 0, 24, 0, eq_tlv),
928};
929
930static int cp_event(struct snd_soc_dapm_widget *w,
931 struct snd_kcontrol *kcontrol, int event)
932{
933 BUG_ON(event != SND_SOC_DAPM_POST_PMU);
934
935 /* Maximum startup time */
936 udelay(500);
937
938 return 0;
939}
940
941static int sysclk_event(struct snd_soc_dapm_widget *w,
942 struct snd_kcontrol *kcontrol, int event)
943{
944 struct snd_soc_codec *codec = w->codec;
945 struct wm8904_priv *wm8904 = codec->private_data;
946
947 switch (event) {
948 case SND_SOC_DAPM_PRE_PMU:
949 /* If we're using the FLL then we only start it when
950 * required; we assume that the configuration has been
951 * done previously and all we need to do is kick it
952 * off.
953 */
954 switch (wm8904->sysclk_src) {
955 case WM8904_CLK_FLL:
956 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
957 WM8904_FLL_OSC_ENA,
958 WM8904_FLL_OSC_ENA);
959
960 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
961 WM8904_FLL_ENA,
962 WM8904_FLL_ENA);
963 break;
964
965 default:
966 break;
967 }
968 break;
969
970 case SND_SOC_DAPM_POST_PMD:
971 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
972 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
973 break;
974 }
975
976 return 0;
977}
978
979static int out_pga_event(struct snd_soc_dapm_widget *w,
980 struct snd_kcontrol *kcontrol, int event)
981{
982 struct snd_soc_codec *codec = w->codec;
983 struct wm8904_priv *wm8904 = codec->private_data;
984 int reg, val;
985 int dcs_mask;
986 int dcs_l, dcs_r;
987 int dcs_l_reg, dcs_r_reg;
988 int timeout;
989 int pwr_reg;
990
991 /* This code is shared between HP and LINEOUT; we do all our
992 * power management in stereo pairs to avoid latency issues so
993 * we reuse shift to identify which rather than strcmp() the
994 * name. */
995 reg = w->shift;
996
997 switch (reg) {
998 case WM8904_ANALOGUE_HP_0:
999 pwr_reg = WM8904_POWER_MANAGEMENT_2;
1000 dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
1001 dcs_r_reg = WM8904_DC_SERVO_8;
1002 dcs_l_reg = WM8904_DC_SERVO_9;
1003 dcs_l = 0;
1004 dcs_r = 1;
1005 break;
1006 case WM8904_ANALOGUE_LINEOUT_0:
1007 pwr_reg = WM8904_POWER_MANAGEMENT_3;
1008 dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
1009 dcs_r_reg = WM8904_DC_SERVO_6;
1010 dcs_l_reg = WM8904_DC_SERVO_7;
1011 dcs_l = 2;
1012 dcs_r = 3;
1013 break;
1014 default:
1015 BUG();
1016 return -EINVAL;
1017 }
1018
1019 switch (event) {
1020 case SND_SOC_DAPM_PRE_PMU:
1021 /* Power on the PGAs */
1022 snd_soc_update_bits(codec, pwr_reg,
1023 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1024 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA);
1025
1026 /* Power on the amplifier */
1027 snd_soc_update_bits(codec, reg,
1028 WM8904_HPL_ENA | WM8904_HPR_ENA,
1029 WM8904_HPL_ENA | WM8904_HPR_ENA);
1030
1031
1032 /* Enable the first stage */
1033 snd_soc_update_bits(codec, reg,
1034 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
1035 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);
1036
1037 /* Power up the DC servo */
1038 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1039 dcs_mask, dcs_mask);
1040
1041 /* Either calibrate the DC servo or restore cached state
1042 * if we have that.
1043 */
1044 if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
1045 dev_dbg(codec->dev, "Restoring DC servo state\n");
1046
1047 snd_soc_write(codec, dcs_l_reg,
1048 wm8904->dcs_state[dcs_l]);
1049 snd_soc_write(codec, dcs_r_reg,
1050 wm8904->dcs_state[dcs_r]);
1051
1052 snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);
1053
1054 timeout = 20;
1055 } else {
1056 dev_dbg(codec->dev, "Calibrating DC servo\n");
1057
1058 snd_soc_write(codec, WM8904_DC_SERVO_1,
1059 dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);
1060
1061 timeout = 500;
1062 }
1063
1064 /* Wait for DC servo to complete */
1065 dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
1066 do {
1067 val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
1068 if ((val & dcs_mask) == dcs_mask)
1069 break;
1070
1071 msleep(1);
1072 } while (--timeout);
1073
1074 if ((val & dcs_mask) != dcs_mask)
1075 dev_warn(codec->dev, "DC servo timed out\n");
1076 else
1077 dev_dbg(codec->dev, "DC servo ready\n");
1078
1079 /* Enable the output stage */
1080 snd_soc_update_bits(codec, reg,
1081 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1082 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
1083 break;
1084
1085 case SND_SOC_DAPM_POST_PMU:
1086 /* Unshort the output itself */
1087 snd_soc_update_bits(codec, reg,
1088 WM8904_HPL_RMV_SHORT |
1089 WM8904_HPR_RMV_SHORT,
1090 WM8904_HPL_RMV_SHORT |
1091 WM8904_HPR_RMV_SHORT);
1092
1093 break;
1094
1095 case SND_SOC_DAPM_PRE_PMD:
1096 /* Short the output */
1097 snd_soc_update_bits(codec, reg,
1098 WM8904_HPL_RMV_SHORT |
1099 WM8904_HPR_RMV_SHORT, 0);
1100 break;
1101
1102 case SND_SOC_DAPM_POST_PMD:
1103 /* Cache the DC servo configuration; this will be
1104 * invalidated if we change the configuration. */
1105 wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg);
1106 wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg);
1107
1108 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1109 dcs_mask, 0);
1110
1111 /* Disable the amplifier input and output stages */
1112 snd_soc_update_bits(codec, reg,
1113 WM8904_HPL_ENA | WM8904_HPR_ENA |
1114 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY |
1115 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1116 0);
1117
1118 /* PGAs too */
1119 snd_soc_update_bits(codec, pwr_reg,
1120 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1121 0);
1122 break;
1123 }
1124
1125 return 0;
1126}
1127
1128static const char *lin_text[] = {
1129 "IN1L", "IN2L", "IN3L"
1130};
1131
1132static const struct soc_enum lin_enum =
1133 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text);
1134
1135static const struct snd_kcontrol_new lin_mux =
1136 SOC_DAPM_ENUM("Left Capture Mux", lin_enum);
1137
1138static const struct soc_enum lin_inv_enum =
1139 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text);
1140
1141static const struct snd_kcontrol_new lin_inv_mux =
1142 SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
1143
1144static const char *rin_text[] = {
1145 "IN1R", "IN2R", "IN3R"
1146};
1147
1148static const struct soc_enum rin_enum =
1149 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text);
1150
1151static const struct snd_kcontrol_new rin_mux =
1152 SOC_DAPM_ENUM("Right Capture Mux", rin_enum);
1153
1154static const struct soc_enum rin_inv_enum =
1155 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text);
1156
1157static const struct snd_kcontrol_new rin_inv_mux =
1158 SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
1159
1160static const char *aif_text[] = {
1161 "Left", "Right"
1162};
1163
1164static const struct soc_enum aifoutl_enum =
1165 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text);
1166
1167static const struct snd_kcontrol_new aifoutl_mux =
1168 SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
1169
1170static const struct soc_enum aifoutr_enum =
1171 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text);
1172
1173static const struct snd_kcontrol_new aifoutr_mux =
1174 SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
1175
1176static const struct soc_enum aifinl_enum =
1177 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text);
1178
1179static const struct snd_kcontrol_new aifinl_mux =
1180 SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
1181
1182static const struct soc_enum aifinr_enum =
1183 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text);
1184
1185static const struct snd_kcontrol_new aifinr_mux =
1186 SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
1187
1188static const struct snd_soc_dapm_widget wm8904_core_dapm_widgets[] = {
1189SND_SOC_DAPM_SUPPLY("SYSCLK", WM8904_CLOCK_RATES_2, 2, 0, sysclk_event,
1190 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1191SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8904_CLOCK_RATES_2, 1, 0, NULL, 0),
1192SND_SOC_DAPM_SUPPLY("TOCLK", WM8904_CLOCK_RATES_2, 0, 0, NULL, 0),
1193};
1194
1195static const struct snd_soc_dapm_widget wm8904_adc_dapm_widgets[] = {
1196SND_SOC_DAPM_INPUT("IN1L"),
1197SND_SOC_DAPM_INPUT("IN1R"),
1198SND_SOC_DAPM_INPUT("IN2L"),
1199SND_SOC_DAPM_INPUT("IN2R"),
1200SND_SOC_DAPM_INPUT("IN3L"),
1201SND_SOC_DAPM_INPUT("IN3R"),
1202
1203SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0),
1204
1205SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
1206SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1207 &lin_inv_mux),
1208SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
1209SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1210 &rin_inv_mux),
1211
1212SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
1213 NULL, 0),
1214SND_SOC_DAPM_PGA("Right Capture PGA", WM8904_POWER_MANAGEMENT_0, 0, 0,
1215 NULL, 0),
1216
1217SND_SOC_DAPM_ADC("ADCL", NULL, WM8904_POWER_MANAGEMENT_6, 1, 0),
1218SND_SOC_DAPM_ADC("ADCR", NULL, WM8904_POWER_MANAGEMENT_6, 0, 0),
1219
1220SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
1221SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
1222
1223SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
1224SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
1225};
1226
1227static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = {
1228SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
1229SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
1230
1231SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
1232SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
1233
1234SND_SOC_DAPM_DAC("DACL", NULL, WM8904_POWER_MANAGEMENT_6, 3, 0),
1235SND_SOC_DAPM_DAC("DACR", NULL, WM8904_POWER_MANAGEMENT_6, 2, 0),
1236
1237SND_SOC_DAPM_SUPPLY("Charge pump", WM8904_CHARGE_PUMP_0, 0, 0, cp_event,
1238 SND_SOC_DAPM_POST_PMU),
1239
1240SND_SOC_DAPM_PGA("HPL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1241SND_SOC_DAPM_PGA("HPR PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1242
1243SND_SOC_DAPM_PGA("LINEL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1244SND_SOC_DAPM_PGA("LINER PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1245
1246SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM, WM8904_ANALOGUE_HP_0,
1247 0, NULL, 0, out_pga_event,
1248 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1249 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1250SND_SOC_DAPM_PGA_E("Line Output", SND_SOC_NOPM, WM8904_ANALOGUE_LINEOUT_0,
1251 0, NULL, 0, out_pga_event,
1252 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1253 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1254
1255SND_SOC_DAPM_OUTPUT("HPOUTL"),
1256SND_SOC_DAPM_OUTPUT("HPOUTR"),
1257SND_SOC_DAPM_OUTPUT("LINEOUTL"),
1258SND_SOC_DAPM_OUTPUT("LINEOUTR"),
1259};
1260
1261static const char *out_mux_text[] = {
1262 "DAC", "Bypass"
1263};
1264
1265static const struct soc_enum hpl_enum =
1266 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text);
1267
1268static const struct snd_kcontrol_new hpl_mux =
1269 SOC_DAPM_ENUM("HPL Mux", hpl_enum);
1270
1271static const struct soc_enum hpr_enum =
1272 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text);
1273
1274static const struct snd_kcontrol_new hpr_mux =
1275 SOC_DAPM_ENUM("HPR Mux", hpr_enum);
1276
1277static const struct soc_enum linel_enum =
1278 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text);
1279
1280static const struct snd_kcontrol_new linel_mux =
1281 SOC_DAPM_ENUM("LINEL Mux", linel_enum);
1282
1283static const struct soc_enum liner_enum =
1284 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text);
1285
1286static const struct snd_kcontrol_new liner_mux =
1287 SOC_DAPM_ENUM("LINEL Mux", liner_enum);
1288
1289static const char *sidetone_text[] = {
1290 "None", "Left", "Right"
1291};
1292
1293static const struct soc_enum dacl_sidetone_enum =
1294 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text);
1295
1296static const struct snd_kcontrol_new dacl_sidetone_mux =
1297 SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum);
1298
1299static const struct soc_enum dacr_sidetone_enum =
1300 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text);
1301
1302static const struct snd_kcontrol_new dacr_sidetone_mux =
1303 SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum);
1304
1305static const struct snd_soc_dapm_widget wm8904_dapm_widgets[] = {
1306SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0),
1307SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1308SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1309
1310SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &dacl_sidetone_mux),
1311SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &dacr_sidetone_mux),
1312
1313SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1314SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1315SND_SOC_DAPM_MUX("LINEL Mux", SND_SOC_NOPM, 0, 0, &linel_mux),
1316SND_SOC_DAPM_MUX("LINER Mux", SND_SOC_NOPM, 0, 0, &liner_mux),
1317};
1318
1319static const struct snd_soc_dapm_route core_intercon[] = {
1320 { "CLK_DSP", NULL, "SYSCLK" },
1321 { "TOCLK", NULL, "SYSCLK" },
1322};
1323
1324static const struct snd_soc_dapm_route adc_intercon[] = {
1325 { "Left Capture Mux", "IN1L", "IN1L" },
1326 { "Left Capture Mux", "IN2L", "IN2L" },
1327 { "Left Capture Mux", "IN3L", "IN3L" },
1328
1329 { "Left Capture Inverting Mux", "IN1L", "IN1L" },
1330 { "Left Capture Inverting Mux", "IN2L", "IN2L" },
1331 { "Left Capture Inverting Mux", "IN3L", "IN3L" },
1332
1333 { "Right Capture Mux", "IN1R", "IN1R" },
1334 { "Right Capture Mux", "IN2R", "IN2R" },
1335 { "Right Capture Mux", "IN3R", "IN3R" },
1336
1337 { "Right Capture Inverting Mux", "IN1R", "IN1R" },
1338 { "Right Capture Inverting Mux", "IN2R", "IN2R" },
1339 { "Right Capture Inverting Mux", "IN3R", "IN3R" },
1340
1341 { "Left Capture PGA", NULL, "Left Capture Mux" },
1342 { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
1343
1344 { "Right Capture PGA", NULL, "Right Capture Mux" },
1345 { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
1346
1347 { "AIFOUTL", "Left", "ADCL" },
1348 { "AIFOUTL", "Right", "ADCR" },
1349 { "AIFOUTR", "Left", "ADCL" },
1350 { "AIFOUTR", "Right", "ADCR" },
1351
1352 { "ADCL", NULL, "CLK_DSP" },
1353 { "ADCL", NULL, "Left Capture PGA" },
1354
1355 { "ADCR", NULL, "CLK_DSP" },
1356 { "ADCR", NULL, "Right Capture PGA" },
1357};
1358
1359static const struct snd_soc_dapm_route dac_intercon[] = {
1360 { "DACL", "Right", "AIFINR" },
1361 { "DACL", "Left", "AIFINL" },
1362 { "DACL", NULL, "CLK_DSP" },
1363
1364 { "DACR", "Right", "AIFINR" },
1365 { "DACR", "Left", "AIFINL" },
1366 { "DACR", NULL, "CLK_DSP" },
1367
1368 { "Charge pump", NULL, "SYSCLK" },
1369
1370 { "Headphone Output", NULL, "HPL PGA" },
1371 { "Headphone Output", NULL, "HPR PGA" },
1372 { "Headphone Output", NULL, "Charge pump" },
1373 { "Headphone Output", NULL, "TOCLK" },
1374
1375 { "Line Output", NULL, "LINEL PGA" },
1376 { "Line Output", NULL, "LINER PGA" },
1377 { "Line Output", NULL, "Charge pump" },
1378 { "Line Output", NULL, "TOCLK" },
1379
1380 { "HPOUTL", NULL, "Headphone Output" },
1381 { "HPOUTR", NULL, "Headphone Output" },
1382
1383 { "LINEOUTL", NULL, "Line Output" },
1384 { "LINEOUTR", NULL, "Line Output" },
1385};
1386
1387static const struct snd_soc_dapm_route wm8904_intercon[] = {
1388 { "Left Sidetone", "Left", "ADCL" },
1389 { "Left Sidetone", "Right", "ADCR" },
1390 { "DACL", NULL, "Left Sidetone" },
1391
1392 { "Right Sidetone", "Left", "ADCL" },
1393 { "Right Sidetone", "Right", "ADCR" },
1394 { "DACR", NULL, "Right Sidetone" },
1395
1396 { "Left Bypass", NULL, "Class G" },
1397 { "Left Bypass", NULL, "Left Capture PGA" },
1398
1399 { "Right Bypass", NULL, "Class G" },
1400 { "Right Bypass", NULL, "Right Capture PGA" },
1401
1402 { "HPL Mux", "DAC", "DACL" },
1403 { "HPL Mux", "Bypass", "Left Bypass" },
1404
1405 { "HPR Mux", "DAC", "DACR" },
1406 { "HPR Mux", "Bypass", "Right Bypass" },
1407
1408 { "LINEL Mux", "DAC", "DACL" },
1409 { "LINEL Mux", "Bypass", "Left Bypass" },
1410
1411 { "LINER Mux", "DAC", "DACR" },
1412 { "LINER Mux", "Bypass", "Right Bypass" },
1413
1414 { "HPL PGA", NULL, "HPL Mux" },
1415 { "HPR PGA", NULL, "HPR Mux" },
1416
1417 { "LINEL PGA", NULL, "LINEL Mux" },
1418 { "LINER PGA", NULL, "LINER Mux" },
1419};
1420
1421static const struct snd_soc_dapm_route wm8912_intercon[] = {
1422 { "HPL PGA", NULL, "DACL" },
1423 { "HPR PGA", NULL, "DACR" },
1424
1425 { "LINEL PGA", NULL, "DACL" },
1426 { "LINER PGA", NULL, "DACR" },
1427};
1428
1429static int wm8904_add_widgets(struct snd_soc_codec *codec)
1430{
1431 struct wm8904_priv *wm8904 = codec->private_data;
1432
1433 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1434 ARRAY_SIZE(wm8904_core_dapm_widgets));
1435 snd_soc_dapm_add_routes(codec, core_intercon,
1436 ARRAY_SIZE(core_intercon));
1437
1438 switch (wm8904->devtype) {
1439 case WM8904:
1440 snd_soc_add_controls(codec, wm8904_adc_snd_controls,
1441 ARRAY_SIZE(wm8904_adc_snd_controls));
1442 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1443 ARRAY_SIZE(wm8904_dac_snd_controls));
1444 snd_soc_add_controls(codec, wm8904_snd_controls,
1445 ARRAY_SIZE(wm8904_snd_controls));
1446
1447 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
1448 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1449 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1450 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1451 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
1452 ARRAY_SIZE(wm8904_dapm_widgets));
1453
1454 snd_soc_dapm_add_routes(codec, core_intercon,
1455 ARRAY_SIZE(core_intercon));
1456 snd_soc_dapm_add_routes(codec, adc_intercon,
1457 ARRAY_SIZE(adc_intercon));
1458 snd_soc_dapm_add_routes(codec, dac_intercon,
1459 ARRAY_SIZE(dac_intercon));
1460 snd_soc_dapm_add_routes(codec, wm8904_intercon,
1461 ARRAY_SIZE(wm8904_intercon));
1462 break;
1463
1464 case WM8912:
1465 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1466 ARRAY_SIZE(wm8904_dac_snd_controls));
1467
1468 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1469 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1470
1471 snd_soc_dapm_add_routes(codec, dac_intercon,
1472 ARRAY_SIZE(dac_intercon));
1473 snd_soc_dapm_add_routes(codec, wm8912_intercon,
1474 ARRAY_SIZE(wm8912_intercon));
1475 break;
1476 }
1477
1478 snd_soc_dapm_new_widgets(codec);
1479 return 0;
1480}
1481
1482static struct {
1483 int ratio;
1484 unsigned int clk_sys_rate;
1485} clk_sys_rates[] = {
1486 { 64, 0 },
1487 { 128, 1 },
1488 { 192, 2 },
1489 { 256, 3 },
1490 { 384, 4 },
1491 { 512, 5 },
1492 { 786, 6 },
1493 { 1024, 7 },
1494 { 1408, 8 },
1495 { 1536, 9 },
1496};
1497
1498static struct {
1499 int rate;
1500 int sample_rate;
1501} sample_rates[] = {
1502 { 8000, 0 },
1503 { 11025, 1 },
1504 { 12000, 1 },
1505 { 16000, 2 },
1506 { 22050, 3 },
1507 { 24000, 3 },
1508 { 32000, 4 },
1509 { 44100, 5 },
1510 { 48000, 5 },
1511};
1512
1513static struct {
1514 int div; /* *10 due to .5s */
1515 int bclk_div;
1516} bclk_divs[] = {
1517 { 10, 0 },
1518 { 15, 1 },
1519 { 20, 2 },
1520 { 30, 3 },
1521 { 40, 4 },
1522 { 50, 5 },
1523 { 55, 6 },
1524 { 60, 7 },
1525 { 80, 8 },
1526 { 100, 9 },
1527 { 110, 10 },
1528 { 120, 11 },
1529 { 160, 12 },
1530 { 200, 13 },
1531 { 220, 14 },
1532 { 240, 16 },
1533 { 200, 17 },
1534 { 320, 18 },
1535 { 440, 19 },
1536 { 480, 20 },
1537};
1538
1539
1540static int wm8904_hw_params(struct snd_pcm_substream *substream,
1541 struct snd_pcm_hw_params *params,
1542 struct snd_soc_dai *dai)
1543{
1544 struct snd_soc_codec *codec = dai->codec;
1545 struct wm8904_priv *wm8904 = codec->private_data;
1546 int ret, i, best, best_val, cur_val;
1547 unsigned int aif1 = 0;
1548 unsigned int aif2 = 0;
1549 unsigned int aif3 = 0;
1550 unsigned int clock1 = 0;
1551 unsigned int dac_digital1 = 0;
1552
1553 /* What BCLK do we need? */
1554 wm8904->fs = params_rate(params);
1555 if (wm8904->tdm_slots) {
1556 dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
1557 wm8904->tdm_slots, wm8904->tdm_width);
1558 wm8904->bclk = snd_soc_calc_bclk(wm8904->fs,
1559 wm8904->tdm_width, 2,
1560 wm8904->tdm_slots);
1561 } else {
1562 wm8904->bclk = snd_soc_params_to_bclk(params);
1563 }
1564
1565 switch (params_format(params)) {
1566 case SNDRV_PCM_FORMAT_S16_LE:
1567 break;
1568 case SNDRV_PCM_FORMAT_S20_3LE:
1569 aif1 |= 0x40;
1570 break;
1571 case SNDRV_PCM_FORMAT_S24_LE:
1572 aif1 |= 0x80;
1573 break;
1574 case SNDRV_PCM_FORMAT_S32_LE:
1575 aif1 |= 0xc0;
1576 break;
1577 default:
1578 return -EINVAL;
1579 }
1580
1581
1582 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk);
1583
1584 ret = wm8904_configure_clocking(codec);
1585 if (ret != 0)
1586 return ret;
1587
1588 /* Select nearest CLK_SYS_RATE */
1589 best = 0;
1590 best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio)
1591 - wm8904->fs);
1592 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1593 cur_val = abs((wm8904->sysclk_rate /
1594 clk_sys_rates[i].ratio) - wm8904->fs);;
1595 if (cur_val < best_val) {
1596 best = i;
1597 best_val = cur_val;
1598 }
1599 }
1600 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1601 clk_sys_rates[best].ratio);
1602 clock1 |= (clk_sys_rates[best].clk_sys_rate
1603 << WM8904_CLK_SYS_RATE_SHIFT);
1604
1605 /* SAMPLE_RATE */
1606 best = 0;
1607 best_val = abs(wm8904->fs - sample_rates[0].rate);
1608 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1609 /* Closest match */
1610 cur_val = abs(wm8904->fs - sample_rates[i].rate);
1611 if (cur_val < best_val) {
1612 best = i;
1613 best_val = cur_val;
1614 }
1615 }
1616 dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
1617 sample_rates[best].rate);
1618 clock1 |= (sample_rates[best].sample_rate
1619 << WM8904_SAMPLE_RATE_SHIFT);
1620
1621 /* Enable sloping stopband filter for low sample rates */
1622 if (wm8904->fs <= 24000)
1623 dac_digital1 |= WM8904_DAC_SB_FILT;
1624
1625 /* BCLK_DIV */
1626 best = 0;
1627 best_val = INT_MAX;
1628 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1629 cur_val = ((wm8904->sysclk_rate * 10) / bclk_divs[i].div)
1630 - wm8904->bclk;
1631 if (cur_val < 0) /* Table is sorted */
1632 break;
1633 if (cur_val < best_val) {
1634 best = i;
1635 best_val = cur_val;
1636 }
1637 }
1638 wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div;
1639 dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
1640 bclk_divs[best].div, wm8904->bclk);
1641 aif2 |= bclk_divs[best].bclk_div;
1642
1643 /* LRCLK is a simple fraction of BCLK */
1644 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
1645 aif3 |= wm8904->bclk / wm8904->fs;
1646
1647 /* Apply the settings */
1648 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
1649 WM8904_DAC_SB_FILT, dac_digital1);
1650 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1651 WM8904_AIF_WL_MASK, aif1);
1652 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2,
1653 WM8904_BCLK_DIV_MASK, aif2);
1654 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1655 WM8904_LRCLK_RATE_MASK, aif3);
1656 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1,
1657 WM8904_SAMPLE_RATE_MASK |
1658 WM8904_CLK_SYS_RATE_MASK, clock1);
1659
1660 /* Update filters for the new settings */
1661 wm8904_set_retune_mobile(codec);
1662 wm8904_set_deemph(codec);
1663
1664 return 0;
1665}
1666
1667
1668static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1669 unsigned int freq, int dir)
1670{
1671 struct snd_soc_codec *codec = dai->codec;
1672 struct wm8904_priv *priv = codec->private_data;
1673
1674 switch (clk_id) {
1675 case WM8904_CLK_MCLK:
1676 priv->sysclk_src = clk_id;
1677 priv->mclk_rate = freq;
1678 break;
1679
1680 case WM8904_CLK_FLL:
1681 priv->sysclk_src = clk_id;
1682 break;
1683
1684 default:
1685 return -EINVAL;
1686 }
1687
1688 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1689
1690 wm8904_configure_clocking(codec);
1691
1692 return 0;
1693}
1694
1695static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1696{
1697 struct snd_soc_codec *codec = dai->codec;
1698 unsigned int aif1 = 0;
1699 unsigned int aif3 = 0;
1700
1701 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1702 case SND_SOC_DAIFMT_CBS_CFS:
1703 break;
1704 case SND_SOC_DAIFMT_CBS_CFM:
1705 aif3 |= WM8904_LRCLK_DIR;
1706 break;
1707 case SND_SOC_DAIFMT_CBM_CFS:
1708 aif1 |= WM8904_BCLK_DIR;
1709 break;
1710 case SND_SOC_DAIFMT_CBM_CFM:
1711 aif1 |= WM8904_BCLK_DIR;
1712 aif3 |= WM8904_LRCLK_DIR;
1713 break;
1714 default:
1715 return -EINVAL;
1716 }
1717
1718 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1719 case SND_SOC_DAIFMT_DSP_B:
1720 aif1 |= WM8904_AIF_LRCLK_INV;
1721 case SND_SOC_DAIFMT_DSP_A:
1722 aif1 |= 0x3;
1723 break;
1724 case SND_SOC_DAIFMT_I2S:
1725 aif1 |= 0x2;
1726 break;
1727 case SND_SOC_DAIFMT_RIGHT_J:
1728 break;
1729 case SND_SOC_DAIFMT_LEFT_J:
1730 aif1 |= 0x1;
1731 break;
1732 default:
1733 return -EINVAL;
1734 }
1735
1736 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1737 case SND_SOC_DAIFMT_DSP_A:
1738 case SND_SOC_DAIFMT_DSP_B:
1739 /* frame inversion not valid for DSP modes */
1740 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1741 case SND_SOC_DAIFMT_NB_NF:
1742 break;
1743 case SND_SOC_DAIFMT_IB_NF:
1744 aif1 |= WM8904_AIF_BCLK_INV;
1745 break;
1746 default:
1747 return -EINVAL;
1748 }
1749 break;
1750
1751 case SND_SOC_DAIFMT_I2S:
1752 case SND_SOC_DAIFMT_RIGHT_J:
1753 case SND_SOC_DAIFMT_LEFT_J:
1754 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1755 case SND_SOC_DAIFMT_NB_NF:
1756 break;
1757 case SND_SOC_DAIFMT_IB_IF:
1758 aif1 |= WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV;
1759 break;
1760 case SND_SOC_DAIFMT_IB_NF:
1761 aif1 |= WM8904_AIF_BCLK_INV;
1762 break;
1763 case SND_SOC_DAIFMT_NB_IF:
1764 aif1 |= WM8904_AIF_LRCLK_INV;
1765 break;
1766 default:
1767 return -EINVAL;
1768 }
1769 break;
1770 default:
1771 return -EINVAL;
1772 }
1773
1774 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1775 WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV |
1776 WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1);
1777 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1778 WM8904_LRCLK_DIR, aif3);
1779
1780 return 0;
1781}
1782
1783
1784static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1785 unsigned int rx_mask, int slots, int slot_width)
1786{
1787 struct snd_soc_codec *codec = dai->codec;
1788 struct wm8904_priv *wm8904 = codec->private_data;
1789 int aif1 = 0;
1790
1791 /* Don't need to validate anything if we're turning off TDM */
1792 if (slots == 0)
1793 goto out;
1794
1795 /* Note that we allow configurations we can't handle ourselves -
1796 * for example, we can generate clocks for slots 2 and up even if
1797 * we can't use those slots ourselves.
1798 */
1799 aif1 |= WM8904_AIFADC_TDM | WM8904_AIFDAC_TDM;
1800
1801 switch (rx_mask) {
1802 case 3:
1803 break;
1804 case 0xc:
1805 aif1 |= WM8904_AIFADC_TDM_CHAN;
1806 break;
1807 default:
1808 return -EINVAL;
1809 }
1810
1811
1812 switch (tx_mask) {
1813 case 3:
1814 break;
1815 case 0xc:
1816 aif1 |= WM8904_AIFDAC_TDM_CHAN;
1817 break;
1818 default:
1819 return -EINVAL;
1820 }
1821
1822out:
1823 wm8904->tdm_width = slot_width;
1824 wm8904->tdm_slots = slots / 2;
1825
1826 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1827 WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN |
1828 WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1);
1829
1830 return 0;
1831}
1832
1833struct _fll_div {
1834 u16 fll_fratio;
1835 u16 fll_outdiv;
1836 u16 fll_clk_ref_div;
1837 u16 n;
1838 u16 k;
1839};
1840
1841/* The size in bits of the FLL divide multiplied by 10
1842 * to allow rounding later */
1843#define FIXED_FLL_SIZE ((1 << 16) * 10)
1844
1845static struct {
1846 unsigned int min;
1847 unsigned int max;
1848 u16 fll_fratio;
1849 int ratio;
1850} fll_fratios[] = {
1851 { 0, 64000, 4, 16 },
1852 { 64000, 128000, 3, 8 },
1853 { 128000, 256000, 2, 4 },
1854 { 256000, 1000000, 1, 2 },
1855 { 1000000, 13500000, 0, 1 },
1856};
1857
1858static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1859 unsigned int Fout)
1860{
1861 u64 Kpart;
1862 unsigned int K, Ndiv, Nmod, target;
1863 unsigned int div;
1864 int i;
1865
1866 /* Fref must be <=13.5MHz */
1867 div = 1;
1868 fll_div->fll_clk_ref_div = 0;
1869 while ((Fref / div) > 13500000) {
1870 div *= 2;
1871 fll_div->fll_clk_ref_div++;
1872
1873 if (div > 8) {
1874 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1875 Fref);
1876 return -EINVAL;
1877 }
1878 }
1879
1880 pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
1881
1882 /* Apply the division for our remaining calculations */
1883 Fref /= div;
1884
1885 /* Fvco should be 90-100MHz; don't check the upper bound */
1886 div = 4;
1887 while (Fout * div < 90000000) {
1888 div++;
1889 if (div > 64) {
1890 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1891 Fout);
1892 return -EINVAL;
1893 }
1894 }
1895 target = Fout * div;
1896 fll_div->fll_outdiv = div - 1;
1897
1898 pr_debug("Fvco=%dHz\n", target);
1899
1900 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1901 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1902 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1903 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1904 target /= fll_fratios[i].ratio;
1905 break;
1906 }
1907 }
1908 if (i == ARRAY_SIZE(fll_fratios)) {
1909 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1910 return -EINVAL;
1911 }
1912
1913 /* Now, calculate N.K */
1914 Ndiv = target / Fref;
1915
1916 fll_div->n = Ndiv;
1917 Nmod = target % Fref;
1918 pr_debug("Nmod=%d\n", Nmod);
1919
1920 /* Calculate fractional part - scale up so we can round. */
1921 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1922
1923 do_div(Kpart, Fref);
1924
1925 K = Kpart & 0xFFFFFFFF;
1926
1927 if ((K % 10) >= 5)
1928 K += 5;
1929
1930 /* Move down to proper range now rounding is done */
1931 fll_div->k = K / 10;
1932
1933 pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
1934 fll_div->n, fll_div->k,
1935 fll_div->fll_fratio, fll_div->fll_outdiv,
1936 fll_div->fll_clk_ref_div);
1937
1938 return 0;
1939}
1940
1941static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1942 unsigned int Fref, unsigned int Fout)
1943{
1944 struct snd_soc_codec *codec = dai->codec;
1945 struct wm8904_priv *wm8904 = codec->private_data;
1946 struct _fll_div fll_div;
1947 int ret, val;
1948 int clock2, fll1;
1949
1950 /* Any change? */
1951 if (source == wm8904->fll_src && Fref == wm8904->fll_fref &&
1952 Fout == wm8904->fll_fout)
1953 return 0;
1954
1955 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
1956
1957 if (Fout == 0) {
1958 dev_dbg(codec->dev, "FLL disabled\n");
1959
1960 wm8904->fll_fref = 0;
1961 wm8904->fll_fout = 0;
1962
1963 /* Gate SYSCLK to avoid glitches */
1964 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
1965 WM8904_CLK_SYS_ENA, 0);
1966
1967 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1968 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
1969
1970 goto out;
1971 }
1972
1973 /* Validate the FLL ID */
1974 switch (source) {
1975 case WM8904_FLL_MCLK:
1976 case WM8904_FLL_LRCLK:
1977 case WM8904_FLL_BCLK:
1978 ret = fll_factors(&fll_div, Fref, Fout);
1979 if (ret != 0)
1980 return ret;
1981 break;
1982
1983 case WM8904_FLL_FREE_RUNNING:
1984 dev_dbg(codec->dev, "Using free running FLL\n");
1985 /* Force 12MHz and output/4 for now */
1986 Fout = 12000000;
1987 Fref = 12000000;
1988
1989 memset(&fll_div, 0, sizeof(fll_div));
1990 fll_div.fll_outdiv = 3;
1991 break;
1992
1993 default:
1994 dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
1995 return -EINVAL;
1996 }
1997
1998 /* Save current state then disable the FLL and SYSCLK to avoid
1999 * misclocking */
2000 fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1);
2001 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2002 WM8904_CLK_SYS_ENA, 0);
2003 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2004 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
2005
2006 /* Unlock forced oscilator control to switch it on/off */
2007 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2008 WM8904_USER_KEY, WM8904_USER_KEY);
2009
2010 if (fll_id == WM8904_FLL_FREE_RUNNING) {
2011 val = WM8904_FLL_FRC_NCO;
2012 } else {
2013 val = 0;
2014 }
2015
2016 snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
2017 val);
2018 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2019 WM8904_USER_KEY, 0);
2020
2021 switch (fll_id) {
2022 case WM8904_FLL_MCLK:
2023 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2024 WM8904_FLL_CLK_REF_SRC_MASK, 0);
2025 break;
2026
2027 case WM8904_FLL_LRCLK:
2028 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2029 WM8904_FLL_CLK_REF_SRC_MASK, 1);
2030 break;
2031
2032 case WM8904_FLL_BCLK:
2033 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2034 WM8904_FLL_CLK_REF_SRC_MASK, 2);
2035 break;
2036 }
2037
2038 if (fll_div.k)
2039 val = WM8904_FLL_FRACN_ENA;
2040 else
2041 val = 0;
2042 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2043 WM8904_FLL_FRACN_ENA, val);
2044
2045 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2,
2046 WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK,
2047 (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) |
2048 (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT));
2049
2050 snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k);
2051
2052 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
2053 fll_div.n << WM8904_FLL_N_SHIFT);
2054
2055 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2056 WM8904_FLL_CLK_REF_DIV_MASK,
2057 fll_div.fll_clk_ref_div
2058 << WM8904_FLL_CLK_REF_DIV_SHIFT);
2059
2060 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2061
2062 wm8904->fll_fref = Fref;
2063 wm8904->fll_fout = Fout;
2064 wm8904->fll_src = source;
2065
2066 /* Enable the FLL if it was previously active */
2067 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2068 WM8904_FLL_OSC_ENA, fll1);
2069 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2070 WM8904_FLL_ENA, fll1);
2071
2072out:
2073 /* Reenable SYSCLK if it was previously active */
2074 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2075 WM8904_CLK_SYS_ENA, clock2);
2076
2077 return 0;
2078}
2079
2080static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2081{
2082 struct snd_soc_codec *codec = codec_dai->codec;
2083 int val;
2084
2085 if (mute)
2086 val = WM8904_DAC_MUTE;
2087 else
2088 val = 0;
2089
2090 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
2091
2092 return 0;
2093}
2094
2095static void wm8904_sync_cache(struct snd_soc_codec *codec)
2096{
2097 struct wm8904_priv *wm8904 = codec->private_data;
2098 int i;
2099
2100 if (!codec->cache_sync)
2101 return;
2102
2103 codec->cache_only = 0;
2104
2105 /* Sync back cached values if they're different from the
2106 * hardware default.
2107 */
2108 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
2109 if (!wm8904_access[i].writable)
2110 continue;
2111
2112 if (wm8904->reg_cache[i] == wm8904_reg[i])
2113 continue;
2114
2115 snd_soc_write(codec, i, wm8904->reg_cache[i]);
2116 }
2117
2118 codec->cache_sync = 0;
2119}
2120
2121static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2122 enum snd_soc_bias_level level)
2123{
2124 struct wm8904_priv *wm8904 = codec->private_data;
2125 int ret;
2126
2127 switch (level) {
2128 case SND_SOC_BIAS_ON:
2129 break;
2130
2131 case SND_SOC_BIAS_PREPARE:
2132 /* VMID resistance 2*50k */
2133 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2134 WM8904_VMID_RES_MASK,
2135 0x1 << WM8904_VMID_RES_SHIFT);
2136
2137 /* Normal bias current */
2138 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2139 WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT);
2140 break;
2141
2142 case SND_SOC_BIAS_STANDBY:
2143 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2144 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2145 wm8904->supplies);
2146 if (ret != 0) {
2147 dev_err(codec->dev,
2148 "Failed to enable supplies: %d\n",
2149 ret);
2150 return ret;
2151 }
2152
2153 wm8904_sync_cache(codec);
2154
2155 /* Enable bias */
2156 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2157 WM8904_BIAS_ENA, WM8904_BIAS_ENA);
2158
2159 /* Enable VMID, VMID buffering, 2*5k resistance */
2160 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2161 WM8904_VMID_ENA |
2162 WM8904_VMID_RES_MASK,
2163 WM8904_VMID_ENA |
2164 0x3 << WM8904_VMID_RES_SHIFT);
2165
2166 /* Let VMID ramp */
2167 msleep(1);
2168 }
2169
2170 /* Maintain VMID with 2*250k */
2171 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2172 WM8904_VMID_RES_MASK,
2173 0x2 << WM8904_VMID_RES_SHIFT);
2174
2175 /* Bias current *0.5 */
2176 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2177 WM8904_ISEL_MASK, 0);
2178 break;
2179
2180 case SND_SOC_BIAS_OFF:
2181 /* Turn off VMID */
2182 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2183 WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0);
2184
2185 /* Stop bias generation */
2186 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2187 WM8904_BIAS_ENA, 0);
2188
2189#ifdef CONFIG_REGULATOR
2190 /* Post 2.6.34 we will be able to get a callback when
2191 * the regulators are disabled which we can use but
2192 * for now just assume that the power will be cut if
2193 * the regulator API is in use.
2194 */
2195 codec->cache_sync = 1;
2196#endif
2197
2198 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
2199 wm8904->supplies);
2200 break;
2201 }
2202 codec->bias_level = level;
2203 return 0;
2204}
2205
2206#define WM8904_RATES SNDRV_PCM_RATE_8000_96000
2207
2208#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2209 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2210
2211static struct snd_soc_dai_ops wm8904_dai_ops = {
2212 .set_sysclk = wm8904_set_sysclk,
2213 .set_fmt = wm8904_set_fmt,
2214 .set_tdm_slot = wm8904_set_tdm_slot,
2215 .set_pll = wm8904_set_fll,
2216 .hw_params = wm8904_hw_params,
2217 .digital_mute = wm8904_digital_mute,
2218};
2219
2220struct snd_soc_dai wm8904_dai = {
2221 .name = "WM8904",
2222 .playback = {
2223 .stream_name = "Playback",
2224 .channels_min = 2,
2225 .channels_max = 2,
2226 .rates = WM8904_RATES,
2227 .formats = WM8904_FORMATS,
2228 },
2229 .capture = {
2230 .stream_name = "Capture",
2231 .channels_min = 2,
2232 .channels_max = 2,
2233 .rates = WM8904_RATES,
2234 .formats = WM8904_FORMATS,
2235 },
2236 .ops = &wm8904_dai_ops,
2237 .symmetric_rates = 1,
2238};
2239EXPORT_SYMBOL_GPL(wm8904_dai);
2240
2241#ifdef CONFIG_PM
2242static int wm8904_suspend(struct platform_device *pdev, pm_message_t state)
2243{
2244 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2245 struct snd_soc_codec *codec = socdev->card->codec;
2246
2247 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2248
2249 return 0;
2250}
2251
2252static int wm8904_resume(struct platform_device *pdev)
2253{
2254 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2255 struct snd_soc_codec *codec = socdev->card->codec;
2256
2257 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2258
2259 return 0;
2260}
2261#else
2262#define wm8904_suspend NULL
2263#define wm8904_resume NULL
2264#endif
2265
2266static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2267{
2268 struct snd_soc_codec *codec = &wm8904->codec;
2269 struct wm8904_pdata *pdata = wm8904->pdata;
2270 struct snd_kcontrol_new control =
2271 SOC_ENUM_EXT("EQ Mode",
2272 wm8904->retune_mobile_enum,
2273 wm8904_get_retune_mobile_enum,
2274 wm8904_put_retune_mobile_enum);
2275 int ret, i, j;
2276 const char **t;
2277
2278 /* We need an array of texts for the enum API but the number
2279 * of texts is likely to be less than the number of
2280 * configurations due to the sample rate dependency of the
2281 * configurations. */
2282 wm8904->num_retune_mobile_texts = 0;
2283 wm8904->retune_mobile_texts = NULL;
2284 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2285 for (j = 0; j < wm8904->num_retune_mobile_texts; j++) {
2286 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2287 wm8904->retune_mobile_texts[j]) == 0)
2288 break;
2289 }
2290
2291 if (j != wm8904->num_retune_mobile_texts)
2292 continue;
2293
2294 /* Expand the array... */
2295 t = krealloc(wm8904->retune_mobile_texts,
2296 sizeof(char *) *
2297 (wm8904->num_retune_mobile_texts + 1),
2298 GFP_KERNEL);
2299 if (t == NULL)
2300 continue;
2301
2302 /* ...store the new entry... */
2303 t[wm8904->num_retune_mobile_texts] =
2304 pdata->retune_mobile_cfgs[i].name;
2305
2306 /* ...and remember the new version. */
2307 wm8904->num_retune_mobile_texts++;
2308 wm8904->retune_mobile_texts = t;
2309 }
2310
2311 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2312 wm8904->num_retune_mobile_texts);
2313
2314 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2315 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2316
2317 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2318 if (ret != 0)
2319 dev_err(wm8904->codec.dev,
2320 "Failed to add ReTune Mobile control: %d\n", ret);
2321}
2322
2323static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2324{
2325 struct snd_soc_codec *codec = &wm8904->codec;
2326 struct wm8904_pdata *pdata = wm8904->pdata;
2327 int ret, i;
2328
2329 if (!pdata) {
2330 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2331 ARRAY_SIZE(wm8904_eq_controls));
2332 return;
2333 }
2334
2335 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
2336
2337 if (pdata->num_drc_cfgs) {
2338 struct snd_kcontrol_new control =
2339 SOC_ENUM_EXT("DRC Mode", wm8904->drc_enum,
2340 wm8904_get_drc_enum, wm8904_put_drc_enum);
2341
2342 /* We need an array of texts for the enum API */
2343 wm8904->drc_texts = kmalloc(sizeof(char *)
2344 * pdata->num_drc_cfgs, GFP_KERNEL);
2345 if (!wm8904->drc_texts) {
2346 dev_err(wm8904->codec.dev,
2347 "Failed to allocate %d DRC config texts\n",
2348 pdata->num_drc_cfgs);
2349 return;
2350 }
2351
2352 for (i = 0; i < pdata->num_drc_cfgs; i++)
2353 wm8904->drc_texts[i] = pdata->drc_cfgs[i].name;
2354
2355 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2356 wm8904->drc_enum.texts = wm8904->drc_texts;
2357
2358 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2359 if (ret != 0)
2360 dev_err(wm8904->codec.dev,
2361 "Failed to add DRC mode control: %d\n", ret);
2362
2363 wm8904_set_drc(codec);
2364 }
2365
2366 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2367 pdata->num_retune_mobile_cfgs);
2368
2369 if (pdata->num_retune_mobile_cfgs)
2370 wm8904_handle_retune_mobile_pdata(wm8904);
2371 else
2372 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2373 ARRAY_SIZE(wm8904_eq_controls));
2374}
2375
2376static int wm8904_probe(struct platform_device *pdev)
2377{
2378 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2379 struct snd_soc_codec *codec;
2380 int ret = 0;
2381
2382 if (wm8904_codec == NULL) {
2383 dev_err(&pdev->dev, "Codec device not registered\n");
2384 return -ENODEV;
2385 }
2386
2387 socdev->card->codec = wm8904_codec;
2388 codec = wm8904_codec;
2389
2390 /* register pcms */
2391 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2392 if (ret < 0) {
2393 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2394 goto pcm_err;
2395 }
2396
2397 wm8904_handle_pdata(codec->private_data);
2398
2399 wm8904_add_widgets(codec);
2400
2401 return ret;
2402
2403pcm_err:
2404 return ret;
2405}
2406
2407static int wm8904_remove(struct platform_device *pdev)
2408{
2409 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2410
2411 snd_soc_free_pcms(socdev);
2412 snd_soc_dapm_free(socdev);
2413
2414 return 0;
2415}
2416
2417struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2418 .probe = wm8904_probe,
2419 .remove = wm8904_remove,
2420 .suspend = wm8904_suspend,
2421 .resume = wm8904_resume,
2422};
2423EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2424
2425static int wm8904_register(struct wm8904_priv *wm8904,
2426 enum snd_soc_control_type control)
2427{
2428 int ret;
2429 struct snd_soc_codec *codec = &wm8904->codec;
2430 int i;
2431
2432 if (wm8904_codec) {
2433 dev_err(codec->dev, "Another WM8904 is registered\n");
2434 return -EINVAL;
2435 }
2436
2437 mutex_init(&codec->mutex);
2438 INIT_LIST_HEAD(&codec->dapm_widgets);
2439 INIT_LIST_HEAD(&codec->dapm_paths);
2440
2441 codec->private_data = wm8904;
2442 codec->name = "WM8904";
2443 codec->owner = THIS_MODULE;
2444 codec->bias_level = SND_SOC_BIAS_OFF;
2445 codec->set_bias_level = wm8904_set_bias_level;
2446 codec->dai = &wm8904_dai;
2447 codec->num_dai = 1;
2448 codec->reg_cache_size = WM8904_MAX_REGISTER;
2449 codec->reg_cache = &wm8904->reg_cache;
2450 codec->volatile_register = wm8904_volatile_register;
2451 codec->cache_sync = 1;
2452 codec->idle_bias_off = 1;
2453
2454 switch (wm8904->devtype) {
2455 case WM8904:
2456 break;
2457 case WM8912:
2458 memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture));
2459 break;
2460 default:
2461 dev_err(codec->dev, "Unknown device type %d\n",
2462 wm8904->devtype);
2463 return -EINVAL;
2464 }
2465
2466 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
2467
2468 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2469 if (ret != 0) {
2470 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2471 goto err;
2472 }
2473
2474 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2475 wm8904->supplies[i].supply = wm8904_supply_names[i];
2476
2477 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
2478 wm8904->supplies);
2479 if (ret != 0) {
2480 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2481 goto err;
2482 }
2483
2484 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2485 wm8904->supplies);
2486 if (ret != 0) {
2487 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2488 goto err_get;
2489 }
2490
2491 ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
2492 if (ret < 0) {
2493 dev_err(codec->dev, "Failed to read ID register\n");
2494 goto err_enable;
2495 }
2496 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) {
2497 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2498 ret = -EINVAL;
2499 goto err_enable;
2500 }
2501
2502 ret = snd_soc_read(codec, WM8904_REVISION);
2503 if (ret < 0) {
2504 dev_err(codec->dev, "Failed to read device revision: %d\n",
2505 ret);
2506 goto err_enable;
2507 }
2508 dev_info(codec->dev, "revision %c\n", ret + 'A');
2509
2510 ret = wm8904_reset(codec);
2511 if (ret < 0) {
2512 dev_err(codec->dev, "Failed to issue reset\n");
2513 goto err_enable;
2514 }
2515
2516 wm8904_dai.dev = codec->dev;
2517
2518 /* Change some default settings - latch VU and enable ZC */
2519 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
2520 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
2521 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
2522 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
2523 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
2524 WM8904_HPOUTLZC;
2525 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
2526 WM8904_HPOUTRZC;
2527 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
2528 WM8904_LINEOUTLZC;
2529 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
2530 WM8904_LINEOUTRZC;
2531 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
2532
2533 /* Set Class W by default - this will be managed by the Class
2534 * G widget at runtime where bypass paths are available.
2535 */
2536 wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
2537
2538 /* Use normal bias source */
2539 wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
2540
2541 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2542
2543 /* Bias level configuration will have done an extra enable */
2544 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2545
2546 wm8904_codec = codec;
2547
2548 ret = snd_soc_register_codec(codec);
2549 if (ret != 0) {
2550 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2551 return ret;
2552 }
2553
2554 ret = snd_soc_register_dai(&wm8904_dai);
2555 if (ret != 0) {
2556 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2557 snd_soc_unregister_codec(codec);
2558 return ret;
2559 }
2560
2561 return 0;
2562
2563err_enable:
2564 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2565err_get:
2566 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2567err:
2568 kfree(wm8904);
2569 return ret;
2570}
2571
2572static void wm8904_unregister(struct wm8904_priv *wm8904)
2573{
2574 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF);
2575 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2576 snd_soc_unregister_dai(&wm8904_dai);
2577 snd_soc_unregister_codec(&wm8904->codec);
2578 kfree(wm8904);
2579 wm8904_codec = NULL;
2580}
2581
2582#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2583static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2584 const struct i2c_device_id *id)
2585{
2586 struct wm8904_priv *wm8904;
2587 struct snd_soc_codec *codec;
2588
2589 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2590 if (wm8904 == NULL)
2591 return -ENOMEM;
2592
2593 codec = &wm8904->codec;
2594 codec->hw_write = (hw_write_t)i2c_master_send;
2595
2596 wm8904->devtype = id->driver_data;
2597
2598 i2c_set_clientdata(i2c, wm8904);
2599 codec->control_data = i2c;
2600 wm8904->pdata = i2c->dev.platform_data;
2601
2602 codec->dev = &i2c->dev;
2603
2604 return wm8904_register(wm8904, SND_SOC_I2C);
2605}
2606
2607static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2608{
2609 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2610 wm8904_unregister(wm8904);
2611 return 0;
2612}
2613
2614static const struct i2c_device_id wm8904_i2c_id[] = {
2615 { "wm8904", WM8904 },
2616 { "wm8912", WM8912 },
2617 { }
2618};
2619MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2620
2621static struct i2c_driver wm8904_i2c_driver = {
2622 .driver = {
2623 .name = "WM8904",
2624 .owner = THIS_MODULE,
2625 },
2626 .probe = wm8904_i2c_probe,
2627 .remove = __devexit_p(wm8904_i2c_remove),
2628 .id_table = wm8904_i2c_id,
2629};
2630#endif
2631
2632static int __init wm8904_modinit(void)
2633{
2634 int ret;
2635#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2636 ret = i2c_add_driver(&wm8904_i2c_driver);
2637 if (ret != 0) {
2638 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n",
2639 ret);
2640 }
2641#endif
2642 return 0;
2643}
2644module_init(wm8904_modinit);
2645
2646static void __exit wm8904_exit(void)
2647{
2648#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2649 i2c_del_driver(&wm8904_i2c_driver);
2650#endif
2651}
2652module_exit(wm8904_exit);
2653
2654MODULE_DESCRIPTION("ASoC WM8904 driver");
2655MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2656MODULE_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
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
new file mode 100644
index 000000000000..615dab2b62ef
--- /dev/null
+++ b/sound/soc/codecs/wm8955.c
@@ -0,0 +1,1151 @@
1/*
2 * wm8955.c -- WM8955 ALSA SoC Audio 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#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/consumer.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28#include <sound/wm8955.h>
29
30#include "wm8955.h"
31
32static struct snd_soc_codec *wm8955_codec;
33struct snd_soc_codec_device soc_codec_dev_wm8955;
34
35#define WM8955_NUM_SUPPLIES 4
36static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
37 "DCVDD",
38 "DBVDD",
39 "HPVDD",
40 "AVDD",
41};
42
43/* codec private data */
44struct wm8955_priv {
45 struct snd_soc_codec codec;
46 u16 reg_cache[WM8955_MAX_REGISTER + 1];
47
48 unsigned int mclk_rate;
49
50 int deemph;
51 int fs;
52
53 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
54
55 struct wm8955_pdata *pdata;
56};
57
58static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
59 0x0000, /* R0 */
60 0x0000, /* R1 */
61 0x0079, /* R2 - LOUT1 volume */
62 0x0079, /* R3 - ROUT1 volume */
63 0x0000, /* R4 */
64 0x0008, /* R5 - DAC Control */
65 0x0000, /* R6 */
66 0x000A, /* R7 - Audio Interface */
67 0x0000, /* R8 - Sample Rate */
68 0x0000, /* R9 */
69 0x00FF, /* R10 - Left DAC volume */
70 0x00FF, /* R11 - Right DAC volume */
71 0x000F, /* R12 - Bass control */
72 0x000F, /* R13 - Treble control */
73 0x0000, /* R14 */
74 0x0000, /* R15 - Reset */
75 0x0000, /* R16 */
76 0x0000, /* R17 */
77 0x0000, /* R18 */
78 0x0000, /* R19 */
79 0x0000, /* R20 */
80 0x0000, /* R21 */
81 0x0000, /* R22 */
82 0x00C1, /* R23 - Additional control (1) */
83 0x0000, /* R24 - Additional control (2) */
84 0x0000, /* R25 - Power Management (1) */
85 0x0000, /* R26 - Power Management (2) */
86 0x0000, /* R27 - Additional Control (3) */
87 0x0000, /* R28 */
88 0x0000, /* R29 */
89 0x0000, /* R30 */
90 0x0000, /* R31 */
91 0x0000, /* R32 */
92 0x0000, /* R33 */
93 0x0050, /* R34 - Left out Mix (1) */
94 0x0050, /* R35 - Left out Mix (2) */
95 0x0050, /* R36 - Right out Mix (1) */
96 0x0050, /* R37 - Right Out Mix (2) */
97 0x0050, /* R38 - Mono out Mix (1) */
98 0x0050, /* R39 - Mono out Mix (2) */
99 0x0079, /* R40 - LOUT2 volume */
100 0x0079, /* R41 - ROUT2 volume */
101 0x0079, /* R42 - MONOOUT volume */
102 0x0000, /* R43 - Clocking / PLL */
103 0x0103, /* R44 - PLL Control 1 */
104 0x0024, /* R45 - PLL Control 2 */
105 0x01BA, /* R46 - PLL Control 3 */
106 0x0000, /* R47 */
107 0x0000, /* R48 */
108 0x0000, /* R49 */
109 0x0000, /* R50 */
110 0x0000, /* R51 */
111 0x0000, /* R52 */
112 0x0000, /* R53 */
113 0x0000, /* R54 */
114 0x0000, /* R55 */
115 0x0000, /* R56 */
116 0x0000, /* R57 */
117 0x0000, /* R58 */
118 0x0000, /* R59 - PLL Control 4 */
119};
120
121static int wm8955_reset(struct snd_soc_codec *codec)
122{
123 return snd_soc_write(codec, WM8955_RESET, 0);
124}
125
126struct pll_factors {
127 int n;
128 int k;
129 int outdiv;
130};
131
132/* The size in bits of the FLL divide multiplied by 10
133 * to allow rounding later */
134#define FIXED_FLL_SIZE ((1 << 22) * 10)
135
136static int wm8995_pll_factors(struct device *dev,
137 int Fref, int Fout, struct pll_factors *pll)
138{
139 u64 Kpart;
140 unsigned int K, Ndiv, Nmod, target;
141
142 dev_dbg(dev, "Fref=%u Fout=%u\n", Fref, Fout);
143
144 /* The oscilator should run at should be 90-100MHz, and
145 * there's a divide by 4 plus an optional divide by 2 in the
146 * output path to generate the system clock. The clock table
147 * is sortd so we should always generate a suitable target. */
148 target = Fout * 4;
149 if (target < 90000000) {
150 pll->outdiv = 1;
151 target *= 2;
152 } else {
153 pll->outdiv = 0;
154 }
155
156 WARN_ON(target < 90000000 || target > 100000000);
157
158 dev_dbg(dev, "Fvco=%dHz\n", target);
159
160 /* Now, calculate N.K */
161 Ndiv = target / Fref;
162
163 pll->n = Ndiv;
164 Nmod = target % Fref;
165 dev_dbg(dev, "Nmod=%d\n", Nmod);
166
167 /* Calculate fractional part - scale up so we can round. */
168 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
169
170 do_div(Kpart, Fref);
171
172 K = Kpart & 0xFFFFFFFF;
173
174 if ((K % 10) >= 5)
175 K += 5;
176
177 /* Move down to proper range now rounding is done */
178 pll->k = K / 10;
179
180 dev_dbg(dev, "N=%x K=%x OUTDIV=%x\n", pll->n, pll->k, pll->outdiv);
181
182 return 0;
183}
184
185/* Lookup table specifiying SRATE (table 25 in datasheet); some of the
186 * output frequencies have been rounded to the standard frequencies
187 * they are intended to match where the error is slight. */
188static struct {
189 int mclk;
190 int fs;
191 int usb;
192 int sr;
193} clock_cfgs[] = {
194 { 18432000, 8000, 0, 3, },
195 { 18432000, 12000, 0, 9, },
196 { 18432000, 16000, 0, 11, },
197 { 18432000, 24000, 0, 29, },
198 { 18432000, 32000, 0, 13, },
199 { 18432000, 48000, 0, 1, },
200 { 18432000, 96000, 0, 15, },
201
202 { 16934400, 8018, 0, 19, },
203 { 16934400, 11025, 0, 25, },
204 { 16934400, 22050, 0, 27, },
205 { 16934400, 44100, 0, 17, },
206 { 16934400, 88200, 0, 31, },
207
208 { 12000000, 8000, 1, 2, },
209 { 12000000, 11025, 1, 25, },
210 { 12000000, 12000, 1, 8, },
211 { 12000000, 16000, 1, 10, },
212 { 12000000, 22050, 1, 27, },
213 { 12000000, 24000, 1, 28, },
214 { 12000000, 32000, 1, 12, },
215 { 12000000, 44100, 1, 17, },
216 { 12000000, 48000, 1, 0, },
217 { 12000000, 88200, 1, 31, },
218 { 12000000, 96000, 1, 14, },
219
220 { 12288000, 8000, 0, 2, },
221 { 12288000, 12000, 0, 8, },
222 { 12288000, 16000, 0, 10, },
223 { 12288000, 24000, 0, 28, },
224 { 12288000, 32000, 0, 12, },
225 { 12288000, 48000, 0, 0, },
226 { 12288000, 96000, 0, 14, },
227
228 { 12289600, 8018, 0, 18, },
229 { 12289600, 11025, 0, 24, },
230 { 12289600, 22050, 0, 26, },
231 { 11289600, 44100, 0, 16, },
232 { 11289600, 88200, 0, 31, },
233};
234
235static int wm8955_configure_clocking(struct snd_soc_codec *codec)
236{
237 struct wm8955_priv *wm8955 = codec->private_data;
238 int i, ret, val;
239 int clocking = 0;
240 int srate = 0;
241 int sr = -1;
242 struct pll_factors pll;
243
244 /* If we're not running a sample rate currently just pick one */
245 if (wm8955->fs == 0)
246 wm8955->fs = 8000;
247
248 /* Can we generate an exact output? */
249 for (i = 0; i < ARRAY_SIZE(clock_cfgs); i++) {
250 if (wm8955->fs != clock_cfgs[i].fs)
251 continue;
252 sr = i;
253
254 if (wm8955->mclk_rate == clock_cfgs[i].mclk)
255 break;
256 }
257
258 /* We should never get here with an unsupported sample rate */
259 if (sr == -1) {
260 dev_err(codec->dev, "Sample rate %dHz unsupported\n",
261 wm8955->fs);
262 WARN_ON(sr == -1);
263 return -EINVAL;
264 }
265
266 if (i == ARRAY_SIZE(clock_cfgs)) {
267 /* If we can't generate the right clock from MCLK then
268 * we should configure the PLL to supply us with an
269 * appropriate clock.
270 */
271 clocking |= WM8955_MCLKSEL;
272
273 /* Use the last divider configuration we saw for the
274 * sample rate. */
275 ret = wm8995_pll_factors(codec->dev, wm8955->mclk_rate,
276 clock_cfgs[sr].mclk, &pll);
277 if (ret != 0) {
278 dev_err(codec->dev,
279 "Unable to generate %dHz from %dHz MCLK\n",
280 wm8955->fs, wm8955->mclk_rate);
281 return -EINVAL;
282 }
283
284 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_1,
285 WM8955_N_MASK | WM8955_K_21_18_MASK,
286 (pll.n << WM8955_N_SHIFT) |
287 pll.k >> 18);
288 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
289 WM8955_K_17_9_MASK,
290 (pll.k >> 9) & WM8955_K_17_9_MASK);
291 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
292 WM8955_K_8_0_MASK,
293 pll.k & WM8955_K_8_0_MASK);
294 if (pll.k)
295 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
296 WM8955_KEN, WM8955_KEN);
297 else
298 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
299 WM8955_KEN, 0);
300
301 if (pll.outdiv)
302 val = WM8955_PLL_RB | WM8955_PLLOUTDIV2;
303 else
304 val = WM8955_PLL_RB;
305
306 /* Now start the PLL running */
307 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
308 WM8955_PLL_RB | WM8955_PLLOUTDIV2, val);
309 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
310 WM8955_PLLEN, WM8955_PLLEN);
311 }
312
313 srate = clock_cfgs[sr].usb | (clock_cfgs[sr].sr << WM8955_SR_SHIFT);
314
315 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
316 WM8955_USB | WM8955_SR_MASK, srate);
317 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
318 WM8955_MCLKSEL, clocking);
319
320 return 0;
321}
322
323static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
324 struct snd_kcontrol *kcontrol, int event)
325{
326 struct snd_soc_codec *codec = w->codec;
327 int ret = 0;
328
329 /* Always disable the clocks - if we're doing reconfiguration this
330 * avoids misclocking.
331 */
332 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
333 WM8955_DIGENB, 0);
334 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
335 WM8955_PLL_RB | WM8955_PLLEN, 0);
336
337 switch (event) {
338 case SND_SOC_DAPM_POST_PMD:
339 break;
340 case SND_SOC_DAPM_PRE_PMU:
341 ret = wm8955_configure_clocking(codec);
342 break;
343 default:
344 ret = -EINVAL;
345 break;
346 }
347
348 return ret;
349}
350
351static int deemph_settings[] = { 0, 32000, 44100, 48000 };
352
353static int wm8955_set_deemph(struct snd_soc_codec *codec)
354{
355 struct wm8955_priv *wm8955 = codec->private_data;
356 int val, i, best;
357
358 /* If we're using deemphasis select the nearest available sample
359 * rate.
360 */
361 if (wm8955->deemph) {
362 best = 1;
363 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
364 if (abs(deemph_settings[i] - wm8955->fs) <
365 abs(deemph_settings[best] - wm8955->fs))
366 best = i;
367 }
368
369 val = best << WM8955_DEEMPH_SHIFT;
370 } else {
371 val = 0;
372 }
373
374 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
375
376 return snd_soc_update_bits(codec, WM8955_DAC_CONTROL,
377 WM8955_DEEMPH_MASK, val);
378}
379
380static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
384 struct wm8955_priv *wm8955 = codec->private_data;
385
386 return wm8955->deemph;
387}
388
389static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
390 struct snd_ctl_elem_value *ucontrol)
391{
392 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
393 struct wm8955_priv *wm8955 = codec->private_data;
394 int deemph = ucontrol->value.enumerated.item[0];
395
396 if (deemph > 1)
397 return -EINVAL;
398
399 wm8955->deemph = deemph;
400
401 return wm8955_set_deemph(codec);
402}
403
404static const char *bass_mode_text[] = {
405 "Linear", "Adaptive",
406};
407
408static const struct soc_enum bass_mode =
409 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 7, 2, bass_mode_text);
410
411static const char *bass_cutoff_text[] = {
412 "Low", "High"
413};
414
415static const struct soc_enum bass_cutoff =
416 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 6, 2, bass_cutoff_text);
417
418static const char *treble_cutoff_text[] = {
419 "High", "Low"
420};
421
422static const struct soc_enum treble_cutoff =
423 SOC_ENUM_SINGLE(WM8955_TREBLE_CONTROL, 6, 2, treble_cutoff_text);
424
425static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
426static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0);
427static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
428static const DECLARE_TLV_DB_SCALE(mono_tlv, -2100, 300, 0);
429static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
430static const DECLARE_TLV_DB_SCALE(treble_tlv, -1200, 150, 1);
431
432static const struct snd_kcontrol_new wm8955_snd_controls[] = {
433SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8955_LEFT_DAC_VOLUME,
434 WM8955_RIGHT_DAC_VOLUME, 0, 255, 0, digital_tlv),
435SOC_SINGLE_TLV("Playback Attenuation Volume", WM8955_DAC_CONTROL, 7, 1, 1,
436 atten_tlv),
437SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
438 wm8955_get_deemph, wm8955_put_deemph),
439
440SOC_ENUM("Bass Mode", bass_mode),
441SOC_ENUM("Bass Cutoff", bass_cutoff),
442SOC_SINGLE("Bass Volume", WM8955_BASS_CONTROL, 0, 15, 1),
443
444SOC_ENUM("Treble Cutoff", treble_cutoff),
445SOC_SINGLE_TLV("Treble Volume", WM8955_TREBLE_CONTROL, 0, 14, 1, treble_tlv),
446
447SOC_SINGLE_TLV("Left Bypass Volume", WM8955_LEFT_OUT_MIX_1, 4, 7, 1,
448 bypass_tlv),
449SOC_SINGLE_TLV("Left Mono Volume", WM8955_LEFT_OUT_MIX_2, 4, 7, 1,
450 bypass_tlv),
451
452SOC_SINGLE_TLV("Right Mono Volume", WM8955_RIGHT_OUT_MIX_1, 4, 7, 1,
453 bypass_tlv),
454SOC_SINGLE_TLV("Right Bypass Volume", WM8955_RIGHT_OUT_MIX_2, 4, 7, 1,
455 bypass_tlv),
456
457/* Not a stereo pair so they line up with the DAPM switches */
458SOC_SINGLE_TLV("Mono Left Bypass Volume", WM8955_MONO_OUT_MIX_1, 4, 7, 1,
459 mono_tlv),
460SOC_SINGLE_TLV("Mono Right Bypass Volume", WM8955_MONO_OUT_MIX_2, 4, 7, 1,
461 mono_tlv),
462
463SOC_DOUBLE_R_TLV("Headphone Volume", WM8955_LOUT1_VOLUME,
464 WM8955_ROUT1_VOLUME, 0, 127, 0, out_tlv),
465SOC_DOUBLE_R("Headphone ZC Switch", WM8955_LOUT1_VOLUME,
466 WM8955_ROUT1_VOLUME, 7, 1, 0),
467
468SOC_DOUBLE_R_TLV("Speaker Volume", WM8955_LOUT2_VOLUME,
469 WM8955_ROUT2_VOLUME, 0, 127, 0, out_tlv),
470SOC_DOUBLE_R("Speaker ZC Switch", WM8955_LOUT2_VOLUME,
471 WM8955_ROUT2_VOLUME, 7, 1, 0),
472
473SOC_SINGLE_TLV("Mono Volume", WM8955_MONOOUT_VOLUME, 0, 127, 0, out_tlv),
474SOC_SINGLE("Mono ZC Switch", WM8955_MONOOUT_VOLUME, 7, 1, 0),
475};
476
477static const struct snd_kcontrol_new lmixer[] = {
478SOC_DAPM_SINGLE("Playback Switch", WM8955_LEFT_OUT_MIX_1, 8, 1, 0),
479SOC_DAPM_SINGLE("Bypass Switch", WM8955_LEFT_OUT_MIX_1, 7, 1, 0),
480SOC_DAPM_SINGLE("Right Playback Switch", WM8955_LEFT_OUT_MIX_2, 8, 1, 0),
481SOC_DAPM_SINGLE("Mono Switch", WM8955_LEFT_OUT_MIX_2, 7, 1, 0),
482};
483
484static const struct snd_kcontrol_new rmixer[] = {
485SOC_DAPM_SINGLE("Left Playback Switch", WM8955_RIGHT_OUT_MIX_1, 8, 1, 0),
486SOC_DAPM_SINGLE("Mono Switch", WM8955_RIGHT_OUT_MIX_1, 7, 1, 0),
487SOC_DAPM_SINGLE("Playback Switch", WM8955_RIGHT_OUT_MIX_2, 8, 1, 0),
488SOC_DAPM_SINGLE("Bypass Switch", WM8955_RIGHT_OUT_MIX_2, 7, 1, 0),
489};
490
491static const struct snd_kcontrol_new mmixer[] = {
492SOC_DAPM_SINGLE("Left Playback Switch", WM8955_MONO_OUT_MIX_1, 8, 1, 0),
493SOC_DAPM_SINGLE("Left Bypass Switch", WM8955_MONO_OUT_MIX_1, 7, 1, 0),
494SOC_DAPM_SINGLE("Right Playback Switch", WM8955_MONO_OUT_MIX_2, 8, 1, 0),
495SOC_DAPM_SINGLE("Right Bypass Switch", WM8955_MONO_OUT_MIX_2, 7, 1, 0),
496};
497
498static const struct snd_soc_dapm_widget wm8955_dapm_widgets[] = {
499SND_SOC_DAPM_INPUT("MONOIN-"),
500SND_SOC_DAPM_INPUT("MONOIN+"),
501SND_SOC_DAPM_INPUT("LINEINR"),
502SND_SOC_DAPM_INPUT("LINEINL"),
503
504SND_SOC_DAPM_PGA("Mono Input", SND_SOC_NOPM, 0, 0, NULL, 0),
505
506SND_SOC_DAPM_SUPPLY("SYSCLK", WM8955_POWER_MANAGEMENT_1, 0, 1, wm8955_sysclk,
507 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
508SND_SOC_DAPM_SUPPLY("TSDEN", WM8955_ADDITIONAL_CONTROL_1, 8, 0, NULL, 0),
509
510SND_SOC_DAPM_DAC("DACL", "Playback", WM8955_POWER_MANAGEMENT_2, 8, 0),
511SND_SOC_DAPM_DAC("DACR", "Playback", WM8955_POWER_MANAGEMENT_2, 7, 0),
512
513SND_SOC_DAPM_PGA("LOUT1 PGA", WM8955_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
514SND_SOC_DAPM_PGA("ROUT1 PGA", WM8955_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
515SND_SOC_DAPM_PGA("LOUT2 PGA", WM8955_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
516SND_SOC_DAPM_PGA("ROUT2 PGA", WM8955_POWER_MANAGEMENT_2, 3, 0, NULL, 0),
517SND_SOC_DAPM_PGA("MOUT PGA", WM8955_POWER_MANAGEMENT_2, 2, 0, NULL, 0),
518SND_SOC_DAPM_PGA("OUT3 PGA", WM8955_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
519
520/* The names are chosen to make the control names nice */
521SND_SOC_DAPM_MIXER("Left", SND_SOC_NOPM, 0, 0,
522 lmixer, ARRAY_SIZE(lmixer)),
523SND_SOC_DAPM_MIXER("Right", SND_SOC_NOPM, 0, 0,
524 rmixer, ARRAY_SIZE(rmixer)),
525SND_SOC_DAPM_MIXER("Mono", SND_SOC_NOPM, 0, 0,
526 mmixer, ARRAY_SIZE(mmixer)),
527
528SND_SOC_DAPM_OUTPUT("LOUT1"),
529SND_SOC_DAPM_OUTPUT("ROUT1"),
530SND_SOC_DAPM_OUTPUT("LOUT2"),
531SND_SOC_DAPM_OUTPUT("ROUT2"),
532SND_SOC_DAPM_OUTPUT("MONOOUT"),
533SND_SOC_DAPM_OUTPUT("OUT3"),
534};
535
536static const struct snd_soc_dapm_route wm8955_intercon[] = {
537 { "DACL", NULL, "SYSCLK" },
538 { "DACR", NULL, "SYSCLK" },
539
540 { "Mono Input", NULL, "MONOIN-" },
541 { "Mono Input", NULL, "MONOIN+" },
542
543 { "Left", "Playback Switch", "DACL" },
544 { "Left", "Right Playback Switch", "DACR" },
545 { "Left", "Bypass Switch", "LINEINL" },
546 { "Left", "Mono Switch", "Mono Input" },
547
548 { "Right", "Playback Switch", "DACR" },
549 { "Right", "Left Playback Switch", "DACL" },
550 { "Right", "Bypass Switch", "LINEINR" },
551 { "Right", "Mono Switch", "Mono Input" },
552
553 { "Mono", "Left Playback Switch", "DACL" },
554 { "Mono", "Right Playback Switch", "DACR" },
555 { "Mono", "Left Bypass Switch", "LINEINL" },
556 { "Mono", "Right Bypass Switch", "LINEINR" },
557
558 { "LOUT1 PGA", NULL, "Left" },
559 { "LOUT1", NULL, "TSDEN" },
560 { "LOUT1", NULL, "LOUT1 PGA" },
561
562 { "ROUT1 PGA", NULL, "Right" },
563 { "ROUT1", NULL, "TSDEN" },
564 { "ROUT1", NULL, "ROUT1 PGA" },
565
566 { "LOUT2 PGA", NULL, "Left" },
567 { "LOUT2", NULL, "TSDEN" },
568 { "LOUT2", NULL, "LOUT2 PGA" },
569
570 { "ROUT2 PGA", NULL, "Right" },
571 { "ROUT2", NULL, "TSDEN" },
572 { "ROUT2", NULL, "ROUT2 PGA" },
573
574 { "MOUT PGA", NULL, "Mono" },
575 { "MONOOUT", NULL, "MOUT PGA" },
576
577 /* OUT3 not currently implemented */
578 { "OUT3", NULL, "OUT3 PGA" },
579};
580
581static int wm8955_add_widgets(struct snd_soc_codec *codec)
582{
583 snd_soc_add_controls(codec, wm8955_snd_controls,
584 ARRAY_SIZE(wm8955_snd_controls));
585
586 snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets,
587 ARRAY_SIZE(wm8955_dapm_widgets));
588
589 snd_soc_dapm_add_routes(codec, wm8955_intercon,
590 ARRAY_SIZE(wm8955_intercon));
591
592 return 0;
593}
594
595static int wm8955_hw_params(struct snd_pcm_substream *substream,
596 struct snd_pcm_hw_params *params,
597 struct snd_soc_dai *dai)
598{
599 struct snd_soc_codec *codec = dai->codec;
600 struct wm8955_priv *wm8955 = codec->private_data;
601 int ret;
602 int wl;
603
604 switch (params_format(params)) {
605 case SNDRV_PCM_FORMAT_S16_LE:
606 wl = 0;
607 break;
608 case SNDRV_PCM_FORMAT_S20_3LE:
609 wl = 0x4;
610 break;
611 case SNDRV_PCM_FORMAT_S24_LE:
612 wl = 0x8;
613 break;
614 case SNDRV_PCM_FORMAT_S32_LE:
615 wl = 0xc;
616 break;
617 default:
618 return -EINVAL;
619 }
620 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
621 WM8955_WL_MASK, wl);
622
623 wm8955->fs = params_rate(params);
624 wm8955_set_deemph(codec);
625
626 /* If the chip is clocked then disable the clocks and force a
627 * reconfiguration, otherwise DAPM will power up the
628 * clocks for us later. */
629 ret = snd_soc_read(codec, WM8955_POWER_MANAGEMENT_1);
630 if (ret < 0)
631 return ret;
632 if (ret & WM8955_DIGENB) {
633 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
634 WM8955_DIGENB, 0);
635 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
636 WM8955_PLL_RB | WM8955_PLLEN, 0);
637
638 wm8955_configure_clocking(codec);
639 }
640
641 return 0;
642}
643
644
645static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
646 unsigned int freq, int dir)
647{
648 struct snd_soc_codec *codec = dai->codec;
649 struct wm8955_priv *priv = codec->private_data;
650 int div;
651
652 switch (clk_id) {
653 case WM8955_CLK_MCLK:
654 if (freq > 15000000) {
655 priv->mclk_rate = freq /= 2;
656 div = WM8955_MCLKDIV2;
657 } else {
658 priv->mclk_rate = freq;
659 div = 0;
660 }
661
662 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
663 WM8955_MCLKDIV2, div);
664 break;
665
666 default:
667 return -EINVAL;
668 }
669
670 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
671
672 return 0;
673}
674
675static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
676{
677 struct snd_soc_codec *codec = dai->codec;
678 u16 aif = 0;
679
680 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
681 case SND_SOC_DAIFMT_CBS_CFS:
682 break;
683 case SND_SOC_DAIFMT_CBM_CFM:
684 aif |= WM8955_MS;
685 break;
686 default:
687 return -EINVAL;
688 }
689
690 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
691 case SND_SOC_DAIFMT_DSP_B:
692 aif |= WM8955_LRP;
693 case SND_SOC_DAIFMT_DSP_A:
694 aif |= 0x3;
695 break;
696 case SND_SOC_DAIFMT_I2S:
697 aif |= 0x2;
698 break;
699 case SND_SOC_DAIFMT_RIGHT_J:
700 break;
701 case SND_SOC_DAIFMT_LEFT_J:
702 aif |= 0x1;
703 break;
704 default:
705 return -EINVAL;
706 }
707
708 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
709 case SND_SOC_DAIFMT_DSP_A:
710 case SND_SOC_DAIFMT_DSP_B:
711 /* frame inversion not valid for DSP modes */
712 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
713 case SND_SOC_DAIFMT_NB_NF:
714 break;
715 case SND_SOC_DAIFMT_IB_NF:
716 aif |= WM8955_BCLKINV;
717 break;
718 default:
719 return -EINVAL;
720 }
721 break;
722
723 case SND_SOC_DAIFMT_I2S:
724 case SND_SOC_DAIFMT_RIGHT_J:
725 case SND_SOC_DAIFMT_LEFT_J:
726 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
727 case SND_SOC_DAIFMT_NB_NF:
728 break;
729 case SND_SOC_DAIFMT_IB_IF:
730 aif |= WM8955_BCLKINV | WM8955_LRP;
731 break;
732 case SND_SOC_DAIFMT_IB_NF:
733 aif |= WM8955_BCLKINV;
734 break;
735 case SND_SOC_DAIFMT_NB_IF:
736 aif |= WM8955_LRP;
737 break;
738 default:
739 return -EINVAL;
740 }
741 break;
742 default:
743 return -EINVAL;
744 }
745
746 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
747 WM8955_MS | WM8955_FORMAT_MASK | WM8955_BCLKINV |
748 WM8955_LRP, aif);
749
750 return 0;
751}
752
753
754static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
755{
756 struct snd_soc_codec *codec = codec_dai->codec;
757 int val;
758
759 if (mute)
760 val = WM8955_DACMU;
761 else
762 val = 0;
763
764 snd_soc_update_bits(codec, WM8955_DAC_CONTROL, WM8955_DACMU, val);
765
766 return 0;
767}
768
769static int wm8955_set_bias_level(struct snd_soc_codec *codec,
770 enum snd_soc_bias_level level)
771{
772 struct wm8955_priv *wm8955 = codec->private_data;
773 int ret, i;
774
775 switch (level) {
776 case SND_SOC_BIAS_ON:
777 break;
778
779 case SND_SOC_BIAS_PREPARE:
780 /* VMID resistance 2*50k */
781 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
782 WM8955_VMIDSEL_MASK,
783 0x1 << WM8955_VMIDSEL_SHIFT);
784
785 /* Default bias current */
786 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
787 WM8955_VSEL_MASK,
788 0x2 << WM8955_VSEL_SHIFT);
789 break;
790
791 case SND_SOC_BIAS_STANDBY:
792 if (codec->bias_level == SND_SOC_BIAS_OFF) {
793 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
794 wm8955->supplies);
795 if (ret != 0) {
796 dev_err(codec->dev,
797 "Failed to enable supplies: %d\n",
798 ret);
799 return ret;
800 }
801
802 /* Sync back cached values if they're
803 * different from the hardware default.
804 */
805 for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
806 if (i == WM8955_RESET)
807 continue;
808
809 if (wm8955->reg_cache[i] == wm8955_reg[i])
810 continue;
811
812 snd_soc_write(codec, i, wm8955->reg_cache[i]);
813 }
814
815 /* Enable VREF and VMID */
816 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
817 WM8955_VREF |
818 WM8955_VMIDSEL_MASK,
819 WM8955_VREF |
820 0x3 << WM8955_VREF_SHIFT);
821
822 /* Let VMID ramp */
823 msleep(500);
824
825 /* High resistance VROI to maintain outputs */
826 snd_soc_update_bits(codec,
827 WM8955_ADDITIONAL_CONTROL_3,
828 WM8955_VROI, WM8955_VROI);
829 }
830
831 /* Maintain VMID with 2*250k */
832 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
833 WM8955_VMIDSEL_MASK,
834 0x2 << WM8955_VMIDSEL_SHIFT);
835
836 /* Minimum bias current */
837 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
838 WM8955_VSEL_MASK, 0);
839 break;
840
841 case SND_SOC_BIAS_OFF:
842 /* Low resistance VROI to help discharge */
843 snd_soc_update_bits(codec,
844 WM8955_ADDITIONAL_CONTROL_3,
845 WM8955_VROI, 0);
846
847 /* Turn off VMID and VREF */
848 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
849 WM8955_VREF |
850 WM8955_VMIDSEL_MASK, 0);
851
852 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies),
853 wm8955->supplies);
854 break;
855 }
856 codec->bias_level = level;
857 return 0;
858}
859
860#define WM8955_RATES SNDRV_PCM_RATE_8000_96000
861
862#define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
863 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
864
865static struct snd_soc_dai_ops wm8955_dai_ops = {
866 .set_sysclk = wm8955_set_sysclk,
867 .set_fmt = wm8955_set_fmt,
868 .hw_params = wm8955_hw_params,
869 .digital_mute = wm8955_digital_mute,
870};
871
872struct snd_soc_dai wm8955_dai = {
873 .name = "WM8955",
874 .playback = {
875 .stream_name = "Playback",
876 .channels_min = 2,
877 .channels_max = 2,
878 .rates = WM8955_RATES,
879 .formats = WM8955_FORMATS,
880 },
881 .ops = &wm8955_dai_ops,
882};
883EXPORT_SYMBOL_GPL(wm8955_dai);
884
885#ifdef CONFIG_PM
886static int wm8955_suspend(struct platform_device *pdev, pm_message_t state)
887{
888 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
889 struct snd_soc_codec *codec = socdev->card->codec;
890
891 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
892
893 return 0;
894}
895
896static int wm8955_resume(struct platform_device *pdev)
897{
898 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
899 struct snd_soc_codec *codec = socdev->card->codec;
900
901 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
902
903 return 0;
904}
905#else
906#define wm8955_suspend NULL
907#define wm8955_resume NULL
908#endif
909
910static int wm8955_probe(struct platform_device *pdev)
911{
912 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
913 struct snd_soc_codec *codec;
914 int ret = 0;
915
916 if (wm8955_codec == NULL) {
917 dev_err(&pdev->dev, "Codec device not registered\n");
918 return -ENODEV;
919 }
920
921 socdev->card->codec = wm8955_codec;
922 codec = wm8955_codec;
923
924 /* register pcms */
925 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
926 if (ret < 0) {
927 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
928 goto pcm_err;
929 }
930
931 wm8955_add_widgets(codec);
932
933 return ret;
934
935pcm_err:
936 return ret;
937}
938
939static int wm8955_remove(struct platform_device *pdev)
940{
941 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
942
943 snd_soc_free_pcms(socdev);
944 snd_soc_dapm_free(socdev);
945
946 return 0;
947}
948
949struct snd_soc_codec_device soc_codec_dev_wm8955 = {
950 .probe = wm8955_probe,
951 .remove = wm8955_remove,
952 .suspend = wm8955_suspend,
953 .resume = wm8955_resume,
954};
955EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955);
956
957static int wm8955_register(struct wm8955_priv *wm8955,
958 enum snd_soc_control_type control)
959{
960 int ret;
961 struct snd_soc_codec *codec = &wm8955->codec;
962 int i;
963
964 if (wm8955_codec) {
965 dev_err(codec->dev, "Another WM8955 is registered\n");
966 return -EINVAL;
967 }
968
969 mutex_init(&codec->mutex);
970 INIT_LIST_HEAD(&codec->dapm_widgets);
971 INIT_LIST_HEAD(&codec->dapm_paths);
972
973 codec->private_data = wm8955;
974 codec->name = "WM8955";
975 codec->owner = THIS_MODULE;
976 codec->bias_level = SND_SOC_BIAS_OFF;
977 codec->set_bias_level = wm8955_set_bias_level;
978 codec->dai = &wm8955_dai;
979 codec->num_dai = 1;
980 codec->reg_cache_size = WM8955_MAX_REGISTER;
981 codec->reg_cache = &wm8955->reg_cache;
982
983 memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg));
984
985 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
986 if (ret != 0) {
987 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
988 goto err;
989 }
990
991 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
992 wm8955->supplies[i].supply = wm8955_supply_names[i];
993
994 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies),
995 wm8955->supplies);
996 if (ret != 0) {
997 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
998 goto err;
999 }
1000
1001 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
1002 wm8955->supplies);
1003 if (ret != 0) {
1004 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1005 goto err_get;
1006 }
1007
1008 ret = wm8955_reset(codec);
1009 if (ret < 0) {
1010 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1011 goto err_enable;
1012 }
1013
1014 wm8955_dai.dev = codec->dev;
1015
1016 /* Change some default settings - latch VU and enable ZC */
1017 wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
1018 wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
1019 wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
1020 wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
1021 wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
1022 wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
1023 wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
1024
1025 /* Also enable adaptive bass boost by default */
1026 wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
1027
1028 /* Set platform data values */
1029 if (wm8955->pdata) {
1030 if (wm8955->pdata->out2_speaker)
1031 wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
1032 |= WM8955_ROUT2INV;
1033
1034 if (wm8955->pdata->monoin_diff)
1035 wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
1036 |= WM8955_DMEN;
1037 }
1038
1039 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1040
1041 /* Bias level configuration will have done an extra enable */
1042 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1043
1044 wm8955_codec = codec;
1045
1046 ret = snd_soc_register_codec(codec);
1047 if (ret != 0) {
1048 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1049 return ret;
1050 }
1051
1052 ret = snd_soc_register_dai(&wm8955_dai);
1053 if (ret != 0) {
1054 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1055 snd_soc_unregister_codec(codec);
1056 return ret;
1057 }
1058
1059 return 0;
1060
1061err_enable:
1062 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1063err_get:
1064 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1065err:
1066 kfree(wm8955);
1067 return ret;
1068}
1069
1070static void wm8955_unregister(struct wm8955_priv *wm8955)
1071{
1072 wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF);
1073 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1074 snd_soc_unregister_dai(&wm8955_dai);
1075 snd_soc_unregister_codec(&wm8955->codec);
1076 kfree(wm8955);
1077 wm8955_codec = NULL;
1078}
1079
1080#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1081static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
1082 const struct i2c_device_id *id)
1083{
1084 struct wm8955_priv *wm8955;
1085 struct snd_soc_codec *codec;
1086
1087 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
1088 if (wm8955 == NULL)
1089 return -ENOMEM;
1090
1091 codec = &wm8955->codec;
1092 codec->hw_write = (hw_write_t)i2c_master_send;
1093
1094 i2c_set_clientdata(i2c, wm8955);
1095 codec->control_data = i2c;
1096 wm8955->pdata = i2c->dev.platform_data;
1097
1098 codec->dev = &i2c->dev;
1099
1100 return wm8955_register(wm8955, SND_SOC_I2C);
1101}
1102
1103static __devexit int wm8955_i2c_remove(struct i2c_client *client)
1104{
1105 struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
1106 wm8955_unregister(wm8955);
1107 return 0;
1108}
1109
1110static const struct i2c_device_id wm8955_i2c_id[] = {
1111 { "wm8955", 0 },
1112 { }
1113};
1114MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
1115
1116static struct i2c_driver wm8955_i2c_driver = {
1117 .driver = {
1118 .name = "wm8955",
1119 .owner = THIS_MODULE,
1120 },
1121 .probe = wm8955_i2c_probe,
1122 .remove = __devexit_p(wm8955_i2c_remove),
1123 .id_table = wm8955_i2c_id,
1124};
1125#endif
1126
1127static int __init wm8955_modinit(void)
1128{
1129 int ret;
1130#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1131 ret = i2c_add_driver(&wm8955_i2c_driver);
1132 if (ret != 0) {
1133 printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
1134 ret);
1135 }
1136#endif
1137 return 0;
1138}
1139module_init(wm8955_modinit);
1140
1141static void __exit wm8955_exit(void)
1142{
1143#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1144 i2c_del_driver(&wm8955_i2c_driver);
1145#endif
1146}
1147module_exit(wm8955_exit);
1148
1149MODULE_DESCRIPTION("ASoC WM8955 driver");
1150MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1151MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8955.h b/sound/soc/codecs/wm8955.h
new file mode 100644
index 000000000000..ae349c8531f6
--- /dev/null
+++ b/sound/soc/codecs/wm8955.h
@@ -0,0 +1,489 @@
1/*
2 * wm8955.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 _WM8955_H
14#define _WM8955_H
15
16#define WM8955_CLK_MCLK 1
17
18extern struct snd_soc_dai wm8955_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8955;
20
21/*
22 * Register values.
23 */
24#define WM8955_LOUT1_VOLUME 0x02
25#define WM8955_ROUT1_VOLUME 0x03
26#define WM8955_DAC_CONTROL 0x05
27#define WM8955_AUDIO_INTERFACE 0x07
28#define WM8955_SAMPLE_RATE 0x08
29#define WM8955_LEFT_DAC_VOLUME 0x0A
30#define WM8955_RIGHT_DAC_VOLUME 0x0B
31#define WM8955_BASS_CONTROL 0x0C
32#define WM8955_TREBLE_CONTROL 0x0D
33#define WM8955_RESET 0x0F
34#define WM8955_ADDITIONAL_CONTROL_1 0x17
35#define WM8955_ADDITIONAL_CONTROL_2 0x18
36#define WM8955_POWER_MANAGEMENT_1 0x19
37#define WM8955_POWER_MANAGEMENT_2 0x1A
38#define WM8955_ADDITIONAL_CONTROL_3 0x1B
39#define WM8955_LEFT_OUT_MIX_1 0x22
40#define WM8955_LEFT_OUT_MIX_2 0x23
41#define WM8955_RIGHT_OUT_MIX_1 0x24
42#define WM8955_RIGHT_OUT_MIX_2 0x25
43#define WM8955_MONO_OUT_MIX_1 0x26
44#define WM8955_MONO_OUT_MIX_2 0x27
45#define WM8955_LOUT2_VOLUME 0x28
46#define WM8955_ROUT2_VOLUME 0x29
47#define WM8955_MONOOUT_VOLUME 0x2A
48#define WM8955_CLOCKING_PLL 0x2B
49#define WM8955_PLL_CONTROL_1 0x2C
50#define WM8955_PLL_CONTROL_2 0x2D
51#define WM8955_PLL_CONTROL_3 0x2E
52#define WM8955_PLL_CONTROL_4 0x3B
53
54#define WM8955_REGISTER_COUNT 29
55#define WM8955_MAX_REGISTER 0x3B
56
57/*
58 * Field Definitions.
59 */
60
61/*
62 * R2 (0x02) - LOUT1 volume
63 */
64#define WM8955_LO1VU 0x0100 /* LO1VU */
65#define WM8955_LO1VU_MASK 0x0100 /* LO1VU */
66#define WM8955_LO1VU_SHIFT 8 /* LO1VU */
67#define WM8955_LO1VU_WIDTH 1 /* LO1VU */
68#define WM8955_LO1ZC 0x0080 /* LO1ZC */
69#define WM8955_LO1ZC_MASK 0x0080 /* LO1ZC */
70#define WM8955_LO1ZC_SHIFT 7 /* LO1ZC */
71#define WM8955_LO1ZC_WIDTH 1 /* LO1ZC */
72#define WM8955_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
73#define WM8955_LOUTVOL_SHIFT 0 /* LOUTVOL - [6:0] */
74#define WM8955_LOUTVOL_WIDTH 7 /* LOUTVOL - [6:0] */
75
76/*
77 * R3 (0x03) - ROUT1 volume
78 */
79#define WM8955_RO1VU 0x0100 /* RO1VU */
80#define WM8955_RO1VU_MASK 0x0100 /* RO1VU */
81#define WM8955_RO1VU_SHIFT 8 /* RO1VU */
82#define WM8955_RO1VU_WIDTH 1 /* RO1VU */
83#define WM8955_RO1ZC 0x0080 /* RO1ZC */
84#define WM8955_RO1ZC_MASK 0x0080 /* RO1ZC */
85#define WM8955_RO1ZC_SHIFT 7 /* RO1ZC */
86#define WM8955_RO1ZC_WIDTH 1 /* RO1ZC */
87#define WM8955_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
88#define WM8955_ROUTVOL_SHIFT 0 /* ROUTVOL - [6:0] */
89#define WM8955_ROUTVOL_WIDTH 7 /* ROUTVOL - [6:0] */
90
91/*
92 * R5 (0x05) - DAC Control
93 */
94#define WM8955_DAT 0x0080 /* DAT */
95#define WM8955_DAT_MASK 0x0080 /* DAT */
96#define WM8955_DAT_SHIFT 7 /* DAT */
97#define WM8955_DAT_WIDTH 1 /* DAT */
98#define WM8955_DACMU 0x0008 /* DACMU */
99#define WM8955_DACMU_MASK 0x0008 /* DACMU */
100#define WM8955_DACMU_SHIFT 3 /* DACMU */
101#define WM8955_DACMU_WIDTH 1 /* DACMU */
102#define WM8955_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
103#define WM8955_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
104#define WM8955_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
105
106/*
107 * R7 (0x07) - Audio Interface
108 */
109#define WM8955_BCLKINV 0x0080 /* BCLKINV */
110#define WM8955_BCLKINV_MASK 0x0080 /* BCLKINV */
111#define WM8955_BCLKINV_SHIFT 7 /* BCLKINV */
112#define WM8955_BCLKINV_WIDTH 1 /* BCLKINV */
113#define WM8955_MS 0x0040 /* MS */
114#define WM8955_MS_MASK 0x0040 /* MS */
115#define WM8955_MS_SHIFT 6 /* MS */
116#define WM8955_MS_WIDTH 1 /* MS */
117#define WM8955_LRSWAP 0x0020 /* LRSWAP */
118#define WM8955_LRSWAP_MASK 0x0020 /* LRSWAP */
119#define WM8955_LRSWAP_SHIFT 5 /* LRSWAP */
120#define WM8955_LRSWAP_WIDTH 1 /* LRSWAP */
121#define WM8955_LRP 0x0010 /* LRP */
122#define WM8955_LRP_MASK 0x0010 /* LRP */
123#define WM8955_LRP_SHIFT 4 /* LRP */
124#define WM8955_LRP_WIDTH 1 /* LRP */
125#define WM8955_WL_MASK 0x000C /* WL - [3:2] */
126#define WM8955_WL_SHIFT 2 /* WL - [3:2] */
127#define WM8955_WL_WIDTH 2 /* WL - [3:2] */
128#define WM8955_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
129#define WM8955_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
130#define WM8955_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
131
132/*
133 * R8 (0x08) - Sample Rate
134 */
135#define WM8955_BCLKDIV2 0x0080 /* BCLKDIV2 */
136#define WM8955_BCLKDIV2_MASK 0x0080 /* BCLKDIV2 */
137#define WM8955_BCLKDIV2_SHIFT 7 /* BCLKDIV2 */
138#define WM8955_BCLKDIV2_WIDTH 1 /* BCLKDIV2 */
139#define WM8955_MCLKDIV2 0x0040 /* MCLKDIV2 */
140#define WM8955_MCLKDIV2_MASK 0x0040 /* MCLKDIV2 */
141#define WM8955_MCLKDIV2_SHIFT 6 /* MCLKDIV2 */
142#define WM8955_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
143#define WM8955_SR_MASK 0x003E /* SR - [5:1] */
144#define WM8955_SR_SHIFT 1 /* SR - [5:1] */
145#define WM8955_SR_WIDTH 5 /* SR - [5:1] */
146#define WM8955_USB 0x0001 /* USB */
147#define WM8955_USB_MASK 0x0001 /* USB */
148#define WM8955_USB_SHIFT 0 /* USB */
149#define WM8955_USB_WIDTH 1 /* USB */
150
151/*
152 * R10 (0x0A) - Left DAC volume
153 */
154#define WM8955_LDVU 0x0100 /* LDVU */
155#define WM8955_LDVU_MASK 0x0100 /* LDVU */
156#define WM8955_LDVU_SHIFT 8 /* LDVU */
157#define WM8955_LDVU_WIDTH 1 /* LDVU */
158#define WM8955_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */
159#define WM8955_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */
160#define WM8955_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */
161
162/*
163 * R11 (0x0B) - Right DAC volume
164 */
165#define WM8955_RDVU 0x0100 /* RDVU */
166#define WM8955_RDVU_MASK 0x0100 /* RDVU */
167#define WM8955_RDVU_SHIFT 8 /* RDVU */
168#define WM8955_RDVU_WIDTH 1 /* RDVU */
169#define WM8955_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */
170#define WM8955_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */
171#define WM8955_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */
172
173/*
174 * R12 (0x0C) - Bass control
175 */
176#define WM8955_BB 0x0080 /* BB */
177#define WM8955_BB_MASK 0x0080 /* BB */
178#define WM8955_BB_SHIFT 7 /* BB */
179#define WM8955_BB_WIDTH 1 /* BB */
180#define WM8955_BC 0x0040 /* BC */
181#define WM8955_BC_MASK 0x0040 /* BC */
182#define WM8955_BC_SHIFT 6 /* BC */
183#define WM8955_BC_WIDTH 1 /* BC */
184#define WM8955_BASS_MASK 0x000F /* BASS - [3:0] */
185#define WM8955_BASS_SHIFT 0 /* BASS - [3:0] */
186#define WM8955_BASS_WIDTH 4 /* BASS - [3:0] */
187
188/*
189 * R13 (0x0D) - Treble control
190 */
191#define WM8955_TC 0x0040 /* TC */
192#define WM8955_TC_MASK 0x0040 /* TC */
193#define WM8955_TC_SHIFT 6 /* TC */
194#define WM8955_TC_WIDTH 1 /* TC */
195#define WM8955_TRBL_MASK 0x000F /* TRBL - [3:0] */
196#define WM8955_TRBL_SHIFT 0 /* TRBL - [3:0] */
197#define WM8955_TRBL_WIDTH 4 /* TRBL - [3:0] */
198
199/*
200 * R15 (0x0F) - Reset
201 */
202#define WM8955_RESET_MASK 0x01FF /* RESET - [8:0] */
203#define WM8955_RESET_SHIFT 0 /* RESET - [8:0] */
204#define WM8955_RESET_WIDTH 9 /* RESET - [8:0] */
205
206/*
207 * R23 (0x17) - Additional control (1)
208 */
209#define WM8955_TSDEN 0x0100 /* TSDEN */
210#define WM8955_TSDEN_MASK 0x0100 /* TSDEN */
211#define WM8955_TSDEN_SHIFT 8 /* TSDEN */
212#define WM8955_TSDEN_WIDTH 1 /* TSDEN */
213#define WM8955_VSEL_MASK 0x00C0 /* VSEL - [7:6] */
214#define WM8955_VSEL_SHIFT 6 /* VSEL - [7:6] */
215#define WM8955_VSEL_WIDTH 2 /* VSEL - [7:6] */
216#define WM8955_DMONOMIX_MASK 0x0030 /* DMONOMIX - [5:4] */
217#define WM8955_DMONOMIX_SHIFT 4 /* DMONOMIX - [5:4] */
218#define WM8955_DMONOMIX_WIDTH 2 /* DMONOMIX - [5:4] */
219#define WM8955_DACINV 0x0002 /* DACINV */
220#define WM8955_DACINV_MASK 0x0002 /* DACINV */
221#define WM8955_DACINV_SHIFT 1 /* DACINV */
222#define WM8955_DACINV_WIDTH 1 /* DACINV */
223#define WM8955_TOEN 0x0001 /* TOEN */
224#define WM8955_TOEN_MASK 0x0001 /* TOEN */
225#define WM8955_TOEN_SHIFT 0 /* TOEN */
226#define WM8955_TOEN_WIDTH 1 /* TOEN */
227
228/*
229 * R24 (0x18) - Additional control (2)
230 */
231#define WM8955_OUT3SW_MASK 0x0180 /* OUT3SW - [8:7] */
232#define WM8955_OUT3SW_SHIFT 7 /* OUT3SW - [8:7] */
233#define WM8955_OUT3SW_WIDTH 2 /* OUT3SW - [8:7] */
234#define WM8955_ROUT2INV 0x0010 /* ROUT2INV */
235#define WM8955_ROUT2INV_MASK 0x0010 /* ROUT2INV */
236#define WM8955_ROUT2INV_SHIFT 4 /* ROUT2INV */
237#define WM8955_ROUT2INV_WIDTH 1 /* ROUT2INV */
238#define WM8955_DACOSR 0x0001 /* DACOSR */
239#define WM8955_DACOSR_MASK 0x0001 /* DACOSR */
240#define WM8955_DACOSR_SHIFT 0 /* DACOSR */
241#define WM8955_DACOSR_WIDTH 1 /* DACOSR */
242
243/*
244 * R25 (0x19) - Power Management (1)
245 */
246#define WM8955_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */
247#define WM8955_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */
248#define WM8955_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */
249#define WM8955_VREF 0x0040 /* VREF */
250#define WM8955_VREF_MASK 0x0040 /* VREF */
251#define WM8955_VREF_SHIFT 6 /* VREF */
252#define WM8955_VREF_WIDTH 1 /* VREF */
253#define WM8955_DIGENB 0x0001 /* DIGENB */
254#define WM8955_DIGENB_MASK 0x0001 /* DIGENB */
255#define WM8955_DIGENB_SHIFT 0 /* DIGENB */
256#define WM8955_DIGENB_WIDTH 1 /* DIGENB */
257
258/*
259 * R26 (0x1A) - Power Management (2)
260 */
261#define WM8955_DACL 0x0100 /* DACL */
262#define WM8955_DACL_MASK 0x0100 /* DACL */
263#define WM8955_DACL_SHIFT 8 /* DACL */
264#define WM8955_DACL_WIDTH 1 /* DACL */
265#define WM8955_DACR 0x0080 /* DACR */
266#define WM8955_DACR_MASK 0x0080 /* DACR */
267#define WM8955_DACR_SHIFT 7 /* DACR */
268#define WM8955_DACR_WIDTH 1 /* DACR */
269#define WM8955_LOUT1 0x0040 /* LOUT1 */
270#define WM8955_LOUT1_MASK 0x0040 /* LOUT1 */
271#define WM8955_LOUT1_SHIFT 6 /* LOUT1 */
272#define WM8955_LOUT1_WIDTH 1 /* LOUT1 */
273#define WM8955_ROUT1 0x0020 /* ROUT1 */
274#define WM8955_ROUT1_MASK 0x0020 /* ROUT1 */
275#define WM8955_ROUT1_SHIFT 5 /* ROUT1 */
276#define WM8955_ROUT1_WIDTH 1 /* ROUT1 */
277#define WM8955_LOUT2 0x0010 /* LOUT2 */
278#define WM8955_LOUT2_MASK 0x0010 /* LOUT2 */
279#define WM8955_LOUT2_SHIFT 4 /* LOUT2 */
280#define WM8955_LOUT2_WIDTH 1 /* LOUT2 */
281#define WM8955_ROUT2 0x0008 /* ROUT2 */
282#define WM8955_ROUT2_MASK 0x0008 /* ROUT2 */
283#define WM8955_ROUT2_SHIFT 3 /* ROUT2 */
284#define WM8955_ROUT2_WIDTH 1 /* ROUT2 */
285#define WM8955_MONO 0x0004 /* MONO */
286#define WM8955_MONO_MASK 0x0004 /* MONO */
287#define WM8955_MONO_SHIFT 2 /* MONO */
288#define WM8955_MONO_WIDTH 1 /* MONO */
289#define WM8955_OUT3 0x0002 /* OUT3 */
290#define WM8955_OUT3_MASK 0x0002 /* OUT3 */
291#define WM8955_OUT3_SHIFT 1 /* OUT3 */
292#define WM8955_OUT3_WIDTH 1 /* OUT3 */
293
294/*
295 * R27 (0x1B) - Additional Control (3)
296 */
297#define WM8955_VROI 0x0040 /* VROI */
298#define WM8955_VROI_MASK 0x0040 /* VROI */
299#define WM8955_VROI_SHIFT 6 /* VROI */
300#define WM8955_VROI_WIDTH 1 /* VROI */
301
302/*
303 * R34 (0x22) - Left out Mix (1)
304 */
305#define WM8955_LD2LO 0x0100 /* LD2LO */
306#define WM8955_LD2LO_MASK 0x0100 /* LD2LO */
307#define WM8955_LD2LO_SHIFT 8 /* LD2LO */
308#define WM8955_LD2LO_WIDTH 1 /* LD2LO */
309#define WM8955_LI2LO 0x0080 /* LI2LO */
310#define WM8955_LI2LO_MASK 0x0080 /* LI2LO */
311#define WM8955_LI2LO_SHIFT 7 /* LI2LO */
312#define WM8955_LI2LO_WIDTH 1 /* LI2LO */
313#define WM8955_LI2LOVOL_MASK 0x0070 /* LI2LOVOL - [6:4] */
314#define WM8955_LI2LOVOL_SHIFT 4 /* LI2LOVOL - [6:4] */
315#define WM8955_LI2LOVOL_WIDTH 3 /* LI2LOVOL - [6:4] */
316
317/*
318 * R35 (0x23) - Left out Mix (2)
319 */
320#define WM8955_RD2LO 0x0100 /* RD2LO */
321#define WM8955_RD2LO_MASK 0x0100 /* RD2LO */
322#define WM8955_RD2LO_SHIFT 8 /* RD2LO */
323#define WM8955_RD2LO_WIDTH 1 /* RD2LO */
324#define WM8955_RI2LO 0x0080 /* RI2LO */
325#define WM8955_RI2LO_MASK 0x0080 /* RI2LO */
326#define WM8955_RI2LO_SHIFT 7 /* RI2LO */
327#define WM8955_RI2LO_WIDTH 1 /* RI2LO */
328#define WM8955_RI2LOVOL_MASK 0x0070 /* RI2LOVOL - [6:4] */
329#define WM8955_RI2LOVOL_SHIFT 4 /* RI2LOVOL - [6:4] */
330#define WM8955_RI2LOVOL_WIDTH 3 /* RI2LOVOL - [6:4] */
331
332/*
333 * R36 (0x24) - Right out Mix (1)
334 */
335#define WM8955_LD2RO 0x0100 /* LD2RO */
336#define WM8955_LD2RO_MASK 0x0100 /* LD2RO */
337#define WM8955_LD2RO_SHIFT 8 /* LD2RO */
338#define WM8955_LD2RO_WIDTH 1 /* LD2RO */
339#define WM8955_LI2RO 0x0080 /* LI2RO */
340#define WM8955_LI2RO_MASK 0x0080 /* LI2RO */
341#define WM8955_LI2RO_SHIFT 7 /* LI2RO */
342#define WM8955_LI2RO_WIDTH 1 /* LI2RO */
343#define WM8955_LI2ROVOL_MASK 0x0070 /* LI2ROVOL - [6:4] */
344#define WM8955_LI2ROVOL_SHIFT 4 /* LI2ROVOL - [6:4] */
345#define WM8955_LI2ROVOL_WIDTH 3 /* LI2ROVOL - [6:4] */
346
347/*
348 * R37 (0x25) - Right Out Mix (2)
349 */
350#define WM8955_RD2RO 0x0100 /* RD2RO */
351#define WM8955_RD2RO_MASK 0x0100 /* RD2RO */
352#define WM8955_RD2RO_SHIFT 8 /* RD2RO */
353#define WM8955_RD2RO_WIDTH 1 /* RD2RO */
354#define WM8955_RI2RO 0x0080 /* RI2RO */
355#define WM8955_RI2RO_MASK 0x0080 /* RI2RO */
356#define WM8955_RI2RO_SHIFT 7 /* RI2RO */
357#define WM8955_RI2RO_WIDTH 1 /* RI2RO */
358#define WM8955_RI2ROVOL_MASK 0x0070 /* RI2ROVOL - [6:4] */
359#define WM8955_RI2ROVOL_SHIFT 4 /* RI2ROVOL - [6:4] */
360#define WM8955_RI2ROVOL_WIDTH 3 /* RI2ROVOL - [6:4] */
361
362/*
363 * R38 (0x26) - Mono out Mix (1)
364 */
365#define WM8955_LD2MO 0x0100 /* LD2MO */
366#define WM8955_LD2MO_MASK 0x0100 /* LD2MO */
367#define WM8955_LD2MO_SHIFT 8 /* LD2MO */
368#define WM8955_LD2MO_WIDTH 1 /* LD2MO */
369#define WM8955_LI2MO 0x0080 /* LI2MO */
370#define WM8955_LI2MO_MASK 0x0080 /* LI2MO */
371#define WM8955_LI2MO_SHIFT 7 /* LI2MO */
372#define WM8955_LI2MO_WIDTH 1 /* LI2MO */
373#define WM8955_LI2MOVOL_MASK 0x0070 /* LI2MOVOL - [6:4] */
374#define WM8955_LI2MOVOL_SHIFT 4 /* LI2MOVOL - [6:4] */
375#define WM8955_LI2MOVOL_WIDTH 3 /* LI2MOVOL - [6:4] */
376#define WM8955_DMEN 0x0001 /* DMEN */
377#define WM8955_DMEN_MASK 0x0001 /* DMEN */
378#define WM8955_DMEN_SHIFT 0 /* DMEN */
379#define WM8955_DMEN_WIDTH 1 /* DMEN */
380
381/*
382 * R39 (0x27) - Mono out Mix (2)
383 */
384#define WM8955_RD2MO 0x0100 /* RD2MO */
385#define WM8955_RD2MO_MASK 0x0100 /* RD2MO */
386#define WM8955_RD2MO_SHIFT 8 /* RD2MO */
387#define WM8955_RD2MO_WIDTH 1 /* RD2MO */
388#define WM8955_RI2MO 0x0080 /* RI2MO */
389#define WM8955_RI2MO_MASK 0x0080 /* RI2MO */
390#define WM8955_RI2MO_SHIFT 7 /* RI2MO */
391#define WM8955_RI2MO_WIDTH 1 /* RI2MO */
392#define WM8955_RI2MOVOL_MASK 0x0070 /* RI2MOVOL - [6:4] */
393#define WM8955_RI2MOVOL_SHIFT 4 /* RI2MOVOL - [6:4] */
394#define WM8955_RI2MOVOL_WIDTH 3 /* RI2MOVOL - [6:4] */
395
396/*
397 * R40 (0x28) - LOUT2 volume
398 */
399#define WM8955_LO2VU 0x0100 /* LO2VU */
400#define WM8955_LO2VU_MASK 0x0100 /* LO2VU */
401#define WM8955_LO2VU_SHIFT 8 /* LO2VU */
402#define WM8955_LO2VU_WIDTH 1 /* LO2VU */
403#define WM8955_LO2ZC 0x0080 /* LO2ZC */
404#define WM8955_LO2ZC_MASK 0x0080 /* LO2ZC */
405#define WM8955_LO2ZC_SHIFT 7 /* LO2ZC */
406#define WM8955_LO2ZC_WIDTH 1 /* LO2ZC */
407#define WM8955_LOUT2VOL_MASK 0x007F /* LOUT2VOL - [6:0] */
408#define WM8955_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [6:0] */
409#define WM8955_LOUT2VOL_WIDTH 7 /* LOUT2VOL - [6:0] */
410
411/*
412 * R41 (0x29) - ROUT2 volume
413 */
414#define WM8955_RO2VU 0x0100 /* RO2VU */
415#define WM8955_RO2VU_MASK 0x0100 /* RO2VU */
416#define WM8955_RO2VU_SHIFT 8 /* RO2VU */
417#define WM8955_RO2VU_WIDTH 1 /* RO2VU */
418#define WM8955_RO2ZC 0x0080 /* RO2ZC */
419#define WM8955_RO2ZC_MASK 0x0080 /* RO2ZC */
420#define WM8955_RO2ZC_SHIFT 7 /* RO2ZC */
421#define WM8955_RO2ZC_WIDTH 1 /* RO2ZC */
422#define WM8955_ROUT2VOL_MASK 0x007F /* ROUT2VOL - [6:0] */
423#define WM8955_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [6:0] */
424#define WM8955_ROUT2VOL_WIDTH 7 /* ROUT2VOL - [6:0] */
425
426/*
427 * R42 (0x2A) - MONOOUT volume
428 */
429#define WM8955_MOZC 0x0080 /* MOZC */
430#define WM8955_MOZC_MASK 0x0080 /* MOZC */
431#define WM8955_MOZC_SHIFT 7 /* MOZC */
432#define WM8955_MOZC_WIDTH 1 /* MOZC */
433#define WM8955_MOUTVOL_MASK 0x007F /* MOUTVOL - [6:0] */
434#define WM8955_MOUTVOL_SHIFT 0 /* MOUTVOL - [6:0] */
435#define WM8955_MOUTVOL_WIDTH 7 /* MOUTVOL - [6:0] */
436
437/*
438 * R43 (0x2B) - Clocking / PLL
439 */
440#define WM8955_MCLKSEL 0x0100 /* MCLKSEL */
441#define WM8955_MCLKSEL_MASK 0x0100 /* MCLKSEL */
442#define WM8955_MCLKSEL_SHIFT 8 /* MCLKSEL */
443#define WM8955_MCLKSEL_WIDTH 1 /* MCLKSEL */
444#define WM8955_PLLOUTDIV2 0x0020 /* PLLOUTDIV2 */
445#define WM8955_PLLOUTDIV2_MASK 0x0020 /* PLLOUTDIV2 */
446#define WM8955_PLLOUTDIV2_SHIFT 5 /* PLLOUTDIV2 */
447#define WM8955_PLLOUTDIV2_WIDTH 1 /* PLLOUTDIV2 */
448#define WM8955_PLL_RB 0x0010 /* PLL_RB */
449#define WM8955_PLL_RB_MASK 0x0010 /* PLL_RB */
450#define WM8955_PLL_RB_SHIFT 4 /* PLL_RB */
451#define WM8955_PLL_RB_WIDTH 1 /* PLL_RB */
452#define WM8955_PLLEN 0x0008 /* PLLEN */
453#define WM8955_PLLEN_MASK 0x0008 /* PLLEN */
454#define WM8955_PLLEN_SHIFT 3 /* PLLEN */
455#define WM8955_PLLEN_WIDTH 1 /* PLLEN */
456
457/*
458 * R44 (0x2C) - PLL Control 1
459 */
460#define WM8955_N_MASK 0x01E0 /* N - [8:5] */
461#define WM8955_N_SHIFT 5 /* N - [8:5] */
462#define WM8955_N_WIDTH 4 /* N - [8:5] */
463#define WM8955_K_21_18_MASK 0x000F /* K(21:18) - [3:0] */
464#define WM8955_K_21_18_SHIFT 0 /* K(21:18) - [3:0] */
465#define WM8955_K_21_18_WIDTH 4 /* K(21:18) - [3:0] */
466
467/*
468 * R45 (0x2D) - PLL Control 2
469 */
470#define WM8955_K_17_9_MASK 0x01FF /* K(17:9) - [8:0] */
471#define WM8955_K_17_9_SHIFT 0 /* K(17:9) - [8:0] */
472#define WM8955_K_17_9_WIDTH 9 /* K(17:9) - [8:0] */
473
474/*
475 * R46 (0x2E) - PLL Control 3
476 */
477#define WM8955_K_8_0_MASK 0x01FF /* K(8:0) - [8:0] */
478#define WM8955_K_8_0_SHIFT 0 /* K(8:0) - [8:0] */
479#define WM8955_K_8_0_WIDTH 9 /* K(8:0) - [8:0] */
480
481/*
482 * R59 (0x3B) - PLL Control 4
483 */
484#define WM8955_KEN 0x0080 /* KEN */
485#define WM8955_KEN_MASK 0x0080 /* KEN */
486#define WM8955_KEN_SHIFT 7 /* KEN */
487#define WM8955_KEN_WIDTH 1 /* KEN */
488
489#endif
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index a8007d58813f..d2342c5e0425 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1022,6 +1022,9 @@ static int wm8961_resume(struct platform_device *pdev)
1022 int i; 1022 int i;
1023 1023
1024 for (i = 0; i < codec->reg_cache_size; i++) { 1024 for (i = 0; i < codec->reg_cache_size; i++) {
1025 if (reg_cache[i] == wm8961_reg_defaults[i])
1026 continue;
1027
1025 if (i == WM8961_SOFTWARE_RESET) 1028 if (i == WM8961_SOFTWARE_RESET)
1026 continue; 1029 continue;
1027 1030
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 8812751da8c9..ee637af4737a 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -170,6 +170,10 @@ SOC_ENUM("Aux Mode", wm8974_auxmode),
170 170
171SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0), 171SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0),
172SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1), 172SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
173
174/* DAC / ADC oversampling */
175SOC_SINGLE("DAC 128x Oversampling Switch", WM8974_DAC, 8, 1, 0),
176SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 8, 1, 0),
173}; 177};
174 178
175/* Speaker Output Mixer */ 179/* Speaker Output Mixer */
@@ -381,14 +385,6 @@ static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
381 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f; 385 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
382 snd_soc_write(codec, WM8974_CLOCK, reg | div); 386 snd_soc_write(codec, WM8974_CLOCK, reg | div);
383 break; 387 break;
384 case WM8974_ADCCLK:
385 reg = snd_soc_read(codec, WM8974_ADC) & 0x1f7;
386 snd_soc_write(codec, WM8974_ADC, reg | div);
387 break;
388 case WM8974_DACCLK:
389 reg = snd_soc_read(codec, WM8974_DAC) & 0x1f7;
390 snd_soc_write(codec, WM8974_DAC, reg | div);
391 break;
392 case WM8974_BCLKDIV: 388 case WM8974_BCLKDIV:
393 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3; 389 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
394 snd_soc_write(codec, WM8974_CLOCK, reg | div); 390 snd_soc_write(codec, WM8974_CLOCK, reg | div);
diff --git a/sound/soc/codecs/wm8974.h b/sound/soc/codecs/wm8974.h
index 98de9562d4d2..896a7f0f3fc4 100644
--- a/sound/soc/codecs/wm8974.h
+++ b/sound/soc/codecs/wm8974.h
@@ -57,17 +57,7 @@
57/* Clock divider Id's */ 57/* Clock divider Id's */
58#define WM8974_OPCLKDIV 0 58#define WM8974_OPCLKDIV 0
59#define WM8974_MCLKDIV 1 59#define WM8974_MCLKDIV 1
60#define WM8974_ADCCLK 2 60#define WM8974_BCLKDIV 2
61#define WM8974_DACCLK 3
62#define WM8974_BCLKDIV 4
63
64/* DAC clock dividers */
65#define WM8974_DACCLK_F2 (1 << 3)
66#define WM8974_DACCLK_F4 (0 << 3)
67
68/* ADC clock dividers */
69#define WM8974_ADCCLK_F2 (1 << 3)
70#define WM8974_ADCCLK_F4 (0 << 3)
71 61
72/* PLL Out dividers */ 62/* PLL Out dividers */
73#define WM8974_OPCLKDIV_1 (0 << 4) 63#define WM8974_OPCLKDIV_1 (0 << 4)
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
new file mode 100644
index 000000000000..28bb59ea6ea1
--- /dev/null
+++ b/sound/soc/codecs/wm8978.c
@@ -0,0 +1,1149 @@
1/*
2 * wm8978.c -- WM8978 ALSA SoC Audio Codec driver
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2007 Carlos Munoz <carlos@kenati.com>
6 * Copyright 2006-2009 Wolfson Microelectronics PLC.
7 * Based on wm8974 and wm8990 by Liam Girdwood <lrg@slimlogic.co.uk>
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/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.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 <asm/div64.h>
30
31#include "wm8978.h"
32
33static struct snd_soc_codec *wm8978_codec;
34
35/* wm8978 register cache. Note that register 0 is not included in the cache. */
36static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
37 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
38 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */
39 0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */
40 0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */
41 0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */
42 0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */
43 0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */
44 0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */
45 0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */
46 0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */
47 0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */
48 0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */
49 0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */
50 0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */
51 0x0001, 0x0001, /* 0x38...0x3b */
52};
53
54/* codec private data */
55struct wm8978_priv {
56 struct snd_soc_codec codec;
57 unsigned int f_pllout;
58 unsigned int f_mclk;
59 unsigned int f_256fs;
60 unsigned int f_opclk;
61 int mclk_idx;
62 enum wm8978_sysclk_src sysclk;
63 u16 reg_cache[WM8978_CACHEREGNUM];
64};
65
66static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
67static const char *wm8978_eqmode[] = {"Capture", "Playback"};
68static const char *wm8978_bw[] = {"Narrow", "Wide"};
69static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"};
70static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"};
71static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"};
72static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"};
73static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
74static const char *wm8978_alc3[] = {"ALC", "Limiter"};
75static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"};
76
77static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1,
78 wm8978_companding);
79static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3,
80 wm8978_companding);
81static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode);
82static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1);
83static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw);
84static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2);
85static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw);
86static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3);
87static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw);
88static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4);
89static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5);
90static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3);
91static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1);
92
93static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
94static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
95static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
96static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
97static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
98
99static const struct snd_kcontrol_new wm8978_snd_controls[] = {
100
101 SOC_SINGLE("Digital Loopback Switch",
102 WM8978_COMPANDING_CONTROL, 0, 1, 0),
103
104 SOC_ENUM("ADC Companding", adc_compand),
105 SOC_ENUM("DAC Companding", dac_compand),
106
107 SOC_DOUBLE("DAC Inversion Switch", WM8978_DAC_CONTROL, 0, 1, 1, 0),
108
109 SOC_DOUBLE_R_TLV("PCM Volume",
110 WM8978_LEFT_DAC_DIGITAL_VOLUME, WM8978_RIGHT_DAC_DIGITAL_VOLUME,
111 0, 255, 0, digital_tlv),
112
113 SOC_SINGLE("High Pass Filter Switch", WM8978_ADC_CONTROL, 8, 1, 0),
114 SOC_SINGLE("High Pass Cut Off", WM8978_ADC_CONTROL, 4, 7, 0),
115 SOC_DOUBLE("ADC Inversion Switch", WM8978_ADC_CONTROL, 0, 1, 1, 0),
116
117 SOC_DOUBLE_R_TLV("ADC Volume",
118 WM8978_LEFT_ADC_DIGITAL_VOLUME, WM8978_RIGHT_ADC_DIGITAL_VOLUME,
119 0, 255, 0, digital_tlv),
120
121 SOC_ENUM("Equaliser Function", eqmode),
122 SOC_ENUM("EQ1 Cut Off", eq1),
123 SOC_SINGLE_TLV("EQ1 Volume", WM8978_EQ1, 0, 24, 1, eq_tlv),
124
125 SOC_ENUM("Equaliser EQ2 Bandwith", eq2bw),
126 SOC_ENUM("EQ2 Cut Off", eq2),
127 SOC_SINGLE_TLV("EQ2 Volume", WM8978_EQ2, 0, 24, 1, eq_tlv),
128
129 SOC_ENUM("Equaliser EQ3 Bandwith", eq3bw),
130 SOC_ENUM("EQ3 Cut Off", eq3),
131 SOC_SINGLE_TLV("EQ3 Volume", WM8978_EQ3, 0, 24, 1, eq_tlv),
132
133 SOC_ENUM("Equaliser EQ4 Bandwith", eq4bw),
134 SOC_ENUM("EQ4 Cut Off", eq4),
135 SOC_SINGLE_TLV("EQ4 Volume", WM8978_EQ4, 0, 24, 1, eq_tlv),
136
137 SOC_ENUM("EQ5 Cut Off", eq5),
138 SOC_SINGLE_TLV("EQ5 Volume", WM8978_EQ5, 0, 24, 1, eq_tlv),
139
140 SOC_SINGLE("DAC Playback Limiter Switch",
141 WM8978_DAC_LIMITER_1, 8, 1, 0),
142 SOC_SINGLE("DAC Playback Limiter Decay",
143 WM8978_DAC_LIMITER_1, 4, 15, 0),
144 SOC_SINGLE("DAC Playback Limiter Attack",
145 WM8978_DAC_LIMITER_1, 0, 15, 0),
146
147 SOC_SINGLE("DAC Playback Limiter Threshold",
148 WM8978_DAC_LIMITER_2, 4, 7, 0),
149 SOC_SINGLE("DAC Playback Limiter Boost",
150 WM8978_DAC_LIMITER_2, 0, 15, 0),
151
152 SOC_ENUM("ALC Enable Switch", alc1),
153 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
154 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0),
155
156 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 7, 0),
157 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0),
158
159 SOC_ENUM("ALC Capture Mode", alc3),
160 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 15, 0),
161 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 15, 0),
162
163 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0),
164 SOC_SINGLE("ALC Capture Noise Gate Threshold",
165 WM8978_NOISE_GATE, 0, 7, 0),
166
167 SOC_DOUBLE_R("Capture PGA ZC Switch",
168 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
169 7, 1, 0),
170
171 /* OUT1 - Headphones */
172 SOC_DOUBLE_R("Headphone Playback ZC Switch",
173 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 7, 1, 0),
174
175 SOC_DOUBLE_R_TLV("Headphone Playback Volume",
176 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL,
177 0, 63, 0, spk_tlv),
178
179 /* OUT2 - Speakers */
180 SOC_DOUBLE_R("Speaker Playback ZC Switch",
181 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 7, 1, 0),
182
183 SOC_DOUBLE_R_TLV("Speaker Playback Volume",
184 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL,
185 0, 63, 0, spk_tlv),
186
187 /* OUT3/4 - Line Output */
188 SOC_DOUBLE_R("Line Playback Switch",
189 WM8978_OUT3_MIXER_CONTROL, WM8978_OUT4_MIXER_CONTROL, 6, 1, 1),
190
191 /* Mixer #3: Boost (Input) mixer */
192 SOC_DOUBLE_R("PGA Boost (+20dB)",
193 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
194 8, 1, 0),
195 SOC_DOUBLE_R_TLV("L2/R2 Boost Volume",
196 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
197 4, 7, 0, boost_tlv),
198 SOC_DOUBLE_R_TLV("Aux Boost Volume",
199 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
200 0, 7, 0, boost_tlv),
201
202 /* Input PGA volume */
203 SOC_DOUBLE_R_TLV("Input PGA Volume",
204 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
205 0, 63, 0, inpga_tlv),
206
207 /* Headphone */
208 SOC_DOUBLE_R("Headphone Switch",
209 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 6, 1, 1),
210
211 /* Speaker */
212 SOC_DOUBLE_R("Speaker Switch",
213 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1),
214
215 /* DAC / ADC oversampling */
216 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, 8, 1, 0),
217 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, 8, 1, 0),
218};
219
220/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
221static const struct snd_kcontrol_new wm8978_left_out_mixer[] = {
222 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_LEFT_MIXER_CONTROL, 1, 1, 0),
223 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_LEFT_MIXER_CONTROL, 5, 1, 0),
224 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_LEFT_MIXER_CONTROL, 0, 1, 0),
225};
226
227static const struct snd_kcontrol_new wm8978_right_out_mixer[] = {
228 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_RIGHT_MIXER_CONTROL, 1, 1, 0),
229 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 5, 1, 0),
230 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 0, 1, 0),
231};
232
233/* OUT3/OUT4 Mixer not implemented */
234
235/* Mixer #2: Input PGA Mute */
236static const struct snd_kcontrol_new wm8978_left_input_mixer[] = {
237 SOC_DAPM_SINGLE("L2 Switch", WM8978_INPUT_CONTROL, 2, 1, 0),
238 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 1, 1, 0),
239 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 0, 1, 0),
240};
241static const struct snd_kcontrol_new wm8978_right_input_mixer[] = {
242 SOC_DAPM_SINGLE("R2 Switch", WM8978_INPUT_CONTROL, 6, 1, 0),
243 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 5, 1, 0),
244 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 4, 1, 0),
245};
246
247static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = {
248 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
249 WM8978_POWER_MANAGEMENT_3, 0, 0),
250 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
251 WM8978_POWER_MANAGEMENT_3, 1, 0),
252 SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
253 WM8978_POWER_MANAGEMENT_2, 0, 0),
254 SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
255 WM8978_POWER_MANAGEMENT_2, 1, 0),
256
257 /* Mixer #1: OUT1,2 */
258 SOC_MIXER_ARRAY("Left Output Mixer", WM8978_POWER_MANAGEMENT_3,
259 2, 0, wm8978_left_out_mixer),
260 SOC_MIXER_ARRAY("Right Output Mixer", WM8978_POWER_MANAGEMENT_3,
261 3, 0, wm8978_right_out_mixer),
262
263 SOC_MIXER_ARRAY("Left Input Mixer", WM8978_POWER_MANAGEMENT_2,
264 2, 0, wm8978_left_input_mixer),
265 SOC_MIXER_ARRAY("Right Input Mixer", WM8978_POWER_MANAGEMENT_2,
266 3, 0, wm8978_right_input_mixer),
267
268 SND_SOC_DAPM_PGA("Left Boost Mixer", WM8978_POWER_MANAGEMENT_2,
269 4, 0, NULL, 0),
270 SND_SOC_DAPM_PGA("Right Boost Mixer", WM8978_POWER_MANAGEMENT_2,
271 5, 0, NULL, 0),
272
273 SND_SOC_DAPM_PGA("Left Capture PGA", WM8978_LEFT_INP_PGA_CONTROL,
274 6, 1, NULL, 0),
275 SND_SOC_DAPM_PGA("Right Capture PGA", WM8978_RIGHT_INP_PGA_CONTROL,
276 6, 1, NULL, 0),
277
278 SND_SOC_DAPM_PGA("Left Headphone Out", WM8978_POWER_MANAGEMENT_2,
279 7, 0, NULL, 0),
280 SND_SOC_DAPM_PGA("Right Headphone Out", WM8978_POWER_MANAGEMENT_2,
281 8, 0, NULL, 0),
282
283 SND_SOC_DAPM_PGA("Left Speaker Out", WM8978_POWER_MANAGEMENT_3,
284 6, 0, NULL, 0),
285 SND_SOC_DAPM_PGA("Right Speaker Out", WM8978_POWER_MANAGEMENT_3,
286 5, 0, NULL, 0),
287
288 SND_SOC_DAPM_MIXER("OUT4 VMID", WM8978_POWER_MANAGEMENT_3,
289 8, 0, NULL, 0),
290
291 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8978_POWER_MANAGEMENT_1, 4, 0),
292
293 SND_SOC_DAPM_INPUT("LMICN"),
294 SND_SOC_DAPM_INPUT("LMICP"),
295 SND_SOC_DAPM_INPUT("RMICN"),
296 SND_SOC_DAPM_INPUT("RMICP"),
297 SND_SOC_DAPM_INPUT("LAUX"),
298 SND_SOC_DAPM_INPUT("RAUX"),
299 SND_SOC_DAPM_INPUT("L2"),
300 SND_SOC_DAPM_INPUT("R2"),
301 SND_SOC_DAPM_OUTPUT("LHP"),
302 SND_SOC_DAPM_OUTPUT("RHP"),
303 SND_SOC_DAPM_OUTPUT("LSPK"),
304 SND_SOC_DAPM_OUTPUT("RSPK"),
305};
306
307static const struct snd_soc_dapm_route audio_map[] = {
308 /* Output mixer */
309 {"Right Output Mixer", "PCM Playback Switch", "Right DAC"},
310 {"Right Output Mixer", "Aux Playback Switch", "RAUX"},
311 {"Right Output Mixer", "Line Bypass Switch", "Right Boost Mixer"},
312
313 {"Left Output Mixer", "PCM Playback Switch", "Left DAC"},
314 {"Left Output Mixer", "Aux Playback Switch", "LAUX"},
315 {"Left Output Mixer", "Line Bypass Switch", "Left Boost Mixer"},
316
317 /* Outputs */
318 {"Right Headphone Out", NULL, "Right Output Mixer"},
319 {"RHP", NULL, "Right Headphone Out"},
320
321 {"Left Headphone Out", NULL, "Left Output Mixer"},
322 {"LHP", NULL, "Left Headphone Out"},
323
324 {"Right Speaker Out", NULL, "Right Output Mixer"},
325 {"RSPK", NULL, "Right Speaker Out"},
326
327 {"Left Speaker Out", NULL, "Left Output Mixer"},
328 {"LSPK", NULL, "Left Speaker Out"},
329
330 /* Boost Mixer */
331 {"Right ADC", NULL, "Right Boost Mixer"},
332
333 {"Right Boost Mixer", NULL, "RAUX"},
334 {"Right Boost Mixer", NULL, "Right Capture PGA"},
335 {"Right Boost Mixer", NULL, "R2"},
336
337 {"Left ADC", NULL, "Left Boost Mixer"},
338
339 {"Left Boost Mixer", NULL, "LAUX"},
340 {"Left Boost Mixer", NULL, "Left Capture PGA"},
341 {"Left Boost Mixer", NULL, "L2"},
342
343 /* Input PGA */
344 {"Right Capture PGA", NULL, "Right Input Mixer"},
345 {"Left Capture PGA", NULL, "Left Input Mixer"},
346
347 {"Right Input Mixer", "R2 Switch", "R2"},
348 {"Right Input Mixer", "MicN Switch", "RMICN"},
349 {"Right Input Mixer", "MicP Switch", "RMICP"},
350
351 {"Left Input Mixer", "L2 Switch", "L2"},
352 {"Left Input Mixer", "MicN Switch", "LMICN"},
353 {"Left Input Mixer", "MicP Switch", "LMICP"},
354};
355
356static int wm8978_add_widgets(struct snd_soc_codec *codec)
357{
358 snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets,
359 ARRAY_SIZE(wm8978_dapm_widgets));
360
361 /* set up the WM8978 audio map */
362 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
363
364 return 0;
365}
366
367/* PLL divisors */
368struct wm8978_pll_div {
369 u32 k;
370 u8 n;
371 u8 div2;
372};
373
374#define FIXED_PLL_SIZE (1 << 24)
375
376static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
377 unsigned int source)
378{
379 u64 k_part;
380 unsigned int k, n_div, n_mod;
381
382 n_div = target / source;
383 if (n_div < 6) {
384 source >>= 1;
385 pll_div->div2 = 1;
386 n_div = target / source;
387 } else {
388 pll_div->div2 = 0;
389 }
390
391 if (n_div < 6 || n_div > 12)
392 dev_warn(wm8978_codec->dev,
393 "WM8978 N value exceeds recommended range! N = %u\n",
394 n_div);
395
396 pll_div->n = n_div;
397 n_mod = target - source * n_div;
398 k_part = FIXED_PLL_SIZE * (long long)n_mod + source / 2;
399
400 do_div(k_part, source);
401
402 k = k_part & 0xFFFFFFFF;
403
404 pll_div->k = k;
405}
406
407/* MCLK dividers */
408static const int mclk_numerator[] = {1, 3, 2, 3, 4, 6, 8, 12};
409static const int mclk_denominator[] = {1, 2, 1, 1, 1, 1, 1, 1};
410
411/*
412 * find index >= idx, such that, for a given f_out,
413 * 3 * f_mclk / 4 <= f_PLLOUT < 13 * f_mclk / 4
414 * f_out can be f_256fs or f_opclk, currently only used for f_256fs. Can be
415 * generalised for f_opclk with suitable coefficient arrays, but currently
416 * the OPCLK divisor is calculated directly, not iteratively.
417 */
418static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
419 unsigned int *f_pllout)
420{
421 int i;
422
423 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
424 unsigned int f_pllout_x4 = 4 * f_out * mclk_numerator[i] /
425 mclk_denominator[i];
426 if (3 * f_mclk <= f_pllout_x4 && f_pllout_x4 < 13 * f_mclk) {
427 *f_pllout = f_pllout_x4 / 4;
428 return i;
429 }
430 }
431
432 return -EINVAL;
433}
434
435/*
436 * Calculate internal frequencies and dividers, according to Figure 40
437 * "PLL and Clock Select Circuit" in WM8978 datasheet Rev. 2.6
438 */
439static int wm8978_configure_pll(struct snd_soc_codec *codec)
440{
441 struct wm8978_priv *wm8978 = codec->private_data;
442 struct wm8978_pll_div pll_div;
443 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
444 f_256fs = wm8978->f_256fs;
445 unsigned int f2;
446
447 if (!f_mclk)
448 return -EINVAL;
449
450 if (f_opclk) {
451 unsigned int opclk_div;
452 /* Cannot set up MCLK divider now, do later */
453 wm8978->mclk_idx = -1;
454
455 /*
456 * The user needs OPCLK. Choose OPCLKDIV to put
457 * 6 <= R = f2 / f1 < 13, 1 <= OPCLKDIV <= 4.
458 * f_opclk = f_mclk * prescale * R / 4 / OPCLKDIV, where
459 * prescale = 1, or prescale = 2. Prescale is calculated inside
460 * pll_factors(). We have to select f_PLLOUT, such that
461 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
462 * f_mclk * 3 / 16 <= f_opclk < f_mclk * 13 / 4.
463 */
464 if (16 * f_opclk < 3 * f_mclk || 4 * f_opclk >= 13 * f_mclk)
465 return -EINVAL;
466
467 if (4 * f_opclk < 3 * f_mclk)
468 /* Have to use OPCLKDIV */
469 opclk_div = (3 * f_mclk / 4 + f_opclk - 1) / f_opclk;
470 else
471 opclk_div = 1;
472
473 dev_dbg(codec->dev, "%s: OPCLKDIV=%d\n", __func__, opclk_div);
474
475 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 0x30,
476 (opclk_div - 1) << 4);
477
478 wm8978->f_pllout = f_opclk * opclk_div;
479 } else if (f_256fs) {
480 /*
481 * Not using OPCLK, but PLL is used for the codec, choose R:
482 * 6 <= R = f2 / f1 < 13, to put 1 <= MCLKDIV <= 12.
483 * f_256fs = f_mclk * prescale * R / 4 / MCLKDIV, where
484 * prescale = 1, or prescale = 2. Prescale is calculated inside
485 * pll_factors(). We have to select f_PLLOUT, such that
486 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
487 * f_mclk * 3 / 48 <= f_256fs < f_mclk * 13 / 4. This means MCLK
488 * must be 3.781MHz <= f_MCLK <= 32.768MHz
489 */
490 int idx = wm8978_enum_mclk(f_256fs, f_mclk, &wm8978->f_pllout);
491 if (idx < 0)
492 return idx;
493
494 wm8978->mclk_idx = idx;
495
496 /* GPIO1 into default mode as input - before configuring PLL */
497 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
498 } else {
499 return -EINVAL;
500 }
501
502 f2 = wm8978->f_pllout * 4;
503
504 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
505 wm8978->f_mclk, wm8978->f_pllout);
506
507 pll_factors(&pll_div, f2, wm8978->f_mclk);
508
509 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
510 __func__, pll_div.n, pll_div.k, pll_div.div2);
511
512 /* Turn PLL off for configuration... */
513 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
514
515 snd_soc_write(codec, WM8978_PLL_N, (pll_div.div2 << 4) | pll_div.n);
516 snd_soc_write(codec, WM8978_PLL_K1, pll_div.k >> 18);
517 snd_soc_write(codec, WM8978_PLL_K2, (pll_div.k >> 9) & 0x1ff);
518 snd_soc_write(codec, WM8978_PLL_K3, pll_div.k & 0x1ff);
519
520 /* ...and on again */
521 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
522
523 if (f_opclk)
524 /* Output PLL (OPCLK) to GPIO1 */
525 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 4);
526
527 return 0;
528}
529
530/*
531 * Configure WM8978 clock dividers.
532 */
533static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
534 int div_id, int div)
535{
536 struct snd_soc_codec *codec = codec_dai->codec;
537 struct wm8978_priv *wm8978 = codec->private_data;
538 int ret = 0;
539
540 switch (div_id) {
541 case WM8978_OPCLKRATE:
542 wm8978->f_opclk = div;
543
544 if (wm8978->f_mclk)
545 /*
546 * We know the MCLK frequency, the user has requested
547 * OPCLK, configure the PLL based on that and start it
548 * and OPCLK immediately. We will configure PLL to match
549 * user-requested OPCLK frquency as good as possible.
550 * In fact, it is likely, that matching the sampling
551 * rate, when it becomes known, is more important, and
552 * we will not be reconfiguring PLL then, because we
553 * must not interrupt OPCLK. But it should be fine,
554 * because typically the user will request OPCLK to run
555 * at 256fs or 512fs, and for these cases we will also
556 * find an exact MCLK divider configuration - it will
557 * be equal to or double the OPCLK divisor.
558 */
559 ret = wm8978_configure_pll(codec);
560 break;
561 case WM8978_BCLKDIV:
562 if (div & ~0x1c)
563 return -EINVAL;
564 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x1c, div);
565 break;
566 default:
567 return -EINVAL;
568 }
569
570 dev_dbg(codec->dev, "%s: ID %d, value %u\n", __func__, div_id, div);
571
572 return ret;
573}
574
575/*
576 * @freq: when .set_pll() us not used, freq is codec MCLK input frequency
577 */
578static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
579 unsigned int freq, int dir)
580{
581 struct snd_soc_codec *codec = codec_dai->codec;
582 struct wm8978_priv *wm8978 = codec->private_data;
583 int ret = 0;
584
585 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
586
587 if (freq) {
588 wm8978->f_mclk = freq;
589
590 /* Even if MCLK is used for system clock, might have to drive OPCLK */
591 if (wm8978->f_opclk)
592 ret = wm8978_configure_pll(codec);
593
594 /* Our sysclk is fixed to 256 * fs, will configure in .hw_params() */
595
596 if (!ret)
597 wm8978->sysclk = clk_id;
598 }
599
600 if (wm8978->sysclk == WM8978_PLL && (!freq || clk_id == WM8978_MCLK)) {
601 /* Clock CODEC directly from MCLK */
602 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
603
604 /* GPIO1 into default mode as input - before configuring PLL */
605 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
606
607 /* Turn off PLL */
608 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
609 wm8978->sysclk = WM8978_MCLK;
610 wm8978->f_pllout = 0;
611 wm8978->f_opclk = 0;
612 }
613
614 return ret;
615}
616
617/*
618 * Set ADC and Voice DAC format.
619 */
620static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
621{
622 struct snd_soc_codec *codec = codec_dai->codec;
623 /*
624 * BCLK polarity mask = 0x100, LRC clock polarity mask = 0x80,
625 * Data Format mask = 0x18: all will be calculated anew
626 */
627 u16 iface = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x198;
628 u16 clk = snd_soc_read(codec, WM8978_CLOCKING);
629
630 dev_dbg(codec->dev, "%s\n", __func__);
631
632 /* set master/slave audio interface */
633 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
634 case SND_SOC_DAIFMT_CBM_CFM:
635 clk |= 1;
636 break;
637 case SND_SOC_DAIFMT_CBS_CFS:
638 clk &= ~1;
639 break;
640 default:
641 return -EINVAL;
642 }
643
644 /* interface format */
645 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
646 case SND_SOC_DAIFMT_I2S:
647 iface |= 0x10;
648 break;
649 case SND_SOC_DAIFMT_RIGHT_J:
650 break;
651 case SND_SOC_DAIFMT_LEFT_J:
652 iface |= 0x8;
653 break;
654 case SND_SOC_DAIFMT_DSP_A:
655 iface |= 0x18;
656 break;
657 default:
658 return -EINVAL;
659 }
660
661 /* clock inversion */
662 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
663 case SND_SOC_DAIFMT_NB_NF:
664 break;
665 case SND_SOC_DAIFMT_IB_IF:
666 iface |= 0x180;
667 break;
668 case SND_SOC_DAIFMT_IB_NF:
669 iface |= 0x100;
670 break;
671 case SND_SOC_DAIFMT_NB_IF:
672 iface |= 0x80;
673 break;
674 default:
675 return -EINVAL;
676 }
677
678 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface);
679 snd_soc_write(codec, WM8978_CLOCKING, clk);
680
681 return 0;
682}
683
684/*
685 * Set PCM DAI bit size and sample rate.
686 */
687static int wm8978_hw_params(struct snd_pcm_substream *substream,
688 struct snd_pcm_hw_params *params,
689 struct snd_soc_dai *dai)
690{
691 struct snd_soc_pcm_runtime *rtd = substream->private_data;
692 struct snd_soc_device *socdev = rtd->socdev;
693 struct snd_soc_codec *codec = socdev->card->codec;
694 struct wm8978_priv *wm8978 = codec->private_data;
695 /* Word length mask = 0x60 */
696 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
697 /* Sampling rate mask = 0xe (for filters) */
698 u16 add_ctl = snd_soc_read(codec, WM8978_ADDITIONAL_CONTROL) & ~0xe;
699 u16 clking = snd_soc_read(codec, WM8978_CLOCKING);
700 enum wm8978_sysclk_src current_clk_id = clking & 0x100 ?
701 WM8978_PLL : WM8978_MCLK;
702 unsigned int f_sel, diff, diff_best = INT_MAX;
703 int i, best = 0;
704
705 if (!wm8978->f_mclk)
706 return -EINVAL;
707
708 /* bit size */
709 switch (params_format(params)) {
710 case SNDRV_PCM_FORMAT_S16_LE:
711 break;
712 case SNDRV_PCM_FORMAT_S20_3LE:
713 iface_ctl |= 0x20;
714 break;
715 case SNDRV_PCM_FORMAT_S24_LE:
716 iface_ctl |= 0x40;
717 break;
718 case SNDRV_PCM_FORMAT_S32_LE:
719 iface_ctl |= 0x60;
720 break;
721 }
722
723 /* filter coefficient */
724 switch (params_rate(params)) {
725 case 8000:
726 add_ctl |= 0x5 << 1;
727 break;
728 case 11025:
729 add_ctl |= 0x4 << 1;
730 break;
731 case 16000:
732 add_ctl |= 0x3 << 1;
733 break;
734 case 22050:
735 add_ctl |= 0x2 << 1;
736 break;
737 case 32000:
738 add_ctl |= 0x1 << 1;
739 break;
740 case 44100:
741 case 48000:
742 break;
743 }
744
745 /* Sampling rate is known now, can configure the MCLK divider */
746 wm8978->f_256fs = params_rate(params) * 256;
747
748 if (wm8978->sysclk == WM8978_MCLK) {
749 wm8978->mclk_idx = -1;
750 f_sel = wm8978->f_mclk;
751 } else {
752 if (!wm8978->f_pllout) {
753 /* We only enter here, if OPCLK is not used */
754 int ret = wm8978_configure_pll(codec);
755 if (ret < 0)
756 return ret;
757 }
758 f_sel = wm8978->f_pllout;
759 }
760
761 if (wm8978->mclk_idx < 0) {
762 /* Either MCLK is used directly, or OPCLK is used */
763 if (f_sel < wm8978->f_256fs || f_sel > 12 * wm8978->f_256fs)
764 return -EINVAL;
765
766 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
767 diff = abs(wm8978->f_256fs * 3 -
768 f_sel * 3 * mclk_denominator[i] / mclk_numerator[i]);
769
770 if (diff < diff_best) {
771 diff_best = diff;
772 best = i;
773 }
774
775 if (!diff)
776 break;
777 }
778 } else {
779 /* OPCLK not used, codec driven by PLL */
780 best = wm8978->mclk_idx;
781 diff = 0;
782 }
783
784 if (diff)
785 dev_warn(codec->dev, "Imprecise sampling rate: %uHz%s\n",
786 f_sel * mclk_denominator[best] / mclk_numerator[best] / 256,
787 wm8978->sysclk == WM8978_MCLK ?
788 ", consider using PLL" : "");
789
790 dev_dbg(codec->dev, "%s: fmt %d, rate %u, MCLK divisor #%d\n", __func__,
791 params_format(params), params_rate(params), best);
792
793 /* MCLK divisor mask = 0xe0 */
794 snd_soc_update_bits(codec, WM8978_CLOCKING, 0xe0, best << 5);
795
796 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface_ctl);
797 snd_soc_write(codec, WM8978_ADDITIONAL_CONTROL, add_ctl);
798
799 if (wm8978->sysclk != current_clk_id) {
800 if (wm8978->sysclk == WM8978_PLL)
801 /* Run CODEC from PLL instead of MCLK */
802 snd_soc_update_bits(codec, WM8978_CLOCKING,
803 0x100, 0x100);
804 else
805 /* Clock CODEC directly from MCLK */
806 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
807 }
808
809 return 0;
810}
811
812static int wm8978_mute(struct snd_soc_dai *dai, int mute)
813{
814 struct snd_soc_codec *codec = dai->codec;
815
816 dev_dbg(codec->dev, "%s: %d\n", __func__, mute);
817
818 if (mute)
819 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0x40);
820 else
821 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0);
822
823 return 0;
824}
825
826static int wm8978_set_bias_level(struct snd_soc_codec *codec,
827 enum snd_soc_bias_level level)
828{
829 u16 power1 = snd_soc_read(codec, WM8978_POWER_MANAGEMENT_1) & ~3;
830
831 switch (level) {
832 case SND_SOC_BIAS_ON:
833 case SND_SOC_BIAS_PREPARE:
834 power1 |= 1; /* VMID 75k */
835 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
836 break;
837 case SND_SOC_BIAS_STANDBY:
838 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
839 power1 |= 0xc;
840
841 if (codec->bias_level == SND_SOC_BIAS_OFF) {
842 /* Initial cap charge at VMID 5k */
843 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
844 power1 | 0x3);
845 mdelay(100);
846 }
847
848 power1 |= 0x2; /* VMID 500k */
849 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
850 break;
851 case SND_SOC_BIAS_OFF:
852 /* Preserve PLL - OPCLK may be used by someone */
853 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
854 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0);
855 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0);
856 break;
857 }
858
859 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
860
861 codec->bias_level = level;
862 return 0;
863}
864
865#define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
866 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
867
868static struct snd_soc_dai_ops wm8978_dai_ops = {
869 .hw_params = wm8978_hw_params,
870 .digital_mute = wm8978_mute,
871 .set_fmt = wm8978_set_dai_fmt,
872 .set_clkdiv = wm8978_set_dai_clkdiv,
873 .set_sysclk = wm8978_set_dai_sysclk,
874};
875
876/* Also supports 12kHz */
877struct snd_soc_dai wm8978_dai = {
878 .name = "WM8978 HiFi",
879 .id = 1,
880 .playback = {
881 .stream_name = "Playback",
882 .channels_min = 1,
883 .channels_max = 2,
884 .rates = SNDRV_PCM_RATE_8000_48000,
885 .formats = WM8978_FORMATS,
886 },
887 .capture = {
888 .stream_name = "Capture",
889 .channels_min = 1,
890 .channels_max = 2,
891 .rates = SNDRV_PCM_RATE_8000_48000,
892 .formats = WM8978_FORMATS,
893 },
894 .ops = &wm8978_dai_ops,
895};
896EXPORT_SYMBOL_GPL(wm8978_dai);
897
898static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
899{
900 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
901 struct snd_soc_codec *codec = socdev->card->codec;
902
903 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
904 /* Also switch PLL off */
905 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
906
907 return 0;
908}
909
910static int wm8978_resume(struct platform_device *pdev)
911{
912 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
913 struct snd_soc_codec *codec = socdev->card->codec;
914 struct wm8978_priv *wm8978 = codec->private_data;
915 int i;
916 u16 *cache = codec->reg_cache;
917
918 /* Sync reg_cache with the hardware */
919 for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) {
920 if (i == WM8978_RESET)
921 continue;
922 if (cache[i] != wm8978_reg[i])
923 snd_soc_write(codec, i, cache[i]);
924 }
925
926 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
927
928 if (wm8978->f_pllout)
929 /* Switch PLL on */
930 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
931
932 return 0;
933}
934
935static int wm8978_probe(struct platform_device *pdev)
936{
937 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
938 struct snd_soc_codec *codec;
939 int ret = 0;
940
941 if (wm8978_codec == NULL) {
942 dev_err(&pdev->dev, "Codec device not registered\n");
943 return -ENODEV;
944 }
945
946 socdev->card->codec = wm8978_codec;
947 codec = wm8978_codec;
948
949 /* register pcms */
950 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
951 if (ret < 0) {
952 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
953 goto pcm_err;
954 }
955
956 snd_soc_add_controls(codec, wm8978_snd_controls,
957 ARRAY_SIZE(wm8978_snd_controls));
958 wm8978_add_widgets(codec);
959
960pcm_err:
961 return ret;
962}
963
964/* power down chip */
965static int wm8978_remove(struct platform_device *pdev)
966{
967 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
968
969 snd_soc_free_pcms(socdev);
970 snd_soc_dapm_free(socdev);
971
972 return 0;
973}
974
975struct snd_soc_codec_device soc_codec_dev_wm8978 = {
976 .probe = wm8978_probe,
977 .remove = wm8978_remove,
978 .suspend = wm8978_suspend,
979 .resume = wm8978_resume,
980};
981EXPORT_SYMBOL_GPL(soc_codec_dev_wm8978);
982
983/*
984 * These registers contain an "update" bit - bit 8. This means, for example,
985 * that one can write new DAC digital volume for both channels, but only when
986 * the update bit is set, will also the volume be updated - simultaneously for
987 * both channels.
988 */
989static const int update_reg[] = {
990 WM8978_LEFT_DAC_DIGITAL_VOLUME,
991 WM8978_RIGHT_DAC_DIGITAL_VOLUME,
992 WM8978_LEFT_ADC_DIGITAL_VOLUME,
993 WM8978_RIGHT_ADC_DIGITAL_VOLUME,
994 WM8978_LEFT_INP_PGA_CONTROL,
995 WM8978_RIGHT_INP_PGA_CONTROL,
996 WM8978_LOUT1_HP_CONTROL,
997 WM8978_ROUT1_HP_CONTROL,
998 WM8978_LOUT2_SPK_CONTROL,
999 WM8978_ROUT2_SPK_CONTROL,
1000};
1001
1002static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1003{
1004 int ret, i;
1005 struct snd_soc_codec *codec = &wm8978->codec;
1006
1007 if (wm8978_codec) {
1008 dev_err(codec->dev, "Another WM8978 is registered\n");
1009 return -EINVAL;
1010 }
1011
1012 /*
1013 * Set default system clock to PLL, it is more precise, this is also the
1014 * default hardware setting
1015 */
1016 wm8978->sysclk = WM8978_PLL;
1017
1018 mutex_init(&codec->mutex);
1019 INIT_LIST_HEAD(&codec->dapm_widgets);
1020 INIT_LIST_HEAD(&codec->dapm_paths);
1021
1022 codec->private_data = wm8978;
1023 codec->name = "WM8978";
1024 codec->owner = THIS_MODULE;
1025 codec->bias_level = SND_SOC_BIAS_OFF;
1026 codec->set_bias_level = wm8978_set_bias_level;
1027 codec->dai = &wm8978_dai;
1028 codec->num_dai = 1;
1029 codec->reg_cache_size = WM8978_CACHEREGNUM;
1030 codec->reg_cache = &wm8978->reg_cache;
1031
1032 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
1033 if (ret < 0) {
1034 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1035 goto err;
1036 }
1037
1038 memcpy(codec->reg_cache, wm8978_reg, sizeof(wm8978_reg));
1039
1040 /*
1041 * Set the update bit in all registers, that have one. This way all
1042 * writes to those registers will also cause the update bit to be
1043 * written.
1044 */
1045 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
1046 ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100;
1047
1048 /* Reset the codec */
1049 ret = snd_soc_write(codec, WM8978_RESET, 0);
1050 if (ret < 0) {
1051 dev_err(codec->dev, "Failed to issue reset\n");
1052 goto err;
1053 }
1054
1055 wm8978_dai.dev = codec->dev;
1056
1057 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1058
1059 wm8978_codec = codec;
1060
1061 ret = snd_soc_register_codec(codec);
1062 if (ret != 0) {
1063 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1064 goto err;
1065 }
1066
1067 ret = snd_soc_register_dai(&wm8978_dai);
1068 if (ret != 0) {
1069 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1070 goto err_codec;
1071 }
1072
1073 return 0;
1074
1075err_codec:
1076 snd_soc_unregister_codec(codec);
1077err:
1078 kfree(wm8978);
1079 return ret;
1080}
1081
1082static __devexit void wm8978_unregister(struct wm8978_priv *wm8978)
1083{
1084 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF);
1085 snd_soc_unregister_dai(&wm8978_dai);
1086 snd_soc_unregister_codec(&wm8978->codec);
1087 kfree(wm8978);
1088 wm8978_codec = NULL;
1089}
1090
1091static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1092 const struct i2c_device_id *id)
1093{
1094 struct wm8978_priv *wm8978;
1095 struct snd_soc_codec *codec;
1096
1097 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
1098 if (wm8978 == NULL)
1099 return -ENOMEM;
1100
1101 codec = &wm8978->codec;
1102 codec->hw_write = (hw_write_t)i2c_master_send;
1103
1104 i2c_set_clientdata(i2c, wm8978);
1105 codec->control_data = i2c;
1106
1107 codec->dev = &i2c->dev;
1108
1109 return wm8978_register(wm8978);
1110}
1111
1112static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1113{
1114 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1115 wm8978_unregister(wm8978);
1116 return 0;
1117}
1118
1119static const struct i2c_device_id wm8978_i2c_id[] = {
1120 { "wm8978", 0 },
1121 { }
1122};
1123MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1124
1125static struct i2c_driver wm8978_i2c_driver = {
1126 .driver = {
1127 .name = "WM8978",
1128 .owner = THIS_MODULE,
1129 },
1130 .probe = wm8978_i2c_probe,
1131 .remove = __devexit_p(wm8978_i2c_remove),
1132 .id_table = wm8978_i2c_id,
1133};
1134
1135static int __init wm8978_modinit(void)
1136{
1137 return i2c_add_driver(&wm8978_i2c_driver);
1138}
1139module_init(wm8978_modinit);
1140
1141static void __exit wm8978_exit(void)
1142{
1143 i2c_del_driver(&wm8978_i2c_driver);
1144}
1145module_exit(wm8978_exit);
1146
1147MODULE_DESCRIPTION("ASoC WM8978 codec driver");
1148MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1149MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
new file mode 100644
index 000000000000..56ec83270917
--- /dev/null
+++ b/sound/soc/codecs/wm8978.h
@@ -0,0 +1,86 @@
1/*
2 * wm8978.h -- codec driver for WM8978
3 *
4 * Copyright 2009 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __WM8978_H__
12#define __WM8978_H__
13
14/*
15 * Register values.
16 */
17#define WM8978_RESET 0x00
18#define WM8978_POWER_MANAGEMENT_1 0x01
19#define WM8978_POWER_MANAGEMENT_2 0x02
20#define WM8978_POWER_MANAGEMENT_3 0x03
21#define WM8978_AUDIO_INTERFACE 0x04
22#define WM8978_COMPANDING_CONTROL 0x05
23#define WM8978_CLOCKING 0x06
24#define WM8978_ADDITIONAL_CONTROL 0x07
25#define WM8978_GPIO_CONTROL 0x08
26#define WM8978_JACK_DETECT_CONTROL_1 0x09
27#define WM8978_DAC_CONTROL 0x0A
28#define WM8978_LEFT_DAC_DIGITAL_VOLUME 0x0B
29#define WM8978_RIGHT_DAC_DIGITAL_VOLUME 0x0C
30#define WM8978_JACK_DETECT_CONTROL_2 0x0D
31#define WM8978_ADC_CONTROL 0x0E
32#define WM8978_LEFT_ADC_DIGITAL_VOLUME 0x0F
33#define WM8978_RIGHT_ADC_DIGITAL_VOLUME 0x10
34#define WM8978_EQ1 0x12
35#define WM8978_EQ2 0x13
36#define WM8978_EQ3 0x14
37#define WM8978_EQ4 0x15
38#define WM8978_EQ5 0x16
39#define WM8978_DAC_LIMITER_1 0x18
40#define WM8978_DAC_LIMITER_2 0x19
41#define WM8978_NOTCH_FILTER_1 0x1b
42#define WM8978_NOTCH_FILTER_2 0x1c
43#define WM8978_NOTCH_FILTER_3 0x1d
44#define WM8978_NOTCH_FILTER_4 0x1e
45#define WM8978_ALC_CONTROL_1 0x20
46#define WM8978_ALC_CONTROL_2 0x21
47#define WM8978_ALC_CONTROL_3 0x22
48#define WM8978_NOISE_GATE 0x23
49#define WM8978_PLL_N 0x24
50#define WM8978_PLL_K1 0x25
51#define WM8978_PLL_K2 0x26
52#define WM8978_PLL_K3 0x27
53#define WM8978_3D_CONTROL 0x29
54#define WM8978_BEEP_CONTROL 0x2b
55#define WM8978_INPUT_CONTROL 0x2c
56#define WM8978_LEFT_INP_PGA_CONTROL 0x2d
57#define WM8978_RIGHT_INP_PGA_CONTROL 0x2e
58#define WM8978_LEFT_ADC_BOOST_CONTROL 0x2f
59#define WM8978_RIGHT_ADC_BOOST_CONTROL 0x30
60#define WM8978_OUTPUT_CONTROL 0x31
61#define WM8978_LEFT_MIXER_CONTROL 0x32
62#define WM8978_RIGHT_MIXER_CONTROL 0x33
63#define WM8978_LOUT1_HP_CONTROL 0x34
64#define WM8978_ROUT1_HP_CONTROL 0x35
65#define WM8978_LOUT2_SPK_CONTROL 0x36
66#define WM8978_ROUT2_SPK_CONTROL 0x37
67#define WM8978_OUT3_MIXER_CONTROL 0x38
68#define WM8978_OUT4_MIXER_CONTROL 0x39
69
70#define WM8978_CACHEREGNUM 58
71
72/* Clock divider Id's */
73enum wm8978_clk_id {
74 WM8978_OPCLKRATE,
75 WM8978_BCLKDIV,
76};
77
78enum wm8978_sysclk_src {
79 WM8978_PLL,
80 WM8978_MCLK
81};
82
83extern struct snd_soc_dai wm8978_dai;
84extern struct snd_soc_codec_device soc_codec_dev_wm8978;
85
86#endif /* __WM8978_H__ */
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 341481e0e830..a54dc77b7f34 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1319,10 +1319,6 @@ static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
1319 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1319 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1320 struct snd_soc_codec *codec = socdev->card->codec; 1320 struct snd_soc_codec *codec = socdev->card->codec;
1321 1321
1322 /* we only need to suspend if we are a valid card */
1323 if (!codec->card)
1324 return 0;
1325
1326 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); 1322 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1327 return 0; 1323 return 0;
1328} 1324}
@@ -1335,10 +1331,6 @@ static int wm8990_resume(struct platform_device *pdev)
1335 u8 data[2]; 1331 u8 data[2];
1336 u16 *cache = codec->reg_cache; 1332 u16 *cache = codec->reg_cache;
1337 1333
1338 /* we only need to resume if we are a valid card */
1339 if (!codec->card)
1340 return 0;
1341
1342 /* Sync reg_cache with the hardware */ 1334 /* Sync reg_cache with the hardware */
1343 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) { 1335 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) {
1344 if (i + 1 == WM8990_RESET) 1336 if (i + 1 == WM8990_RESET)
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 2981afae842c..bf022f68b84f 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver 2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009, 2010 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/regulator/consumer.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
@@ -29,6 +30,16 @@
29#include "wm8993.h" 30#include "wm8993.h"
30#include "wm_hubs.h" 31#include "wm_hubs.h"
31 32
33#define WM8993_NUM_SUPPLIES 6
34static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
35 "DCVDD",
36 "DBVDD",
37 "AVDD1",
38 "AVDD2",
39 "CPVDD",
40 "SPKVDD",
41};
42
32static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { 43static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = {
33 0x8993, /* R0 - Software Reset */ 44 0x8993, /* R0 - Software Reset */
34 0x0000, /* R1 - Power Management (1) */ 45 0x0000, /* R1 - Power Management (1) */
@@ -213,7 +224,9 @@ static struct {
213}; 224};
214 225
215struct wm8993_priv { 226struct wm8993_priv {
227 struct wm_hubs_data hubs_data;
216 u16 reg_cache[WM8993_REGISTER_COUNT]; 228 u16 reg_cache[WM8993_REGISTER_COUNT];
229 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
217 struct wm8993_platform_data pdata; 230 struct wm8993_platform_data pdata;
218 struct snd_soc_codec codec; 231 struct snd_soc_codec codec;
219 int master; 232 int master;
@@ -227,36 +240,9 @@ struct wm8993_priv {
227 int class_w_users; 240 int class_w_users;
228 unsigned int fll_fref; 241 unsigned int fll_fref;
229 unsigned int fll_fout; 242 unsigned int fll_fout;
243 int fll_src;
230}; 244};
231 245
232static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg)
233{
234 struct i2c_msg xfer[2];
235 u16 data;
236 int ret;
237 struct i2c_client *i2c = codec->control_data;
238
239 /* Write register */
240 xfer[0].addr = i2c->addr;
241 xfer[0].flags = 0;
242 xfer[0].len = 1;
243 xfer[0].buf = &reg;
244
245 /* Read data */
246 xfer[1].addr = i2c->addr;
247 xfer[1].flags = I2C_M_RD;
248 xfer[1].len = 2;
249 xfer[1].buf = (u8 *)&data;
250
251 ret = i2c_transfer(i2c->adapter, xfer, 2);
252 if (ret != 2) {
253 dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret);
254 return 0;
255 }
256
257 return (data >> 8) | ((data & 0xff) << 8);
258}
259
260static int wm8993_volatile(unsigned int reg) 246static int wm8993_volatile(unsigned int reg)
261{ 247{
262 switch (reg) { 248 switch (reg) {
@@ -271,48 +257,6 @@ static int wm8993_volatile(unsigned int reg)
271 } 257 }
272} 258}
273 259
274static unsigned int wm8993_read(struct snd_soc_codec *codec,
275 unsigned int reg)
276{
277 u16 *reg_cache = codec->reg_cache;
278
279 BUG_ON(reg > WM8993_MAX_REGISTER);
280
281 if (wm8993_volatile(reg))
282 return wm8993_read_hw(codec, reg);
283 else
284 return reg_cache[reg];
285}
286
287static int wm8993_write(struct snd_soc_codec *codec, unsigned int reg,
288 unsigned int value)
289{
290 u16 *reg_cache = codec->reg_cache;
291 u8 data[3];
292 int ret;
293
294 BUG_ON(reg > WM8993_MAX_REGISTER);
295
296 /* data is
297 * D15..D9 WM8993 register offset
298 * D8...D0 register data
299 */
300 data[0] = reg;
301 data[1] = value >> 8;
302 data[2] = value & 0x00ff;
303
304 if (!wm8993_volatile(reg))
305 reg_cache[reg] = value;
306
307 ret = codec->hw_write(codec->control_data, data, 3);
308
309 if (ret == 3)
310 return 0;
311 if (ret < 0)
312 return ret;
313 return -EIO;
314}
315
316struct _fll_div { 260struct _fll_div {
317 u16 fll_fratio; 261 u16 fll_fratio;
318 u16 fll_outdiv; 262 u16 fll_outdiv;
@@ -441,9 +385,9 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
441 wm8993->fll_fref = 0; 385 wm8993->fll_fref = 0;
442 wm8993->fll_fout = 0; 386 wm8993->fll_fout = 0;
443 387
444 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 388 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
445 reg1 &= ~WM8993_FLL_ENA; 389 reg1 &= ~WM8993_FLL_ENA;
446 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 390 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
447 391
448 return 0; 392 return 0;
449 } 393 }
@@ -452,7 +396,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
452 if (ret != 0) 396 if (ret != 0)
453 return ret; 397 return ret;
454 398
455 reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5); 399 reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5);
456 reg5 &= ~WM8993_FLL_CLK_SRC_MASK; 400 reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
457 401
458 switch (fll_id) { 402 switch (fll_id) {
@@ -474,38 +418,39 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
474 418
475 /* Any FLL configuration change requires that the FLL be 419 /* Any FLL configuration change requires that the FLL be
476 * disabled first. */ 420 * disabled first. */
477 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 421 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
478 reg1 &= ~WM8993_FLL_ENA; 422 reg1 &= ~WM8993_FLL_ENA;
479 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 423 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
480 424
481 /* Apply the configuration */ 425 /* Apply the configuration */
482 if (fll_div.k) 426 if (fll_div.k)
483 reg1 |= WM8993_FLL_FRAC_MASK; 427 reg1 |= WM8993_FLL_FRAC_MASK;
484 else 428 else
485 reg1 &= ~WM8993_FLL_FRAC_MASK; 429 reg1 &= ~WM8993_FLL_FRAC_MASK;
486 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 430 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
487 431
488 wm8993_write(codec, WM8993_FLL_CONTROL_2, 432 snd_soc_write(codec, WM8993_FLL_CONTROL_2,
489 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) | 433 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
490 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT)); 434 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
491 wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k); 435 snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
492 436
493 reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4); 437 reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4);
494 reg4 &= ~WM8993_FLL_N_MASK; 438 reg4 &= ~WM8993_FLL_N_MASK;
495 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT; 439 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
496 wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4); 440 snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4);
497 441
498 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK; 442 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
499 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; 443 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
500 wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5); 444 snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
501 445
502 /* Enable the FLL */ 446 /* Enable the FLL */
503 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); 447 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
504 448
505 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 449 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
506 450
507 wm8993->fll_fref = Fref; 451 wm8993->fll_fref = Fref;
508 wm8993->fll_fout = Fout; 452 wm8993->fll_fout = Fout;
453 wm8993->fll_src = source;
509 454
510 return 0; 455 return 0;
511} 456}
@@ -520,7 +465,7 @@ static int configure_clock(struct snd_soc_codec *codec)
520 case WM8993_SYSCLK_MCLK: 465 case WM8993_SYSCLK_MCLK:
521 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); 466 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
522 467
523 reg = wm8993_read(codec, WM8993_CLOCKING_2); 468 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
524 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC); 469 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
525 if (wm8993->mclk_rate > 13500000) { 470 if (wm8993->mclk_rate > 13500000) {
526 reg |= WM8993_MCLK_DIV; 471 reg |= WM8993_MCLK_DIV;
@@ -529,14 +474,14 @@ static int configure_clock(struct snd_soc_codec *codec)
529 reg &= ~WM8993_MCLK_DIV; 474 reg &= ~WM8993_MCLK_DIV;
530 wm8993->sysclk_rate = wm8993->mclk_rate; 475 wm8993->sysclk_rate = wm8993->mclk_rate;
531 } 476 }
532 wm8993_write(codec, WM8993_CLOCKING_2, reg); 477 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
533 break; 478 break;
534 479
535 case WM8993_SYSCLK_FLL: 480 case WM8993_SYSCLK_FLL:
536 dev_dbg(codec->dev, "Using %dHz FLL clock\n", 481 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
537 wm8993->fll_fout); 482 wm8993->fll_fout);
538 483
539 reg = wm8993_read(codec, WM8993_CLOCKING_2); 484 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
540 reg |= WM8993_SYSCLK_SRC; 485 reg |= WM8993_SYSCLK_SRC;
541 if (wm8993->fll_fout > 13500000) { 486 if (wm8993->fll_fout > 13500000) {
542 reg |= WM8993_MCLK_DIV; 487 reg |= WM8993_MCLK_DIV;
@@ -545,7 +490,7 @@ static int configure_clock(struct snd_soc_codec *codec)
545 reg &= ~WM8993_MCLK_DIV; 490 reg &= ~WM8993_MCLK_DIV;
546 wm8993->sysclk_rate = wm8993->fll_fout; 491 wm8993->sysclk_rate = wm8993->fll_fout;
547 } 492 }
548 wm8993_write(codec, WM8993_CLOCKING_2, reg); 493 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
549 break; 494 break;
550 495
551 default: 496 default:
@@ -978,10 +923,33 @@ static const struct snd_soc_dapm_route routes[] = {
978 { "Right Headphone Mux", "DAC", "DACR" }, 923 { "Right Headphone Mux", "DAC", "DACR" },
979}; 924};
980 925
926static void wm8993_cache_restore(struct snd_soc_codec *codec)
927{
928 u16 *cache = codec->reg_cache;
929 int i;
930
931 if (!codec->cache_sync)
932 return;
933
934 /* Reenable hardware writes */
935 codec->cache_only = 0;
936
937 /* Restore the register settings */
938 for (i = 1; i < WM8993_MAX_REGISTER; i++) {
939 if (cache[i] == wm8993_reg_defaults[i])
940 continue;
941 snd_soc_write(codec, i, cache[i]);
942 }
943
944 /* We're in sync again */
945 codec->cache_sync = 0;
946}
947
981static int wm8993_set_bias_level(struct snd_soc_codec *codec, 948static int wm8993_set_bias_level(struct snd_soc_codec *codec,
982 enum snd_soc_bias_level level) 949 enum snd_soc_bias_level level)
983{ 950{
984 struct wm8993_priv *wm8993 = codec->private_data; 951 struct wm8993_priv *wm8993 = codec->private_data;
952 int ret;
985 953
986 switch (level) { 954 switch (level) {
987 case SND_SOC_BIAS_ON: 955 case SND_SOC_BIAS_ON:
@@ -995,6 +963,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
995 963
996 case SND_SOC_BIAS_STANDBY: 964 case SND_SOC_BIAS_STANDBY:
997 if (codec->bias_level == SND_SOC_BIAS_OFF) { 965 if (codec->bias_level == SND_SOC_BIAS_OFF) {
966 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
967 wm8993->supplies);
968 if (ret != 0)
969 return ret;
970
971 wm8993_cache_restore(codec);
972
973 /* Tune DC servo configuration */
974 snd_soc_write(codec, 0x44, 3);
975 snd_soc_write(codec, 0x56, 3);
976 snd_soc_write(codec, 0x44, 0);
977
998 /* Bring up VMID with fast soft start */ 978 /* Bring up VMID with fast soft start */
999 snd_soc_update_bits(codec, WM8993_ANTIPOP2, 979 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1000 WM8993_STARTUP_BIAS_ENA | 980 WM8993_STARTUP_BIAS_ENA |
@@ -1042,6 +1022,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1042 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 1022 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1043 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 1023 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1044 0); 1024 0);
1025
1026#ifdef CONFIG_REGULATOR
1027 /* Post 2.6.34 we will be able to get a callback when
1028 * the regulators are disabled which we can use but
1029 * for now just assume that the power will be cut if
1030 * the regulator API is in use.
1031 */
1032 codec->cache_sync = 1;
1033#endif
1034
1035 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
1036 wm8993->supplies);
1045 break; 1037 break;
1046 } 1038 }
1047 1039
@@ -1075,8 +1067,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1075{ 1067{
1076 struct snd_soc_codec *codec = dai->codec; 1068 struct snd_soc_codec *codec = dai->codec;
1077 struct wm8993_priv *wm8993 = codec->private_data; 1069 struct wm8993_priv *wm8993 = codec->private_data;
1078 unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1070 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1079 unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1071 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1080 1072
1081 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | 1073 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1082 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); 1074 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
@@ -1159,8 +1151,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1159 return -EINVAL; 1151 return -EINVAL;
1160 } 1152 }
1161 1153
1162 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1154 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1163 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1155 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1164 1156
1165 return 0; 1157 return 0;
1166} 1158}
@@ -1174,16 +1166,16 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1174 int ret, i, best, best_val, cur_val; 1166 int ret, i, best, best_val, cur_val;
1175 unsigned int clocking1, clocking3, aif1, aif4; 1167 unsigned int clocking1, clocking3, aif1, aif4;
1176 1168
1177 clocking1 = wm8993_read(codec, WM8993_CLOCKING_1); 1169 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
1178 clocking1 &= ~WM8993_BCLK_DIV_MASK; 1170 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1179 1171
1180 clocking3 = wm8993_read(codec, WM8993_CLOCKING_3); 1172 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
1181 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); 1173 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
1182 1174
1183 aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1175 aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1184 aif1 &= ~WM8993_AIF_WL_MASK; 1176 aif1 &= ~WM8993_AIF_WL_MASK;
1185 1177
1186 aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1178 aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1187 aif4 &= ~WM8993_LRCLK_RATE_MASK; 1179 aif4 &= ~WM8993_LRCLK_RATE_MASK;
1188 1180
1189 /* What BCLK do we need? */ 1181 /* What BCLK do we need? */
@@ -1276,14 +1268,14 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1276 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs); 1268 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
1277 aif4 |= wm8993->bclk / wm8993->fs; 1269 aif4 |= wm8993->bclk / wm8993->fs;
1278 1270
1279 wm8993_write(codec, WM8993_CLOCKING_1, clocking1); 1271 snd_soc_write(codec, WM8993_CLOCKING_1, clocking1);
1280 wm8993_write(codec, WM8993_CLOCKING_3, clocking3); 1272 snd_soc_write(codec, WM8993_CLOCKING_3, clocking3);
1281 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1273 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1282 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1274 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1283 1275
1284 /* ReTune Mobile? */ 1276 /* ReTune Mobile? */
1285 if (wm8993->pdata.num_retune_configs) { 1277 if (wm8993->pdata.num_retune_configs) {
1286 u16 eq1 = wm8993_read(codec, WM8993_EQ1); 1278 u16 eq1 = snd_soc_read(codec, WM8993_EQ1);
1287 struct wm8993_retune_mobile_setting *s; 1279 struct wm8993_retune_mobile_setting *s;
1288 1280
1289 best = 0; 1281 best = 0;
@@ -1306,7 +1298,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1306 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0); 1298 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
1307 1299
1308 for (i = 1; i < ARRAY_SIZE(s->config); i++) 1300 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1309 wm8993_write(codec, WM8993_EQ1 + i, s->config[i]); 1301 snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]);
1310 1302
1311 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1); 1303 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
1312 } 1304 }
@@ -1319,14 +1311,14 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1319 struct snd_soc_codec *codec = codec_dai->codec; 1311 struct snd_soc_codec *codec = codec_dai->codec;
1320 unsigned int reg; 1312 unsigned int reg;
1321 1313
1322 reg = wm8993_read(codec, WM8993_DAC_CTRL); 1314 reg = snd_soc_read(codec, WM8993_DAC_CTRL);
1323 1315
1324 if (mute) 1316 if (mute)
1325 reg |= WM8993_DAC_MUTE; 1317 reg |= WM8993_DAC_MUTE;
1326 else 1318 else
1327 reg &= ~WM8993_DAC_MUTE; 1319 reg &= ~WM8993_DAC_MUTE;
1328 1320
1329 wm8993_write(codec, WM8993_DAC_CTRL, reg); 1321 snd_soc_write(codec, WM8993_DAC_CTRL, reg);
1330 1322
1331 return 0; 1323 return 0;
1332} 1324}
@@ -1480,9 +1472,66 @@ static int wm8993_remove(struct platform_device *pdev)
1480 return 0; 1472 return 0;
1481} 1473}
1482 1474
1475#ifdef CONFIG_PM
1476static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1477{
1478 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1479 struct snd_soc_codec *codec = socdev->card->codec;
1480 struct wm8993_priv *wm8993 = codec->private_data;
1481 int fll_fout = wm8993->fll_fout;
1482 int fll_fref = wm8993->fll_fref;
1483 int ret;
1484
1485 /* Stop the FLL in an orderly fashion */
1486 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
1487 if (ret != 0) {
1488 dev_err(&pdev->dev, "Failed to stop FLL\n");
1489 return ret;
1490 }
1491
1492 wm8993->fll_fout = fll_fout;
1493 wm8993->fll_fref = fll_fref;
1494
1495 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1496
1497 return 0;
1498}
1499
1500static int wm8993_resume(struct platform_device *pdev)
1501{
1502 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1503 struct snd_soc_codec *codec = socdev->card->codec;
1504 struct wm8993_priv *wm8993 = codec->private_data;
1505 int ret;
1506
1507 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1508
1509 /* Restart the FLL? */
1510 if (wm8993->fll_fout) {
1511 int fll_fout = wm8993->fll_fout;
1512 int fll_fref = wm8993->fll_fref;
1513
1514 wm8993->fll_fref = 0;
1515 wm8993->fll_fout = 0;
1516
1517 ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src,
1518 fll_fref, fll_fout);
1519 if (ret != 0)
1520 dev_err(codec->dev, "Failed to restart FLL\n");
1521 }
1522
1523 return 0;
1524}
1525#else
1526#define wm8993_suspend NULL
1527#define wm8993_resume NULL
1528#endif
1529
1483struct snd_soc_codec_device soc_codec_dev_wm8993 = { 1530struct snd_soc_codec_device soc_codec_dev_wm8993 = {
1484 .probe = wm8993_probe, 1531 .probe = wm8993_probe,
1485 .remove = wm8993_remove, 1532 .remove = wm8993_remove,
1533 .suspend = wm8993_suspend,
1534 .resume = wm8993_resume,
1486}; 1535};
1487EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993); 1536EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1488 1537
@@ -1493,6 +1542,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1493 struct snd_soc_codec *codec; 1542 struct snd_soc_codec *codec;
1494 unsigned int val; 1543 unsigned int val;
1495 int ret; 1544 int ret;
1545 int i;
1496 1546
1497 if (wm8993_codec) { 1547 if (wm8993_codec) {
1498 dev_err(&i2c->dev, "A WM8993 is already registered\n"); 1548 dev_err(&i2c->dev, "A WM8993 is already registered\n");
@@ -1513,9 +1563,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1513 INIT_LIST_HEAD(&codec->dapm_paths); 1563 INIT_LIST_HEAD(&codec->dapm_paths);
1514 1564
1515 codec->name = "WM8993"; 1565 codec->name = "WM8993";
1516 codec->read = wm8993_read; 1566 codec->volatile_register = wm8993_volatile;
1517 codec->write = wm8993_write;
1518 codec->hw_write = (hw_write_t)i2c_master_send;
1519 codec->reg_cache = wm8993->reg_cache; 1567 codec->reg_cache = wm8993->reg_cache;
1520 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); 1568 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1521 codec->bias_level = SND_SOC_BIAS_OFF; 1569 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -1524,25 +1572,53 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1524 codec->num_dai = 1; 1572 codec->num_dai = 1;
1525 codec->private_data = wm8993; 1573 codec->private_data = wm8993;
1526 1574
1575 wm8993->hubs_data.hp_startup_mode = 1;
1576 wm8993->hubs_data.dcs_codes = -2;
1577
1527 memcpy(wm8993->reg_cache, wm8993_reg_defaults, 1578 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1528 sizeof(wm8993->reg_cache)); 1579 sizeof(wm8993->reg_cache));
1529 1580
1581 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1582 if (ret != 0) {
1583 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1584 goto err;
1585 }
1586
1530 i2c_set_clientdata(i2c, wm8993); 1587 i2c_set_clientdata(i2c, wm8993);
1531 codec->control_data = i2c; 1588 codec->control_data = i2c;
1532 wm8993_codec = codec; 1589 wm8993_codec = codec;
1533 1590
1534 codec->dev = &i2c->dev; 1591 codec->dev = &i2c->dev;
1535 1592
1536 val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET); 1593 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1594 wm8993->supplies[i].supply = wm8993_supply_names[i];
1595
1596 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1597 wm8993->supplies);
1598 if (ret != 0) {
1599 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1600 goto err;
1601 }
1602
1603 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1604 wm8993->supplies);
1605 if (ret != 0) {
1606 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1607 goto err_get;
1608 }
1609
1610 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1537 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { 1611 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1538 dev_err(codec->dev, "Invalid ID register value %x\n", val); 1612 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1539 ret = -EINVAL; 1613 ret = -EINVAL;
1540 goto err; 1614 goto err_enable;
1541 } 1615 }
1542 1616
1543 ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff); 1617 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1544 if (ret != 0) 1618 if (ret != 0)
1545 goto err; 1619 goto err_enable;
1620
1621 codec->cache_only = 1;
1546 1622
1547 /* By default we're using the output mixers */ 1623 /* By default we're using the output mixers */
1548 wm8993->class_w_users = 2; 1624 wm8993->class_w_users = 2;
@@ -1572,7 +1648,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1572 1648
1573 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1649 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1574 if (ret != 0) 1650 if (ret != 0)
1575 goto err; 1651 goto err_enable;
1576 1652
1577 wm8993_dai.dev = codec->dev; 1653 wm8993_dai.dev = codec->dev;
1578 1654
@@ -1586,6 +1662,10 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1586 1662
1587err_bias: 1663err_bias:
1588 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); 1664 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1665err_enable:
1666 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1667err_get:
1668 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1589err: 1669err:
1590 wm8993_codec = NULL; 1670 wm8993_codec = NULL;
1591 kfree(wm8993); 1671 kfree(wm8993);
@@ -1600,6 +1680,7 @@ static int wm8993_i2c_remove(struct i2c_client *client)
1600 snd_soc_unregister_dai(&wm8993_dai); 1680 snd_soc_unregister_dai(&wm8993_dai);
1601 1681
1602 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); 1682 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1683 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1603 kfree(wm8993); 1684 kfree(wm8993);
1604 1685
1605 return 0; 1686 return 0;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
new file mode 100644
index 000000000000..29f3771c33a4
--- /dev/null
+++ b/sound/soc/codecs/wm8994.c
@@ -0,0 +1,3867 @@
1/*
2 * wm8994.c -- WM8994 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
30#include <linux/mfd/wm8994/core.h>
31#include <linux/mfd/wm8994/registers.h>
32#include <linux/mfd/wm8994/pdata.h>
33#include <linux/mfd/wm8994/gpio.h>
34
35#include "wm8994.h"
36#include "wm_hubs.h"
37
38static struct snd_soc_codec *wm8994_codec;
39struct snd_soc_codec_device soc_codec_dev_wm8994;
40
41struct fll_config {
42 int src;
43 int in;
44 int out;
45};
46
47#define WM8994_NUM_DRC 3
48#define WM8994_NUM_EQ 3
49
50static int wm8994_drc_base[] = {
51 WM8994_AIF1_DRC1_1,
52 WM8994_AIF1_DRC2_1,
53 WM8994_AIF2_DRC_1,
54};
55
56static int wm8994_retune_mobile_base[] = {
57 WM8994_AIF1_DAC1_EQ_GAINS_1,
58 WM8994_AIF1_DAC2_EQ_GAINS_1,
59 WM8994_AIF2_EQ_GAINS_1,
60};
61
62#define WM8994_REG_CACHE_SIZE 0x621
63
64/* codec private data */
65struct wm8994_priv {
66 struct wm_hubs_data hubs;
67 struct snd_soc_codec codec;
68 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
69 int sysclk[2];
70 int sysclk_rate[2];
71 int mclk[2];
72 int aifclk[2];
73 struct fll_config fll[2], fll_suspend[2];
74
75 int dac_rates[2];
76 int lrclk_shared[2];
77
78 /* Platform dependant DRC configuration */
79 const char **drc_texts;
80 int drc_cfg[WM8994_NUM_DRC];
81 struct soc_enum drc_enum;
82
83 /* Platform dependant ReTune mobile configuration */
84 int num_retune_mobile_texts;
85 const char **retune_mobile_texts;
86 int retune_mobile_cfg[WM8994_NUM_EQ];
87 struct soc_enum retune_mobile_enum;
88
89 struct wm8994_pdata *pdata;
90};
91
92static struct {
93 unsigned short readable; /* Mask of readable bits */
94 unsigned short writable; /* Mask of writable bits */
95 unsigned short vol; /* Mask of volatile bits */
96} access_masks[] = {
97 { 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Software Reset */
98 { 0x3B37, 0x3B37, 0x0000 }, /* R1 - Power Management (1) */
99 { 0x6BF0, 0x6BF0, 0x0000 }, /* R2 - Power Management (2) */
100 { 0x3FF0, 0x3FF0, 0x0000 }, /* R3 - Power Management (3) */
101 { 0x3F3F, 0x3F3F, 0x0000 }, /* R4 - Power Management (4) */
102 { 0x3F0F, 0x3F0F, 0x0000 }, /* R5 - Power Management (5) */
103 { 0x003F, 0x003F, 0x0000 }, /* R6 - Power Management (6) */
104 { 0x0000, 0x0000, 0x0000 }, /* R7 */
105 { 0x0000, 0x0000, 0x0000 }, /* R8 */
106 { 0x0000, 0x0000, 0x0000 }, /* R9 */
107 { 0x0000, 0x0000, 0x0000 }, /* R10 */
108 { 0x0000, 0x0000, 0x0000 }, /* R11 */
109 { 0x0000, 0x0000, 0x0000 }, /* R12 */
110 { 0x0000, 0x0000, 0x0000 }, /* R13 */
111 { 0x0000, 0x0000, 0x0000 }, /* R14 */
112 { 0x0000, 0x0000, 0x0000 }, /* R15 */
113 { 0x0000, 0x0000, 0x0000 }, /* R16 */
114 { 0x0000, 0x0000, 0x0000 }, /* R17 */
115 { 0x0000, 0x0000, 0x0000 }, /* R18 */
116 { 0x0000, 0x0000, 0x0000 }, /* R19 */
117 { 0x0000, 0x0000, 0x0000 }, /* R20 */
118 { 0x01C0, 0x01C0, 0x0000 }, /* R21 - Input Mixer (1) */
119 { 0x0000, 0x0000, 0x0000 }, /* R22 */
120 { 0x0000, 0x0000, 0x0000 }, /* R23 */
121 { 0x00DF, 0x01DF, 0x0000 }, /* R24 - Left Line Input 1&2 Volume */
122 { 0x00DF, 0x01DF, 0x0000 }, /* R25 - Left Line Input 3&4 Volume */
123 { 0x00DF, 0x01DF, 0x0000 }, /* R26 - Right Line Input 1&2 Volume */
124 { 0x00DF, 0x01DF, 0x0000 }, /* R27 - Right Line Input 3&4 Volume */
125 { 0x00FF, 0x01FF, 0x0000 }, /* R28 - Left Output Volume */
126 { 0x00FF, 0x01FF, 0x0000 }, /* R29 - Right Output Volume */
127 { 0x0077, 0x0077, 0x0000 }, /* R30 - Line Outputs Volume */
128 { 0x0030, 0x0030, 0x0000 }, /* R31 - HPOUT2 Volume */
129 { 0x00FF, 0x01FF, 0x0000 }, /* R32 - Left OPGA Volume */
130 { 0x00FF, 0x01FF, 0x0000 }, /* R33 - Right OPGA Volume */
131 { 0x007F, 0x007F, 0x0000 }, /* R34 - SPKMIXL Attenuation */
132 { 0x017F, 0x017F, 0x0000 }, /* R35 - SPKMIXR Attenuation */
133 { 0x003F, 0x003F, 0x0000 }, /* R36 - SPKOUT Mixers */
134 { 0x003F, 0x003F, 0x0000 }, /* R37 - ClassD */
135 { 0x00FF, 0x01FF, 0x0000 }, /* R38 - Speaker Volume Left */
136 { 0x00FF, 0x01FF, 0x0000 }, /* R39 - Speaker Volume Right */
137 { 0x00FF, 0x00FF, 0x0000 }, /* R40 - Input Mixer (2) */
138 { 0x01B7, 0x01B7, 0x0000 }, /* R41 - Input Mixer (3) */
139 { 0x01B7, 0x01B7, 0x0000 }, /* R42 - Input Mixer (4) */
140 { 0x01C7, 0x01C7, 0x0000 }, /* R43 - Input Mixer (5) */
141 { 0x01C7, 0x01C7, 0x0000 }, /* R44 - Input Mixer (6) */
142 { 0x01FF, 0x01FF, 0x0000 }, /* R45 - Output Mixer (1) */
143 { 0x01FF, 0x01FF, 0x0000 }, /* R46 - Output Mixer (2) */
144 { 0x0FFF, 0x0FFF, 0x0000 }, /* R47 - Output Mixer (3) */
145 { 0x0FFF, 0x0FFF, 0x0000 }, /* R48 - Output Mixer (4) */
146 { 0x0FFF, 0x0FFF, 0x0000 }, /* R49 - Output Mixer (5) */
147 { 0x0FFF, 0x0FFF, 0x0000 }, /* R50 - Output Mixer (6) */
148 { 0x0038, 0x0038, 0x0000 }, /* R51 - HPOUT2 Mixer */
149 { 0x0077, 0x0077, 0x0000 }, /* R52 - Line Mixer (1) */
150 { 0x0077, 0x0077, 0x0000 }, /* R53 - Line Mixer (2) */
151 { 0x03FF, 0x03FF, 0x0000 }, /* R54 - Speaker Mixer */
152 { 0x00C1, 0x00C1, 0x0000 }, /* R55 - Additional Control */
153 { 0x00F0, 0x00F0, 0x0000 }, /* R56 - AntiPOP (1) */
154 { 0x01EF, 0x01EF, 0x0000 }, /* R57 - AntiPOP (2) */
155 { 0x00FF, 0x00FF, 0x0000 }, /* R58 - MICBIAS */
156 { 0x000F, 0x000F, 0x0000 }, /* R59 - LDO 1 */
157 { 0x0007, 0x0007, 0x0000 }, /* R60 - LDO 2 */
158 { 0x0000, 0x0000, 0x0000 }, /* R61 */
159 { 0x0000, 0x0000, 0x0000 }, /* R62 */
160 { 0x0000, 0x0000, 0x0000 }, /* R63 */
161 { 0x0000, 0x0000, 0x0000 }, /* R64 */
162 { 0x0000, 0x0000, 0x0000 }, /* R65 */
163 { 0x0000, 0x0000, 0x0000 }, /* R66 */
164 { 0x0000, 0x0000, 0x0000 }, /* R67 */
165 { 0x0000, 0x0000, 0x0000 }, /* R68 */
166 { 0x0000, 0x0000, 0x0000 }, /* R69 */
167 { 0x0000, 0x0000, 0x0000 }, /* R70 */
168 { 0x0000, 0x0000, 0x0000 }, /* R71 */
169 { 0x0000, 0x0000, 0x0000 }, /* R72 */
170 { 0x0000, 0x0000, 0x0000 }, /* R73 */
171 { 0x0000, 0x0000, 0x0000 }, /* R74 */
172 { 0x0000, 0x0000, 0x0000 }, /* R75 */
173 { 0x8000, 0x8000, 0x0000 }, /* R76 - Charge Pump (1) */
174 { 0x0000, 0x0000, 0x0000 }, /* R77 */
175 { 0x0000, 0x0000, 0x0000 }, /* R78 */
176 { 0x0000, 0x0000, 0x0000 }, /* R79 */
177 { 0x0000, 0x0000, 0x0000 }, /* R80 */
178 { 0x0301, 0x0301, 0x0000 }, /* R81 - Class W (1) */
179 { 0x0000, 0x0000, 0x0000 }, /* R82 */
180 { 0x0000, 0x0000, 0x0000 }, /* R83 */
181 { 0x333F, 0x333F, 0x0000 }, /* R84 - DC Servo (1) */
182 { 0x0FEF, 0x0FEF, 0x0000 }, /* R85 - DC Servo (2) */
183 { 0x0000, 0x0000, 0x0000 }, /* R86 */
184 { 0xFFFF, 0xFFFF, 0x0000 }, /* R87 - DC Servo (4) */
185 { 0x0333, 0x0000, 0x0000 }, /* R88 - DC Servo Readback */
186 { 0x0000, 0x0000, 0x0000 }, /* R89 */
187 { 0x0000, 0x0000, 0x0000 }, /* R90 */
188 { 0x0000, 0x0000, 0x0000 }, /* R91 */
189 { 0x0000, 0x0000, 0x0000 }, /* R92 */
190 { 0x0000, 0x0000, 0x0000 }, /* R93 */
191 { 0x0000, 0x0000, 0x0000 }, /* R94 */
192 { 0x0000, 0x0000, 0x0000 }, /* R95 */
193 { 0x00EE, 0x00EE, 0x0000 }, /* R96 - Analogue HP (1) */
194 { 0x0000, 0x0000, 0x0000 }, /* R97 */
195 { 0x0000, 0x0000, 0x0000 }, /* R98 */
196 { 0x0000, 0x0000, 0x0000 }, /* R99 */
197 { 0x0000, 0x0000, 0x0000 }, /* R100 */
198 { 0x0000, 0x0000, 0x0000 }, /* R101 */
199 { 0x0000, 0x0000, 0x0000 }, /* R102 */
200 { 0x0000, 0x0000, 0x0000 }, /* R103 */
201 { 0x0000, 0x0000, 0x0000 }, /* R104 */
202 { 0x0000, 0x0000, 0x0000 }, /* R105 */
203 { 0x0000, 0x0000, 0x0000 }, /* R106 */
204 { 0x0000, 0x0000, 0x0000 }, /* R107 */
205 { 0x0000, 0x0000, 0x0000 }, /* R108 */
206 { 0x0000, 0x0000, 0x0000 }, /* R109 */
207 { 0x0000, 0x0000, 0x0000 }, /* R110 */
208 { 0x0000, 0x0000, 0x0000 }, /* R111 */
209 { 0x0000, 0x0000, 0x0000 }, /* R112 */
210 { 0x0000, 0x0000, 0x0000 }, /* R113 */
211 { 0x0000, 0x0000, 0x0000 }, /* R114 */
212 { 0x0000, 0x0000, 0x0000 }, /* R115 */
213 { 0x0000, 0x0000, 0x0000 }, /* R116 */
214 { 0x0000, 0x0000, 0x0000 }, /* R117 */
215 { 0x0000, 0x0000, 0x0000 }, /* R118 */
216 { 0x0000, 0x0000, 0x0000 }, /* R119 */
217 { 0x0000, 0x0000, 0x0000 }, /* R120 */
218 { 0x0000, 0x0000, 0x0000 }, /* R121 */
219 { 0x0000, 0x0000, 0x0000 }, /* R122 */
220 { 0x0000, 0x0000, 0x0000 }, /* R123 */
221 { 0x0000, 0x0000, 0x0000 }, /* R124 */
222 { 0x0000, 0x0000, 0x0000 }, /* R125 */
223 { 0x0000, 0x0000, 0x0000 }, /* R126 */
224 { 0x0000, 0x0000, 0x0000 }, /* R127 */
225 { 0x0000, 0x0000, 0x0000 }, /* R128 */
226 { 0x0000, 0x0000, 0x0000 }, /* R129 */
227 { 0x0000, 0x0000, 0x0000 }, /* R130 */
228 { 0x0000, 0x0000, 0x0000 }, /* R131 */
229 { 0x0000, 0x0000, 0x0000 }, /* R132 */
230 { 0x0000, 0x0000, 0x0000 }, /* R133 */
231 { 0x0000, 0x0000, 0x0000 }, /* R134 */
232 { 0x0000, 0x0000, 0x0000 }, /* R135 */
233 { 0x0000, 0x0000, 0x0000 }, /* R136 */
234 { 0x0000, 0x0000, 0x0000 }, /* R137 */
235 { 0x0000, 0x0000, 0x0000 }, /* R138 */
236 { 0x0000, 0x0000, 0x0000 }, /* R139 */
237 { 0x0000, 0x0000, 0x0000 }, /* R140 */
238 { 0x0000, 0x0000, 0x0000 }, /* R141 */
239 { 0x0000, 0x0000, 0x0000 }, /* R142 */
240 { 0x0000, 0x0000, 0x0000 }, /* R143 */
241 { 0x0000, 0x0000, 0x0000 }, /* R144 */
242 { 0x0000, 0x0000, 0x0000 }, /* R145 */
243 { 0x0000, 0x0000, 0x0000 }, /* R146 */
244 { 0x0000, 0x0000, 0x0000 }, /* R147 */
245 { 0x0000, 0x0000, 0x0000 }, /* R148 */
246 { 0x0000, 0x0000, 0x0000 }, /* R149 */
247 { 0x0000, 0x0000, 0x0000 }, /* R150 */
248 { 0x0000, 0x0000, 0x0000 }, /* R151 */
249 { 0x0000, 0x0000, 0x0000 }, /* R152 */
250 { 0x0000, 0x0000, 0x0000 }, /* R153 */
251 { 0x0000, 0x0000, 0x0000 }, /* R154 */
252 { 0x0000, 0x0000, 0x0000 }, /* R155 */
253 { 0x0000, 0x0000, 0x0000 }, /* R156 */
254 { 0x0000, 0x0000, 0x0000 }, /* R157 */
255 { 0x0000, 0x0000, 0x0000 }, /* R158 */
256 { 0x0000, 0x0000, 0x0000 }, /* R159 */
257 { 0x0000, 0x0000, 0x0000 }, /* R160 */
258 { 0x0000, 0x0000, 0x0000 }, /* R161 */
259 { 0x0000, 0x0000, 0x0000 }, /* R162 */
260 { 0x0000, 0x0000, 0x0000 }, /* R163 */
261 { 0x0000, 0x0000, 0x0000 }, /* R164 */
262 { 0x0000, 0x0000, 0x0000 }, /* R165 */
263 { 0x0000, 0x0000, 0x0000 }, /* R166 */
264 { 0x0000, 0x0000, 0x0000 }, /* R167 */
265 { 0x0000, 0x0000, 0x0000 }, /* R168 */
266 { 0x0000, 0x0000, 0x0000 }, /* R169 */
267 { 0x0000, 0x0000, 0x0000 }, /* R170 */
268 { 0x0000, 0x0000, 0x0000 }, /* R171 */
269 { 0x0000, 0x0000, 0x0000 }, /* R172 */
270 { 0x0000, 0x0000, 0x0000 }, /* R173 */
271 { 0x0000, 0x0000, 0x0000 }, /* R174 */
272 { 0x0000, 0x0000, 0x0000 }, /* R175 */
273 { 0x0000, 0x0000, 0x0000 }, /* R176 */
274 { 0x0000, 0x0000, 0x0000 }, /* R177 */
275 { 0x0000, 0x0000, 0x0000 }, /* R178 */
276 { 0x0000, 0x0000, 0x0000 }, /* R179 */
277 { 0x0000, 0x0000, 0x0000 }, /* R180 */
278 { 0x0000, 0x0000, 0x0000 }, /* R181 */
279 { 0x0000, 0x0000, 0x0000 }, /* R182 */
280 { 0x0000, 0x0000, 0x0000 }, /* R183 */
281 { 0x0000, 0x0000, 0x0000 }, /* R184 */
282 { 0x0000, 0x0000, 0x0000 }, /* R185 */
283 { 0x0000, 0x0000, 0x0000 }, /* R186 */
284 { 0x0000, 0x0000, 0x0000 }, /* R187 */
285 { 0x0000, 0x0000, 0x0000 }, /* R188 */
286 { 0x0000, 0x0000, 0x0000 }, /* R189 */
287 { 0x0000, 0x0000, 0x0000 }, /* R190 */
288 { 0x0000, 0x0000, 0x0000 }, /* R191 */
289 { 0x0000, 0x0000, 0x0000 }, /* R192 */
290 { 0x0000, 0x0000, 0x0000 }, /* R193 */
291 { 0x0000, 0x0000, 0x0000 }, /* R194 */
292 { 0x0000, 0x0000, 0x0000 }, /* R195 */
293 { 0x0000, 0x0000, 0x0000 }, /* R196 */
294 { 0x0000, 0x0000, 0x0000 }, /* R197 */
295 { 0x0000, 0x0000, 0x0000 }, /* R198 */
296 { 0x0000, 0x0000, 0x0000 }, /* R199 */
297 { 0x0000, 0x0000, 0x0000 }, /* R200 */
298 { 0x0000, 0x0000, 0x0000 }, /* R201 */
299 { 0x0000, 0x0000, 0x0000 }, /* R202 */
300 { 0x0000, 0x0000, 0x0000 }, /* R203 */
301 { 0x0000, 0x0000, 0x0000 }, /* R204 */
302 { 0x0000, 0x0000, 0x0000 }, /* R205 */
303 { 0x0000, 0x0000, 0x0000 }, /* R206 */
304 { 0x0000, 0x0000, 0x0000 }, /* R207 */
305 { 0x0000, 0x0000, 0x0000 }, /* R208 */
306 { 0x0000, 0x0000, 0x0000 }, /* R209 */
307 { 0x0000, 0x0000, 0x0000 }, /* R210 */
308 { 0x0000, 0x0000, 0x0000 }, /* R211 */
309 { 0x0000, 0x0000, 0x0000 }, /* R212 */
310 { 0x0000, 0x0000, 0x0000 }, /* R213 */
311 { 0x0000, 0x0000, 0x0000 }, /* R214 */
312 { 0x0000, 0x0000, 0x0000 }, /* R215 */
313 { 0x0000, 0x0000, 0x0000 }, /* R216 */
314 { 0x0000, 0x0000, 0x0000 }, /* R217 */
315 { 0x0000, 0x0000, 0x0000 }, /* R218 */
316 { 0x0000, 0x0000, 0x0000 }, /* R219 */
317 { 0x0000, 0x0000, 0x0000 }, /* R220 */
318 { 0x0000, 0x0000, 0x0000 }, /* R221 */
319 { 0x0000, 0x0000, 0x0000 }, /* R222 */
320 { 0x0000, 0x0000, 0x0000 }, /* R223 */
321 { 0x0000, 0x0000, 0x0000 }, /* R224 */
322 { 0x0000, 0x0000, 0x0000 }, /* R225 */
323 { 0x0000, 0x0000, 0x0000 }, /* R226 */
324 { 0x0000, 0x0000, 0x0000 }, /* R227 */
325 { 0x0000, 0x0000, 0x0000 }, /* R228 */
326 { 0x0000, 0x0000, 0x0000 }, /* R229 */
327 { 0x0000, 0x0000, 0x0000 }, /* R230 */
328 { 0x0000, 0x0000, 0x0000 }, /* R231 */
329 { 0x0000, 0x0000, 0x0000 }, /* R232 */
330 { 0x0000, 0x0000, 0x0000 }, /* R233 */
331 { 0x0000, 0x0000, 0x0000 }, /* R234 */
332 { 0x0000, 0x0000, 0x0000 }, /* R235 */
333 { 0x0000, 0x0000, 0x0000 }, /* R236 */
334 { 0x0000, 0x0000, 0x0000 }, /* R237 */
335 { 0x0000, 0x0000, 0x0000 }, /* R238 */
336 { 0x0000, 0x0000, 0x0000 }, /* R239 */
337 { 0x0000, 0x0000, 0x0000 }, /* R240 */
338 { 0x0000, 0x0000, 0x0000 }, /* R241 */
339 { 0x0000, 0x0000, 0x0000 }, /* R242 */
340 { 0x0000, 0x0000, 0x0000 }, /* R243 */
341 { 0x0000, 0x0000, 0x0000 }, /* R244 */
342 { 0x0000, 0x0000, 0x0000 }, /* R245 */
343 { 0x0000, 0x0000, 0x0000 }, /* R246 */
344 { 0x0000, 0x0000, 0x0000 }, /* R247 */
345 { 0x0000, 0x0000, 0x0000 }, /* R248 */
346 { 0x0000, 0x0000, 0x0000 }, /* R249 */
347 { 0x0000, 0x0000, 0x0000 }, /* R250 */
348 { 0x0000, 0x0000, 0x0000 }, /* R251 */
349 { 0x0000, 0x0000, 0x0000 }, /* R252 */
350 { 0x0000, 0x0000, 0x0000 }, /* R253 */
351 { 0x0000, 0x0000, 0x0000 }, /* R254 */
352 { 0x0000, 0x0000, 0x0000 }, /* R255 */
353 { 0x000F, 0x0000, 0x0000 }, /* R256 - Chip Revision */
354 { 0x0074, 0x0074, 0x0000 }, /* R257 - Control Interface */
355 { 0x0000, 0x0000, 0x0000 }, /* R258 */
356 { 0x0000, 0x0000, 0x0000 }, /* R259 */
357 { 0x0000, 0x0000, 0x0000 }, /* R260 */
358 { 0x0000, 0x0000, 0x0000 }, /* R261 */
359 { 0x0000, 0x0000, 0x0000 }, /* R262 */
360 { 0x0000, 0x0000, 0x0000 }, /* R263 */
361 { 0x0000, 0x0000, 0x0000 }, /* R264 */
362 { 0x0000, 0x0000, 0x0000 }, /* R265 */
363 { 0x0000, 0x0000, 0x0000 }, /* R266 */
364 { 0x0000, 0x0000, 0x0000 }, /* R267 */
365 { 0x0000, 0x0000, 0x0000 }, /* R268 */
366 { 0x0000, 0x0000, 0x0000 }, /* R269 */
367 { 0x0000, 0x0000, 0x0000 }, /* R270 */
368 { 0x0000, 0x0000, 0x0000 }, /* R271 */
369 { 0x807F, 0x837F, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
370 { 0x017F, 0x0000, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
371 { 0x0000, 0x0000, 0x0000 }, /* R274 */
372 { 0x0000, 0x0000, 0x0000 }, /* R275 */
373 { 0x0000, 0x0000, 0x0000 }, /* R276 */
374 { 0x0000, 0x0000, 0x0000 }, /* R277 */
375 { 0x0000, 0x0000, 0x0000 }, /* R278 */
376 { 0x0000, 0x0000, 0x0000 }, /* R279 */
377 { 0x0000, 0x0000, 0x0000 }, /* R280 */
378 { 0x0000, 0x0000, 0x0000 }, /* R281 */
379 { 0x0000, 0x0000, 0x0000 }, /* R282 */
380 { 0x0000, 0x0000, 0x0000 }, /* R283 */
381 { 0x0000, 0x0000, 0x0000 }, /* R284 */
382 { 0x0000, 0x0000, 0x0000 }, /* R285 */
383 { 0x0000, 0x0000, 0x0000 }, /* R286 */
384 { 0x0000, 0x0000, 0x0000 }, /* R287 */
385 { 0x0000, 0x0000, 0x0000 }, /* R288 */
386 { 0x0000, 0x0000, 0x0000 }, /* R289 */
387 { 0x0000, 0x0000, 0x0000 }, /* R290 */
388 { 0x0000, 0x0000, 0x0000 }, /* R291 */
389 { 0x0000, 0x0000, 0x0000 }, /* R292 */
390 { 0x0000, 0x0000, 0x0000 }, /* R293 */
391 { 0x0000, 0x0000, 0x0000 }, /* R294 */
392 { 0x0000, 0x0000, 0x0000 }, /* R295 */
393 { 0x0000, 0x0000, 0x0000 }, /* R296 */
394 { 0x0000, 0x0000, 0x0000 }, /* R297 */
395 { 0x0000, 0x0000, 0x0000 }, /* R298 */
396 { 0x0000, 0x0000, 0x0000 }, /* R299 */
397 { 0x0000, 0x0000, 0x0000 }, /* R300 */
398 { 0x0000, 0x0000, 0x0000 }, /* R301 */
399 { 0x0000, 0x0000, 0x0000 }, /* R302 */
400 { 0x0000, 0x0000, 0x0000 }, /* R303 */
401 { 0x0000, 0x0000, 0x0000 }, /* R304 */
402 { 0x0000, 0x0000, 0x0000 }, /* R305 */
403 { 0x0000, 0x0000, 0x0000 }, /* R306 */
404 { 0x0000, 0x0000, 0x0000 }, /* R307 */
405 { 0x0000, 0x0000, 0x0000 }, /* R308 */
406 { 0x0000, 0x0000, 0x0000 }, /* R309 */
407 { 0x0000, 0x0000, 0x0000 }, /* R310 */
408 { 0x0000, 0x0000, 0x0000 }, /* R311 */
409 { 0x0000, 0x0000, 0x0000 }, /* R312 */
410 { 0x0000, 0x0000, 0x0000 }, /* R313 */
411 { 0x0000, 0x0000, 0x0000 }, /* R314 */
412 { 0x0000, 0x0000, 0x0000 }, /* R315 */
413 { 0x0000, 0x0000, 0x0000 }, /* R316 */
414 { 0x0000, 0x0000, 0x0000 }, /* R317 */
415 { 0x0000, 0x0000, 0x0000 }, /* R318 */
416 { 0x0000, 0x0000, 0x0000 }, /* R319 */
417 { 0x0000, 0x0000, 0x0000 }, /* R320 */
418 { 0x0000, 0x0000, 0x0000 }, /* R321 */
419 { 0x0000, 0x0000, 0x0000 }, /* R322 */
420 { 0x0000, 0x0000, 0x0000 }, /* R323 */
421 { 0x0000, 0x0000, 0x0000 }, /* R324 */
422 { 0x0000, 0x0000, 0x0000 }, /* R325 */
423 { 0x0000, 0x0000, 0x0000 }, /* R326 */
424 { 0x0000, 0x0000, 0x0000 }, /* R327 */
425 { 0x0000, 0x0000, 0x0000 }, /* R328 */
426 { 0x0000, 0x0000, 0x0000 }, /* R329 */
427 { 0x0000, 0x0000, 0x0000 }, /* R330 */
428 { 0x0000, 0x0000, 0x0000 }, /* R331 */
429 { 0x0000, 0x0000, 0x0000 }, /* R332 */
430 { 0x0000, 0x0000, 0x0000 }, /* R333 */
431 { 0x0000, 0x0000, 0x0000 }, /* R334 */
432 { 0x0000, 0x0000, 0x0000 }, /* R335 */
433 { 0x0000, 0x0000, 0x0000 }, /* R336 */
434 { 0x0000, 0x0000, 0x0000 }, /* R337 */
435 { 0x0000, 0x0000, 0x0000 }, /* R338 */
436 { 0x0000, 0x0000, 0x0000 }, /* R339 */
437 { 0x0000, 0x0000, 0x0000 }, /* R340 */
438 { 0x0000, 0x0000, 0x0000 }, /* R341 */
439 { 0x0000, 0x0000, 0x0000 }, /* R342 */
440 { 0x0000, 0x0000, 0x0000 }, /* R343 */
441 { 0x0000, 0x0000, 0x0000 }, /* R344 */
442 { 0x0000, 0x0000, 0x0000 }, /* R345 */
443 { 0x0000, 0x0000, 0x0000 }, /* R346 */
444 { 0x0000, 0x0000, 0x0000 }, /* R347 */
445 { 0x0000, 0x0000, 0x0000 }, /* R348 */
446 { 0x0000, 0x0000, 0x0000 }, /* R349 */
447 { 0x0000, 0x0000, 0x0000 }, /* R350 */
448 { 0x0000, 0x0000, 0x0000 }, /* R351 */
449 { 0x0000, 0x0000, 0x0000 }, /* R352 */
450 { 0x0000, 0x0000, 0x0000 }, /* R353 */
451 { 0x0000, 0x0000, 0x0000 }, /* R354 */
452 { 0x0000, 0x0000, 0x0000 }, /* R355 */
453 { 0x0000, 0x0000, 0x0000 }, /* R356 */
454 { 0x0000, 0x0000, 0x0000 }, /* R357 */
455 { 0x0000, 0x0000, 0x0000 }, /* R358 */
456 { 0x0000, 0x0000, 0x0000 }, /* R359 */
457 { 0x0000, 0x0000, 0x0000 }, /* R360 */
458 { 0x0000, 0x0000, 0x0000 }, /* R361 */
459 { 0x0000, 0x0000, 0x0000 }, /* R362 */
460 { 0x0000, 0x0000, 0x0000 }, /* R363 */
461 { 0x0000, 0x0000, 0x0000 }, /* R364 */
462 { 0x0000, 0x0000, 0x0000 }, /* R365 */
463 { 0x0000, 0x0000, 0x0000 }, /* R366 */
464 { 0x0000, 0x0000, 0x0000 }, /* R367 */
465 { 0x0000, 0x0000, 0x0000 }, /* R368 */
466 { 0x0000, 0x0000, 0x0000 }, /* R369 */
467 { 0x0000, 0x0000, 0x0000 }, /* R370 */
468 { 0x0000, 0x0000, 0x0000 }, /* R371 */
469 { 0x0000, 0x0000, 0x0000 }, /* R372 */
470 { 0x0000, 0x0000, 0x0000 }, /* R373 */
471 { 0x0000, 0x0000, 0x0000 }, /* R374 */
472 { 0x0000, 0x0000, 0x0000 }, /* R375 */
473 { 0x0000, 0x0000, 0x0000 }, /* R376 */
474 { 0x0000, 0x0000, 0x0000 }, /* R377 */
475 { 0x0000, 0x0000, 0x0000 }, /* R378 */
476 { 0x0000, 0x0000, 0x0000 }, /* R379 */
477 { 0x0000, 0x0000, 0x0000 }, /* R380 */
478 { 0x0000, 0x0000, 0x0000 }, /* R381 */
479 { 0x0000, 0x0000, 0x0000 }, /* R382 */
480 { 0x0000, 0x0000, 0x0000 }, /* R383 */
481 { 0x0000, 0x0000, 0x0000 }, /* R384 */
482 { 0x0000, 0x0000, 0x0000 }, /* R385 */
483 { 0x0000, 0x0000, 0x0000 }, /* R386 */
484 { 0x0000, 0x0000, 0x0000 }, /* R387 */
485 { 0x0000, 0x0000, 0x0000 }, /* R388 */
486 { 0x0000, 0x0000, 0x0000 }, /* R389 */
487 { 0x0000, 0x0000, 0x0000 }, /* R390 */
488 { 0x0000, 0x0000, 0x0000 }, /* R391 */
489 { 0x0000, 0x0000, 0x0000 }, /* R392 */
490 { 0x0000, 0x0000, 0x0000 }, /* R393 */
491 { 0x0000, 0x0000, 0x0000 }, /* R394 */
492 { 0x0000, 0x0000, 0x0000 }, /* R395 */
493 { 0x0000, 0x0000, 0x0000 }, /* R396 */
494 { 0x0000, 0x0000, 0x0000 }, /* R397 */
495 { 0x0000, 0x0000, 0x0000 }, /* R398 */
496 { 0x0000, 0x0000, 0x0000 }, /* R399 */
497 { 0x0000, 0x0000, 0x0000 }, /* R400 */
498 { 0x0000, 0x0000, 0x0000 }, /* R401 */
499 { 0x0000, 0x0000, 0x0000 }, /* R402 */
500 { 0x0000, 0x0000, 0x0000 }, /* R403 */
501 { 0x0000, 0x0000, 0x0000 }, /* R404 */
502 { 0x0000, 0x0000, 0x0000 }, /* R405 */
503 { 0x0000, 0x0000, 0x0000 }, /* R406 */
504 { 0x0000, 0x0000, 0x0000 }, /* R407 */
505 { 0x0000, 0x0000, 0x0000 }, /* R408 */
506 { 0x0000, 0x0000, 0x0000 }, /* R409 */
507 { 0x0000, 0x0000, 0x0000 }, /* R410 */
508 { 0x0000, 0x0000, 0x0000 }, /* R411 */
509 { 0x0000, 0x0000, 0x0000 }, /* R412 */
510 { 0x0000, 0x0000, 0x0000 }, /* R413 */
511 { 0x0000, 0x0000, 0x0000 }, /* R414 */
512 { 0x0000, 0x0000, 0x0000 }, /* R415 */
513 { 0x0000, 0x0000, 0x0000 }, /* R416 */
514 { 0x0000, 0x0000, 0x0000 }, /* R417 */
515 { 0x0000, 0x0000, 0x0000 }, /* R418 */
516 { 0x0000, 0x0000, 0x0000 }, /* R419 */
517 { 0x0000, 0x0000, 0x0000 }, /* R420 */
518 { 0x0000, 0x0000, 0x0000 }, /* R421 */
519 { 0x0000, 0x0000, 0x0000 }, /* R422 */
520 { 0x0000, 0x0000, 0x0000 }, /* R423 */
521 { 0x0000, 0x0000, 0x0000 }, /* R424 */
522 { 0x0000, 0x0000, 0x0000 }, /* R425 */
523 { 0x0000, 0x0000, 0x0000 }, /* R426 */
524 { 0x0000, 0x0000, 0x0000 }, /* R427 */
525 { 0x0000, 0x0000, 0x0000 }, /* R428 */
526 { 0x0000, 0x0000, 0x0000 }, /* R429 */
527 { 0x0000, 0x0000, 0x0000 }, /* R430 */
528 { 0x0000, 0x0000, 0x0000 }, /* R431 */
529 { 0x0000, 0x0000, 0x0000 }, /* R432 */
530 { 0x0000, 0x0000, 0x0000 }, /* R433 */
531 { 0x0000, 0x0000, 0x0000 }, /* R434 */
532 { 0x0000, 0x0000, 0x0000 }, /* R435 */
533 { 0x0000, 0x0000, 0x0000 }, /* R436 */
534 { 0x0000, 0x0000, 0x0000 }, /* R437 */
535 { 0x0000, 0x0000, 0x0000 }, /* R438 */
536 { 0x0000, 0x0000, 0x0000 }, /* R439 */
537 { 0x0000, 0x0000, 0x0000 }, /* R440 */
538 { 0x0000, 0x0000, 0x0000 }, /* R441 */
539 { 0x0000, 0x0000, 0x0000 }, /* R442 */
540 { 0x0000, 0x0000, 0x0000 }, /* R443 */
541 { 0x0000, 0x0000, 0x0000 }, /* R444 */
542 { 0x0000, 0x0000, 0x0000 }, /* R445 */
543 { 0x0000, 0x0000, 0x0000 }, /* R446 */
544 { 0x0000, 0x0000, 0x0000 }, /* R447 */
545 { 0x0000, 0x0000, 0x0000 }, /* R448 */
546 { 0x0000, 0x0000, 0x0000 }, /* R449 */
547 { 0x0000, 0x0000, 0x0000 }, /* R450 */
548 { 0x0000, 0x0000, 0x0000 }, /* R451 */
549 { 0x0000, 0x0000, 0x0000 }, /* R452 */
550 { 0x0000, 0x0000, 0x0000 }, /* R453 */
551 { 0x0000, 0x0000, 0x0000 }, /* R454 */
552 { 0x0000, 0x0000, 0x0000 }, /* R455 */
553 { 0x0000, 0x0000, 0x0000 }, /* R456 */
554 { 0x0000, 0x0000, 0x0000 }, /* R457 */
555 { 0x0000, 0x0000, 0x0000 }, /* R458 */
556 { 0x0000, 0x0000, 0x0000 }, /* R459 */
557 { 0x0000, 0x0000, 0x0000 }, /* R460 */
558 { 0x0000, 0x0000, 0x0000 }, /* R461 */
559 { 0x0000, 0x0000, 0x0000 }, /* R462 */
560 { 0x0000, 0x0000, 0x0000 }, /* R463 */
561 { 0x0000, 0x0000, 0x0000 }, /* R464 */
562 { 0x0000, 0x0000, 0x0000 }, /* R465 */
563 { 0x0000, 0x0000, 0x0000 }, /* R466 */
564 { 0x0000, 0x0000, 0x0000 }, /* R467 */
565 { 0x0000, 0x0000, 0x0000 }, /* R468 */
566 { 0x0000, 0x0000, 0x0000 }, /* R469 */
567 { 0x0000, 0x0000, 0x0000 }, /* R470 */
568 { 0x0000, 0x0000, 0x0000 }, /* R471 */
569 { 0x0000, 0x0000, 0x0000 }, /* R472 */
570 { 0x0000, 0x0000, 0x0000 }, /* R473 */
571 { 0x0000, 0x0000, 0x0000 }, /* R474 */
572 { 0x0000, 0x0000, 0x0000 }, /* R475 */
573 { 0x0000, 0x0000, 0x0000 }, /* R476 */
574 { 0x0000, 0x0000, 0x0000 }, /* R477 */
575 { 0x0000, 0x0000, 0x0000 }, /* R478 */
576 { 0x0000, 0x0000, 0x0000 }, /* R479 */
577 { 0x0000, 0x0000, 0x0000 }, /* R480 */
578 { 0x0000, 0x0000, 0x0000 }, /* R481 */
579 { 0x0000, 0x0000, 0x0000 }, /* R482 */
580 { 0x0000, 0x0000, 0x0000 }, /* R483 */
581 { 0x0000, 0x0000, 0x0000 }, /* R484 */
582 { 0x0000, 0x0000, 0x0000 }, /* R485 */
583 { 0x0000, 0x0000, 0x0000 }, /* R486 */
584 { 0x0000, 0x0000, 0x0000 }, /* R487 */
585 { 0x0000, 0x0000, 0x0000 }, /* R488 */
586 { 0x0000, 0x0000, 0x0000 }, /* R489 */
587 { 0x0000, 0x0000, 0x0000 }, /* R490 */
588 { 0x0000, 0x0000, 0x0000 }, /* R491 */
589 { 0x0000, 0x0000, 0x0000 }, /* R492 */
590 { 0x0000, 0x0000, 0x0000 }, /* R493 */
591 { 0x0000, 0x0000, 0x0000 }, /* R494 */
592 { 0x0000, 0x0000, 0x0000 }, /* R495 */
593 { 0x0000, 0x0000, 0x0000 }, /* R496 */
594 { 0x0000, 0x0000, 0x0000 }, /* R497 */
595 { 0x0000, 0x0000, 0x0000 }, /* R498 */
596 { 0x0000, 0x0000, 0x0000 }, /* R499 */
597 { 0x0000, 0x0000, 0x0000 }, /* R500 */
598 { 0x0000, 0x0000, 0x0000 }, /* R501 */
599 { 0x0000, 0x0000, 0x0000 }, /* R502 */
600 { 0x0000, 0x0000, 0x0000 }, /* R503 */
601 { 0x0000, 0x0000, 0x0000 }, /* R504 */
602 { 0x0000, 0x0000, 0x0000 }, /* R505 */
603 { 0x0000, 0x0000, 0x0000 }, /* R506 */
604 { 0x0000, 0x0000, 0x0000 }, /* R507 */
605 { 0x0000, 0x0000, 0x0000 }, /* R508 */
606 { 0x0000, 0x0000, 0x0000 }, /* R509 */
607 { 0x0000, 0x0000, 0x0000 }, /* R510 */
608 { 0x0000, 0x0000, 0x0000 }, /* R511 */
609 { 0x001F, 0x001F, 0x0000 }, /* R512 - AIF1 Clocking (1) */
610 { 0x003F, 0x003F, 0x0000 }, /* R513 - AIF1 Clocking (2) */
611 { 0x0000, 0x0000, 0x0000 }, /* R514 */
612 { 0x0000, 0x0000, 0x0000 }, /* R515 */
613 { 0x001F, 0x001F, 0x0000 }, /* R516 - AIF2 Clocking (1) */
614 { 0x003F, 0x003F, 0x0000 }, /* R517 - AIF2 Clocking (2) */
615 { 0x0000, 0x0000, 0x0000 }, /* R518 */
616 { 0x0000, 0x0000, 0x0000 }, /* R519 */
617 { 0x001F, 0x001F, 0x0000 }, /* R520 - Clocking (1) */
618 { 0x0777, 0x0777, 0x0000 }, /* R521 - Clocking (2) */
619 { 0x0000, 0x0000, 0x0000 }, /* R522 */
620 { 0x0000, 0x0000, 0x0000 }, /* R523 */
621 { 0x0000, 0x0000, 0x0000 }, /* R524 */
622 { 0x0000, 0x0000, 0x0000 }, /* R525 */
623 { 0x0000, 0x0000, 0x0000 }, /* R526 */
624 { 0x0000, 0x0000, 0x0000 }, /* R527 */
625 { 0x00FF, 0x00FF, 0x0000 }, /* R528 - AIF1 Rate */
626 { 0x00FF, 0x00FF, 0x0000 }, /* R529 - AIF2 Rate */
627 { 0x000F, 0x0000, 0x0000 }, /* R530 - Rate Status */
628 { 0x0000, 0x0000, 0x0000 }, /* R531 */
629 { 0x0000, 0x0000, 0x0000 }, /* R532 */
630 { 0x0000, 0x0000, 0x0000 }, /* R533 */
631 { 0x0000, 0x0000, 0x0000 }, /* R534 */
632 { 0x0000, 0x0000, 0x0000 }, /* R535 */
633 { 0x0000, 0x0000, 0x0000 }, /* R536 */
634 { 0x0000, 0x0000, 0x0000 }, /* R537 */
635 { 0x0000, 0x0000, 0x0000 }, /* R538 */
636 { 0x0000, 0x0000, 0x0000 }, /* R539 */
637 { 0x0000, 0x0000, 0x0000 }, /* R540 */
638 { 0x0000, 0x0000, 0x0000 }, /* R541 */
639 { 0x0000, 0x0000, 0x0000 }, /* R542 */
640 { 0x0000, 0x0000, 0x0000 }, /* R543 */
641 { 0x0007, 0x0007, 0x0000 }, /* R544 - FLL1 Control (1) */
642 { 0x3F77, 0x3F77, 0x0000 }, /* R545 - FLL1 Control (2) */
643 { 0xFFFF, 0xFFFF, 0x0000 }, /* R546 - FLL1 Control (3) */
644 { 0x7FEF, 0x7FEF, 0x0000 }, /* R547 - FLL1 Control (4) */
645 { 0x1FDB, 0x1FDB, 0x0000 }, /* R548 - FLL1 Control (5) */
646 { 0x0000, 0x0000, 0x0000 }, /* R549 */
647 { 0x0000, 0x0000, 0x0000 }, /* R550 */
648 { 0x0000, 0x0000, 0x0000 }, /* R551 */
649 { 0x0000, 0x0000, 0x0000 }, /* R552 */
650 { 0x0000, 0x0000, 0x0000 }, /* R553 */
651 { 0x0000, 0x0000, 0x0000 }, /* R554 */
652 { 0x0000, 0x0000, 0x0000 }, /* R555 */
653 { 0x0000, 0x0000, 0x0000 }, /* R556 */
654 { 0x0000, 0x0000, 0x0000 }, /* R557 */
655 { 0x0000, 0x0000, 0x0000 }, /* R558 */
656 { 0x0000, 0x0000, 0x0000 }, /* R559 */
657 { 0x0000, 0x0000, 0x0000 }, /* R560 */
658 { 0x0000, 0x0000, 0x0000 }, /* R561 */
659 { 0x0000, 0x0000, 0x0000 }, /* R562 */
660 { 0x0000, 0x0000, 0x0000 }, /* R563 */
661 { 0x0000, 0x0000, 0x0000 }, /* R564 */
662 { 0x0000, 0x0000, 0x0000 }, /* R565 */
663 { 0x0000, 0x0000, 0x0000 }, /* R566 */
664 { 0x0000, 0x0000, 0x0000 }, /* R567 */
665 { 0x0000, 0x0000, 0x0000 }, /* R568 */
666 { 0x0000, 0x0000, 0x0000 }, /* R569 */
667 { 0x0000, 0x0000, 0x0000 }, /* R570 */
668 { 0x0000, 0x0000, 0x0000 }, /* R571 */
669 { 0x0000, 0x0000, 0x0000 }, /* R572 */
670 { 0x0000, 0x0000, 0x0000 }, /* R573 */
671 { 0x0000, 0x0000, 0x0000 }, /* R574 */
672 { 0x0000, 0x0000, 0x0000 }, /* R575 */
673 { 0x0007, 0x0007, 0x0000 }, /* R576 - FLL2 Control (1) */
674 { 0x3F77, 0x3F77, 0x0000 }, /* R577 - FLL2 Control (2) */
675 { 0xFFFF, 0xFFFF, 0x0000 }, /* R578 - FLL2 Control (3) */
676 { 0x7FEF, 0x7FEF, 0x0000 }, /* R579 - FLL2 Control (4) */
677 { 0x1FDB, 0x1FDB, 0x0000 }, /* R580 - FLL2 Control (5) */
678 { 0x0000, 0x0000, 0x0000 }, /* R581 */
679 { 0x0000, 0x0000, 0x0000 }, /* R582 */
680 { 0x0000, 0x0000, 0x0000 }, /* R583 */
681 { 0x0000, 0x0000, 0x0000 }, /* R584 */
682 { 0x0000, 0x0000, 0x0000 }, /* R585 */
683 { 0x0000, 0x0000, 0x0000 }, /* R586 */
684 { 0x0000, 0x0000, 0x0000 }, /* R587 */
685 { 0x0000, 0x0000, 0x0000 }, /* R588 */
686 { 0x0000, 0x0000, 0x0000 }, /* R589 */
687 { 0x0000, 0x0000, 0x0000 }, /* R590 */
688 { 0x0000, 0x0000, 0x0000 }, /* R591 */
689 { 0x0000, 0x0000, 0x0000 }, /* R592 */
690 { 0x0000, 0x0000, 0x0000 }, /* R593 */
691 { 0x0000, 0x0000, 0x0000 }, /* R594 */
692 { 0x0000, 0x0000, 0x0000 }, /* R595 */
693 { 0x0000, 0x0000, 0x0000 }, /* R596 */
694 { 0x0000, 0x0000, 0x0000 }, /* R597 */
695 { 0x0000, 0x0000, 0x0000 }, /* R598 */
696 { 0x0000, 0x0000, 0x0000 }, /* R599 */
697 { 0x0000, 0x0000, 0x0000 }, /* R600 */
698 { 0x0000, 0x0000, 0x0000 }, /* R601 */
699 { 0x0000, 0x0000, 0x0000 }, /* R602 */
700 { 0x0000, 0x0000, 0x0000 }, /* R603 */
701 { 0x0000, 0x0000, 0x0000 }, /* R604 */
702 { 0x0000, 0x0000, 0x0000 }, /* R605 */
703 { 0x0000, 0x0000, 0x0000 }, /* R606 */
704 { 0x0000, 0x0000, 0x0000 }, /* R607 */
705 { 0x0000, 0x0000, 0x0000 }, /* R608 */
706 { 0x0000, 0x0000, 0x0000 }, /* R609 */
707 { 0x0000, 0x0000, 0x0000 }, /* R610 */
708 { 0x0000, 0x0000, 0x0000 }, /* R611 */
709 { 0x0000, 0x0000, 0x0000 }, /* R612 */
710 { 0x0000, 0x0000, 0x0000 }, /* R613 */
711 { 0x0000, 0x0000, 0x0000 }, /* R614 */
712 { 0x0000, 0x0000, 0x0000 }, /* R615 */
713 { 0x0000, 0x0000, 0x0000 }, /* R616 */
714 { 0x0000, 0x0000, 0x0000 }, /* R617 */
715 { 0x0000, 0x0000, 0x0000 }, /* R618 */
716 { 0x0000, 0x0000, 0x0000 }, /* R619 */
717 { 0x0000, 0x0000, 0x0000 }, /* R620 */
718 { 0x0000, 0x0000, 0x0000 }, /* R621 */
719 { 0x0000, 0x0000, 0x0000 }, /* R622 */
720 { 0x0000, 0x0000, 0x0000 }, /* R623 */
721 { 0x0000, 0x0000, 0x0000 }, /* R624 */
722 { 0x0000, 0x0000, 0x0000 }, /* R625 */
723 { 0x0000, 0x0000, 0x0000 }, /* R626 */
724 { 0x0000, 0x0000, 0x0000 }, /* R627 */
725 { 0x0000, 0x0000, 0x0000 }, /* R628 */
726 { 0x0000, 0x0000, 0x0000 }, /* R629 */
727 { 0x0000, 0x0000, 0x0000 }, /* R630 */
728 { 0x0000, 0x0000, 0x0000 }, /* R631 */
729 { 0x0000, 0x0000, 0x0000 }, /* R632 */
730 { 0x0000, 0x0000, 0x0000 }, /* R633 */
731 { 0x0000, 0x0000, 0x0000 }, /* R634 */
732 { 0x0000, 0x0000, 0x0000 }, /* R635 */
733 { 0x0000, 0x0000, 0x0000 }, /* R636 */
734 { 0x0000, 0x0000, 0x0000 }, /* R637 */
735 { 0x0000, 0x0000, 0x0000 }, /* R638 */
736 { 0x0000, 0x0000, 0x0000 }, /* R639 */
737 { 0x0000, 0x0000, 0x0000 }, /* R640 */
738 { 0x0000, 0x0000, 0x0000 }, /* R641 */
739 { 0x0000, 0x0000, 0x0000 }, /* R642 */
740 { 0x0000, 0x0000, 0x0000 }, /* R643 */
741 { 0x0000, 0x0000, 0x0000 }, /* R644 */
742 { 0x0000, 0x0000, 0x0000 }, /* R645 */
743 { 0x0000, 0x0000, 0x0000 }, /* R646 */
744 { 0x0000, 0x0000, 0x0000 }, /* R647 */
745 { 0x0000, 0x0000, 0x0000 }, /* R648 */
746 { 0x0000, 0x0000, 0x0000 }, /* R649 */
747 { 0x0000, 0x0000, 0x0000 }, /* R650 */
748 { 0x0000, 0x0000, 0x0000 }, /* R651 */
749 { 0x0000, 0x0000, 0x0000 }, /* R652 */
750 { 0x0000, 0x0000, 0x0000 }, /* R653 */
751 { 0x0000, 0x0000, 0x0000 }, /* R654 */
752 { 0x0000, 0x0000, 0x0000 }, /* R655 */
753 { 0x0000, 0x0000, 0x0000 }, /* R656 */
754 { 0x0000, 0x0000, 0x0000 }, /* R657 */
755 { 0x0000, 0x0000, 0x0000 }, /* R658 */
756 { 0x0000, 0x0000, 0x0000 }, /* R659 */
757 { 0x0000, 0x0000, 0x0000 }, /* R660 */
758 { 0x0000, 0x0000, 0x0000 }, /* R661 */
759 { 0x0000, 0x0000, 0x0000 }, /* R662 */
760 { 0x0000, 0x0000, 0x0000 }, /* R663 */
761 { 0x0000, 0x0000, 0x0000 }, /* R664 */
762 { 0x0000, 0x0000, 0x0000 }, /* R665 */
763 { 0x0000, 0x0000, 0x0000 }, /* R666 */
764 { 0x0000, 0x0000, 0x0000 }, /* R667 */
765 { 0x0000, 0x0000, 0x0000 }, /* R668 */
766 { 0x0000, 0x0000, 0x0000 }, /* R669 */
767 { 0x0000, 0x0000, 0x0000 }, /* R670 */
768 { 0x0000, 0x0000, 0x0000 }, /* R671 */
769 { 0x0000, 0x0000, 0x0000 }, /* R672 */
770 { 0x0000, 0x0000, 0x0000 }, /* R673 */
771 { 0x0000, 0x0000, 0x0000 }, /* R674 */
772 { 0x0000, 0x0000, 0x0000 }, /* R675 */
773 { 0x0000, 0x0000, 0x0000 }, /* R676 */
774 { 0x0000, 0x0000, 0x0000 }, /* R677 */
775 { 0x0000, 0x0000, 0x0000 }, /* R678 */
776 { 0x0000, 0x0000, 0x0000 }, /* R679 */
777 { 0x0000, 0x0000, 0x0000 }, /* R680 */
778 { 0x0000, 0x0000, 0x0000 }, /* R681 */
779 { 0x0000, 0x0000, 0x0000 }, /* R682 */
780 { 0x0000, 0x0000, 0x0000 }, /* R683 */
781 { 0x0000, 0x0000, 0x0000 }, /* R684 */
782 { 0x0000, 0x0000, 0x0000 }, /* R685 */
783 { 0x0000, 0x0000, 0x0000 }, /* R686 */
784 { 0x0000, 0x0000, 0x0000 }, /* R687 */
785 { 0x0000, 0x0000, 0x0000 }, /* R688 */
786 { 0x0000, 0x0000, 0x0000 }, /* R689 */
787 { 0x0000, 0x0000, 0x0000 }, /* R690 */
788 { 0x0000, 0x0000, 0x0000 }, /* R691 */
789 { 0x0000, 0x0000, 0x0000 }, /* R692 */
790 { 0x0000, 0x0000, 0x0000 }, /* R693 */
791 { 0x0000, 0x0000, 0x0000 }, /* R694 */
792 { 0x0000, 0x0000, 0x0000 }, /* R695 */
793 { 0x0000, 0x0000, 0x0000 }, /* R696 */
794 { 0x0000, 0x0000, 0x0000 }, /* R697 */
795 { 0x0000, 0x0000, 0x0000 }, /* R698 */
796 { 0x0000, 0x0000, 0x0000 }, /* R699 */
797 { 0x0000, 0x0000, 0x0000 }, /* R700 */
798 { 0x0000, 0x0000, 0x0000 }, /* R701 */
799 { 0x0000, 0x0000, 0x0000 }, /* R702 */
800 { 0x0000, 0x0000, 0x0000 }, /* R703 */
801 { 0x0000, 0x0000, 0x0000 }, /* R704 */
802 { 0x0000, 0x0000, 0x0000 }, /* R705 */
803 { 0x0000, 0x0000, 0x0000 }, /* R706 */
804 { 0x0000, 0x0000, 0x0000 }, /* R707 */
805 { 0x0000, 0x0000, 0x0000 }, /* R708 */
806 { 0x0000, 0x0000, 0x0000 }, /* R709 */
807 { 0x0000, 0x0000, 0x0000 }, /* R710 */
808 { 0x0000, 0x0000, 0x0000 }, /* R711 */
809 { 0x0000, 0x0000, 0x0000 }, /* R712 */
810 { 0x0000, 0x0000, 0x0000 }, /* R713 */
811 { 0x0000, 0x0000, 0x0000 }, /* R714 */
812 { 0x0000, 0x0000, 0x0000 }, /* R715 */
813 { 0x0000, 0x0000, 0x0000 }, /* R716 */
814 { 0x0000, 0x0000, 0x0000 }, /* R717 */
815 { 0x0000, 0x0000, 0x0000 }, /* R718 */
816 { 0x0000, 0x0000, 0x0000 }, /* R719 */
817 { 0x0000, 0x0000, 0x0000 }, /* R720 */
818 { 0x0000, 0x0000, 0x0000 }, /* R721 */
819 { 0x0000, 0x0000, 0x0000 }, /* R722 */
820 { 0x0000, 0x0000, 0x0000 }, /* R723 */
821 { 0x0000, 0x0000, 0x0000 }, /* R724 */
822 { 0x0000, 0x0000, 0x0000 }, /* R725 */
823 { 0x0000, 0x0000, 0x0000 }, /* R726 */
824 { 0x0000, 0x0000, 0x0000 }, /* R727 */
825 { 0x0000, 0x0000, 0x0000 }, /* R728 */
826 { 0x0000, 0x0000, 0x0000 }, /* R729 */
827 { 0x0000, 0x0000, 0x0000 }, /* R730 */
828 { 0x0000, 0x0000, 0x0000 }, /* R731 */
829 { 0x0000, 0x0000, 0x0000 }, /* R732 */
830 { 0x0000, 0x0000, 0x0000 }, /* R733 */
831 { 0x0000, 0x0000, 0x0000 }, /* R734 */
832 { 0x0000, 0x0000, 0x0000 }, /* R735 */
833 { 0x0000, 0x0000, 0x0000 }, /* R736 */
834 { 0x0000, 0x0000, 0x0000 }, /* R737 */
835 { 0x0000, 0x0000, 0x0000 }, /* R738 */
836 { 0x0000, 0x0000, 0x0000 }, /* R739 */
837 { 0x0000, 0x0000, 0x0000 }, /* R740 */
838 { 0x0000, 0x0000, 0x0000 }, /* R741 */
839 { 0x0000, 0x0000, 0x0000 }, /* R742 */
840 { 0x0000, 0x0000, 0x0000 }, /* R743 */
841 { 0x0000, 0x0000, 0x0000 }, /* R744 */
842 { 0x0000, 0x0000, 0x0000 }, /* R745 */
843 { 0x0000, 0x0000, 0x0000 }, /* R746 */
844 { 0x0000, 0x0000, 0x0000 }, /* R747 */
845 { 0x0000, 0x0000, 0x0000 }, /* R748 */
846 { 0x0000, 0x0000, 0x0000 }, /* R749 */
847 { 0x0000, 0x0000, 0x0000 }, /* R750 */
848 { 0x0000, 0x0000, 0x0000 }, /* R751 */
849 { 0x0000, 0x0000, 0x0000 }, /* R752 */
850 { 0x0000, 0x0000, 0x0000 }, /* R753 */
851 { 0x0000, 0x0000, 0x0000 }, /* R754 */
852 { 0x0000, 0x0000, 0x0000 }, /* R755 */
853 { 0x0000, 0x0000, 0x0000 }, /* R756 */
854 { 0x0000, 0x0000, 0x0000 }, /* R757 */
855 { 0x0000, 0x0000, 0x0000 }, /* R758 */
856 { 0x0000, 0x0000, 0x0000 }, /* R759 */
857 { 0x0000, 0x0000, 0x0000 }, /* R760 */
858 { 0x0000, 0x0000, 0x0000 }, /* R761 */
859 { 0x0000, 0x0000, 0x0000 }, /* R762 */
860 { 0x0000, 0x0000, 0x0000 }, /* R763 */
861 { 0x0000, 0x0000, 0x0000 }, /* R764 */
862 { 0x0000, 0x0000, 0x0000 }, /* R765 */
863 { 0x0000, 0x0000, 0x0000 }, /* R766 */
864 { 0x0000, 0x0000, 0x0000 }, /* R767 */
865 { 0xE1F8, 0xE1F8, 0x0000 }, /* R768 - AIF1 Control (1) */
866 { 0xCD1F, 0xCD1F, 0x0000 }, /* R769 - AIF1 Control (2) */
867 { 0xF000, 0xF000, 0x0000 }, /* R770 - AIF1 Master/Slave */
868 { 0x01F0, 0x01F0, 0x0000 }, /* R771 - AIF1 BCLK */
869 { 0x0FFF, 0x0FFF, 0x0000 }, /* R772 - AIF1ADC LRCLK */
870 { 0x0FFF, 0x0FFF, 0x0000 }, /* R773 - AIF1DAC LRCLK */
871 { 0x0003, 0x0003, 0x0000 }, /* R774 - AIF1DAC Data */
872 { 0x0003, 0x0003, 0x0000 }, /* R775 - AIF1ADC Data */
873 { 0x0000, 0x0000, 0x0000 }, /* R776 */
874 { 0x0000, 0x0000, 0x0000 }, /* R777 */
875 { 0x0000, 0x0000, 0x0000 }, /* R778 */
876 { 0x0000, 0x0000, 0x0000 }, /* R779 */
877 { 0x0000, 0x0000, 0x0000 }, /* R780 */
878 { 0x0000, 0x0000, 0x0000 }, /* R781 */
879 { 0x0000, 0x0000, 0x0000 }, /* R782 */
880 { 0x0000, 0x0000, 0x0000 }, /* R783 */
881 { 0xF1F8, 0xF1F8, 0x0000 }, /* R784 - AIF2 Control (1) */
882 { 0xFD1F, 0xFD1F, 0x0000 }, /* R785 - AIF2 Control (2) */
883 { 0xF000, 0xF000, 0x0000 }, /* R786 - AIF2 Master/Slave */
884 { 0x01F0, 0x01F0, 0x0000 }, /* R787 - AIF2 BCLK */
885 { 0x0FFF, 0x0FFF, 0x0000 }, /* R788 - AIF2ADC LRCLK */
886 { 0x0FFF, 0x0FFF, 0x0000 }, /* R789 - AIF2DAC LRCLK */
887 { 0x0003, 0x0003, 0x0000 }, /* R790 - AIF2DAC Data */
888 { 0x0003, 0x0003, 0x0000 }, /* R791 - AIF2ADC Data */
889 { 0x0000, 0x0000, 0x0000 }, /* R792 */
890 { 0x0000, 0x0000, 0x0000 }, /* R793 */
891 { 0x0000, 0x0000, 0x0000 }, /* R794 */
892 { 0x0000, 0x0000, 0x0000 }, /* R795 */
893 { 0x0000, 0x0000, 0x0000 }, /* R796 */
894 { 0x0000, 0x0000, 0x0000 }, /* R797 */
895 { 0x0000, 0x0000, 0x0000 }, /* R798 */
896 { 0x0000, 0x0000, 0x0000 }, /* R799 */
897 { 0x0000, 0x0000, 0x0000 }, /* R800 */
898 { 0x0000, 0x0000, 0x0000 }, /* R801 */
899 { 0x0000, 0x0000, 0x0000 }, /* R802 */
900 { 0x0000, 0x0000, 0x0000 }, /* R803 */
901 { 0x0000, 0x0000, 0x0000 }, /* R804 */
902 { 0x0000, 0x0000, 0x0000 }, /* R805 */
903 { 0x0000, 0x0000, 0x0000 }, /* R806 */
904 { 0x0000, 0x0000, 0x0000 }, /* R807 */
905 { 0x0000, 0x0000, 0x0000 }, /* R808 */
906 { 0x0000, 0x0000, 0x0000 }, /* R809 */
907 { 0x0000, 0x0000, 0x0000 }, /* R810 */
908 { 0x0000, 0x0000, 0x0000 }, /* R811 */
909 { 0x0000, 0x0000, 0x0000 }, /* R812 */
910 { 0x0000, 0x0000, 0x0000 }, /* R813 */
911 { 0x0000, 0x0000, 0x0000 }, /* R814 */
912 { 0x0000, 0x0000, 0x0000 }, /* R815 */
913 { 0x0000, 0x0000, 0x0000 }, /* R816 */
914 { 0x0000, 0x0000, 0x0000 }, /* R817 */
915 { 0x0000, 0x0000, 0x0000 }, /* R818 */
916 { 0x0000, 0x0000, 0x0000 }, /* R819 */
917 { 0x0000, 0x0000, 0x0000 }, /* R820 */
918 { 0x0000, 0x0000, 0x0000 }, /* R821 */
919 { 0x0000, 0x0000, 0x0000 }, /* R822 */
920 { 0x0000, 0x0000, 0x0000 }, /* R823 */
921 { 0x0000, 0x0000, 0x0000 }, /* R824 */
922 { 0x0000, 0x0000, 0x0000 }, /* R825 */
923 { 0x0000, 0x0000, 0x0000 }, /* R826 */
924 { 0x0000, 0x0000, 0x0000 }, /* R827 */
925 { 0x0000, 0x0000, 0x0000 }, /* R828 */
926 { 0x0000, 0x0000, 0x0000 }, /* R829 */
927 { 0x0000, 0x0000, 0x0000 }, /* R830 */
928 { 0x0000, 0x0000, 0x0000 }, /* R831 */
929 { 0x0000, 0x0000, 0x0000 }, /* R832 */
930 { 0x0000, 0x0000, 0x0000 }, /* R833 */
931 { 0x0000, 0x0000, 0x0000 }, /* R834 */
932 { 0x0000, 0x0000, 0x0000 }, /* R835 */
933 { 0x0000, 0x0000, 0x0000 }, /* R836 */
934 { 0x0000, 0x0000, 0x0000 }, /* R837 */
935 { 0x0000, 0x0000, 0x0000 }, /* R838 */
936 { 0x0000, 0x0000, 0x0000 }, /* R839 */
937 { 0x0000, 0x0000, 0x0000 }, /* R840 */
938 { 0x0000, 0x0000, 0x0000 }, /* R841 */
939 { 0x0000, 0x0000, 0x0000 }, /* R842 */
940 { 0x0000, 0x0000, 0x0000 }, /* R843 */
941 { 0x0000, 0x0000, 0x0000 }, /* R844 */
942 { 0x0000, 0x0000, 0x0000 }, /* R845 */
943 { 0x0000, 0x0000, 0x0000 }, /* R846 */
944 { 0x0000, 0x0000, 0x0000 }, /* R847 */
945 { 0x0000, 0x0000, 0x0000 }, /* R848 */
946 { 0x0000, 0x0000, 0x0000 }, /* R849 */
947 { 0x0000, 0x0000, 0x0000 }, /* R850 */
948 { 0x0000, 0x0000, 0x0000 }, /* R851 */
949 { 0x0000, 0x0000, 0x0000 }, /* R852 */
950 { 0x0000, 0x0000, 0x0000 }, /* R853 */
951 { 0x0000, 0x0000, 0x0000 }, /* R854 */
952 { 0x0000, 0x0000, 0x0000 }, /* R855 */
953 { 0x0000, 0x0000, 0x0000 }, /* R856 */
954 { 0x0000, 0x0000, 0x0000 }, /* R857 */
955 { 0x0000, 0x0000, 0x0000 }, /* R858 */
956 { 0x0000, 0x0000, 0x0000 }, /* R859 */
957 { 0x0000, 0x0000, 0x0000 }, /* R860 */
958 { 0x0000, 0x0000, 0x0000 }, /* R861 */
959 { 0x0000, 0x0000, 0x0000 }, /* R862 */
960 { 0x0000, 0x0000, 0x0000 }, /* R863 */
961 { 0x0000, 0x0000, 0x0000 }, /* R864 */
962 { 0x0000, 0x0000, 0x0000 }, /* R865 */
963 { 0x0000, 0x0000, 0x0000 }, /* R866 */
964 { 0x0000, 0x0000, 0x0000 }, /* R867 */
965 { 0x0000, 0x0000, 0x0000 }, /* R868 */
966 { 0x0000, 0x0000, 0x0000 }, /* R869 */
967 { 0x0000, 0x0000, 0x0000 }, /* R870 */
968 { 0x0000, 0x0000, 0x0000 }, /* R871 */
969 { 0x0000, 0x0000, 0x0000 }, /* R872 */
970 { 0x0000, 0x0000, 0x0000 }, /* R873 */
971 { 0x0000, 0x0000, 0x0000 }, /* R874 */
972 { 0x0000, 0x0000, 0x0000 }, /* R875 */
973 { 0x0000, 0x0000, 0x0000 }, /* R876 */
974 { 0x0000, 0x0000, 0x0000 }, /* R877 */
975 { 0x0000, 0x0000, 0x0000 }, /* R878 */
976 { 0x0000, 0x0000, 0x0000 }, /* R879 */
977 { 0x0000, 0x0000, 0x0000 }, /* R880 */
978 { 0x0000, 0x0000, 0x0000 }, /* R881 */
979 { 0x0000, 0x0000, 0x0000 }, /* R882 */
980 { 0x0000, 0x0000, 0x0000 }, /* R883 */
981 { 0x0000, 0x0000, 0x0000 }, /* R884 */
982 { 0x0000, 0x0000, 0x0000 }, /* R885 */
983 { 0x0000, 0x0000, 0x0000 }, /* R886 */
984 { 0x0000, 0x0000, 0x0000 }, /* R887 */
985 { 0x0000, 0x0000, 0x0000 }, /* R888 */
986 { 0x0000, 0x0000, 0x0000 }, /* R889 */
987 { 0x0000, 0x0000, 0x0000 }, /* R890 */
988 { 0x0000, 0x0000, 0x0000 }, /* R891 */
989 { 0x0000, 0x0000, 0x0000 }, /* R892 */
990 { 0x0000, 0x0000, 0x0000 }, /* R893 */
991 { 0x0000, 0x0000, 0x0000 }, /* R894 */
992 { 0x0000, 0x0000, 0x0000 }, /* R895 */
993 { 0x0000, 0x0000, 0x0000 }, /* R896 */
994 { 0x0000, 0x0000, 0x0000 }, /* R897 */
995 { 0x0000, 0x0000, 0x0000 }, /* R898 */
996 { 0x0000, 0x0000, 0x0000 }, /* R899 */
997 { 0x0000, 0x0000, 0x0000 }, /* R900 */
998 { 0x0000, 0x0000, 0x0000 }, /* R901 */
999 { 0x0000, 0x0000, 0x0000 }, /* R902 */
1000 { 0x0000, 0x0000, 0x0000 }, /* R903 */
1001 { 0x0000, 0x0000, 0x0000 }, /* R904 */
1002 { 0x0000, 0x0000, 0x0000 }, /* R905 */
1003 { 0x0000, 0x0000, 0x0000 }, /* R906 */
1004 { 0x0000, 0x0000, 0x0000 }, /* R907 */
1005 { 0x0000, 0x0000, 0x0000 }, /* R908 */
1006 { 0x0000, 0x0000, 0x0000 }, /* R909 */
1007 { 0x0000, 0x0000, 0x0000 }, /* R910 */
1008 { 0x0000, 0x0000, 0x0000 }, /* R911 */
1009 { 0x0000, 0x0000, 0x0000 }, /* R912 */
1010 { 0x0000, 0x0000, 0x0000 }, /* R913 */
1011 { 0x0000, 0x0000, 0x0000 }, /* R914 */
1012 { 0x0000, 0x0000, 0x0000 }, /* R915 */
1013 { 0x0000, 0x0000, 0x0000 }, /* R916 */
1014 { 0x0000, 0x0000, 0x0000 }, /* R917 */
1015 { 0x0000, 0x0000, 0x0000 }, /* R918 */
1016 { 0x0000, 0x0000, 0x0000 }, /* R919 */
1017 { 0x0000, 0x0000, 0x0000 }, /* R920 */
1018 { 0x0000, 0x0000, 0x0000 }, /* R921 */
1019 { 0x0000, 0x0000, 0x0000 }, /* R922 */
1020 { 0x0000, 0x0000, 0x0000 }, /* R923 */
1021 { 0x0000, 0x0000, 0x0000 }, /* R924 */
1022 { 0x0000, 0x0000, 0x0000 }, /* R925 */
1023 { 0x0000, 0x0000, 0x0000 }, /* R926 */
1024 { 0x0000, 0x0000, 0x0000 }, /* R927 */
1025 { 0x0000, 0x0000, 0x0000 }, /* R928 */
1026 { 0x0000, 0x0000, 0x0000 }, /* R929 */
1027 { 0x0000, 0x0000, 0x0000 }, /* R930 */
1028 { 0x0000, 0x0000, 0x0000 }, /* R931 */
1029 { 0x0000, 0x0000, 0x0000 }, /* R932 */
1030 { 0x0000, 0x0000, 0x0000 }, /* R933 */
1031 { 0x0000, 0x0000, 0x0000 }, /* R934 */
1032 { 0x0000, 0x0000, 0x0000 }, /* R935 */
1033 { 0x0000, 0x0000, 0x0000 }, /* R936 */
1034 { 0x0000, 0x0000, 0x0000 }, /* R937 */
1035 { 0x0000, 0x0000, 0x0000 }, /* R938 */
1036 { 0x0000, 0x0000, 0x0000 }, /* R939 */
1037 { 0x0000, 0x0000, 0x0000 }, /* R940 */
1038 { 0x0000, 0x0000, 0x0000 }, /* R941 */
1039 { 0x0000, 0x0000, 0x0000 }, /* R942 */
1040 { 0x0000, 0x0000, 0x0000 }, /* R943 */
1041 { 0x0000, 0x0000, 0x0000 }, /* R944 */
1042 { 0x0000, 0x0000, 0x0000 }, /* R945 */
1043 { 0x0000, 0x0000, 0x0000 }, /* R946 */
1044 { 0x0000, 0x0000, 0x0000 }, /* R947 */
1045 { 0x0000, 0x0000, 0x0000 }, /* R948 */
1046 { 0x0000, 0x0000, 0x0000 }, /* R949 */
1047 { 0x0000, 0x0000, 0x0000 }, /* R950 */
1048 { 0x0000, 0x0000, 0x0000 }, /* R951 */
1049 { 0x0000, 0x0000, 0x0000 }, /* R952 */
1050 { 0x0000, 0x0000, 0x0000 }, /* R953 */
1051 { 0x0000, 0x0000, 0x0000 }, /* R954 */
1052 { 0x0000, 0x0000, 0x0000 }, /* R955 */
1053 { 0x0000, 0x0000, 0x0000 }, /* R956 */
1054 { 0x0000, 0x0000, 0x0000 }, /* R957 */
1055 { 0x0000, 0x0000, 0x0000 }, /* R958 */
1056 { 0x0000, 0x0000, 0x0000 }, /* R959 */
1057 { 0x0000, 0x0000, 0x0000 }, /* R960 */
1058 { 0x0000, 0x0000, 0x0000 }, /* R961 */
1059 { 0x0000, 0x0000, 0x0000 }, /* R962 */
1060 { 0x0000, 0x0000, 0x0000 }, /* R963 */
1061 { 0x0000, 0x0000, 0x0000 }, /* R964 */
1062 { 0x0000, 0x0000, 0x0000 }, /* R965 */
1063 { 0x0000, 0x0000, 0x0000 }, /* R966 */
1064 { 0x0000, 0x0000, 0x0000 }, /* R967 */
1065 { 0x0000, 0x0000, 0x0000 }, /* R968 */
1066 { 0x0000, 0x0000, 0x0000 }, /* R969 */
1067 { 0x0000, 0x0000, 0x0000 }, /* R970 */
1068 { 0x0000, 0x0000, 0x0000 }, /* R971 */
1069 { 0x0000, 0x0000, 0x0000 }, /* R972 */
1070 { 0x0000, 0x0000, 0x0000 }, /* R973 */
1071 { 0x0000, 0x0000, 0x0000 }, /* R974 */
1072 { 0x0000, 0x0000, 0x0000 }, /* R975 */
1073 { 0x0000, 0x0000, 0x0000 }, /* R976 */
1074 { 0x0000, 0x0000, 0x0000 }, /* R977 */
1075 { 0x0000, 0x0000, 0x0000 }, /* R978 */
1076 { 0x0000, 0x0000, 0x0000 }, /* R979 */
1077 { 0x0000, 0x0000, 0x0000 }, /* R980 */
1078 { 0x0000, 0x0000, 0x0000 }, /* R981 */
1079 { 0x0000, 0x0000, 0x0000 }, /* R982 */
1080 { 0x0000, 0x0000, 0x0000 }, /* R983 */
1081 { 0x0000, 0x0000, 0x0000 }, /* R984 */
1082 { 0x0000, 0x0000, 0x0000 }, /* R985 */
1083 { 0x0000, 0x0000, 0x0000 }, /* R986 */
1084 { 0x0000, 0x0000, 0x0000 }, /* R987 */
1085 { 0x0000, 0x0000, 0x0000 }, /* R988 */
1086 { 0x0000, 0x0000, 0x0000 }, /* R989 */
1087 { 0x0000, 0x0000, 0x0000 }, /* R990 */
1088 { 0x0000, 0x0000, 0x0000 }, /* R991 */
1089 { 0x0000, 0x0000, 0x0000 }, /* R992 */
1090 { 0x0000, 0x0000, 0x0000 }, /* R993 */
1091 { 0x0000, 0x0000, 0x0000 }, /* R994 */
1092 { 0x0000, 0x0000, 0x0000 }, /* R995 */
1093 { 0x0000, 0x0000, 0x0000 }, /* R996 */
1094 { 0x0000, 0x0000, 0x0000 }, /* R997 */
1095 { 0x0000, 0x0000, 0x0000 }, /* R998 */
1096 { 0x0000, 0x0000, 0x0000 }, /* R999 */
1097 { 0x0000, 0x0000, 0x0000 }, /* R1000 */
1098 { 0x0000, 0x0000, 0x0000 }, /* R1001 */
1099 { 0x0000, 0x0000, 0x0000 }, /* R1002 */
1100 { 0x0000, 0x0000, 0x0000 }, /* R1003 */
1101 { 0x0000, 0x0000, 0x0000 }, /* R1004 */
1102 { 0x0000, 0x0000, 0x0000 }, /* R1005 */
1103 { 0x0000, 0x0000, 0x0000 }, /* R1006 */
1104 { 0x0000, 0x0000, 0x0000 }, /* R1007 */
1105 { 0x0000, 0x0000, 0x0000 }, /* R1008 */
1106 { 0x0000, 0x0000, 0x0000 }, /* R1009 */
1107 { 0x0000, 0x0000, 0x0000 }, /* R1010 */
1108 { 0x0000, 0x0000, 0x0000 }, /* R1011 */
1109 { 0x0000, 0x0000, 0x0000 }, /* R1012 */
1110 { 0x0000, 0x0000, 0x0000 }, /* R1013 */
1111 { 0x0000, 0x0000, 0x0000 }, /* R1014 */
1112 { 0x0000, 0x0000, 0x0000 }, /* R1015 */
1113 { 0x0000, 0x0000, 0x0000 }, /* R1016 */
1114 { 0x0000, 0x0000, 0x0000 }, /* R1017 */
1115 { 0x0000, 0x0000, 0x0000 }, /* R1018 */
1116 { 0x0000, 0x0000, 0x0000 }, /* R1019 */
1117 { 0x0000, 0x0000, 0x0000 }, /* R1020 */
1118 { 0x0000, 0x0000, 0x0000 }, /* R1021 */
1119 { 0x0000, 0x0000, 0x0000 }, /* R1022 */
1120 { 0x0000, 0x0000, 0x0000 }, /* R1023 */
1121 { 0x00FF, 0x01FF, 0x0000 }, /* R1024 - AIF1 ADC1 Left Volume */
1122 { 0x00FF, 0x01FF, 0x0000 }, /* R1025 - AIF1 ADC1 Right Volume */
1123 { 0x00FF, 0x01FF, 0x0000 }, /* R1026 - AIF1 DAC1 Left Volume */
1124 { 0x00FF, 0x01FF, 0x0000 }, /* R1027 - AIF1 DAC1 Right Volume */
1125 { 0x00FF, 0x01FF, 0x0000 }, /* R1028 - AIF1 ADC2 Left Volume */
1126 { 0x00FF, 0x01FF, 0x0000 }, /* R1029 - AIF1 ADC2 Right Volume */
1127 { 0x00FF, 0x01FF, 0x0000 }, /* R1030 - AIF1 DAC2 Left Volume */
1128 { 0x00FF, 0x01FF, 0x0000 }, /* R1031 - AIF1 DAC2 Right Volume */
1129 { 0x0000, 0x0000, 0x0000 }, /* R1032 */
1130 { 0x0000, 0x0000, 0x0000 }, /* R1033 */
1131 { 0x0000, 0x0000, 0x0000 }, /* R1034 */
1132 { 0x0000, 0x0000, 0x0000 }, /* R1035 */
1133 { 0x0000, 0x0000, 0x0000 }, /* R1036 */
1134 { 0x0000, 0x0000, 0x0000 }, /* R1037 */
1135 { 0x0000, 0x0000, 0x0000 }, /* R1038 */
1136 { 0x0000, 0x0000, 0x0000 }, /* R1039 */
1137 { 0xF800, 0xF800, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
1138 { 0x7800, 0x7800, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
1139 { 0x0000, 0x0000, 0x0000 }, /* R1042 */
1140 { 0x0000, 0x0000, 0x0000 }, /* R1043 */
1141 { 0x0000, 0x0000, 0x0000 }, /* R1044 */
1142 { 0x0000, 0x0000, 0x0000 }, /* R1045 */
1143 { 0x0000, 0x0000, 0x0000 }, /* R1046 */
1144 { 0x0000, 0x0000, 0x0000 }, /* R1047 */
1145 { 0x0000, 0x0000, 0x0000 }, /* R1048 */
1146 { 0x0000, 0x0000, 0x0000 }, /* R1049 */
1147 { 0x0000, 0x0000, 0x0000 }, /* R1050 */
1148 { 0x0000, 0x0000, 0x0000 }, /* R1051 */
1149 { 0x0000, 0x0000, 0x0000 }, /* R1052 */
1150 { 0x0000, 0x0000, 0x0000 }, /* R1053 */
1151 { 0x0000, 0x0000, 0x0000 }, /* R1054 */
1152 { 0x0000, 0x0000, 0x0000 }, /* R1055 */
1153 { 0x02B6, 0x02B6, 0x0000 }, /* R1056 - AIF1 DAC1 Filters (1) */
1154 { 0x3F00, 0x3F00, 0x0000 }, /* R1057 - AIF1 DAC1 Filters (2) */
1155 { 0x02B6, 0x02B6, 0x0000 }, /* R1058 - AIF1 DAC2 Filters (1) */
1156 { 0x3F00, 0x3F00, 0x0000 }, /* R1059 - AIF1 DAC2 Filters (2) */
1157 { 0x0000, 0x0000, 0x0000 }, /* R1060 */
1158 { 0x0000, 0x0000, 0x0000 }, /* R1061 */
1159 { 0x0000, 0x0000, 0x0000 }, /* R1062 */
1160 { 0x0000, 0x0000, 0x0000 }, /* R1063 */
1161 { 0x0000, 0x0000, 0x0000 }, /* R1064 */
1162 { 0x0000, 0x0000, 0x0000 }, /* R1065 */
1163 { 0x0000, 0x0000, 0x0000 }, /* R1066 */
1164 { 0x0000, 0x0000, 0x0000 }, /* R1067 */
1165 { 0x0000, 0x0000, 0x0000 }, /* R1068 */
1166 { 0x0000, 0x0000, 0x0000 }, /* R1069 */
1167 { 0x0000, 0x0000, 0x0000 }, /* R1070 */
1168 { 0x0000, 0x0000, 0x0000 }, /* R1071 */
1169 { 0x0000, 0x0000, 0x0000 }, /* R1072 */
1170 { 0x0000, 0x0000, 0x0000 }, /* R1073 */
1171 { 0x0000, 0x0000, 0x0000 }, /* R1074 */
1172 { 0x0000, 0x0000, 0x0000 }, /* R1075 */
1173 { 0x0000, 0x0000, 0x0000 }, /* R1076 */
1174 { 0x0000, 0x0000, 0x0000 }, /* R1077 */
1175 { 0x0000, 0x0000, 0x0000 }, /* R1078 */
1176 { 0x0000, 0x0000, 0x0000 }, /* R1079 */
1177 { 0x0000, 0x0000, 0x0000 }, /* R1080 */
1178 { 0x0000, 0x0000, 0x0000 }, /* R1081 */
1179 { 0x0000, 0x0000, 0x0000 }, /* R1082 */
1180 { 0x0000, 0x0000, 0x0000 }, /* R1083 */
1181 { 0x0000, 0x0000, 0x0000 }, /* R1084 */
1182 { 0x0000, 0x0000, 0x0000 }, /* R1085 */
1183 { 0x0000, 0x0000, 0x0000 }, /* R1086 */
1184 { 0x0000, 0x0000, 0x0000 }, /* R1087 */
1185 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1088 - AIF1 DRC1 (1) */
1186 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1089 - AIF1 DRC1 (2) */
1187 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
1188 { 0x07FF, 0x07FF, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
1189 { 0x03FF, 0x03FF, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
1190 { 0x0000, 0x0000, 0x0000 }, /* R1093 */
1191 { 0x0000, 0x0000, 0x0000 }, /* R1094 */
1192 { 0x0000, 0x0000, 0x0000 }, /* R1095 */
1193 { 0x0000, 0x0000, 0x0000 }, /* R1096 */
1194 { 0x0000, 0x0000, 0x0000 }, /* R1097 */
1195 { 0x0000, 0x0000, 0x0000 }, /* R1098 */
1196 { 0x0000, 0x0000, 0x0000 }, /* R1099 */
1197 { 0x0000, 0x0000, 0x0000 }, /* R1100 */
1198 { 0x0000, 0x0000, 0x0000 }, /* R1101 */
1199 { 0x0000, 0x0000, 0x0000 }, /* R1102 */
1200 { 0x0000, 0x0000, 0x0000 }, /* R1103 */
1201 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1104 - AIF1 DRC2 (1) */
1202 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1105 - AIF1 DRC2 (2) */
1203 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
1204 { 0x07FF, 0x07FF, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
1205 { 0x03FF, 0x03FF, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
1206 { 0x0000, 0x0000, 0x0000 }, /* R1109 */
1207 { 0x0000, 0x0000, 0x0000 }, /* R1110 */
1208 { 0x0000, 0x0000, 0x0000 }, /* R1111 */
1209 { 0x0000, 0x0000, 0x0000 }, /* R1112 */
1210 { 0x0000, 0x0000, 0x0000 }, /* R1113 */
1211 { 0x0000, 0x0000, 0x0000 }, /* R1114 */
1212 { 0x0000, 0x0000, 0x0000 }, /* R1115 */
1213 { 0x0000, 0x0000, 0x0000 }, /* R1116 */
1214 { 0x0000, 0x0000, 0x0000 }, /* R1117 */
1215 { 0x0000, 0x0000, 0x0000 }, /* R1118 */
1216 { 0x0000, 0x0000, 0x0000 }, /* R1119 */
1217 { 0x0000, 0x0000, 0x0000 }, /* R1120 */
1218 { 0x0000, 0x0000, 0x0000 }, /* R1121 */
1219 { 0x0000, 0x0000, 0x0000 }, /* R1122 */
1220 { 0x0000, 0x0000, 0x0000 }, /* R1123 */
1221 { 0x0000, 0x0000, 0x0000 }, /* R1124 */
1222 { 0x0000, 0x0000, 0x0000 }, /* R1125 */
1223 { 0x0000, 0x0000, 0x0000 }, /* R1126 */
1224 { 0x0000, 0x0000, 0x0000 }, /* R1127 */
1225 { 0x0000, 0x0000, 0x0000 }, /* R1128 */
1226 { 0x0000, 0x0000, 0x0000 }, /* R1129 */
1227 { 0x0000, 0x0000, 0x0000 }, /* R1130 */
1228 { 0x0000, 0x0000, 0x0000 }, /* R1131 */
1229 { 0x0000, 0x0000, 0x0000 }, /* R1132 */
1230 { 0x0000, 0x0000, 0x0000 }, /* R1133 */
1231 { 0x0000, 0x0000, 0x0000 }, /* R1134 */
1232 { 0x0000, 0x0000, 0x0000 }, /* R1135 */
1233 { 0x0000, 0x0000, 0x0000 }, /* R1136 */
1234 { 0x0000, 0x0000, 0x0000 }, /* R1137 */
1235 { 0x0000, 0x0000, 0x0000 }, /* R1138 */
1236 { 0x0000, 0x0000, 0x0000 }, /* R1139 */
1237 { 0x0000, 0x0000, 0x0000 }, /* R1140 */
1238 { 0x0000, 0x0000, 0x0000 }, /* R1141 */
1239 { 0x0000, 0x0000, 0x0000 }, /* R1142 */
1240 { 0x0000, 0x0000, 0x0000 }, /* R1143 */
1241 { 0x0000, 0x0000, 0x0000 }, /* R1144 */
1242 { 0x0000, 0x0000, 0x0000 }, /* R1145 */
1243 { 0x0000, 0x0000, 0x0000 }, /* R1146 */
1244 { 0x0000, 0x0000, 0x0000 }, /* R1147 */
1245 { 0x0000, 0x0000, 0x0000 }, /* R1148 */
1246 { 0x0000, 0x0000, 0x0000 }, /* R1149 */
1247 { 0x0000, 0x0000, 0x0000 }, /* R1150 */
1248 { 0x0000, 0x0000, 0x0000 }, /* R1151 */
1249 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1250 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1251 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1252 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1253 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1254 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1255 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1256 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1257 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1258 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1259 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1260 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1261 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1262 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1263 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1264 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1265 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1266 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1267 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1268 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1269 { 0x0000, 0x0000, 0x0000 }, /* R1172 */
1270 { 0x0000, 0x0000, 0x0000 }, /* R1173 */
1271 { 0x0000, 0x0000, 0x0000 }, /* R1174 */
1272 { 0x0000, 0x0000, 0x0000 }, /* R1175 */
1273 { 0x0000, 0x0000, 0x0000 }, /* R1176 */
1274 { 0x0000, 0x0000, 0x0000 }, /* R1177 */
1275 { 0x0000, 0x0000, 0x0000 }, /* R1178 */
1276 { 0x0000, 0x0000, 0x0000 }, /* R1179 */
1277 { 0x0000, 0x0000, 0x0000 }, /* R1180 */
1278 { 0x0000, 0x0000, 0x0000 }, /* R1181 */
1279 { 0x0000, 0x0000, 0x0000 }, /* R1182 */
1280 { 0x0000, 0x0000, 0x0000 }, /* R1183 */
1281 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1282 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1283 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1284 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1285 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1286 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1287 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1288 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1289 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1290 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1291 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1292 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1293 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1294 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1295 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1296 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1297 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1298 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1299 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1300 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1301 { 0x0000, 0x0000, 0x0000 }, /* R1204 */
1302 { 0x0000, 0x0000, 0x0000 }, /* R1205 */
1303 { 0x0000, 0x0000, 0x0000 }, /* R1206 */
1304 { 0x0000, 0x0000, 0x0000 }, /* R1207 */
1305 { 0x0000, 0x0000, 0x0000 }, /* R1208 */
1306 { 0x0000, 0x0000, 0x0000 }, /* R1209 */
1307 { 0x0000, 0x0000, 0x0000 }, /* R1210 */
1308 { 0x0000, 0x0000, 0x0000 }, /* R1211 */
1309 { 0x0000, 0x0000, 0x0000 }, /* R1212 */
1310 { 0x0000, 0x0000, 0x0000 }, /* R1213 */
1311 { 0x0000, 0x0000, 0x0000 }, /* R1214 */
1312 { 0x0000, 0x0000, 0x0000 }, /* R1215 */
1313 { 0x0000, 0x0000, 0x0000 }, /* R1216 */
1314 { 0x0000, 0x0000, 0x0000 }, /* R1217 */
1315 { 0x0000, 0x0000, 0x0000 }, /* R1218 */
1316 { 0x0000, 0x0000, 0x0000 }, /* R1219 */
1317 { 0x0000, 0x0000, 0x0000 }, /* R1220 */
1318 { 0x0000, 0x0000, 0x0000 }, /* R1221 */
1319 { 0x0000, 0x0000, 0x0000 }, /* R1222 */
1320 { 0x0000, 0x0000, 0x0000 }, /* R1223 */
1321 { 0x0000, 0x0000, 0x0000 }, /* R1224 */
1322 { 0x0000, 0x0000, 0x0000 }, /* R1225 */
1323 { 0x0000, 0x0000, 0x0000 }, /* R1226 */
1324 { 0x0000, 0x0000, 0x0000 }, /* R1227 */
1325 { 0x0000, 0x0000, 0x0000 }, /* R1228 */
1326 { 0x0000, 0x0000, 0x0000 }, /* R1229 */
1327 { 0x0000, 0x0000, 0x0000 }, /* R1230 */
1328 { 0x0000, 0x0000, 0x0000 }, /* R1231 */
1329 { 0x0000, 0x0000, 0x0000 }, /* R1232 */
1330 { 0x0000, 0x0000, 0x0000 }, /* R1233 */
1331 { 0x0000, 0x0000, 0x0000 }, /* R1234 */
1332 { 0x0000, 0x0000, 0x0000 }, /* R1235 */
1333 { 0x0000, 0x0000, 0x0000 }, /* R1236 */
1334 { 0x0000, 0x0000, 0x0000 }, /* R1237 */
1335 { 0x0000, 0x0000, 0x0000 }, /* R1238 */
1336 { 0x0000, 0x0000, 0x0000 }, /* R1239 */
1337 { 0x0000, 0x0000, 0x0000 }, /* R1240 */
1338 { 0x0000, 0x0000, 0x0000 }, /* R1241 */
1339 { 0x0000, 0x0000, 0x0000 }, /* R1242 */
1340 { 0x0000, 0x0000, 0x0000 }, /* R1243 */
1341 { 0x0000, 0x0000, 0x0000 }, /* R1244 */
1342 { 0x0000, 0x0000, 0x0000 }, /* R1245 */
1343 { 0x0000, 0x0000, 0x0000 }, /* R1246 */
1344 { 0x0000, 0x0000, 0x0000 }, /* R1247 */
1345 { 0x0000, 0x0000, 0x0000 }, /* R1248 */
1346 { 0x0000, 0x0000, 0x0000 }, /* R1249 */
1347 { 0x0000, 0x0000, 0x0000 }, /* R1250 */
1348 { 0x0000, 0x0000, 0x0000 }, /* R1251 */
1349 { 0x0000, 0x0000, 0x0000 }, /* R1252 */
1350 { 0x0000, 0x0000, 0x0000 }, /* R1253 */
1351 { 0x0000, 0x0000, 0x0000 }, /* R1254 */
1352 { 0x0000, 0x0000, 0x0000 }, /* R1255 */
1353 { 0x0000, 0x0000, 0x0000 }, /* R1256 */
1354 { 0x0000, 0x0000, 0x0000 }, /* R1257 */
1355 { 0x0000, 0x0000, 0x0000 }, /* R1258 */
1356 { 0x0000, 0x0000, 0x0000 }, /* R1259 */
1357 { 0x0000, 0x0000, 0x0000 }, /* R1260 */
1358 { 0x0000, 0x0000, 0x0000 }, /* R1261 */
1359 { 0x0000, 0x0000, 0x0000 }, /* R1262 */
1360 { 0x0000, 0x0000, 0x0000 }, /* R1263 */
1361 { 0x0000, 0x0000, 0x0000 }, /* R1264 */
1362 { 0x0000, 0x0000, 0x0000 }, /* R1265 */
1363 { 0x0000, 0x0000, 0x0000 }, /* R1266 */
1364 { 0x0000, 0x0000, 0x0000 }, /* R1267 */
1365 { 0x0000, 0x0000, 0x0000 }, /* R1268 */
1366 { 0x0000, 0x0000, 0x0000 }, /* R1269 */
1367 { 0x0000, 0x0000, 0x0000 }, /* R1270 */
1368 { 0x0000, 0x0000, 0x0000 }, /* R1271 */
1369 { 0x0000, 0x0000, 0x0000 }, /* R1272 */
1370 { 0x0000, 0x0000, 0x0000 }, /* R1273 */
1371 { 0x0000, 0x0000, 0x0000 }, /* R1274 */
1372 { 0x0000, 0x0000, 0x0000 }, /* R1275 */
1373 { 0x0000, 0x0000, 0x0000 }, /* R1276 */
1374 { 0x0000, 0x0000, 0x0000 }, /* R1277 */
1375 { 0x0000, 0x0000, 0x0000 }, /* R1278 */
1376 { 0x0000, 0x0000, 0x0000 }, /* R1279 */
1377 { 0x00FF, 0x01FF, 0x0000 }, /* R1280 - AIF2 ADC Left Volume */
1378 { 0x00FF, 0x01FF, 0x0000 }, /* R1281 - AIF2 ADC Right Volume */
1379 { 0x00FF, 0x01FF, 0x0000 }, /* R1282 - AIF2 DAC Left Volume */
1380 { 0x00FF, 0x01FF, 0x0000 }, /* R1283 - AIF2 DAC Right Volume */
1381 { 0x0000, 0x0000, 0x0000 }, /* R1284 */
1382 { 0x0000, 0x0000, 0x0000 }, /* R1285 */
1383 { 0x0000, 0x0000, 0x0000 }, /* R1286 */
1384 { 0x0000, 0x0000, 0x0000 }, /* R1287 */
1385 { 0x0000, 0x0000, 0x0000 }, /* R1288 */
1386 { 0x0000, 0x0000, 0x0000 }, /* R1289 */
1387 { 0x0000, 0x0000, 0x0000 }, /* R1290 */
1388 { 0x0000, 0x0000, 0x0000 }, /* R1291 */
1389 { 0x0000, 0x0000, 0x0000 }, /* R1292 */
1390 { 0x0000, 0x0000, 0x0000 }, /* R1293 */
1391 { 0x0000, 0x0000, 0x0000 }, /* R1294 */
1392 { 0x0000, 0x0000, 0x0000 }, /* R1295 */
1393 { 0xF800, 0xF800, 0x0000 }, /* R1296 - AIF2 ADC Filters */
1394 { 0x0000, 0x0000, 0x0000 }, /* R1297 */
1395 { 0x0000, 0x0000, 0x0000 }, /* R1298 */
1396 { 0x0000, 0x0000, 0x0000 }, /* R1299 */
1397 { 0x0000, 0x0000, 0x0000 }, /* R1300 */
1398 { 0x0000, 0x0000, 0x0000 }, /* R1301 */
1399 { 0x0000, 0x0000, 0x0000 }, /* R1302 */
1400 { 0x0000, 0x0000, 0x0000 }, /* R1303 */
1401 { 0x0000, 0x0000, 0x0000 }, /* R1304 */
1402 { 0x0000, 0x0000, 0x0000 }, /* R1305 */
1403 { 0x0000, 0x0000, 0x0000 }, /* R1306 */
1404 { 0x0000, 0x0000, 0x0000 }, /* R1307 */
1405 { 0x0000, 0x0000, 0x0000 }, /* R1308 */
1406 { 0x0000, 0x0000, 0x0000 }, /* R1309 */
1407 { 0x0000, 0x0000, 0x0000 }, /* R1310 */
1408 { 0x0000, 0x0000, 0x0000 }, /* R1311 */
1409 { 0x02B6, 0x02B6, 0x0000 }, /* R1312 - AIF2 DAC Filters (1) */
1410 { 0x3F00, 0x3F00, 0x0000 }, /* R1313 - AIF2 DAC Filters (2) */
1411 { 0x0000, 0x0000, 0x0000 }, /* R1314 */
1412 { 0x0000, 0x0000, 0x0000 }, /* R1315 */
1413 { 0x0000, 0x0000, 0x0000 }, /* R1316 */
1414 { 0x0000, 0x0000, 0x0000 }, /* R1317 */
1415 { 0x0000, 0x0000, 0x0000 }, /* R1318 */
1416 { 0x0000, 0x0000, 0x0000 }, /* R1319 */
1417 { 0x0000, 0x0000, 0x0000 }, /* R1320 */
1418 { 0x0000, 0x0000, 0x0000 }, /* R1321 */
1419 { 0x0000, 0x0000, 0x0000 }, /* R1322 */
1420 { 0x0000, 0x0000, 0x0000 }, /* R1323 */
1421 { 0x0000, 0x0000, 0x0000 }, /* R1324 */
1422 { 0x0000, 0x0000, 0x0000 }, /* R1325 */
1423 { 0x0000, 0x0000, 0x0000 }, /* R1326 */
1424 { 0x0000, 0x0000, 0x0000 }, /* R1327 */
1425 { 0x0000, 0x0000, 0x0000 }, /* R1328 */
1426 { 0x0000, 0x0000, 0x0000 }, /* R1329 */
1427 { 0x0000, 0x0000, 0x0000 }, /* R1330 */
1428 { 0x0000, 0x0000, 0x0000 }, /* R1331 */
1429 { 0x0000, 0x0000, 0x0000 }, /* R1332 */
1430 { 0x0000, 0x0000, 0x0000 }, /* R1333 */
1431 { 0x0000, 0x0000, 0x0000 }, /* R1334 */
1432 { 0x0000, 0x0000, 0x0000 }, /* R1335 */
1433 { 0x0000, 0x0000, 0x0000 }, /* R1336 */
1434 { 0x0000, 0x0000, 0x0000 }, /* R1337 */
1435 { 0x0000, 0x0000, 0x0000 }, /* R1338 */
1436 { 0x0000, 0x0000, 0x0000 }, /* R1339 */
1437 { 0x0000, 0x0000, 0x0000 }, /* R1340 */
1438 { 0x0000, 0x0000, 0x0000 }, /* R1341 */
1439 { 0x0000, 0x0000, 0x0000 }, /* R1342 */
1440 { 0x0000, 0x0000, 0x0000 }, /* R1343 */
1441 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1344 - AIF2 DRC (1) */
1442 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1345 - AIF2 DRC (2) */
1443 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1346 - AIF2 DRC (3) */
1444 { 0x07FF, 0x07FF, 0x0000 }, /* R1347 - AIF2 DRC (4) */
1445 { 0x03FF, 0x03FF, 0x0000 }, /* R1348 - AIF2 DRC (5) */
1446 { 0x0000, 0x0000, 0x0000 }, /* R1349 */
1447 { 0x0000, 0x0000, 0x0000 }, /* R1350 */
1448 { 0x0000, 0x0000, 0x0000 }, /* R1351 */
1449 { 0x0000, 0x0000, 0x0000 }, /* R1352 */
1450 { 0x0000, 0x0000, 0x0000 }, /* R1353 */
1451 { 0x0000, 0x0000, 0x0000 }, /* R1354 */
1452 { 0x0000, 0x0000, 0x0000 }, /* R1355 */
1453 { 0x0000, 0x0000, 0x0000 }, /* R1356 */
1454 { 0x0000, 0x0000, 0x0000 }, /* R1357 */
1455 { 0x0000, 0x0000, 0x0000 }, /* R1358 */
1456 { 0x0000, 0x0000, 0x0000 }, /* R1359 */
1457 { 0x0000, 0x0000, 0x0000 }, /* R1360 */
1458 { 0x0000, 0x0000, 0x0000 }, /* R1361 */
1459 { 0x0000, 0x0000, 0x0000 }, /* R1362 */
1460 { 0x0000, 0x0000, 0x0000 }, /* R1363 */
1461 { 0x0000, 0x0000, 0x0000 }, /* R1364 */
1462 { 0x0000, 0x0000, 0x0000 }, /* R1365 */
1463 { 0x0000, 0x0000, 0x0000 }, /* R1366 */
1464 { 0x0000, 0x0000, 0x0000 }, /* R1367 */
1465 { 0x0000, 0x0000, 0x0000 }, /* R1368 */
1466 { 0x0000, 0x0000, 0x0000 }, /* R1369 */
1467 { 0x0000, 0x0000, 0x0000 }, /* R1370 */
1468 { 0x0000, 0x0000, 0x0000 }, /* R1371 */
1469 { 0x0000, 0x0000, 0x0000 }, /* R1372 */
1470 { 0x0000, 0x0000, 0x0000 }, /* R1373 */
1471 { 0x0000, 0x0000, 0x0000 }, /* R1374 */
1472 { 0x0000, 0x0000, 0x0000 }, /* R1375 */
1473 { 0x0000, 0x0000, 0x0000 }, /* R1376 */
1474 { 0x0000, 0x0000, 0x0000 }, /* R1377 */
1475 { 0x0000, 0x0000, 0x0000 }, /* R1378 */
1476 { 0x0000, 0x0000, 0x0000 }, /* R1379 */
1477 { 0x0000, 0x0000, 0x0000 }, /* R1380 */
1478 { 0x0000, 0x0000, 0x0000 }, /* R1381 */
1479 { 0x0000, 0x0000, 0x0000 }, /* R1382 */
1480 { 0x0000, 0x0000, 0x0000 }, /* R1383 */
1481 { 0x0000, 0x0000, 0x0000 }, /* R1384 */
1482 { 0x0000, 0x0000, 0x0000 }, /* R1385 */
1483 { 0x0000, 0x0000, 0x0000 }, /* R1386 */
1484 { 0x0000, 0x0000, 0x0000 }, /* R1387 */
1485 { 0x0000, 0x0000, 0x0000 }, /* R1388 */
1486 { 0x0000, 0x0000, 0x0000 }, /* R1389 */
1487 { 0x0000, 0x0000, 0x0000 }, /* R1390 */
1488 { 0x0000, 0x0000, 0x0000 }, /* R1391 */
1489 { 0x0000, 0x0000, 0x0000 }, /* R1392 */
1490 { 0x0000, 0x0000, 0x0000 }, /* R1393 */
1491 { 0x0000, 0x0000, 0x0000 }, /* R1394 */
1492 { 0x0000, 0x0000, 0x0000 }, /* R1395 */
1493 { 0x0000, 0x0000, 0x0000 }, /* R1396 */
1494 { 0x0000, 0x0000, 0x0000 }, /* R1397 */
1495 { 0x0000, 0x0000, 0x0000 }, /* R1398 */
1496 { 0x0000, 0x0000, 0x0000 }, /* R1399 */
1497 { 0x0000, 0x0000, 0x0000 }, /* R1400 */
1498 { 0x0000, 0x0000, 0x0000 }, /* R1401 */
1499 { 0x0000, 0x0000, 0x0000 }, /* R1402 */
1500 { 0x0000, 0x0000, 0x0000 }, /* R1403 */
1501 { 0x0000, 0x0000, 0x0000 }, /* R1404 */
1502 { 0x0000, 0x0000, 0x0000 }, /* R1405 */
1503 { 0x0000, 0x0000, 0x0000 }, /* R1406 */
1504 { 0x0000, 0x0000, 0x0000 }, /* R1407 */
1505 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1408 - AIF2 EQ Gains (1) */
1506 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1409 - AIF2 EQ Gains (2) */
1507 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1410 - AIF2 EQ Band 1 A */
1508 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1411 - AIF2 EQ Band 1 B */
1509 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1412 - AIF2 EQ Band 1 PG */
1510 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1413 - AIF2 EQ Band 2 A */
1511 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1414 - AIF2 EQ Band 2 B */
1512 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1415 - AIF2 EQ Band 2 C */
1513 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1416 - AIF2 EQ Band 2 PG */
1514 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1417 - AIF2 EQ Band 3 A */
1515 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1418 - AIF2 EQ Band 3 B */
1516 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1419 - AIF2 EQ Band 3 C */
1517 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1420 - AIF2 EQ Band 3 PG */
1518 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1421 - AIF2 EQ Band 4 A */
1519 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1422 - AIF2 EQ Band 4 B */
1520 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1423 - AIF2 EQ Band 4 C */
1521 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1424 - AIF2 EQ Band 4 PG */
1522 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1425 - AIF2 EQ Band 5 A */
1523 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1426 - AIF2 EQ Band 5 B */
1524 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1427 - AIF2 EQ Band 5 PG */
1525 { 0x0000, 0x0000, 0x0000 }, /* R1428 */
1526 { 0x0000, 0x0000, 0x0000 }, /* R1429 */
1527 { 0x0000, 0x0000, 0x0000 }, /* R1430 */
1528 { 0x0000, 0x0000, 0x0000 }, /* R1431 */
1529 { 0x0000, 0x0000, 0x0000 }, /* R1432 */
1530 { 0x0000, 0x0000, 0x0000 }, /* R1433 */
1531 { 0x0000, 0x0000, 0x0000 }, /* R1434 */
1532 { 0x0000, 0x0000, 0x0000 }, /* R1435 */
1533 { 0x0000, 0x0000, 0x0000 }, /* R1436 */
1534 { 0x0000, 0x0000, 0x0000 }, /* R1437 */
1535 { 0x0000, 0x0000, 0x0000 }, /* R1438 */
1536 { 0x0000, 0x0000, 0x0000 }, /* R1439 */
1537 { 0x0000, 0x0000, 0x0000 }, /* R1440 */
1538 { 0x0000, 0x0000, 0x0000 }, /* R1441 */
1539 { 0x0000, 0x0000, 0x0000 }, /* R1442 */
1540 { 0x0000, 0x0000, 0x0000 }, /* R1443 */
1541 { 0x0000, 0x0000, 0x0000 }, /* R1444 */
1542 { 0x0000, 0x0000, 0x0000 }, /* R1445 */
1543 { 0x0000, 0x0000, 0x0000 }, /* R1446 */
1544 { 0x0000, 0x0000, 0x0000 }, /* R1447 */
1545 { 0x0000, 0x0000, 0x0000 }, /* R1448 */
1546 { 0x0000, 0x0000, 0x0000 }, /* R1449 */
1547 { 0x0000, 0x0000, 0x0000 }, /* R1450 */
1548 { 0x0000, 0x0000, 0x0000 }, /* R1451 */
1549 { 0x0000, 0x0000, 0x0000 }, /* R1452 */
1550 { 0x0000, 0x0000, 0x0000 }, /* R1453 */
1551 { 0x0000, 0x0000, 0x0000 }, /* R1454 */
1552 { 0x0000, 0x0000, 0x0000 }, /* R1455 */
1553 { 0x0000, 0x0000, 0x0000 }, /* R1456 */
1554 { 0x0000, 0x0000, 0x0000 }, /* R1457 */
1555 { 0x0000, 0x0000, 0x0000 }, /* R1458 */
1556 { 0x0000, 0x0000, 0x0000 }, /* R1459 */
1557 { 0x0000, 0x0000, 0x0000 }, /* R1460 */
1558 { 0x0000, 0x0000, 0x0000 }, /* R1461 */
1559 { 0x0000, 0x0000, 0x0000 }, /* R1462 */
1560 { 0x0000, 0x0000, 0x0000 }, /* R1463 */
1561 { 0x0000, 0x0000, 0x0000 }, /* R1464 */
1562 { 0x0000, 0x0000, 0x0000 }, /* R1465 */
1563 { 0x0000, 0x0000, 0x0000 }, /* R1466 */
1564 { 0x0000, 0x0000, 0x0000 }, /* R1467 */
1565 { 0x0000, 0x0000, 0x0000 }, /* R1468 */
1566 { 0x0000, 0x0000, 0x0000 }, /* R1469 */
1567 { 0x0000, 0x0000, 0x0000 }, /* R1470 */
1568 { 0x0000, 0x0000, 0x0000 }, /* R1471 */
1569 { 0x0000, 0x0000, 0x0000 }, /* R1472 */
1570 { 0x0000, 0x0000, 0x0000 }, /* R1473 */
1571 { 0x0000, 0x0000, 0x0000 }, /* R1474 */
1572 { 0x0000, 0x0000, 0x0000 }, /* R1475 */
1573 { 0x0000, 0x0000, 0x0000 }, /* R1476 */
1574 { 0x0000, 0x0000, 0x0000 }, /* R1477 */
1575 { 0x0000, 0x0000, 0x0000 }, /* R1478 */
1576 { 0x0000, 0x0000, 0x0000 }, /* R1479 */
1577 { 0x0000, 0x0000, 0x0000 }, /* R1480 */
1578 { 0x0000, 0x0000, 0x0000 }, /* R1481 */
1579 { 0x0000, 0x0000, 0x0000 }, /* R1482 */
1580 { 0x0000, 0x0000, 0x0000 }, /* R1483 */
1581 { 0x0000, 0x0000, 0x0000 }, /* R1484 */
1582 { 0x0000, 0x0000, 0x0000 }, /* R1485 */
1583 { 0x0000, 0x0000, 0x0000 }, /* R1486 */
1584 { 0x0000, 0x0000, 0x0000 }, /* R1487 */
1585 { 0x0000, 0x0000, 0x0000 }, /* R1488 */
1586 { 0x0000, 0x0000, 0x0000 }, /* R1489 */
1587 { 0x0000, 0x0000, 0x0000 }, /* R1490 */
1588 { 0x0000, 0x0000, 0x0000 }, /* R1491 */
1589 { 0x0000, 0x0000, 0x0000 }, /* R1492 */
1590 { 0x0000, 0x0000, 0x0000 }, /* R1493 */
1591 { 0x0000, 0x0000, 0x0000 }, /* R1494 */
1592 { 0x0000, 0x0000, 0x0000 }, /* R1495 */
1593 { 0x0000, 0x0000, 0x0000 }, /* R1496 */
1594 { 0x0000, 0x0000, 0x0000 }, /* R1497 */
1595 { 0x0000, 0x0000, 0x0000 }, /* R1498 */
1596 { 0x0000, 0x0000, 0x0000 }, /* R1499 */
1597 { 0x0000, 0x0000, 0x0000 }, /* R1500 */
1598 { 0x0000, 0x0000, 0x0000 }, /* R1501 */
1599 { 0x0000, 0x0000, 0x0000 }, /* R1502 */
1600 { 0x0000, 0x0000, 0x0000 }, /* R1503 */
1601 { 0x0000, 0x0000, 0x0000 }, /* R1504 */
1602 { 0x0000, 0x0000, 0x0000 }, /* R1505 */
1603 { 0x0000, 0x0000, 0x0000 }, /* R1506 */
1604 { 0x0000, 0x0000, 0x0000 }, /* R1507 */
1605 { 0x0000, 0x0000, 0x0000 }, /* R1508 */
1606 { 0x0000, 0x0000, 0x0000 }, /* R1509 */
1607 { 0x0000, 0x0000, 0x0000 }, /* R1510 */
1608 { 0x0000, 0x0000, 0x0000 }, /* R1511 */
1609 { 0x0000, 0x0000, 0x0000 }, /* R1512 */
1610 { 0x0000, 0x0000, 0x0000 }, /* R1513 */
1611 { 0x0000, 0x0000, 0x0000 }, /* R1514 */
1612 { 0x0000, 0x0000, 0x0000 }, /* R1515 */
1613 { 0x0000, 0x0000, 0x0000 }, /* R1516 */
1614 { 0x0000, 0x0000, 0x0000 }, /* R1517 */
1615 { 0x0000, 0x0000, 0x0000 }, /* R1518 */
1616 { 0x0000, 0x0000, 0x0000 }, /* R1519 */
1617 { 0x0000, 0x0000, 0x0000 }, /* R1520 */
1618 { 0x0000, 0x0000, 0x0000 }, /* R1521 */
1619 { 0x0000, 0x0000, 0x0000 }, /* R1522 */
1620 { 0x0000, 0x0000, 0x0000 }, /* R1523 */
1621 { 0x0000, 0x0000, 0x0000 }, /* R1524 */
1622 { 0x0000, 0x0000, 0x0000 }, /* R1525 */
1623 { 0x0000, 0x0000, 0x0000 }, /* R1526 */
1624 { 0x0000, 0x0000, 0x0000 }, /* R1527 */
1625 { 0x0000, 0x0000, 0x0000 }, /* R1528 */
1626 { 0x0000, 0x0000, 0x0000 }, /* R1529 */
1627 { 0x0000, 0x0000, 0x0000 }, /* R1530 */
1628 { 0x0000, 0x0000, 0x0000 }, /* R1531 */
1629 { 0x0000, 0x0000, 0x0000 }, /* R1532 */
1630 { 0x0000, 0x0000, 0x0000 }, /* R1533 */
1631 { 0x0000, 0x0000, 0x0000 }, /* R1534 */
1632 { 0x0000, 0x0000, 0x0000 }, /* R1535 */
1633 { 0x01EF, 0x01EF, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
1634 { 0x0037, 0x0037, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
1635 { 0x0037, 0x0037, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
1636 { 0x01EF, 0x01EF, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
1637 { 0x0037, 0x0037, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
1638 { 0x0037, 0x0037, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
1639 { 0x0003, 0x0003, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1640 { 0x0003, 0x0003, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1641 { 0x0003, 0x0003, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1642 { 0x0003, 0x0003, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1643 { 0x0000, 0x0000, 0x0000 }, /* R1546 */
1644 { 0x0000, 0x0000, 0x0000 }, /* R1547 */
1645 { 0x0000, 0x0000, 0x0000 }, /* R1548 */
1646 { 0x0000, 0x0000, 0x0000 }, /* R1549 */
1647 { 0x0000, 0x0000, 0x0000 }, /* R1550 */
1648 { 0x0000, 0x0000, 0x0000 }, /* R1551 */
1649 { 0x02FF, 0x03FF, 0x0000 }, /* R1552 - DAC1 Left Volume */
1650 { 0x02FF, 0x03FF, 0x0000 }, /* R1553 - DAC1 Right Volume */
1651 { 0x02FF, 0x03FF, 0x0000 }, /* R1554 - DAC2 Left Volume */
1652 { 0x02FF, 0x03FF, 0x0000 }, /* R1555 - DAC2 Right Volume */
1653 { 0x0003, 0x0003, 0x0000 }, /* R1556 - DAC Softmute */
1654 { 0x0000, 0x0000, 0x0000 }, /* R1557 */
1655 { 0x0000, 0x0000, 0x0000 }, /* R1558 */
1656 { 0x0000, 0x0000, 0x0000 }, /* R1559 */
1657 { 0x0000, 0x0000, 0x0000 }, /* R1560 */
1658 { 0x0000, 0x0000, 0x0000 }, /* R1561 */
1659 { 0x0000, 0x0000, 0x0000 }, /* R1562 */
1660 { 0x0000, 0x0000, 0x0000 }, /* R1563 */
1661 { 0x0000, 0x0000, 0x0000 }, /* R1564 */
1662 { 0x0000, 0x0000, 0x0000 }, /* R1565 */
1663 { 0x0000, 0x0000, 0x0000 }, /* R1566 */
1664 { 0x0000, 0x0000, 0x0000 }, /* R1567 */
1665 { 0x0003, 0x0003, 0x0000 }, /* R1568 - Oversampling */
1666 { 0x03C3, 0x03C3, 0x0000 }, /* R1569 - Sidetone */
1667};
1668
1669static int wm8994_readable(unsigned int reg)
1670{
1671 if (reg >= ARRAY_SIZE(access_masks))
1672 return 0;
1673 return access_masks[reg].readable != 0;
1674}
1675
1676static int wm8994_volatile(unsigned int reg)
1677{
1678 if (reg >= WM8994_REG_CACHE_SIZE)
1679 return 1;
1680
1681 switch (reg) {
1682 case WM8994_SOFTWARE_RESET:
1683 case WM8994_CHIP_REVISION:
1684 case WM8994_DC_SERVO_1:
1685 case WM8994_DC_SERVO_READBACK:
1686 case WM8994_RATE_STATUS:
1687 case WM8994_LDO_1:
1688 case WM8994_LDO_2:
1689 return 1;
1690 default:
1691 return 0;
1692 }
1693}
1694
1695static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1696 unsigned int value)
1697{
1698 struct wm8994_priv *wm8994 = codec->private_data;
1699
1700 BUG_ON(reg > WM8994_MAX_REGISTER);
1701
1702 if (!wm8994_volatile(reg))
1703 wm8994->reg_cache[reg] = value;
1704
1705 return wm8994_reg_write(codec->control_data, reg, value);
1706}
1707
1708static unsigned int wm8994_read(struct snd_soc_codec *codec,
1709 unsigned int reg)
1710{
1711 u16 *reg_cache = codec->reg_cache;
1712
1713 BUG_ON(reg > WM8994_MAX_REGISTER);
1714
1715 if (wm8994_volatile(reg))
1716 return wm8994_reg_read(codec->control_data, reg);
1717 else
1718 return reg_cache[reg];
1719}
1720
1721static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1722{
1723 struct wm8994_priv *wm8994 = codec->private_data;
1724 int rate;
1725 int reg1 = 0;
1726 int offset;
1727
1728 if (aif)
1729 offset = 4;
1730 else
1731 offset = 0;
1732
1733 switch (wm8994->sysclk[aif]) {
1734 case WM8994_SYSCLK_MCLK1:
1735 rate = wm8994->mclk[0];
1736 break;
1737
1738 case WM8994_SYSCLK_MCLK2:
1739 reg1 |= 0x8;
1740 rate = wm8994->mclk[1];
1741 break;
1742
1743 case WM8994_SYSCLK_FLL1:
1744 reg1 |= 0x10;
1745 rate = wm8994->fll[0].out;
1746 break;
1747
1748 case WM8994_SYSCLK_FLL2:
1749 reg1 |= 0x18;
1750 rate = wm8994->fll[1].out;
1751 break;
1752
1753 default:
1754 return -EINVAL;
1755 }
1756
1757 if (rate >= 13500000) {
1758 rate /= 2;
1759 reg1 |= WM8994_AIF1CLK_DIV;
1760
1761 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
1762 aif + 1, rate);
1763 }
1764 wm8994->aifclk[aif] = rate;
1765
1766 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
1767 WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
1768 reg1);
1769
1770 return 0;
1771}
1772
1773static int configure_clock(struct snd_soc_codec *codec)
1774{
1775 struct wm8994_priv *wm8994 = codec->private_data;
1776 int old, new;
1777
1778 /* Bring up the AIF clocks first */
1779 configure_aif_clock(codec, 0);
1780 configure_aif_clock(codec, 1);
1781
1782 /* Then switch CLK_SYS over to the higher of them; a change
1783 * can only happen as a result of a clocking change which can
1784 * only be made outside of DAPM so we can safely redo the
1785 * clocking.
1786 */
1787
1788 /* If they're equal it doesn't matter which is used */
1789 if (wm8994->aifclk[0] == wm8994->aifclk[1])
1790 return 0;
1791
1792 if (wm8994->aifclk[0] < wm8994->aifclk[1])
1793 new = WM8994_SYSCLK_SRC;
1794 else
1795 new = 0;
1796
1797 old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC;
1798
1799 /* If there's no change then we're done. */
1800 if (old == new)
1801 return 0;
1802
1803 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
1804
1805 snd_soc_dapm_sync(codec);
1806
1807 return 0;
1808}
1809
1810static int check_clk_sys(struct snd_soc_dapm_widget *source,
1811 struct snd_soc_dapm_widget *sink)
1812{
1813 int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1);
1814 const char *clk;
1815
1816 /* Check what we're currently using for CLK_SYS */
1817 if (reg & WM8994_SYSCLK_SRC)
1818 clk = "AIF2CLK";
1819 else
1820 clk = "AIF1CLK";
1821
1822 return strcmp(source->name, clk) == 0;
1823}
1824
1825static const char *sidetone_hpf_text[] = {
1826 "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
1827};
1828
1829static const struct soc_enum sidetone_hpf =
1830 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
1831
1832static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
1833static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
1834static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
1835static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
1836static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1837
1838#define WM8994_DRC_SWITCH(xname, reg, shift) \
1839{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1840 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
1841 .put = wm8994_put_drc_sw, \
1842 .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
1843
1844static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1845 struct snd_ctl_elem_value *ucontrol)
1846{
1847 struct soc_mixer_control *mc =
1848 (struct soc_mixer_control *)kcontrol->private_value;
1849 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1850 int mask, ret;
1851
1852 /* Can't enable both ADC and DAC paths simultaneously */
1853 if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT)
1854 mask = WM8994_AIF1ADC1L_DRC_ENA_MASK |
1855 WM8994_AIF1ADC1R_DRC_ENA_MASK;
1856 else
1857 mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
1858
1859 ret = snd_soc_read(codec, mc->reg);
1860 if (ret < 0)
1861 return ret;
1862 if (ret & mask)
1863 return -EINVAL;
1864
1865 return snd_soc_put_volsw(kcontrol, ucontrol);
1866}
1867
1868
1869
1870static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1871{
1872 struct wm8994_priv *wm8994 = codec->private_data;
1873 struct wm8994_pdata *pdata = wm8994->pdata;
1874 int base = wm8994_drc_base[drc];
1875 int cfg = wm8994->drc_cfg[drc];
1876 int save, i;
1877
1878 /* Save any enables; the configuration should clear them. */
1879 save = snd_soc_read(codec, base);
1880 save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
1881 WM8994_AIF1ADC1R_DRC_ENA;
1882
1883 for (i = 0; i < WM8994_DRC_REGS; i++)
1884 snd_soc_update_bits(codec, base + i, 0xffff,
1885 pdata->drc_cfgs[cfg].regs[i]);
1886
1887 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA |
1888 WM8994_AIF1ADC1L_DRC_ENA |
1889 WM8994_AIF1ADC1R_DRC_ENA, save);
1890}
1891
1892/* Icky as hell but saves code duplication */
1893static int wm8994_get_drc(const char *name)
1894{
1895 if (strcmp(name, "AIF1DRC1 Mode") == 0)
1896 return 0;
1897 if (strcmp(name, "AIF1DRC2 Mode") == 0)
1898 return 1;
1899 if (strcmp(name, "AIF2DRC Mode") == 0)
1900 return 2;
1901 return -EINVAL;
1902}
1903
1904static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1905 struct snd_ctl_elem_value *ucontrol)
1906{
1907 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1908 struct wm8994_priv *wm8994 = codec->private_data;
1909 struct wm8994_pdata *pdata = wm8994->pdata;
1910 int drc = wm8994_get_drc(kcontrol->id.name);
1911 int value = ucontrol->value.integer.value[0];
1912
1913 if (drc < 0)
1914 return drc;
1915
1916 if (value >= pdata->num_drc_cfgs)
1917 return -EINVAL;
1918
1919 wm8994->drc_cfg[drc] = value;
1920
1921 wm8994_set_drc(codec, drc);
1922
1923 return 0;
1924}
1925
1926static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol)
1928{
1929 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1930 struct wm8994_priv *wm8994 = codec->private_data;
1931 int drc = wm8994_get_drc(kcontrol->id.name);
1932
1933 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
1934
1935 return 0;
1936}
1937
1938static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
1939{
1940 struct wm8994_priv *wm8994 = codec->private_data;
1941 struct wm8994_pdata *pdata = wm8994->pdata;
1942 int base = wm8994_retune_mobile_base[block];
1943 int iface, best, best_val, save, i, cfg;
1944
1945 if (!pdata || !wm8994->num_retune_mobile_texts)
1946 return;
1947
1948 switch (block) {
1949 case 0:
1950 case 1:
1951 iface = 0;
1952 break;
1953 case 2:
1954 iface = 1;
1955 break;
1956 default:
1957 return;
1958 }
1959
1960 /* Find the version of the currently selected configuration
1961 * with the nearest sample rate. */
1962 cfg = wm8994->retune_mobile_cfg[block];
1963 best = 0;
1964 best_val = INT_MAX;
1965 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
1966 if (strcmp(pdata->retune_mobile_cfgs[i].name,
1967 wm8994->retune_mobile_texts[cfg]) == 0 &&
1968 abs(pdata->retune_mobile_cfgs[i].rate
1969 - wm8994->dac_rates[iface]) < best_val) {
1970 best = i;
1971 best_val = abs(pdata->retune_mobile_cfgs[i].rate
1972 - wm8994->dac_rates[iface]);
1973 }
1974 }
1975
1976 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
1977 block,
1978 pdata->retune_mobile_cfgs[best].name,
1979 pdata->retune_mobile_cfgs[best].rate,
1980 wm8994->dac_rates[iface]);
1981
1982 /* The EQ will be disabled while reconfiguring it, remember the
1983 * current configuration.
1984 */
1985 save = snd_soc_read(codec, base);
1986 save &= WM8994_AIF1DAC1_EQ_ENA;
1987
1988 for (i = 0; i < WM8994_EQ_REGS; i++)
1989 snd_soc_update_bits(codec, base + i, 0xffff,
1990 pdata->retune_mobile_cfgs[best].regs[i]);
1991
1992 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save);
1993}
1994
1995/* Icky as hell but saves code duplication */
1996static int wm8994_get_retune_mobile_block(const char *name)
1997{
1998 if (strcmp(name, "AIF1.1 EQ Mode") == 0)
1999 return 0;
2000 if (strcmp(name, "AIF1.2 EQ Mode") == 0)
2001 return 1;
2002 if (strcmp(name, "AIF2 EQ Mode") == 0)
2003 return 2;
2004 return -EINVAL;
2005}
2006
2007static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2008 struct snd_ctl_elem_value *ucontrol)
2009{
2010 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2011 struct wm8994_priv *wm8994 = codec->private_data;
2012 struct wm8994_pdata *pdata = wm8994->pdata;
2013 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2014 int value = ucontrol->value.integer.value[0];
2015
2016 if (block < 0)
2017 return block;
2018
2019 if (value >= pdata->num_retune_mobile_cfgs)
2020 return -EINVAL;
2021
2022 wm8994->retune_mobile_cfg[block] = value;
2023
2024 wm8994_set_retune_mobile(codec, block);
2025
2026 return 0;
2027}
2028
2029static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2030 struct snd_ctl_elem_value *ucontrol)
2031{
2032 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2033 struct wm8994_priv *wm8994 = codec->private_data;
2034 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2035
2036 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
2037
2038 return 0;
2039}
2040
2041static const struct snd_kcontrol_new wm8994_snd_controls[] = {
2042SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
2043 WM8994_AIF1_ADC1_RIGHT_VOLUME,
2044 1, 119, 0, digital_tlv),
2045SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
2046 WM8994_AIF1_ADC2_RIGHT_VOLUME,
2047 1, 119, 0, digital_tlv),
2048SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
2049 WM8994_AIF2_ADC_RIGHT_VOLUME,
2050 1, 119, 0, digital_tlv),
2051
2052SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
2053 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2054SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
2055 WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2056SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
2057 WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2058
2059SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
2060SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
2061
2062SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
2063SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
2064SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
2065
2066WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
2067WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
2068WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
2069
2070WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
2071WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
2072WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
2073
2074WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
2075WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
2076WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
2077
2078SOC_SINGLE_TLV("DAC1 Right Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2079 5, 12, 0, st_tlv),
2080SOC_SINGLE_TLV("DAC1 Left Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2081 0, 12, 0, st_tlv),
2082SOC_SINGLE_TLV("DAC2 Right Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2083 5, 12, 0, st_tlv),
2084SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2085 0, 12, 0, st_tlv),
2086SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
2087SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
2088
2089SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
2090 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2091SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
2092 WM8994_DAC1_RIGHT_VOLUME, 9, 1, 1),
2093
2094SOC_DOUBLE_R_TLV("DAC2 Volume", WM8994_DAC2_LEFT_VOLUME,
2095 WM8994_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2096SOC_DOUBLE_R("DAC2 Switch", WM8994_DAC2_LEFT_VOLUME,
2097 WM8994_DAC2_RIGHT_VOLUME, 9, 1, 1),
2098
2099SOC_SINGLE_TLV("SPKL DAC2 Volume", WM8994_SPKMIXL_ATTENUATION,
2100 6, 1, 1, wm_hubs_spkmix_tlv),
2101SOC_SINGLE_TLV("SPKL DAC1 Volume", WM8994_SPKMIXL_ATTENUATION,
2102 2, 1, 1, wm_hubs_spkmix_tlv),
2103
2104SOC_SINGLE_TLV("SPKR DAC2 Volume", WM8994_SPKMIXR_ATTENUATION,
2105 6, 1, 1, wm_hubs_spkmix_tlv),
2106SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
2107 2, 1, 1, wm_hubs_spkmix_tlv),
2108
2109SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2110 10, 15, 0, wm8994_3d_tlv),
2111SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2112 8, 1, 0),
2113SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
2114 10, 15, 0, wm8994_3d_tlv),
2115SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2116 8, 1, 0),
2117SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2118 10, 15, 0, wm8994_3d_tlv),
2119SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2120 8, 1, 0),
2121};
2122
2123static const struct snd_kcontrol_new wm8994_eq_controls[] = {
2124SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
2125 eq_tlv),
2126SOC_SINGLE_TLV("AIF1DAC1 EQ2 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 6, 31, 0,
2127 eq_tlv),
2128SOC_SINGLE_TLV("AIF1DAC1 EQ3 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 1, 31, 0,
2129 eq_tlv),
2130SOC_SINGLE_TLV("AIF1DAC1 EQ4 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 11, 31, 0,
2131 eq_tlv),
2132SOC_SINGLE_TLV("AIF1DAC1 EQ5 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 6, 31, 0,
2133 eq_tlv),
2134
2135SOC_SINGLE_TLV("AIF1DAC2 EQ1 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 11, 31, 0,
2136 eq_tlv),
2137SOC_SINGLE_TLV("AIF1DAC2 EQ2 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 6, 31, 0,
2138 eq_tlv),
2139SOC_SINGLE_TLV("AIF1DAC2 EQ3 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 1, 31, 0,
2140 eq_tlv),
2141SOC_SINGLE_TLV("AIF1DAC2 EQ4 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 11, 31, 0,
2142 eq_tlv),
2143SOC_SINGLE_TLV("AIF1DAC2 EQ5 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 6, 31, 0,
2144 eq_tlv),
2145
2146SOC_SINGLE_TLV("AIF2 EQ1 Volume", WM8994_AIF2_EQ_GAINS_1, 11, 31, 0,
2147 eq_tlv),
2148SOC_SINGLE_TLV("AIF2 EQ2 Volume", WM8994_AIF2_EQ_GAINS_1, 6, 31, 0,
2149 eq_tlv),
2150SOC_SINGLE_TLV("AIF2 EQ3 Volume", WM8994_AIF2_EQ_GAINS_1, 1, 31, 0,
2151 eq_tlv),
2152SOC_SINGLE_TLV("AIF2 EQ4 Volume", WM8994_AIF2_EQ_GAINS_2, 11, 31, 0,
2153 eq_tlv),
2154SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
2155 eq_tlv),
2156};
2157
2158static int clk_sys_event(struct snd_soc_dapm_widget *w,
2159 struct snd_kcontrol *kcontrol, int event)
2160{
2161 struct snd_soc_codec *codec = w->codec;
2162
2163 switch (event) {
2164 case SND_SOC_DAPM_PRE_PMU:
2165 return configure_clock(codec);
2166
2167 case SND_SOC_DAPM_POST_PMD:
2168 configure_clock(codec);
2169 break;
2170 }
2171
2172 return 0;
2173}
2174
2175static void wm8994_update_class_w(struct snd_soc_codec *codec)
2176{
2177 int enable = 1;
2178 int source = 0; /* GCC flow analysis can't track enable */
2179 int reg, reg_r;
2180
2181 /* Only support direct DAC->headphone paths */
2182 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
2183 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
2184 dev_dbg(codec->dev, "HPL connected to output mixer\n");
2185 enable = 0;
2186 }
2187
2188 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
2189 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
2190 dev_dbg(codec->dev, "HPR connected to output mixer\n");
2191 enable = 0;
2192 }
2193
2194 /* We also need the same setting for L/R and only one path */
2195 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
2196 switch (reg) {
2197 case WM8994_AIF2DACL_TO_DAC1L:
2198 dev_dbg(codec->dev, "Class W source AIF2DAC\n");
2199 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2200 break;
2201 case WM8994_AIF1DAC2L_TO_DAC1L:
2202 dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
2203 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2204 break;
2205 case WM8994_AIF1DAC1L_TO_DAC1L:
2206 dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
2207 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2208 break;
2209 default:
2210 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
2211 enable = 0;
2212 break;
2213 }
2214
2215 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
2216 if (reg_r != reg) {
2217 dev_dbg(codec->dev, "Left and right DAC mixers different\n");
2218 enable = 0;
2219 }
2220
2221 if (enable) {
2222 dev_dbg(codec->dev, "Class W enabled\n");
2223 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2224 WM8994_CP_DYN_PWR |
2225 WM8994_CP_DYN_SRC_SEL_MASK,
2226 source | WM8994_CP_DYN_PWR);
2227
2228 } else {
2229 dev_dbg(codec->dev, "Class W disabled\n");
2230 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2231 WM8994_CP_DYN_PWR, 0);
2232 }
2233}
2234
2235static const char *hp_mux_text[] = {
2236 "Mixer",
2237 "DAC",
2238};
2239
2240#define WM8994_HP_ENUM(xname, xenum) \
2241{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2242 .info = snd_soc_info_enum_double, \
2243 .get = snd_soc_dapm_get_enum_double, \
2244 .put = wm8994_put_hp_enum, \
2245 .private_value = (unsigned long)&xenum }
2246
2247static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
2248 struct snd_ctl_elem_value *ucontrol)
2249{
2250 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2251 struct snd_soc_codec *codec = w->codec;
2252 int ret;
2253
2254 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
2255
2256 wm8994_update_class_w(codec);
2257
2258 return ret;
2259}
2260
2261static const struct soc_enum hpl_enum =
2262 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text);
2263
2264static const struct snd_kcontrol_new hpl_mux =
2265 WM8994_HP_ENUM("Left Headphone Mux", hpl_enum);
2266
2267static const struct soc_enum hpr_enum =
2268 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text);
2269
2270static const struct snd_kcontrol_new hpr_mux =
2271 WM8994_HP_ENUM("Right Headphone Mux", hpr_enum);
2272
2273static const char *adc_mux_text[] = {
2274 "ADC",
2275 "DMIC",
2276};
2277
2278static const struct soc_enum adc_enum =
2279 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
2280
2281static const struct snd_kcontrol_new adcl_mux =
2282 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
2283
2284static const struct snd_kcontrol_new adcr_mux =
2285 SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
2286
2287static const struct snd_kcontrol_new left_speaker_mixer[] = {
2288SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0),
2289SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 7, 1, 0),
2290SOC_DAPM_SINGLE("IN1LP Switch", WM8994_SPEAKER_MIXER, 5, 1, 0),
2291SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 3, 1, 0),
2292SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 1, 1, 0),
2293};
2294
2295static const struct snd_kcontrol_new right_speaker_mixer[] = {
2296SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 8, 1, 0),
2297SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 6, 1, 0),
2298SOC_DAPM_SINGLE("IN1RP Switch", WM8994_SPEAKER_MIXER, 4, 1, 0),
2299SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 2, 1, 0),
2300SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
2301};
2302
2303/* Debugging; dump chip status after DAPM transitions */
2304static int post_ev(struct snd_soc_dapm_widget *w,
2305 struct snd_kcontrol *kcontrol, int event)
2306{
2307 struct snd_soc_codec *codec = w->codec;
2308 dev_dbg(codec->dev, "SRC status: %x\n",
2309 snd_soc_read(codec,
2310 WM8994_RATE_STATUS));
2311 return 0;
2312}
2313
2314static const struct snd_kcontrol_new aif1adc1l_mix[] = {
2315SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2316 1, 1, 0),
2317SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2318 0, 1, 0),
2319};
2320
2321static const struct snd_kcontrol_new aif1adc1r_mix[] = {
2322SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2323 1, 1, 0),
2324SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2325 0, 1, 0),
2326};
2327
2328static const struct snd_kcontrol_new aif2dac2l_mix[] = {
2329SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2330 5, 1, 0),
2331SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2332 4, 1, 0),
2333SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2334 2, 1, 0),
2335SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2336 1, 1, 0),
2337SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2338 0, 1, 0),
2339};
2340
2341static const struct snd_kcontrol_new aif2dac2r_mix[] = {
2342SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2343 5, 1, 0),
2344SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2345 4, 1, 0),
2346SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2347 2, 1, 0),
2348SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2349 1, 1, 0),
2350SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2351 0, 1, 0),
2352};
2353
2354#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
2355{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2356 .info = snd_soc_info_volsw, \
2357 .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
2358 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
2359
2360static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
2361 struct snd_ctl_elem_value *ucontrol)
2362{
2363 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2364 struct snd_soc_codec *codec = w->codec;
2365 int ret;
2366
2367 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
2368
2369 wm8994_update_class_w(codec);
2370
2371 return ret;
2372}
2373
2374static const struct snd_kcontrol_new dac1l_mix[] = {
2375WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2376 5, 1, 0),
2377WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2378 4, 1, 0),
2379WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2380 2, 1, 0),
2381WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2382 1, 1, 0),
2383WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2384 0, 1, 0),
2385};
2386
2387static const struct snd_kcontrol_new dac1r_mix[] = {
2388WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2389 5, 1, 0),
2390WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2391 4, 1, 0),
2392WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2393 2, 1, 0),
2394WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2395 1, 1, 0),
2396WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2397 0, 1, 0),
2398};
2399
2400static const char *sidetone_text[] = {
2401 "ADC/DMIC1", "DMIC2",
2402};
2403
2404static const struct soc_enum sidetone1_enum =
2405 SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text);
2406
2407static const struct snd_kcontrol_new sidetone1_mux =
2408 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
2409
2410static const struct soc_enum sidetone2_enum =
2411 SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text);
2412
2413static const struct snd_kcontrol_new sidetone2_mux =
2414 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
2415
2416static const char *aif1dac_text[] = {
2417 "AIF1DACDAT", "AIF3DACDAT",
2418};
2419
2420static const struct soc_enum aif1dac_enum =
2421 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
2422
2423static const struct snd_kcontrol_new aif1dac_mux =
2424 SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
2425
2426static const char *aif2dac_text[] = {
2427 "AIF2DACDAT", "AIF3DACDAT",
2428};
2429
2430static const struct soc_enum aif2dac_enum =
2431 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text);
2432
2433static const struct snd_kcontrol_new aif2dac_mux =
2434 SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
2435
2436static const char *aif2adc_text[] = {
2437 "AIF2ADCDAT", "AIF3DACDAT",
2438};
2439
2440static const struct soc_enum aif2adc_enum =
2441 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text);
2442
2443static const struct snd_kcontrol_new aif2adc_mux =
2444 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
2445
2446static const char *aif3adc_text[] = {
2447 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT",
2448};
2449
2450static const struct soc_enum aif3adc_enum =
2451 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
2452
2453static const struct snd_kcontrol_new aif3adc_mux =
2454 SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum);
2455
2456static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2457SND_SOC_DAPM_INPUT("DMIC1DAT"),
2458SND_SOC_DAPM_INPUT("DMIC2DAT"),
2459
2460SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
2461 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2462
2463SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
2464SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
2465SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
2466
2467SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
2468SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
2469
2470SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
2471 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
2472SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
2473 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
2474SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0,
2475 WM8994_POWER_MANAGEMENT_5, 9, 0),
2476SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0,
2477 WM8994_POWER_MANAGEMENT_5, 8, 0),
2478
2479SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
2480 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
2481SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
2482 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
2483SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0,
2484 WM8994_POWER_MANAGEMENT_5, 11, 0),
2485SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0,
2486 WM8994_POWER_MANAGEMENT_5, 10, 0),
2487
2488SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2489 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
2490SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
2491 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
2492
2493SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
2494 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
2495SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
2496 aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
2497
2498SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
2499SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
2500
2501SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
2502 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
2503SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
2504 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
2505
2506SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
2507 WM8994_POWER_MANAGEMENT_4, 13, 0),
2508SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
2509 WM8994_POWER_MANAGEMENT_4, 12, 0),
2510SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0,
2511 WM8994_POWER_MANAGEMENT_5, 13, 0),
2512SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0,
2513 WM8994_POWER_MANAGEMENT_5, 12, 0),
2514
2515SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2516SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
2517SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2518
2519SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
2520SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
2521SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
2522SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
2523
2524SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2525SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
2526
2527SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
2528
2529SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8994_POWER_MANAGEMENT_4, 5, 0),
2530SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8994_POWER_MANAGEMENT_4, 4, 0),
2531SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8994_POWER_MANAGEMENT_4, 3, 0),
2532SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
2533
2534/* Power is done with the muxes since the ADC power also controls the
2535 * downsampling chain, the chip will automatically manage the analogue
2536 * specific portions.
2537 */
2538SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
2539SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
2540
2541SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
2542SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
2543
2544SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
2545SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
2546SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
2547SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
2548
2549SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
2550SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
2551
2552SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
2553 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
2554SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
2555 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
2556
2557SND_SOC_DAPM_POST("Debug log", post_ev),
2558};
2559
2560static const struct snd_soc_dapm_route intercon[] = {
2561
2562 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
2563 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
2564
2565 { "DSP1CLK", NULL, "CLK_SYS" },
2566 { "DSP2CLK", NULL, "CLK_SYS" },
2567 { "DSPINTCLK", NULL, "CLK_SYS" },
2568
2569 { "AIF1ADC1L", NULL, "AIF1CLK" },
2570 { "AIF1ADC1L", NULL, "DSP1CLK" },
2571 { "AIF1ADC1R", NULL, "AIF1CLK" },
2572 { "AIF1ADC1R", NULL, "DSP1CLK" },
2573 { "AIF1ADC1R", NULL, "DSPINTCLK" },
2574
2575 { "AIF1DAC1L", NULL, "AIF1CLK" },
2576 { "AIF1DAC1L", NULL, "DSP1CLK" },
2577 { "AIF1DAC1R", NULL, "AIF1CLK" },
2578 { "AIF1DAC1R", NULL, "DSP1CLK" },
2579 { "AIF1DAC1R", NULL, "DSPINTCLK" },
2580
2581 { "AIF1ADC2L", NULL, "AIF1CLK" },
2582 { "AIF1ADC2L", NULL, "DSP1CLK" },
2583 { "AIF1ADC2R", NULL, "AIF1CLK" },
2584 { "AIF1ADC2R", NULL, "DSP1CLK" },
2585 { "AIF1ADC2R", NULL, "DSPINTCLK" },
2586
2587 { "AIF1DAC2L", NULL, "AIF1CLK" },
2588 { "AIF1DAC2L", NULL, "DSP1CLK" },
2589 { "AIF1DAC2R", NULL, "AIF1CLK" },
2590 { "AIF1DAC2R", NULL, "DSP1CLK" },
2591 { "AIF1DAC2R", NULL, "DSPINTCLK" },
2592
2593 { "AIF2ADCL", NULL, "AIF2CLK" },
2594 { "AIF2ADCL", NULL, "DSP2CLK" },
2595 { "AIF2ADCR", NULL, "AIF2CLK" },
2596 { "AIF2ADCR", NULL, "DSP2CLK" },
2597 { "AIF2ADCR", NULL, "DSPINTCLK" },
2598
2599 { "AIF2DACL", NULL, "AIF2CLK" },
2600 { "AIF2DACL", NULL, "DSP2CLK" },
2601 { "AIF2DACR", NULL, "AIF2CLK" },
2602 { "AIF2DACR", NULL, "DSP2CLK" },
2603 { "AIF2DACR", NULL, "DSPINTCLK" },
2604
2605 { "DMIC1L", NULL, "DMIC1DAT" },
2606 { "DMIC1L", NULL, "CLK_SYS" },
2607 { "DMIC1R", NULL, "DMIC1DAT" },
2608 { "DMIC1R", NULL, "CLK_SYS" },
2609 { "DMIC2L", NULL, "DMIC2DAT" },
2610 { "DMIC2L", NULL, "CLK_SYS" },
2611 { "DMIC2R", NULL, "DMIC2DAT" },
2612 { "DMIC2R", NULL, "CLK_SYS" },
2613
2614 { "ADCL", NULL, "AIF1CLK" },
2615 { "ADCL", NULL, "DSP1CLK" },
2616 { "ADCL", NULL, "DSPINTCLK" },
2617
2618 { "ADCR", NULL, "AIF1CLK" },
2619 { "ADCR", NULL, "DSP1CLK" },
2620 { "ADCR", NULL, "DSPINTCLK" },
2621
2622 { "ADCL Mux", "ADC", "ADCL" },
2623 { "ADCL Mux", "DMIC", "DMIC1L" },
2624 { "ADCR Mux", "ADC", "ADCR" },
2625 { "ADCR Mux", "DMIC", "DMIC1R" },
2626
2627 { "DAC1L", NULL, "AIF1CLK" },
2628 { "DAC1L", NULL, "DSP1CLK" },
2629 { "DAC1L", NULL, "DSPINTCLK" },
2630
2631 { "DAC1R", NULL, "AIF1CLK" },
2632 { "DAC1R", NULL, "DSP1CLK" },
2633 { "DAC1R", NULL, "DSPINTCLK" },
2634
2635 { "DAC2L", NULL, "AIF2CLK" },
2636 { "DAC2L", NULL, "DSP2CLK" },
2637 { "DAC2L", NULL, "DSPINTCLK" },
2638
2639 { "DAC2R", NULL, "AIF2DACR" },
2640 { "DAC2R", NULL, "AIF2CLK" },
2641 { "DAC2R", NULL, "DSP2CLK" },
2642 { "DAC2R", NULL, "DSPINTCLK" },
2643
2644 { "TOCLK", NULL, "CLK_SYS" },
2645
2646 /* AIF1 outputs */
2647 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
2648 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
2649 { "AIF1ADC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2650
2651 { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
2652 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
2653 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2654
2655 /* Pin level routing for AIF3 */
2656 { "AIF1DAC1L", NULL, "AIF1DAC Mux" },
2657 { "AIF1DAC1R", NULL, "AIF1DAC Mux" },
2658 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
2659 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
2660
2661 { "AIF2DACL", NULL, "AIF2DAC Mux" },
2662 { "AIF2DACR", NULL, "AIF2DAC Mux" },
2663
2664 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
2665 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2666 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
2667 { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2668 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
2669 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
2670 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
2671
2672 /* DAC1 inputs */
2673 { "DAC1L", NULL, "DAC1L Mixer" },
2674 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2675 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2676 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2677 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2678 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2679
2680 { "DAC1R", NULL, "DAC1R Mixer" },
2681 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2682 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2683 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2684 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2685 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2686
2687 /* DAC2/AIF2 outputs */
2688 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
2689 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
2690 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
2691 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2692 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2693 { "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2694 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2695
2696 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
2697 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
2698 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
2699 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2700 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2701 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2702 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2703
2704 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
2705
2706 /* AIF3 output */
2707 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" },
2708 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" },
2709 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" },
2710 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" },
2711 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" },
2712 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" },
2713 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
2714 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
2715
2716 /* Sidetone */
2717 { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
2718 { "Left Sidetone", "DMIC2", "DMIC2L" },
2719 { "Right Sidetone", "ADC/DMIC1", "ADCR Mux" },
2720 { "Right Sidetone", "DMIC2", "DMIC2R" },
2721
2722 /* Output stages */
2723 { "Left Output Mixer", "DAC Switch", "DAC1L" },
2724 { "Right Output Mixer", "DAC Switch", "DAC1R" },
2725
2726 { "SPKL", "DAC1 Switch", "DAC1L" },
2727 { "SPKL", "DAC2 Switch", "DAC2L" },
2728
2729 { "SPKR", "DAC1 Switch", "DAC1R" },
2730 { "SPKR", "DAC2 Switch", "DAC2R" },
2731
2732 { "Left Headphone Mux", "DAC", "DAC1L" },
2733 { "Right Headphone Mux", "DAC", "DAC1R" },
2734};
2735
2736/* The size in bits of the FLL divide multiplied by 10
2737 * to allow rounding later */
2738#define FIXED_FLL_SIZE ((1 << 16) * 10)
2739
2740struct fll_div {
2741 u16 outdiv;
2742 u16 n;
2743 u16 k;
2744 u16 clk_ref_div;
2745 u16 fll_fratio;
2746};
2747
2748static int wm8994_get_fll_config(struct fll_div *fll,
2749 int freq_in, int freq_out)
2750{
2751 u64 Kpart;
2752 unsigned int K, Ndiv, Nmod;
2753
2754 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
2755
2756 /* Scale the input frequency down to <= 13.5MHz */
2757 fll->clk_ref_div = 0;
2758 while (freq_in > 13500000) {
2759 fll->clk_ref_div++;
2760 freq_in /= 2;
2761
2762 if (fll->clk_ref_div > 3)
2763 return -EINVAL;
2764 }
2765 pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
2766
2767 /* Scale the output to give 90MHz<=Fvco<=100MHz */
2768 fll->outdiv = 3;
2769 while (freq_out * (fll->outdiv + 1) < 90000000) {
2770 fll->outdiv++;
2771 if (fll->outdiv > 63)
2772 return -EINVAL;
2773 }
2774 freq_out *= fll->outdiv + 1;
2775 pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
2776
2777 if (freq_in > 1000000) {
2778 fll->fll_fratio = 0;
2779 } else {
2780 fll->fll_fratio = 3;
2781 freq_in *= 8;
2782 }
2783 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
2784
2785 /* Now, calculate N.K */
2786 Ndiv = freq_out / freq_in;
2787
2788 fll->n = Ndiv;
2789 Nmod = freq_out % freq_in;
2790 pr_debug("Nmod=%d\n", Nmod);
2791
2792 /* Calculate fractional part - scale up so we can round. */
2793 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
2794
2795 do_div(Kpart, freq_in);
2796
2797 K = Kpart & 0xFFFFFFFF;
2798
2799 if ((K % 10) >= 5)
2800 K += 5;
2801
2802 /* Move down to proper range now rounding is done */
2803 fll->k = K / 10;
2804
2805 pr_debug("N=%x K=%x\n", fll->n, fll->k);
2806
2807 return 0;
2808}
2809
2810static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2811 unsigned int freq_in, unsigned int freq_out)
2812{
2813 struct snd_soc_codec *codec = dai->codec;
2814 struct wm8994_priv *wm8994 = codec->private_data;
2815 int reg_offset, ret;
2816 struct fll_div fll;
2817 u16 reg, aif1, aif2;
2818
2819 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
2820 & WM8994_AIF1CLK_ENA;
2821
2822 aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
2823 & WM8994_AIF2CLK_ENA;
2824
2825 switch (id) {
2826 case WM8994_FLL1:
2827 reg_offset = 0;
2828 id = 0;
2829 break;
2830 case WM8994_FLL2:
2831 reg_offset = 0x20;
2832 id = 1;
2833 break;
2834 default:
2835 return -EINVAL;
2836 }
2837
2838 /* Are we changing anything? */
2839 if (wm8994->fll[id].src == src &&
2840 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
2841 return 0;
2842
2843 /* If we're stopping the FLL redo the old config - no
2844 * registers will actually be written but we avoid GCC flow
2845 * analysis bugs spewing warnings.
2846 */
2847 if (freq_out)
2848 ret = wm8994_get_fll_config(&fll, freq_in, freq_out);
2849 else
2850 ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in,
2851 wm8994->fll[id].out);
2852 if (ret < 0)
2853 return ret;
2854
2855 /* Gate the AIF clocks while we reclock */
2856 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2857 WM8994_AIF1CLK_ENA, 0);
2858 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2859 WM8994_AIF2CLK_ENA, 0);
2860
2861 /* We always need to disable the FLL while reconfiguring */
2862 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2863 WM8994_FLL1_ENA, 0);
2864
2865 reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
2866 (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
2867 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
2868 WM8994_FLL1_OUTDIV_MASK |
2869 WM8994_FLL1_FRATIO_MASK, reg);
2870
2871 snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k);
2872
2873 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
2874 WM8994_FLL1_N_MASK,
2875 fll.n << WM8994_FLL1_N_SHIFT);
2876
2877 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2878 WM8994_FLL1_REFCLK_DIV_MASK,
2879 fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT);
2880
2881 /* Enable (with fractional mode if required) */
2882 if (freq_out) {
2883 if (fll.k)
2884 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
2885 else
2886 reg = WM8994_FLL1_ENA;
2887 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2888 WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
2889 reg);
2890 }
2891
2892 wm8994->fll[id].in = freq_in;
2893 wm8994->fll[id].out = freq_out;
2894
2895 /* Enable any gated AIF clocks */
2896 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2897 WM8994_AIF1CLK_ENA, aif1);
2898 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2899 WM8994_AIF2CLK_ENA, aif2);
2900
2901 configure_clock(codec);
2902
2903 return 0;
2904}
2905
2906static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2907 int clk_id, unsigned int freq, int dir)
2908{
2909 struct snd_soc_codec *codec = dai->codec;
2910 struct wm8994_priv *wm8994 = codec->private_data;
2911
2912 switch (dai->id) {
2913 case 1:
2914 case 2:
2915 break;
2916
2917 default:
2918 /* AIF3 shares clocking with AIF1/2 */
2919 return -EINVAL;
2920 }
2921
2922 switch (clk_id) {
2923 case WM8994_SYSCLK_MCLK1:
2924 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
2925 wm8994->mclk[0] = freq;
2926 dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
2927 dai->id, freq);
2928 break;
2929
2930 case WM8994_SYSCLK_MCLK2:
2931 /* TODO: Set GPIO AF */
2932 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
2933 wm8994->mclk[1] = freq;
2934 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
2935 dai->id, freq);
2936 break;
2937
2938 case WM8994_SYSCLK_FLL1:
2939 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
2940 dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id);
2941 break;
2942
2943 case WM8994_SYSCLK_FLL2:
2944 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
2945 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
2946 break;
2947
2948 default:
2949 return -EINVAL;
2950 }
2951
2952 configure_clock(codec);
2953
2954 return 0;
2955}
2956
2957static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2958 enum snd_soc_bias_level level)
2959{
2960 switch (level) {
2961 case SND_SOC_BIAS_ON:
2962 break;
2963
2964 case SND_SOC_BIAS_PREPARE:
2965 /* VMID=2x40k */
2966 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2967 WM8994_VMID_SEL_MASK, 0x2);
2968 break;
2969
2970 case SND_SOC_BIAS_STANDBY:
2971 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2972 /* Tweak DC servo configuration for improved
2973 * performance. */
2974 snd_soc_write(codec, 0x102, 0x3);
2975 snd_soc_write(codec, 0x56, 0x3);
2976 snd_soc_write(codec, 0x102, 0);
2977
2978 /* Discharge LINEOUT1 & 2 */
2979 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
2980 WM8994_LINEOUT1_DISCH |
2981 WM8994_LINEOUT2_DISCH,
2982 WM8994_LINEOUT1_DISCH |
2983 WM8994_LINEOUT2_DISCH);
2984
2985 /* Startup bias, VMID ramp & buffer */
2986 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
2987 WM8994_STARTUP_BIAS_ENA |
2988 WM8994_VMID_BUF_ENA |
2989 WM8994_VMID_RAMP_MASK,
2990 WM8994_STARTUP_BIAS_ENA |
2991 WM8994_VMID_BUF_ENA |
2992 (0x11 << WM8994_VMID_RAMP_SHIFT));
2993
2994 /* Main bias enable, VMID=2x40k */
2995 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2996 WM8994_BIAS_ENA |
2997 WM8994_VMID_SEL_MASK,
2998 WM8994_BIAS_ENA | 0x2);
2999
3000 msleep(20);
3001 }
3002
3003 /* VMID=2x500k */
3004 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3005 WM8994_VMID_SEL_MASK, 0x4);
3006
3007 break;
3008
3009 case SND_SOC_BIAS_OFF:
3010 /* Switch over to startup biases */
3011 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3012 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3013 WM8994_VMID_BUF_ENA |
3014 WM8994_VMID_RAMP_MASK,
3015 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3016 WM8994_VMID_BUF_ENA |
3017 (1 << WM8994_VMID_RAMP_SHIFT));
3018
3019 /* Disable main biases */
3020 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3021 WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
3022
3023 /* Discharge line */
3024 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
3025 WM8994_LINEOUT1_DISCH |
3026 WM8994_LINEOUT2_DISCH,
3027 WM8994_LINEOUT1_DISCH |
3028 WM8994_LINEOUT2_DISCH);
3029
3030 msleep(5);
3031
3032 /* Switch off startup biases */
3033 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3034 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3035 WM8994_VMID_BUF_ENA |
3036 WM8994_VMID_RAMP_MASK, 0);
3037
3038 break;
3039 }
3040 codec->bias_level = level;
3041 return 0;
3042}
3043
3044static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3045{
3046 struct snd_soc_codec *codec = dai->codec;
3047 int ms_reg;
3048 int aif1_reg;
3049 int ms = 0;
3050 int aif1 = 0;
3051
3052 switch (dai->id) {
3053 case 1:
3054 ms_reg = WM8994_AIF1_MASTER_SLAVE;
3055 aif1_reg = WM8994_AIF1_CONTROL_1;
3056 break;
3057 case 2:
3058 ms_reg = WM8994_AIF2_MASTER_SLAVE;
3059 aif1_reg = WM8994_AIF2_CONTROL_1;
3060 break;
3061 default:
3062 return -EINVAL;
3063 }
3064
3065 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3066 case SND_SOC_DAIFMT_CBS_CFS:
3067 break;
3068 case SND_SOC_DAIFMT_CBM_CFM:
3069 ms = WM8994_AIF1_MSTR;
3070 break;
3071 default:
3072 return -EINVAL;
3073 }
3074
3075 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3076 case SND_SOC_DAIFMT_DSP_B:
3077 aif1 |= WM8994_AIF1_LRCLK_INV;
3078 case SND_SOC_DAIFMT_DSP_A:
3079 aif1 |= 0x18;
3080 break;
3081 case SND_SOC_DAIFMT_I2S:
3082 aif1 |= 0x10;
3083 break;
3084 case SND_SOC_DAIFMT_RIGHT_J:
3085 break;
3086 case SND_SOC_DAIFMT_LEFT_J:
3087 aif1 |= 0x8;
3088 break;
3089 default:
3090 return -EINVAL;
3091 }
3092
3093 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3094 case SND_SOC_DAIFMT_DSP_A:
3095 case SND_SOC_DAIFMT_DSP_B:
3096 /* frame inversion not valid for DSP modes */
3097 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3098 case SND_SOC_DAIFMT_NB_NF:
3099 break;
3100 case SND_SOC_DAIFMT_IB_NF:
3101 aif1 |= WM8994_AIF1_BCLK_INV;
3102 break;
3103 default:
3104 return -EINVAL;
3105 }
3106 break;
3107
3108 case SND_SOC_DAIFMT_I2S:
3109 case SND_SOC_DAIFMT_RIGHT_J:
3110 case SND_SOC_DAIFMT_LEFT_J:
3111 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3112 case SND_SOC_DAIFMT_NB_NF:
3113 break;
3114 case SND_SOC_DAIFMT_IB_IF:
3115 aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
3116 break;
3117 case SND_SOC_DAIFMT_IB_NF:
3118 aif1 |= WM8994_AIF1_BCLK_INV;
3119 break;
3120 case SND_SOC_DAIFMT_NB_IF:
3121 aif1 |= WM8994_AIF1_LRCLK_INV;
3122 break;
3123 default:
3124 return -EINVAL;
3125 }
3126 break;
3127 default:
3128 return -EINVAL;
3129 }
3130
3131 snd_soc_update_bits(codec, aif1_reg,
3132 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
3133 WM8994_AIF1_FMT_MASK,
3134 aif1);
3135 snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
3136 ms);
3137
3138 return 0;
3139}
3140
3141static struct {
3142 int val, rate;
3143} srs[] = {
3144 { 0, 8000 },
3145 { 1, 11025 },
3146 { 2, 12000 },
3147 { 3, 16000 },
3148 { 4, 22050 },
3149 { 5, 24000 },
3150 { 6, 32000 },
3151 { 7, 44100 },
3152 { 8, 48000 },
3153 { 9, 88200 },
3154 { 10, 96000 },
3155};
3156
3157static int fs_ratios[] = {
3158 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
3159};
3160
3161static int bclk_divs[] = {
3162 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
3163 640, 880, 960, 1280, 1760, 1920
3164};
3165
3166static int wm8994_hw_params(struct snd_pcm_substream *substream,
3167 struct snd_pcm_hw_params *params,
3168 struct snd_soc_dai *dai)
3169{
3170 struct snd_soc_codec *codec = dai->codec;
3171 struct wm8994_priv *wm8994 = codec->private_data;
3172 int aif1_reg;
3173 int bclk_reg;
3174 int lrclk_reg;
3175 int rate_reg;
3176 int aif1 = 0;
3177 int bclk = 0;
3178 int lrclk = 0;
3179 int rate_val = 0;
3180 int id = dai->id - 1;
3181
3182 int i, cur_val, best_val, bclk_rate, best;
3183
3184 switch (dai->id) {
3185 case 1:
3186 aif1_reg = WM8994_AIF1_CONTROL_1;
3187 bclk_reg = WM8994_AIF1_BCLK;
3188 rate_reg = WM8994_AIF1_RATE;
3189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3190 wm8994->lrclk_shared[0])
3191 lrclk_reg = WM8994_AIF1DAC_LRCLK;
3192 else
3193 lrclk_reg = WM8994_AIF1ADC_LRCLK;
3194 break;
3195 case 2:
3196 aif1_reg = WM8994_AIF2_CONTROL_1;
3197 bclk_reg = WM8994_AIF2_BCLK;
3198 rate_reg = WM8994_AIF2_RATE;
3199 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3200 wm8994->lrclk_shared[1])
3201 lrclk_reg = WM8994_AIF2DAC_LRCLK;
3202 else
3203 lrclk_reg = WM8994_AIF2ADC_LRCLK;
3204 break;
3205 default:
3206 return -EINVAL;
3207 }
3208
3209 bclk_rate = params_rate(params) * 2;
3210 switch (params_format(params)) {
3211 case SNDRV_PCM_FORMAT_S16_LE:
3212 bclk_rate *= 16;
3213 break;
3214 case SNDRV_PCM_FORMAT_S20_3LE:
3215 bclk_rate *= 20;
3216 aif1 |= 0x20;
3217 break;
3218 case SNDRV_PCM_FORMAT_S24_LE:
3219 bclk_rate *= 24;
3220 aif1 |= 0x40;
3221 break;
3222 case SNDRV_PCM_FORMAT_S32_LE:
3223 bclk_rate *= 32;
3224 aif1 |= 0x60;
3225 break;
3226 default:
3227 return -EINVAL;
3228 }
3229
3230 /* Try to find an appropriate sample rate; look for an exact match. */
3231 for (i = 0; i < ARRAY_SIZE(srs); i++)
3232 if (srs[i].rate == params_rate(params))
3233 break;
3234 if (i == ARRAY_SIZE(srs))
3235 return -EINVAL;
3236 rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
3237
3238 dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
3239 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
3240 dai->id, wm8994->aifclk[id], bclk_rate);
3241
3242 if (wm8994->aifclk[id] == 0) {
3243 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
3244 return -EINVAL;
3245 }
3246
3247 /* AIFCLK/fs ratio; look for a close match in either direction */
3248 best = 0;
3249 best_val = abs((fs_ratios[0] * params_rate(params))
3250 - wm8994->aifclk[id]);
3251 for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
3252 cur_val = abs((fs_ratios[i] * params_rate(params))
3253 - wm8994->aifclk[id]);
3254 if (cur_val >= best_val)
3255 continue;
3256 best = i;
3257 best_val = cur_val;
3258 }
3259 dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
3260 dai->id, fs_ratios[best]);
3261 rate_val |= best;
3262
3263 /* We may not get quite the right frequency if using
3264 * approximate clocks so look for the closest match that is
3265 * higher than the target (we need to ensure that there enough
3266 * BCLKs to clock out the samples).
3267 */
3268 best = 0;
3269 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
3270 cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate;
3271 if (cur_val < 0) /* BCLK table is sorted */
3272 break;
3273 best = i;
3274 }
3275 bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
3276 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
3277 bclk_divs[best], bclk_rate);
3278 bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
3279
3280 lrclk = bclk_rate / params_rate(params);
3281 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
3282 lrclk, bclk_rate / lrclk);
3283
3284 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
3285 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
3286 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
3287 lrclk);
3288 snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK |
3289 WM8994_AIF1CLK_RATE_MASK, rate_val);
3290
3291 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3292 switch (dai->id) {
3293 case 1:
3294 wm8994->dac_rates[0] = params_rate(params);
3295 wm8994_set_retune_mobile(codec, 0);
3296 wm8994_set_retune_mobile(codec, 1);
3297 break;
3298 case 2:
3299 wm8994->dac_rates[1] = params_rate(params);
3300 wm8994_set_retune_mobile(codec, 2);
3301 break;
3302 }
3303 }
3304
3305 return 0;
3306}
3307
3308static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3309{
3310 struct snd_soc_codec *codec = codec_dai->codec;
3311 int mute_reg;
3312 int reg;
3313
3314 switch (codec_dai->id) {
3315 case 1:
3316 mute_reg = WM8994_AIF1_DAC1_FILTERS_1;
3317 break;
3318 case 2:
3319 mute_reg = WM8994_AIF2_DAC_FILTERS_1;
3320 break;
3321 default:
3322 return -EINVAL;
3323 }
3324
3325 if (mute)
3326 reg = WM8994_AIF1DAC1_MUTE;
3327 else
3328 reg = 0;
3329
3330 snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
3331
3332 return 0;
3333}
3334
3335#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
3336
3337#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
3338 SNDRV_PCM_FMTBIT_S24_LE)
3339
3340static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
3341 .set_sysclk = wm8994_set_dai_sysclk,
3342 .set_fmt = wm8994_set_dai_fmt,
3343 .hw_params = wm8994_hw_params,
3344 .digital_mute = wm8994_aif_mute,
3345 .set_pll = wm8994_set_fll,
3346};
3347
3348static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3349 .set_sysclk = wm8994_set_dai_sysclk,
3350 .set_fmt = wm8994_set_dai_fmt,
3351 .hw_params = wm8994_hw_params,
3352 .digital_mute = wm8994_aif_mute,
3353 .set_pll = wm8994_set_fll,
3354};
3355
3356struct snd_soc_dai wm8994_dai[] = {
3357 {
3358 .name = "WM8994 AIF1",
3359 .id = 1,
3360 .playback = {
3361 .stream_name = "AIF1 Playback",
3362 .channels_min = 2,
3363 .channels_max = 2,
3364 .rates = WM8994_RATES,
3365 .formats = WM8994_FORMATS,
3366 },
3367 .capture = {
3368 .stream_name = "AIF1 Capture",
3369 .channels_min = 2,
3370 .channels_max = 2,
3371 .rates = WM8994_RATES,
3372 .formats = WM8994_FORMATS,
3373 },
3374 .ops = &wm8994_aif1_dai_ops,
3375 },
3376 {
3377 .name = "WM8994 AIF2",
3378 .id = 2,
3379 .playback = {
3380 .stream_name = "AIF2 Playback",
3381 .channels_min = 2,
3382 .channels_max = 2,
3383 .rates = WM8994_RATES,
3384 .formats = WM8994_FORMATS,
3385 },
3386 .capture = {
3387 .stream_name = "AIF2 Capture",
3388 .channels_min = 2,
3389 .channels_max = 2,
3390 .rates = WM8994_RATES,
3391 .formats = WM8994_FORMATS,
3392 },
3393 .ops = &wm8994_aif2_dai_ops,
3394 },
3395 {
3396 .name = "WM8994 AIF3",
3397 .playback = {
3398 .stream_name = "AIF3 Playback",
3399 .channels_min = 2,
3400 .channels_max = 2,
3401 .rates = WM8994_RATES,
3402 .formats = WM8994_FORMATS,
3403 },
3404 .playback = {
3405 .stream_name = "AIF3 Capture",
3406 .channels_min = 2,
3407 .channels_max = 2,
3408 .rates = WM8994_RATES,
3409 .formats = WM8994_FORMATS,
3410 },
3411 }
3412};
3413EXPORT_SYMBOL_GPL(wm8994_dai);
3414
3415#ifdef CONFIG_PM
3416static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3417{
3418 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3419 struct snd_soc_codec *codec = socdev->card->codec;
3420 struct wm8994_priv *wm8994 = codec->private_data;
3421 int i, ret;
3422
3423 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3424 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
3425 sizeof(struct fll_config));
3426 ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0);
3427 if (ret < 0)
3428 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
3429 i + 1, ret);
3430 }
3431
3432 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3433
3434 return 0;
3435}
3436
3437static int wm8994_resume(struct platform_device *pdev)
3438{
3439 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3440 struct snd_soc_codec *codec = socdev->card->codec;
3441 struct wm8994_priv *wm8994 = codec->private_data;
3442 u16 *reg_cache = codec->reg_cache;
3443 int i, ret;
3444
3445 /* Restore the registers */
3446 for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) {
3447 switch (i) {
3448 case WM8994_LDO_1:
3449 case WM8994_LDO_2:
3450 case WM8994_SOFTWARE_RESET:
3451 /* Handled by other MFD drivers */
3452 continue;
3453 default:
3454 break;
3455 }
3456
3457 if (!access_masks[i].writable)
3458 continue;
3459
3460 wm8994_reg_write(codec->control_data, i, reg_cache[i]);
3461 }
3462
3463 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3464
3465 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3466 ret = wm8994_set_fll(&codec->dai[0], i + 1,
3467 wm8994->fll_suspend[i].src,
3468 wm8994->fll_suspend[i].in,
3469 wm8994->fll_suspend[i].out);
3470 if (ret < 0)
3471 dev_warn(codec->dev, "Failed to restore FLL%d: %d\n",
3472 i + 1, ret);
3473 }
3474
3475 return 0;
3476}
3477#else
3478#define wm8994_suspend NULL
3479#define wm8994_resume NULL
3480#endif
3481
3482static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3483{
3484 struct snd_soc_codec *codec = &wm8994->codec;
3485 struct wm8994_pdata *pdata = wm8994->pdata;
3486 struct snd_kcontrol_new controls[] = {
3487 SOC_ENUM_EXT("AIF1.1 EQ Mode",
3488 wm8994->retune_mobile_enum,
3489 wm8994_get_retune_mobile_enum,
3490 wm8994_put_retune_mobile_enum),
3491 SOC_ENUM_EXT("AIF1.2 EQ Mode",
3492 wm8994->retune_mobile_enum,
3493 wm8994_get_retune_mobile_enum,
3494 wm8994_put_retune_mobile_enum),
3495 SOC_ENUM_EXT("AIF2 EQ Mode",
3496 wm8994->retune_mobile_enum,
3497 wm8994_get_retune_mobile_enum,
3498 wm8994_put_retune_mobile_enum),
3499 };
3500 int ret, i, j;
3501 const char **t;
3502
3503 /* We need an array of texts for the enum API but the number
3504 * of texts is likely to be less than the number of
3505 * configurations due to the sample rate dependency of the
3506 * configurations. */
3507 wm8994->num_retune_mobile_texts = 0;
3508 wm8994->retune_mobile_texts = NULL;
3509 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
3510 for (j = 0; j < wm8994->num_retune_mobile_texts; j++) {
3511 if (strcmp(pdata->retune_mobile_cfgs[i].name,
3512 wm8994->retune_mobile_texts[j]) == 0)
3513 break;
3514 }
3515
3516 if (j != wm8994->num_retune_mobile_texts)
3517 continue;
3518
3519 /* Expand the array... */
3520 t = krealloc(wm8994->retune_mobile_texts,
3521 sizeof(char *) *
3522 (wm8994->num_retune_mobile_texts + 1),
3523 GFP_KERNEL);
3524 if (t == NULL)
3525 continue;
3526
3527 /* ...store the new entry... */
3528 t[wm8994->num_retune_mobile_texts] =
3529 pdata->retune_mobile_cfgs[i].name;
3530
3531 /* ...and remember the new version. */
3532 wm8994->num_retune_mobile_texts++;
3533 wm8994->retune_mobile_texts = t;
3534 }
3535
3536 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
3537 wm8994->num_retune_mobile_texts);
3538
3539 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
3540 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3541
3542 ret = snd_soc_add_controls(&wm8994->codec, controls,
3543 ARRAY_SIZE(controls));
3544 if (ret != 0)
3545 dev_err(wm8994->codec.dev,
3546 "Failed to add ReTune Mobile controls: %d\n", ret);
3547}
3548
3549static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3550{
3551 struct snd_soc_codec *codec = &wm8994->codec;
3552 struct wm8994_pdata *pdata = wm8994->pdata;
3553 int ret, i;
3554
3555 if (!pdata)
3556 return;
3557
3558 wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff,
3559 pdata->lineout2_diff,
3560 pdata->lineout1fb,
3561 pdata->lineout2fb,
3562 pdata->jd_scthr,
3563 pdata->jd_thr,
3564 pdata->micbias1_lvl,
3565 pdata->micbias2_lvl);
3566
3567 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
3568
3569 if (pdata->num_drc_cfgs) {
3570 struct snd_kcontrol_new controls[] = {
3571 SOC_ENUM_EXT("AIF1DRC1 Mode", wm8994->drc_enum,
3572 wm8994_get_drc_enum, wm8994_put_drc_enum),
3573 SOC_ENUM_EXT("AIF1DRC2 Mode", wm8994->drc_enum,
3574 wm8994_get_drc_enum, wm8994_put_drc_enum),
3575 SOC_ENUM_EXT("AIF2DRC Mode", wm8994->drc_enum,
3576 wm8994_get_drc_enum, wm8994_put_drc_enum),
3577 };
3578
3579 /* We need an array of texts for the enum API */
3580 wm8994->drc_texts = kmalloc(sizeof(char *)
3581 * pdata->num_drc_cfgs, GFP_KERNEL);
3582 if (!wm8994->drc_texts) {
3583 dev_err(wm8994->codec.dev,
3584 "Failed to allocate %d DRC config texts\n",
3585 pdata->num_drc_cfgs);
3586 return;
3587 }
3588
3589 for (i = 0; i < pdata->num_drc_cfgs; i++)
3590 wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
3591
3592 wm8994->drc_enum.max = pdata->num_drc_cfgs;
3593 wm8994->drc_enum.texts = wm8994->drc_texts;
3594
3595 ret = snd_soc_add_controls(&wm8994->codec, controls,
3596 ARRAY_SIZE(controls));
3597 if (ret != 0)
3598 dev_err(wm8994->codec.dev,
3599 "Failed to add DRC mode controls: %d\n", ret);
3600
3601 for (i = 0; i < WM8994_NUM_DRC; i++)
3602 wm8994_set_drc(codec, i);
3603 }
3604
3605 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
3606 pdata->num_retune_mobile_cfgs);
3607
3608 if (pdata->num_retune_mobile_cfgs)
3609 wm8994_handle_retune_mobile_pdata(wm8994);
3610 else
3611 snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls,
3612 ARRAY_SIZE(wm8994_eq_controls));
3613}
3614
3615static int wm8994_probe(struct platform_device *pdev)
3616{
3617 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3618 struct snd_soc_codec *codec;
3619 int ret = 0;
3620
3621 if (wm8994_codec == NULL) {
3622 dev_err(&pdev->dev, "Codec device not registered\n");
3623 return -ENODEV;
3624 }
3625
3626 socdev->card->codec = wm8994_codec;
3627 codec = wm8994_codec;
3628
3629 /* register pcms */
3630 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
3631 if (ret < 0) {
3632 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
3633 return ret;
3634 }
3635
3636 wm8994_handle_pdata(codec->private_data);
3637
3638 wm_hubs_add_analogue_controls(codec);
3639 snd_soc_add_controls(codec, wm8994_snd_controls,
3640 ARRAY_SIZE(wm8994_snd_controls));
3641 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
3642 ARRAY_SIZE(wm8994_dapm_widgets));
3643 wm_hubs_add_analogue_routes(codec, 0, 0);
3644 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
3645
3646 return 0;
3647}
3648
3649static int wm8994_remove(struct platform_device *pdev)
3650{
3651 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3652
3653 snd_soc_free_pcms(socdev);
3654 snd_soc_dapm_free(socdev);
3655
3656 return 0;
3657}
3658
3659struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3660 .probe = wm8994_probe,
3661 .remove = wm8994_remove,
3662 .suspend = wm8994_suspend,
3663 .resume = wm8994_resume,
3664};
3665EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3666
3667static int wm8994_codec_probe(struct platform_device *pdev)
3668{
3669 int ret;
3670 struct wm8994_priv *wm8994;
3671 struct snd_soc_codec *codec;
3672 int i;
3673 u16 rev;
3674
3675 if (wm8994_codec) {
3676 dev_err(&pdev->dev, "Another WM8994 is registered\n");
3677 return -EINVAL;
3678 }
3679
3680 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
3681 if (!wm8994) {
3682 dev_err(&pdev->dev, "Failed to allocate private data\n");
3683 return -ENOMEM;
3684 }
3685
3686 codec = &wm8994->codec;
3687
3688 mutex_init(&codec->mutex);
3689 INIT_LIST_HEAD(&codec->dapm_widgets);
3690 INIT_LIST_HEAD(&codec->dapm_paths);
3691
3692 codec->private_data = wm8994;
3693 codec->control_data = dev_get_drvdata(pdev->dev.parent);
3694 codec->name = "WM8994";
3695 codec->owner = THIS_MODULE;
3696 codec->read = wm8994_read;
3697 codec->write = wm8994_write;
3698 codec->readable_register = wm8994_readable;
3699 codec->bias_level = SND_SOC_BIAS_OFF;
3700 codec->set_bias_level = wm8994_set_bias_level;
3701 codec->dai = &wm8994_dai[0];
3702 codec->num_dai = 3;
3703 codec->reg_cache_size = WM8994_MAX_REGISTER;
3704 codec->reg_cache = &wm8994->reg_cache;
3705 codec->dev = &pdev->dev;
3706
3707 wm8994->pdata = pdev->dev.parent->platform_data;
3708
3709 /* Fill the cache with physical values we inherited; don't reset */
3710 ret = wm8994_bulk_read(codec->control_data, 0,
3711 ARRAY_SIZE(wm8994->reg_cache) - 1,
3712 codec->reg_cache);
3713 if (ret < 0) {
3714 dev_err(codec->dev, "Failed to fill register cache: %d\n",
3715 ret);
3716 goto err;
3717 }
3718
3719 /* Clear the cached values for unreadable/volatile registers to
3720 * avoid potential confusion.
3721 */
3722 for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++)
3723 if (wm8994_volatile(i) || !wm8994_readable(i))
3724 wm8994->reg_cache[i] = 0;
3725
3726 /* Set revision-specific configuration */
3727 rev = snd_soc_read(codec, WM8994_CHIP_REVISION);
3728 switch (rev) {
3729 case 2:
3730 case 3:
3731 wm8994->hubs.dcs_codes = -5;
3732 wm8994->hubs.hp_startup_mode = 1;
3733 break;
3734 default:
3735 break;
3736 }
3737
3738
3739 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3740 * configured on init - if a system wants to do this dynamically
3741 * at runtime we can deal with that then.
3742 */
3743 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
3744 if (ret < 0) {
3745 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
3746 goto err;
3747 }
3748 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3749 wm8994->lrclk_shared[0] = 1;
3750 wm8994_dai[0].symmetric_rates = 1;
3751 } else {
3752 wm8994->lrclk_shared[0] = 0;
3753 }
3754
3755 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
3756 if (ret < 0) {
3757 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
3758 goto err;
3759 }
3760 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3761 wm8994->lrclk_shared[1] = 1;
3762 wm8994_dai[1].symmetric_rates = 1;
3763 } else {
3764 wm8994->lrclk_shared[1] = 0;
3765 }
3766
3767 for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
3768 wm8994_dai[i].dev = codec->dev;
3769
3770 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3771
3772 wm8994_codec = codec;
3773
3774 /* Latch volume updates (right only; we always do left then right). */
3775 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
3776 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
3777 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME,
3778 WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
3779 snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME,
3780 WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
3781 snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME,
3782 WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
3783 snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME,
3784 WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
3785 snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME,
3786 WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
3787 snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME,
3788 WM8994_DAC1_VU, WM8994_DAC1_VU);
3789 snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME,
3790 WM8994_DAC2_VU, WM8994_DAC2_VU);
3791
3792 /* Set the low bit of the 3D stereo depth so TLV matches */
3793 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
3794 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
3795 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
3796 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2,
3797 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
3798 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
3799 snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2,
3800 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
3801 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
3802
3803 wm8994_update_class_w(codec);
3804
3805 ret = snd_soc_register_codec(codec);
3806 if (ret != 0) {
3807 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
3808 goto err;
3809 }
3810
3811 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3812 if (ret != 0) {
3813 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
3814 goto err_codec;
3815 }
3816
3817 platform_set_drvdata(pdev, wm8994);
3818
3819 return 0;
3820
3821err_codec:
3822 snd_soc_unregister_codec(codec);
3823err:
3824 kfree(wm8994);
3825 return ret;
3826}
3827
3828static int __devexit wm8994_codec_remove(struct platform_device *pdev)
3829{
3830 struct wm8994_priv *wm8994 = platform_get_drvdata(pdev);
3831 struct snd_soc_codec *codec = &wm8994->codec;
3832
3833 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3834 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3835 snd_soc_unregister_codec(&wm8994->codec);
3836 kfree(wm8994);
3837 wm8994_codec = NULL;
3838
3839 return 0;
3840}
3841
3842static struct platform_driver wm8994_codec_driver = {
3843 .driver = {
3844 .name = "wm8994-codec",
3845 .owner = THIS_MODULE,
3846 },
3847 .probe = wm8994_codec_probe,
3848 .remove = __devexit_p(wm8994_codec_remove),
3849};
3850
3851static __init int wm8994_init(void)
3852{
3853 return platform_driver_register(&wm8994_codec_driver);
3854}
3855module_init(wm8994_init);
3856
3857static __exit void wm8994_exit(void)
3858{
3859 platform_driver_unregister(&wm8994_codec_driver);
3860}
3861module_exit(wm8994_exit);
3862
3863
3864MODULE_DESCRIPTION("ASoC WM8994 driver");
3865MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
3866MODULE_LICENSE("GPL");
3867MODULE_ALIAS("platform:wm8994-codec");
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
new file mode 100644
index 000000000000..0a5e1424dea0
--- /dev/null
+++ b/sound/soc/codecs/wm8994.h
@@ -0,0 +1,26 @@
1/*
2 * wm8994.h -- WM8994 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM8994_H
10#define _WM8994_H
11
12#include <sound/soc.h>
13
14extern struct snd_soc_codec_device soc_codec_dev_wm8994;
15extern struct snd_soc_dai wm8994_dai[];
16
17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
18#define WM8994_SYSCLK_MCLK1 1
19#define WM8994_SYSCLK_MCLK2 2
20#define WM8994_SYSCLK_FLL1 3
21#define WM8994_SYSCLK_FLL2 4
22
23#define WM8994_FLL1 1
24#define WM8994_FLL2 2
25
26#endif
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index c58aab375edb..ceb86b4ddb25 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -23,13 +23,12 @@
23#include <sound/ac97_codec.h> 23#include <sound/ac97_codec.h>
24#include <sound/initval.h> 24#include <sound/initval.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/tlv.h>
26#include <sound/soc.h> 27#include <sound/soc.h>
27#include <sound/soc-dapm.h> 28#include <sound/soc-dapm.h>
28 29
29#include "wm9713.h" 30#include "wm9713.h"
30 31
31#define WM9713_VERSION "0.15"
32
33struct wm9713_priv { 32struct wm9713_priv {
34 u32 pll_in; /* PLL input frequency */ 33 u32 pll_in; /* PLL input frequency */
35}; 34};
@@ -115,15 +114,27 @@ SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18
115SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */ 114SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */
116}; 115};
117 116
117static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
118static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
119static const DECLARE_TLV_DB_SCALE(misc_tlv, -1500, 300, 0);
120static unsigned int mic_tlv[] = {
121 TLV_DB_RANGE_HEAD(2),
122 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
123 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
124};
125
118static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = { 126static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = {
119SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1), 127SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, out_tlv),
120SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1), 128SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1),
121SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), 129SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1,
130 out_tlv),
122SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1), 131SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1),
123SOC_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), 132SOC_DOUBLE_TLV("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1, main_tlv),
124SOC_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), 133SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1, main_tlv),
125SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 134SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
126SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 135SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
136SOC_SINGLE_TLV("Mic 1 Preamp Volume", AC97_3D_CONTROL, 10, 3, 0, mic_tlv),
137SOC_SINGLE_TLV("Mic 2 Preamp Volume", AC97_3D_CONTROL, 12, 3, 0, mic_tlv),
127 138
128SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), 139SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
129SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), 140SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
@@ -133,7 +144,7 @@ SOC_ENUM("Capture Volume Steps", wm9713_enum[5]),
133SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0), 144SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0),
134SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), 145SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
135 146
136SOC_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), 147SOC_SINGLE_TLV("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1, misc_tlv),
137SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), 148SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
138SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), 149SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
139 150
@@ -154,28 +165,43 @@ SOC_DOUBLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
154 165
155SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1), 166SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
156SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0), 167SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0),
157SOC_SINGLE("Out4 Playback Volume", AC97_MASTER_MONO, 8, 63, 1), 168SOC_SINGLE_TLV("Out4 Playback Volume", AC97_MASTER_MONO, 8, 31, 1, out_tlv),
158 169
159SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1), 170SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1),
160SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0), 171SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0),
161SOC_SINGLE("Out3 Playback Volume", AC97_MASTER_MONO, 0, 63, 1), 172SOC_SINGLE_TLV("Out3 Playback Volume", AC97_MASTER_MONO, 0, 31, 1, out_tlv),
162 173
163SOC_SINGLE("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1), 174SOC_SINGLE_TLV("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1, main_tlv),
164SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1), 175SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
165SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0), 176SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
166SOC_SINGLE("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1), 177SOC_SINGLE_TLV("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1, out_tlv),
167 178
168SOC_SINGLE("Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1), 179SOC_SINGLE_TLV("Headphone Mixer Beep Playback Volume", AC97_AUX, 12, 7, 1,
169SOC_SINGLE("Beep Playback Speaker Volume", AC97_AUX, 8, 7, 1), 180 misc_tlv),
170SOC_SINGLE("Beep Playback Mono Volume", AC97_AUX, 4, 7, 1), 181SOC_SINGLE_TLV("Speaker Mixer Beep Playback Volume", AC97_AUX, 8, 7, 1,
182 misc_tlv),
183SOC_SINGLE_TLV("Mono Mixer Beep Playback Volume", AC97_AUX, 4, 7, 1, misc_tlv),
171 184
172SOC_SINGLE("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1), 185SOC_SINGLE_TLV("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1,
186 misc_tlv),
173SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1), 187SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
174SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1), 188SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1),
175 189
190SOC_SINGLE_TLV("Headphone Mixer Aux Playback Volume", AC97_REC_SEL, 12, 7, 1,
191 misc_tlv),
192
193SOC_SINGLE_TLV("Speaker Mixer Voice Playback Volume", AC97_PCM, 8, 7, 1,
194 misc_tlv),
195SOC_SINGLE_TLV("Speaker Mixer Aux Playback Volume", AC97_REC_SEL, 8, 7, 1,
196 misc_tlv),
197
198SOC_SINGLE_TLV("Mono Mixer Voice Playback Volume", AC97_PCM, 4, 7, 1,
199 misc_tlv),
200SOC_SINGLE_TLV("Mono Mixer Aux Playback Volume", AC97_REC_SEL, 4, 7, 1,
201 misc_tlv),
202
176SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1), 203SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1),
177SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1), 204SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1),
178SOC_SINGLE("Aux Playback Mono Volume", AC97_REC_SEL, 4, 7, 1),
179 205
180SOC_ENUM("Bass Control", wm9713_enum[16]), 206SOC_ENUM("Bass Control", wm9713_enum[16]),
181SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), 207SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
@@ -1186,8 +1212,6 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1186 struct snd_soc_codec *codec; 1212 struct snd_soc_codec *codec;
1187 int ret = 0, reg; 1213 int ret = 0, reg;
1188 1214
1189 printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION);
1190
1191 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), 1215 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
1192 GFP_KERNEL); 1216 GFP_KERNEL);
1193 if (socdev->card->codec == NULL) 1217 if (socdev->card->codec == NULL)
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index d73c30536a2c..0ad9f5d536c6 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -68,24 +68,77 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
68 int count = 0; 68 int count = 0;
69 69
70 dev_dbg(codec->dev, "Waiting for DC servo...\n"); 70 dev_dbg(codec->dev, "Waiting for DC servo...\n");
71
71 do { 72 do {
72 count++; 73 count++;
73 msleep(1); 74 msleep(1);
74 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); 75 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
75 dev_dbg(codec->dev, "DC servo status: %x\n", reg); 76 dev_dbg(codec->dev, "DC servo: %x\n", reg);
76 } while ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 77 } while (reg & WM8993_DCS_DATAPATH_BUSY);
77 != WM8993_DCS_CAL_COMPLETE_MASK && count < 1000);
78 78
79 if ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 79 if (reg & WM8993_DCS_DATAPATH_BUSY)
80 != WM8993_DCS_CAL_COMPLETE_MASK)
81 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 80 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
82} 81}
83 82
84/* 83/*
84 * Startup calibration of the DC servo
85 */
86static void calibrate_dc_servo(struct snd_soc_codec *codec)
87{
88 struct wm_hubs_data *hubs = codec->private_data;
89 u16 reg, dcs_cfg;
90
91 /* Set for 32 series updates */
92 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
93 WM8993_DCS_SERIES_NO_01_MASK,
94 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
95
96 /* Enable the DC servo. Write all bits to avoid triggering startup
97 * or write calibration.
98 */
99 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
100 0xFFFF,
101 WM8993_DCS_ENA_CHAN_0 |
102 WM8993_DCS_ENA_CHAN_1 |
103 WM8993_DCS_TRIG_SERIES_1 |
104 WM8993_DCS_TRIG_SERIES_0);
105
106 wait_for_dc_servo(codec);
107
108 /* Apply correction to DC servo result */
109 if (hubs->dcs_codes) {
110 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
111 hubs->dcs_codes);
112
113 /* HPOUT1L */
114 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) &
115 WM8993_DCS_INTEG_CHAN_0_MASK;;
116 reg += hubs->dcs_codes;
117 dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
118
119 /* HPOUT1R */
120 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) &
121 WM8993_DCS_INTEG_CHAN_1_MASK;
122 reg += hubs->dcs_codes;
123 dcs_cfg |= reg;
124
125 /* Do it */
126 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
127 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
128 WM8993_DCS_TRIG_DAC_WR_0 |
129 WM8993_DCS_TRIG_DAC_WR_1,
130 WM8993_DCS_TRIG_DAC_WR_0 |
131 WM8993_DCS_TRIG_DAC_WR_1);
132
133 wait_for_dc_servo(codec);
134 }
135}
136
137/*
85 * Update the DC servo calibration on gain changes 138 * Update the DC servo calibration on gain changes
86 */ 139 */
87static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, 140static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
88 struct snd_ctl_elem_value *ucontrol) 141 struct snd_ctl_elem_value *ucontrol)
89{ 142{
90 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 143 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
91 int ret; 144 int ret;
@@ -251,6 +304,47 @@ SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
251 line_tlv), 304 line_tlv),
252}; 305};
253 306
307static int hp_supply_event(struct snd_soc_dapm_widget *w,
308 struct snd_kcontrol *kcontrol, int event)
309{
310 struct snd_soc_codec *codec = w->codec;
311 struct wm_hubs_data *hubs = codec->private_data;
312
313 switch (event) {
314 case SND_SOC_DAPM_PRE_PMU:
315 switch (hubs->hp_startup_mode) {
316 case 0:
317 break;
318 case 1:
319 /* Enable the headphone amp */
320 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
321 WM8993_HPOUT1L_ENA |
322 WM8993_HPOUT1R_ENA,
323 WM8993_HPOUT1L_ENA |
324 WM8993_HPOUT1R_ENA);
325
326 /* Enable the second stage */
327 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
328 WM8993_HPOUT1L_DLY |
329 WM8993_HPOUT1R_DLY,
330 WM8993_HPOUT1L_DLY |
331 WM8993_HPOUT1R_DLY);
332 break;
333 default:
334 dev_err(codec->dev, "Unknown HP startup mode %d\n",
335 hubs->hp_startup_mode);
336 break;
337 }
338
339 case SND_SOC_DAPM_PRE_PMD:
340 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
341 WM8993_CP_ENA, 0);
342 break;
343 }
344
345 return 0;
346}
347
254static int hp_event(struct snd_soc_dapm_widget *w, 348static int hp_event(struct snd_soc_dapm_widget *w,
255 struct snd_kcontrol *kcontrol, int event) 349 struct snd_kcontrol *kcontrol, int event)
256{ 350{
@@ -271,14 +365,11 @@ static int hp_event(struct snd_soc_dapm_widget *w,
271 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY; 365 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
272 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg); 366 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
273 367
274 /* Start the DC servo */ 368 /* Smallest supported update interval */
275 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 369 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
276 0xFFFF, 370 WM8993_DCS_TIMER_PERIOD_01_MASK, 1);
277 WM8993_DCS_ENA_CHAN_0 | 371
278 WM8993_DCS_ENA_CHAN_1 | 372 calibrate_dc_servo(codec);
279 WM8993_DCS_TRIG_STARTUP_1 |
280 WM8993_DCS_TRIG_STARTUP_0);
281 wait_for_dc_servo(codec);
282 373
283 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | 374 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
284 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; 375 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
@@ -286,23 +377,19 @@ static int hp_event(struct snd_soc_dapm_widget *w,
286 break; 377 break;
287 378
288 case SND_SOC_DAPM_PRE_PMD: 379 case SND_SOC_DAPM_PRE_PMD:
289 reg &= ~(WM8993_HPOUT1L_RMV_SHORT | 380 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
290 WM8993_HPOUT1L_DLY | 381 WM8993_HPOUT1L_DLY |
291 WM8993_HPOUT1L_OUTP | 382 WM8993_HPOUT1R_DLY |
292 WM8993_HPOUT1R_RMV_SHORT | 383 WM8993_HPOUT1L_RMV_SHORT |
293 WM8993_HPOUT1R_DLY | 384 WM8993_HPOUT1R_RMV_SHORT, 0);
294 WM8993_HPOUT1R_OUTP);
295 385
296 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 386 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
297 0xffff, 0); 387 WM8993_HPOUT1L_OUTP |
388 WM8993_HPOUT1R_OUTP, 0);
298 389
299 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
300 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 390 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
301 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 391 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
302 0); 392 0);
303
304 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
305 WM8993_CP_ENA, 0);
306 break; 393 break;
307 } 394 }
308 395
@@ -473,6 +560,8 @@ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8993_POWER_MANAGEMENT_3, 4, 0,
473SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0), 560SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0),
474SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0), 561SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
475 562
563SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
564 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
476SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, 565SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0,
477 NULL, 0, 566 NULL, 0,
478 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 567 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -626,6 +715,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
626 { "Headphone PGA", NULL, "Left Headphone Mux" }, 715 { "Headphone PGA", NULL, "Left Headphone Mux" },
627 { "Headphone PGA", NULL, "Right Headphone Mux" }, 716 { "Headphone PGA", NULL, "Right Headphone Mux" },
628 { "Headphone PGA", NULL, "CLK_SYS" }, 717 { "Headphone PGA", NULL, "CLK_SYS" },
718 { "Headphone PGA", NULL, "Headphone Supply" },
629 719
630 { "HPOUT1L", NULL, "Headphone PGA" }, 720 { "HPOUT1L", NULL, "Headphone PGA" },
631 { "HPOUT1R", NULL, "Headphone PGA" }, 721 { "HPOUT1R", NULL, "Headphone PGA" },
@@ -753,6 +843,12 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
753 WM8993_LINEOUT2_MODE, 843 WM8993_LINEOUT2_MODE,
754 WM8993_LINEOUT2_MODE); 844 WM8993_LINEOUT2_MODE);
755 845
846 /* If the line outputs are differential then we aren't presenting
847 * VMID as an output and can disable it.
848 */
849 if (lineout1_diff && lineout2_diff)
850 codec->idle_bias_off = 1;
851
756 if (lineout1fb) 852 if (lineout1fb)
757 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, 853 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
758 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB); 854 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 36d3fba1de8b..420104fe9c90 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -18,6 +18,12 @@ struct snd_soc_codec;
18 18
19extern const unsigned int wm_hubs_spkmix_tlv[]; 19extern const unsigned int wm_hubs_spkmix_tlv[];
20 20
21/* This *must* be the first element of the codec->private_data struct */
22struct wm_hubs_data {
23 int dcs_codes;
24 int hp_startup_mode;
25};
26
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 27extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int); 28extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
23extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *, 29extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,