aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig49
-rw-r--r--sound/soc/codecs/Makefile28
-rw-r--r--sound/soc/codecs/ac97.c13
-rw-r--r--sound/soc/codecs/ad1836.c109
-rw-r--r--sound/soc/codecs/ad1836.h1
-rw-r--r--sound/soc/codecs/ad1938.c241
-rw-r--r--sound/soc/codecs/ad1980.c6
-rw-r--r--sound/soc/codecs/ad73311.c9
-rw-r--r--sound/soc/codecs/ads117x.c124
-rw-r--r--sound/soc/codecs/ads117x.h13
-rw-r--r--sound/soc/codecs/ak4104.c19
-rw-r--r--sound/soc/codecs/ak4535.c10
-rw-r--r--sound/soc/codecs/ak4642.c12
-rw-r--r--sound/soc/codecs/ak4671.c816
-rw-r--r--sound/soc/codecs/ak4671.h156
-rw-r--r--sound/soc/codecs/cs4270.c114
-rw-r--r--sound/soc/codecs/cx20442.c13
-rw-r--r--sound/soc/codecs/da7210.c590
-rw-r--r--sound/soc/codecs/da7210.h24
-rw-r--r--sound/soc/codecs/pcm3008.c10
-rw-r--r--sound/soc/codecs/ssm2602.c10
-rw-r--r--sound/soc/codecs/stac9766.c22
-rw-r--r--sound/soc/codecs/tlv320aic23.c14
-rw-r--r--sound/soc/codecs/tlv320aic26.c12
-rw-r--r--sound/soc/codecs/tlv320aic3x.c87
-rw-r--r--sound/soc/codecs/tlv320dac33.c1423
-rw-r--r--sound/soc/codecs/tlv320dac33.h267
-rw-r--r--sound/soc/codecs/tpa6130a2.c531
-rw-r--r--sound/soc/codecs/tpa6130a2.h61
-rw-r--r--sound/soc/codecs/twl4030.c490
-rw-r--r--sound/soc/codecs/twl4030.h242
-rw-r--r--sound/soc/codecs/uda134x.c14
-rw-r--r--sound/soc/codecs/uda1380.c11
-rw-r--r--sound/soc/codecs/wm2000.c888
-rw-r--r--sound/soc/codecs/wm2000.h79
-rw-r--r--sound/soc/codecs/wm8350.c66
-rw-r--r--sound/soc/codecs/wm8400.c33
-rw-r--r--sound/soc/codecs/wm8510.c29
-rw-r--r--sound/soc/codecs/wm8523.c27
-rw-r--r--sound/soc/codecs/wm8580.c31
-rw-r--r--sound/soc/codecs/wm8711.c634
-rw-r--r--sound/soc/codecs/wm8711.h42
-rw-r--r--sound/soc/codecs/wm8727.c168
-rw-r--r--sound/soc/codecs/wm8727.h21
-rw-r--r--sound/soc/codecs/wm8728.c11
-rw-r--r--sound/soc/codecs/wm8731.c98
-rw-r--r--sound/soc/codecs/wm8750.c10
-rw-r--r--sound/soc/codecs/wm8753.c58
-rw-r--r--sound/soc/codecs/wm8776.c46
-rw-r--r--sound/soc/codecs/wm8900.c37
-rw-r--r--sound/soc/codecs/wm8903.c38
-rw-r--r--sound/soc/codecs/wm8904.c2657
-rw-r--r--sound/soc/codecs/wm8904.h1681
-rw-r--r--sound/soc/codecs/wm8940.c43
-rw-r--r--sound/soc/codecs/wm8955.c1152
-rw-r--r--sound/soc/codecs/wm8955.h489
-rw-r--r--sound/soc/codecs/wm8960.c31
-rw-r--r--sound/soc/codecs/wm8961.c31
-rw-r--r--sound/soc/codecs/wm8971.c12
-rw-r--r--sound/soc/codecs/wm8974.c65
-rw-r--r--sound/soc/codecs/wm8974.h12
-rw-r--r--sound/soc/codecs/wm8978.c1150
-rw-r--r--sound/soc/codecs/wm8978.h86
-rw-r--r--sound/soc/codecs/wm8988.c45
-rw-r--r--sound/soc/codecs/wm8990.c25
-rw-r--r--sound/soc/codecs/wm8993.c361
-rw-r--r--sound/soc/codecs/wm8994.c3874
-rw-r--r--sound/soc/codecs/wm8994.h26
-rw-r--r--sound/soc/codecs/wm9081.c28
-rw-r--r--sound/soc/codecs/wm9705.c8
-rw-r--r--sound/soc/codecs/wm9712.c11
-rw-r--r--sound/soc/codecs/wm9713.c91
-rw-r--r--sound/soc/codecs/wm_hubs.c222
-rw-r--r--sound/soc/codecs/wm_hubs.h12
74 files changed, 18149 insertions, 1820 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0edca93af3b0..1743d565e996 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -15,12 +15,15 @@ config SND_SOC_ALL_CODECS
15 select SND_SOC_AD1836 if SPI_MASTER 15 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD1938 if SPI_MASTER 16 select SND_SOC_AD1938 if SPI_MASTER
17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
18 select SND_SOC_ADS117X
18 select SND_SOC_AD73311 if I2C 19 select SND_SOC_AD73311 if I2C
19 select SND_SOC_AK4104 if SPI_MASTER 20 select SND_SOC_AK4104 if SPI_MASTER
20 select SND_SOC_AK4535 if I2C 21 select SND_SOC_AK4535 if I2C
21 select SND_SOC_AK4642 if I2C 22 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C
22 select SND_SOC_CS4270 if I2C 24 select SND_SOC_CS4270 if I2C
23 select SND_SOC_MAX9877 if I2C 25 select SND_SOC_MAX9877 if I2C
26 select SND_SOC_DA7210 if I2C
24 select SND_SOC_PCM3008 27 select SND_SOC_PCM3008
25 select SND_SOC_SPDIF 28 select SND_SOC_SPDIF
26 select SND_SOC_SSM2602 if I2C 29 select SND_SOC_SSM2602 if I2C
@@ -28,14 +31,19 @@ config SND_SOC_ALL_CODECS
28 select SND_SOC_TLV320AIC23 if I2C 31 select SND_SOC_TLV320AIC23 if I2C
29 select SND_SOC_TLV320AIC26 if SPI_MASTER 32 select SND_SOC_TLV320AIC26 if SPI_MASTER
30 select SND_SOC_TLV320AIC3X if I2C 33 select SND_SOC_TLV320AIC3X if I2C
34 select SND_SOC_TPA6130A2 if I2C
35 select SND_SOC_TLV320DAC33 if I2C
31 select SND_SOC_TWL4030 if TWL4030_CORE 36 select SND_SOC_TWL4030 if TWL4030_CORE
32 select SND_SOC_UDA134X 37 select SND_SOC_UDA134X
33 select SND_SOC_UDA1380 if I2C 38 select SND_SOC_UDA1380 if I2C
39 select SND_SOC_WM2000 if I2C
34 select SND_SOC_WM8350 if MFD_WM8350 40 select SND_SOC_WM8350 if MFD_WM8350
35 select SND_SOC_WM8400 if MFD_WM8400 41 select SND_SOC_WM8400 if MFD_WM8400
36 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 42 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
37 select SND_SOC_WM8523 if I2C 43 select SND_SOC_WM8523 if I2C
38 select SND_SOC_WM8580 if I2C 44 select SND_SOC_WM8580 if I2C
45 select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI
46 select SND_SOC_WM8727
39 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 47 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
40 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 48 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
41 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 49 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
@@ -43,14 +51,18 @@ config SND_SOC_ALL_CODECS
43 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 51 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
44 select SND_SOC_WM8900 if I2C 52 select SND_SOC_WM8900 if I2C
45 select SND_SOC_WM8903 if I2C 53 select SND_SOC_WM8903 if I2C
54 select SND_SOC_WM8904 if I2C
46 select SND_SOC_WM8940 if I2C 55 select SND_SOC_WM8940 if I2C
56 select SND_SOC_WM8955 if I2C
47 select SND_SOC_WM8960 if I2C 57 select SND_SOC_WM8960 if I2C
48 select SND_SOC_WM8961 if I2C 58 select SND_SOC_WM8961 if I2C
49 select SND_SOC_WM8971 if I2C 59 select SND_SOC_WM8971 if I2C
50 select SND_SOC_WM8974 if I2C 60 select SND_SOC_WM8974 if I2C
61 select SND_SOC_WM8978 if I2C
51 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 62 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
52 select SND_SOC_WM8990 if I2C 63 select SND_SOC_WM8990 if I2C
53 select SND_SOC_WM8993 if I2C 64 select SND_SOC_WM8993 if I2C
65 select SND_SOC_WM8994 if MFD_WM8994
54 select SND_SOC_WM9081 if I2C 66 select SND_SOC_WM9081 if I2C
55 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 67 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
56 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 68 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -86,6 +98,9 @@ config SND_SOC_AD1980
86 98
87config SND_SOC_AD73311 99config SND_SOC_AD73311
88 tristate 100 tristate
101
102config SND_SOC_ADS117X
103 tristate
89 104
90config SND_SOC_AK4104 105config SND_SOC_AK4104
91 tristate 106 tristate
@@ -96,10 +111,16 @@ config SND_SOC_AK4535
96config SND_SOC_AK4642 111config SND_SOC_AK4642
97 tristate 112 tristate
98 113
114config SND_SOC_AK4671
115 tristate
116
99# Cirrus Logic CS4270 Codec 117# Cirrus Logic CS4270 Codec
100config SND_SOC_CS4270 118config SND_SOC_CS4270
101 tristate 119 tristate
102 120
121config SND_SOC_DA7210
122 tristate
123
103# Cirrus Logic CS4270 Codec VD = 3.3V Errata 124# Cirrus Logic CS4270 Codec VD = 3.3V Errata
104# 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
105# 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
@@ -136,7 +157,11 @@ config SND_SOC_TLV320AIC26
136config SND_SOC_TLV320AIC3X 157config SND_SOC_TLV320AIC3X
137 tristate 158 tristate
138 159
160config SND_SOC_TLV320DAC33
161 tristate
162
139config SND_SOC_TWL4030 163config SND_SOC_TWL4030
164 select TWL4030_CODEC
140 tristate 165 tristate
141 166
142config SND_SOC_UDA134X 167config SND_SOC_UDA134X
@@ -160,6 +185,12 @@ config SND_SOC_WM8523
160config SND_SOC_WM8580 185config SND_SOC_WM8580
161 tristate 186 tristate
162 187
188config SND_SOC_WM8711
189 tristate
190
191config SND_SOC_WM8727
192 tristate
193
163config SND_SOC_WM8728 194config SND_SOC_WM8728
164 tristate 195 tristate
165 196
@@ -181,9 +212,15 @@ config SND_SOC_WM8900
181config SND_SOC_WM8903 212config SND_SOC_WM8903
182 tristate 213 tristate
183 214
215config SND_SOC_WM8904
216 tristate
217
184config SND_SOC_WM8940 218config SND_SOC_WM8940
185 tristate 219 tristate
186 220
221config SND_SOC_WM8955
222 tristate
223
187config SND_SOC_WM8960 224config SND_SOC_WM8960
188 tristate 225 tristate
189 226
@@ -196,6 +233,9 @@ config SND_SOC_WM8971
196config SND_SOC_WM8974 233config SND_SOC_WM8974
197 tristate 234 tristate
198 235
236config SND_SOC_WM8978
237 tristate
238
199config SND_SOC_WM8988 239config SND_SOC_WM8988
200 tristate 240 tristate
201 241
@@ -205,6 +245,9 @@ config SND_SOC_WM8990
205config SND_SOC_WM8993 245config SND_SOC_WM8993
206 tristate 246 tristate
207 247
248config SND_SOC_WM8994
249 tristate
250
208config SND_SOC_WM9081 251config SND_SOC_WM9081
209 tristate 252 tristate
210 253
@@ -220,3 +263,9 @@ config SND_SOC_WM9713
220# Amp 263# Amp
221config SND_SOC_MAX9877 264config SND_SOC_MAX9877
222 tristate 265 tristate
266
267config SND_SOC_TPA6130A2
268 tristate
269
270config SND_SOC_WM2000
271 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fb4af28486ba..dd5ce6df6292 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,11 +3,14 @@ snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad1938-objs := ad1938.o 3snd-soc-ad1938-objs := ad1938.o
4snd-soc-ad1980-objs := ad1980.o 4snd-soc-ad1980-objs := ad1980.o
5snd-soc-ad73311-objs := ad73311.o 5snd-soc-ad73311-objs := ad73311.o
6snd-soc-ads117x-objs := ads117x.o
6snd-soc-ak4104-objs := ak4104.o 7snd-soc-ak4104-objs := ak4104.o
7snd-soc-ak4535-objs := ak4535.o 8snd-soc-ak4535-objs := ak4535.o
8snd-soc-ak4642-objs := ak4642.o 9snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o
9snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
10snd-soc-cx20442-objs := cx20442.o 12snd-soc-cx20442-objs := cx20442.o
13snd-soc-da7210-objs := da7210.o
11snd-soc-l3-objs := l3.o 14snd-soc-l3-objs := l3.o
12snd-soc-pcm3008-objs := pcm3008.o 15snd-soc-pcm3008-objs := pcm3008.o
13snd-soc-spdif-objs := spdif_transciever.o 16snd-soc-spdif-objs := spdif_transciever.o
@@ -16,6 +19,7 @@ snd-soc-stac9766-objs := stac9766.o
16snd-soc-tlv320aic23-objs := tlv320aic23.o 19snd-soc-tlv320aic23-objs := tlv320aic23.o
17snd-soc-tlv320aic26-objs := tlv320aic26.o 20snd-soc-tlv320aic26-objs := tlv320aic26.o
18snd-soc-tlv320aic3x-objs := tlv320aic3x.o 21snd-soc-tlv320aic3x-objs := tlv320aic3x.o
22snd-soc-tlv320dac33-objs := tlv320dac33.o
19snd-soc-twl4030-objs := twl4030.o 23snd-soc-twl4030-objs := twl4030.o
20snd-soc-uda134x-objs := uda134x.o 24snd-soc-uda134x-objs := uda134x.o
21snd-soc-uda1380-objs := uda1380.o 25snd-soc-uda1380-objs := uda1380.o
@@ -24,6 +28,8 @@ snd-soc-wm8400-objs := wm8400.o
24snd-soc-wm8510-objs := wm8510.o 28snd-soc-wm8510-objs := wm8510.o
25snd-soc-wm8523-objs := wm8523.o 29snd-soc-wm8523-objs := wm8523.o
26snd-soc-wm8580-objs := wm8580.o 30snd-soc-wm8580-objs := wm8580.o
31snd-soc-wm8711-objs := wm8711.o
32snd-soc-wm8727-objs := wm8727.o
27snd-soc-wm8728-objs := wm8728.o 33snd-soc-wm8728-objs := wm8728.o
28snd-soc-wm8731-objs := wm8731.o 34snd-soc-wm8731-objs := wm8731.o
29snd-soc-wm8750-objs := wm8750.o 35snd-soc-wm8750-objs := wm8750.o
@@ -31,14 +37,18 @@ snd-soc-wm8753-objs := wm8753.o
31snd-soc-wm8776-objs := wm8776.o 37snd-soc-wm8776-objs := wm8776.o
32snd-soc-wm8900-objs := wm8900.o 38snd-soc-wm8900-objs := wm8900.o
33snd-soc-wm8903-objs := wm8903.o 39snd-soc-wm8903-objs := wm8903.o
40snd-soc-wm8904-objs := wm8904.o
34snd-soc-wm8940-objs := wm8940.o 41snd-soc-wm8940-objs := wm8940.o
42snd-soc-wm8955-objs := wm8955.o
35snd-soc-wm8960-objs := wm8960.o 43snd-soc-wm8960-objs := wm8960.o
36snd-soc-wm8961-objs := wm8961.o 44snd-soc-wm8961-objs := wm8961.o
37snd-soc-wm8971-objs := wm8971.o 45snd-soc-wm8971-objs := wm8971.o
38snd-soc-wm8974-objs := wm8974.o 46snd-soc-wm8974-objs := wm8974.o
47snd-soc-wm8978-objs := wm8978.o
39snd-soc-wm8988-objs := wm8988.o 48snd-soc-wm8988-objs := wm8988.o
40snd-soc-wm8990-objs := wm8990.o 49snd-soc-wm8990-objs := wm8990.o
41snd-soc-wm8993-objs := wm8993.o 50snd-soc-wm8993-objs := wm8993.o
51snd-soc-wm8994-objs := wm8994.o
42snd-soc-wm9081-objs := wm9081.o 52snd-soc-wm9081-objs := wm9081.o
43snd-soc-wm9705-objs := wm9705.o 53snd-soc-wm9705-objs := wm9705.o
44snd-soc-wm9712-objs := wm9712.o 54snd-soc-wm9712-objs := wm9712.o
@@ -47,17 +57,22 @@ snd-soc-wm-hubs-objs := wm_hubs.o
47 57
48# Amp 58# Amp
49snd-soc-max9877-objs := max9877.o 59snd-soc-max9877-objs := max9877.o
60snd-soc-tpa6130a2-objs := tpa6130a2.o
61snd-soc-wm2000-objs := wm2000.o
50 62
51obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 63obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
52obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 64obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
53obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o 65obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o
54obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 66obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
55obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 67obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
68obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
56obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 69obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
57obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 70obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
58obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 71obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
72obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
59obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 73obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
60obj-$(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
61obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 76obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
62obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 77obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
63obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 78obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
@@ -66,6 +81,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
66obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 81obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
67obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 82obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
68obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 83obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
84obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
69obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 85obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
70obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 86obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
71obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 87obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
@@ -74,6 +90,8 @@ obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
74obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 90obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
75obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o 91obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
76obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 92obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
93obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
94obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
77obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 95obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
78obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 96obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
79obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 97obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
@@ -81,14 +99,18 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
81obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 99obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
82obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 100obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
83obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 101obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
84obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 102obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
85obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
86obj-$(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
87obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 105obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
88obj-$(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
89obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 110obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
90obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 111obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
91obj-$(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
92obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 114obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
93obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 115obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
94obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 116obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
@@ -97,3 +119,5 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
97 119
98# Amp 120# Amp
99obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 121obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.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/ac97.c b/sound/soc/codecs/ac97.c
index 932299bb5d1e..1f5e57a4bb7a 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/slab.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/device.h> 18#include <linux/device.h>
18#include <sound/core.h> 19#include <sound/core.h>
@@ -80,9 +81,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
80static int ac97_soc_probe(struct platform_device *pdev) 81static int ac97_soc_probe(struct platform_device *pdev)
81{ 82{
82 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 83 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
84 struct snd_soc_card *card = socdev->card;
83 struct snd_soc_codec *codec; 85 struct snd_soc_codec *codec;
84 struct snd_ac97_bus *ac97_bus; 86 struct snd_ac97_bus *ac97_bus;
85 struct snd_ac97_template ac97_template; 87 struct snd_ac97_template ac97_template;
88 int i;
86 int ret = 0; 89 int ret = 0;
87 90
88 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); 91 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
@@ -117,9 +120,13 @@ static int ac97_soc_probe(struct platform_device *pdev)
117 if (ret < 0) 120 if (ret < 0)
118 goto bus_err; 121 goto bus_err;
119 122
120 ret = snd_soc_init_card(socdev); 123 for (i = 0; i < card->num_links; i++) {
121 if (ret < 0) 124 if (card->dai_link[i].codec_dai->ac97_control) {
122 goto bus_err; 125 snd_ac97_dev_add_pdata(codec->ac97,
126 card->dai_link[i].cpu_dai->ac97_pdata);
127 }
128 }
129
123 return 0; 130 return 0;
124 131
125bus_err: 132bus_err:
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c48485f2c55d..11b62dee842c 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/slab.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/device.h> 23#include <linux/device.h>
@@ -171,57 +172,35 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
171 return 0; 172 return 0;
172} 173}
173 174
174 175#ifdef CONFIG_PM
175/* 176static int ad1836_soc_suspend(struct platform_device *pdev,
176 * interface to read/write ad1836 register 177 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{ 178{
189 u16 *reg_cache = codec->reg_cache; 179 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
190 int ret = 0; 180 struct snd_soc_codec *codec = socdev->card->codec;
191 181
192 if (value != reg_cache[reg]) { 182 /* reset clock control mode */
193 unsigned short buf; 183 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
194 struct spi_transfer t = { 184 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 185
209 return ret; 186 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
210} 187}
211 188
212/* 189static 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{ 190{
218 u16 *reg_cache = codec->reg_cache; 191 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
192 struct snd_soc_codec *codec = socdev->card->codec;
219 193
220 if (reg >= codec->reg_cache_size) 194 /* restore clock control mode */
221 return -EINVAL; 195 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
196 adc_ctrl2 |= AD1836_ADC_AUX;
222 197
223 return reg_cache[reg]; 198 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
224} 199}
200#else
201#define ad1836_soc_suspend NULL
202#define ad1836_soc_resume NULL
203#endif
225 204
226static int __devinit ad1836_spi_probe(struct spi_device *spi) 205static int __devinit ad1836_spi_probe(struct spi_device *spi)
227{ 206{
@@ -306,32 +285,38 @@ static int ad1836_register(struct ad1836_priv *ad1836)
306 codec->owner = THIS_MODULE; 285 codec->owner = THIS_MODULE;
307 codec->dai = &ad1836_dai; 286 codec->dai = &ad1836_dai;
308 codec->num_dai = 1; 287 codec->num_dai = 1;
309 codec->write = ad1836_write_reg;
310 codec->read = ad1836_read_reg_cache;
311 INIT_LIST_HEAD(&codec->dapm_widgets); 288 INIT_LIST_HEAD(&codec->dapm_widgets);
312 INIT_LIST_HEAD(&codec->dapm_paths); 289 INIT_LIST_HEAD(&codec->dapm_paths);
313 290
314 ad1836_dai.dev = codec->dev; 291 ad1836_dai.dev = codec->dev;
315 ad1836_codec = codec; 292 ad1836_codec = codec;
316 293
294 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
295 if (ret < 0) {
296 dev_err(codec->dev, "failed to set cache I/O: %d\n",
297 ret);
298 kfree(ad1836);
299 return ret;
300 }
301
317 /* default setting for ad1836 */ 302 /* default setting for ad1836 */
318 /* de-emphasis: 48kHz, power-on dac */ 303 /* de-emphasis: 48kHz, power-on dac */
319 codec->write(codec, AD1836_DAC_CTRL1, 0x300); 304 snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
320 /* unmute dac channels */ 305 /* unmute dac channels */
321 codec->write(codec, AD1836_DAC_CTRL2, 0x0); 306 snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
322 /* high-pass filter enable, power-on adc */ 307 /* high-pass filter enable, power-on adc */
323 codec->write(codec, AD1836_ADC_CTRL1, 0x100); 308 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
324 /* unmute adc channles, adc aux mode */ 309 /* unmute adc channles, adc aux mode */
325 codec->write(codec, AD1836_ADC_CTRL2, 0x180); 310 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
326 /* left/right diff:PGA/MUX */ 311 /* left/right diff:PGA/MUX */
327 codec->write(codec, AD1836_ADC_CTRL3, 0x3A); 312 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
328 /* volume */ 313 /* volume */
329 codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); 314 snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF);
330 codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); 315 snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF);
331 codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); 316 snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF);
332 codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); 317 snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF);
333 codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); 318 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
334 codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); 319 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
335 320
336 ret = snd_soc_register_codec(codec); 321 ret = snd_soc_register_codec(codec);
337 if (ret != 0) { 322 if (ret != 0) {
@@ -385,19 +370,7 @@ static int ad1836_probe(struct platform_device *pdev)
385 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, 370 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
386 ARRAY_SIZE(ad1836_dapm_widgets)); 371 ARRAY_SIZE(ad1836_dapm_widgets));
387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 372 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
388 snd_soc_dapm_new_widgets(codec);
389 373
390 ret = snd_soc_init_card(socdev);
391 if (ret < 0) {
392 dev_err(codec->dev, "failed to register card: %d\n", ret);
393 goto card_err;
394 }
395
396 return ret;
397
398card_err:
399 snd_soc_free_pcms(socdev);
400 snd_soc_dapm_free(socdev);
401pcm_err: 374pcm_err:
402 return ret; 375 return ret;
403} 376}
@@ -416,6 +389,8 @@ static int ad1836_remove(struct platform_device *pdev)
416struct snd_soc_codec_device soc_codec_dev_ad1836 = { 389struct snd_soc_codec_device soc_codec_dev_ad1836 = {
417 .probe = ad1836_probe, 390 .probe = ad1836_probe,
418 .remove = ad1836_remove, 391 .remove = ad1836_remove,
392 .suspend = ad1836_soc_suspend,
393 .resume = ad1836_soc_resume,
419}; 394};
420EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836); 395EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
421 396
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 34b30efc3cb0..240cd155b313 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -27,6 +27,7 @@
27 */ 27 */
28 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/slab.h>
30#include <linux/module.h> 31#include <linux/module.h>
31#include <linux/kernel.h> 32#include <linux/kernel.h>
32#include <linux/device.h> 33#include <linux/device.h>
@@ -46,6 +47,11 @@ struct ad1938_priv {
46 u8 reg_cache[AD1938_NUM_REGS]; 47 u8 reg_cache[AD1938_NUM_REGS];
47}; 48};
48 49
50/* ad1938 register cache & default register settings */
51static const u8 ad1938_reg[AD1938_NUM_REGS] = {
52 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
53};
54
49static struct snd_soc_codec *ad1938_codec; 55static struct snd_soc_codec *ad1938_codec;
50struct snd_soc_codec_device soc_codec_dev_ad1938; 56struct snd_soc_codec_device soc_codec_dev_ad1938;
51static int ad1938_register(struct ad1938_priv *ad1938); 57static int ad1938_register(struct ad1938_priv *ad1938);
@@ -97,6 +103,7 @@ static const struct snd_kcontrol_new ad1938_snd_controls[] = {
97static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = { 103static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
98 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1), 104 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
99 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 105 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
106 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), 107 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
101 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 108 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
102 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 109 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
@@ -107,6 +114,8 @@ static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
107}; 114};
108 115
109static const struct snd_soc_dapm_route audio_paths[] = { 116static const struct snd_soc_dapm_route audio_paths[] = {
117 { "DAC", NULL, "PLL_PWR" },
118 { "ADC", NULL, "PLL_PWR" },
110 { "DAC", NULL, "ADC_PWR" }, 119 { "DAC", NULL, "ADC_PWR" },
111 { "ADC", NULL, "ADC_PWR" }, 120 { "ADC", NULL, "ADC_PWR" },
112 { "DAC1OUT", "DAC1 Switch", "DAC" }, 121 { "DAC1OUT", "DAC1 Switch", "DAC" },
@@ -126,30 +135,20 @@ static int ad1938_mute(struct snd_soc_dai *dai, int mute)
126 struct snd_soc_codec *codec = dai->codec; 135 struct snd_soc_codec *codec = dai->codec;
127 int reg; 136 int reg;
128 137
129 reg = codec->read(codec, AD1938_DAC_CTRL2); 138 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
130 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg & 139 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
131 (~AD1938_DAC_MASTER_MUTE); 140 (~AD1938_DAC_MASTER_MUTE);
132 codec->write(codec, AD1938_DAC_CTRL2, reg); 141 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 142
144 return 0; 143 return 0;
145} 144}
146 145
147static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 146static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
148 unsigned int mask, int slots, int width) 147 unsigned int rx_mask, int slots, int width)
149{ 148{
150 struct snd_soc_codec *codec = dai->codec; 149 struct snd_soc_codec *codec = dai->codec;
151 int dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 150 int dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
152 int adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 151 int adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
153 152
154 dac_reg &= ~AD1938_DAC_CHAN_MASK; 153 dac_reg &= ~AD1938_DAC_CHAN_MASK;
155 adc_reg &= ~AD1938_ADC_CHAN_MASK; 154 adc_reg &= ~AD1938_ADC_CHAN_MASK;
@@ -175,8 +174,8 @@ static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
175 return -EINVAL; 174 return -EINVAL;
176 } 175 }
177 176
178 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 177 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
179 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 178 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
180 179
181 return 0; 180 return 0;
182} 181}
@@ -187,8 +186,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
187 struct snd_soc_codec *codec = codec_dai->codec; 186 struct snd_soc_codec *codec = codec_dai->codec;
188 int adc_reg, dac_reg; 187 int adc_reg, dac_reg;
189 188
190 adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 189 adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
191 dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 190 dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
192 191
193 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S 192 /* 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) 193 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
@@ -265,8 +264,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
265 return -EINVAL; 264 return -EINVAL;
266 } 265 }
267 266
268 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 267 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
269 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 268 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
270 269
271 return 0; 270 return 0;
272} 271}
@@ -295,134 +294,13 @@ static int ad1938_hw_params(struct snd_pcm_substream *substream,
295 break; 294 break;
296 } 295 }
297 296
298 reg = codec->read(codec, AD1938_DAC_CTRL2); 297 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
299 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len; 298 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
300 codec->write(codec, AD1938_DAC_CTRL2, reg); 299 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
301 300
302 reg = codec->read(codec, AD1938_ADC_CTRL1); 301 reg = snd_soc_read(codec, AD1938_ADC_CTRL1);
303 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len; 302 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
304 codec->write(codec, AD1938_ADC_CTRL1, reg); 303 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 304
427 return 0; 305 return 0;
428} 306}
@@ -512,32 +390,37 @@ static int ad1938_register(struct ad1938_priv *ad1938)
512 codec->owner = THIS_MODULE; 390 codec->owner = THIS_MODULE;
513 codec->dai = &ad1938_dai; 391 codec->dai = &ad1938_dai;
514 codec->num_dai = 1; 392 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); 393 INIT_LIST_HEAD(&codec->dapm_widgets);
519 INIT_LIST_HEAD(&codec->dapm_paths); 394 INIT_LIST_HEAD(&codec->dapm_paths);
520 395
521 ad1938_dai.dev = codec->dev; 396 ad1938_dai.dev = codec->dev;
522 ad1938_codec = codec; 397 ad1938_codec = codec;
523 398
399 memcpy(codec->reg_cache, ad1938_reg, AD1938_NUM_REGS);
400
401 ret = snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_SPI);
402 if (ret < 0) {
403 dev_err(codec->dev, "failed to set cache I/O: %d\n",
404 ret);
405 kfree(ad1938);
406 return ret;
407 }
408
524 /* default setting for ad1938 */ 409 /* default setting for ad1938 */
525 410
526 /* unmute dac channels */ 411 /* unmute dac channels */
527 codec->write(codec, AD1938_DAC_CHNL_MUTE, 0x0); 412 snd_soc_write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
528 /* de-emphasis: 48kHz, powedown dac */ 413 /* de-emphasis: 48kHz, powedown dac */
529 codec->write(codec, AD1938_DAC_CTRL2, 0x1A); 414 snd_soc_write(codec, AD1938_DAC_CTRL2, 0x1A);
530 /* powerdown dac, dac in tdm mode */ 415 /* powerdown dac, dac in tdm mode */
531 codec->write(codec, AD1938_DAC_CTRL0, 0x41); 416 snd_soc_write(codec, AD1938_DAC_CTRL0, 0x41);
532 /* high-pass filter enable */ 417 /* high-pass filter enable */
533 codec->write(codec, AD1938_ADC_CTRL0, 0x3); 418 snd_soc_write(codec, AD1938_ADC_CTRL0, 0x3);
534 /* sata delay=1, adc aux mode */ 419 /* sata delay=1, adc aux mode */
535 codec->write(codec, AD1938_ADC_CTRL1, 0x43); 420 snd_soc_write(codec, AD1938_ADC_CTRL1, 0x43);
536 /* pll input: mclki/xi */ 421 /* pll input: mclki/xi */
537 codec->write(codec, AD1938_PLL_CLK_CTRL0, 0x9D); 422 snd_soc_write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
538 codec->write(codec, AD1938_PLL_CLK_CTRL1, 0x04); 423 snd_soc_write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
539
540 ad1938_fill_cache(codec);
541 424
542 ret = snd_soc_register_codec(codec); 425 ret = snd_soc_register_codec(codec);
543 if (ret != 0) { 426 if (ret != 0) {
@@ -559,7 +442,6 @@ static int ad1938_register(struct ad1938_priv *ad1938)
559 442
560static void ad1938_unregister(struct ad1938_priv *ad1938) 443static void ad1938_unregister(struct ad1938_priv *ad1938)
561{ 444{
562 ad1938_set_bias_level(&ad1938->codec, SND_SOC_BIAS_OFF);
563 snd_soc_unregister_dai(&ad1938_dai); 445 snd_soc_unregister_dai(&ad1938_dai);
564 snd_soc_unregister_codec(&ad1938->codec); 446 snd_soc_unregister_codec(&ad1938->codec);
565 kfree(ad1938); 447 kfree(ad1938);
@@ -592,21 +474,8 @@ static int ad1938_probe(struct platform_device *pdev)
592 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets, 474 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets,
593 ARRAY_SIZE(ad1938_dapm_widgets)); 475 ARRAY_SIZE(ad1938_dapm_widgets));
594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 476 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
595 snd_soc_dapm_new_widgets(codec);
596 477
597 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
598 478
599 ret = snd_soc_init_card(socdev);
600 if (ret < 0) {
601 dev_err(codec->dev, "failed to register card: %d\n", ret);
602 goto card_err;
603 }
604
605 return ret;
606
607card_err:
608 snd_soc_free_pcms(socdev);
609 snd_soc_dapm_free(socdev);
610pcm_err: 479pcm_err:
611 return ret; 480 return ret;
612} 481}
@@ -622,37 +491,9 @@ static int ad1938_remove(struct platform_device *pdev)
622 return 0; 491 return 0;
623} 492}
624 493
625#ifdef CONFIG_PM
626static int ad1938_suspend(struct platform_device *pdev,
627 pm_message_t state)
628{
629 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
630 struct snd_soc_codec *codec = socdev->card->codec;
631
632 ad1938_set_bias_level(codec, SND_SOC_BIAS_OFF);
633 return 0;
634}
635
636static int ad1938_resume(struct platform_device *pdev)
637{
638 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
639 struct snd_soc_codec *codec = socdev->card->codec;
640
641 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
642 ad1938_set_bias_level(codec, SND_SOC_BIAS_ON);
643
644 return 0;
645}
646#else
647#define ad1938_suspend NULL
648#define ad1938_resume NULL
649#endif
650
651struct snd_soc_codec_device soc_codec_dev_ad1938 = { 494struct snd_soc_codec_device soc_codec_dev_ad1938 = {
652 .probe = ad1938_probe, 495 .probe = ad1938_probe,
653 .remove = ad1938_remove, 496 .remove = ad1938_remove,
654 .suspend = ad1938_suspend,
655 .resume = ad1938_resume,
656}; 497};
657EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938); 498EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
658 499
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index d7440a982d22..042072738cdc 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/device.h> 18#include <linux/device.h>
@@ -257,11 +258,6 @@ static int ad1980_soc_probe(struct platform_device *pdev)
257 258
258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls, 259 snd_soc_add_controls(codec, ad1980_snd_ac97_controls,
259 ARRAY_SIZE(ad1980_snd_ac97_controls)); 260 ARRAY_SIZE(ad1980_snd_ac97_controls));
260 ret = snd_soc_init_card(socdev);
261 if (ret < 0) {
262 printk(KERN_ERR "ad1980: failed to register card\n");
263 goto reset_err;
264 }
265 261
266 return 0; 262 return 0;
267 263
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index e61dac5e7b8f..475807bea2c2 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/slab.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/device.h> 17#include <linux/device.h>
@@ -64,16 +65,8 @@ static int ad73311_soc_probe(struct platform_device *pdev)
64 goto pcm_err; 65 goto pcm_err;
65 } 66 }
66 67
67 ret = snd_soc_init_card(socdev);
68 if (ret < 0) {
69 printk(KERN_ERR "ad73311: failed to register card\n");
70 goto register_err;
71 }
72
73 return ret; 68 return ret;
74 69
75register_err:
76 snd_soc_free_pcms(socdev);
77pcm_err: 70pcm_err:
78 kfree(socdev->card->codec); 71 kfree(socdev->card->codec);
79 socdev->card->codec = NULL; 72 socdev->card->codec = NULL;
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
new file mode 100644
index 000000000000..f8e75edb27b7
--- /dev/null
+++ b/sound/soc/codecs/ads117x.c
@@ -0,0 +1,124 @@
1/*
2 * ads117x.c -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/initval.h>
20#include <sound/soc.h>
21
22#include "ads117x.h"
23
24#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
25
26#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
27
28struct snd_soc_dai ads117x_dai = {
29/* ADC */
30 .name = "ADS117X ADC",
31 .id = 1,
32 .capture = {
33 .stream_name = "Capture",
34 .channels_min = 1,
35 .channels_max = 32,
36 .rates = ADS117X_RATES,
37 .formats = ADS117X_FORMATS,},
38};
39EXPORT_SYMBOL_GPL(ads117x_dai);
40
41static int ads117x_probe(struct platform_device *pdev)
42{
43 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
44 struct snd_soc_codec *codec;
45 int ret;
46
47 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
48 if (codec == NULL)
49 return -ENOMEM;
50
51 socdev->card->codec = codec;
52 mutex_init(&codec->mutex);
53 INIT_LIST_HEAD(&codec->dapm_widgets);
54 INIT_LIST_HEAD(&codec->dapm_paths);
55 codec->name = "ADS117X";
56 codec->owner = THIS_MODULE;
57 codec->dai = &ads117x_dai;
58 codec->num_dai = 1;
59
60 /* register pcms */
61 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
62 if (ret < 0) {
63 printk(KERN_ERR "ads117x: failed to create pcms\n");
64 kfree(codec);
65 return ret;
66 }
67
68 return 0;
69}
70
71static int ads117x_remove(struct platform_device *pdev)
72{
73 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
74 struct snd_soc_codec *codec = socdev->card->codec;
75
76 snd_soc_free_pcms(socdev);
77 kfree(codec);
78
79 return 0;
80}
81
82struct snd_soc_codec_device soc_codec_dev_ads117x = {
83 .probe = ads117x_probe,
84 .remove = ads117x_remove,
85};
86EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
87
88static __devinit int ads117x_platform_probe(struct platform_device *pdev)
89{
90 ads117x_dai.dev = &pdev->dev;
91 return snd_soc_register_dai(&ads117x_dai);
92}
93
94static int __devexit ads117x_platform_remove(struct platform_device *pdev)
95{
96 snd_soc_unregister_dai(&ads117x_dai);
97 return 0;
98}
99
100static struct platform_driver ads117x_codec_driver = {
101 .driver = {
102 .name = "ads117x",
103 .owner = THIS_MODULE,
104 },
105
106 .probe = ads117x_platform_probe,
107 .remove = __devexit_p(ads117x_platform_remove),
108};
109
110static int __init ads117x_init(void)
111{
112 return platform_driver_register(&ads117x_codec_driver);
113}
114module_init(ads117x_init);
115
116static void __exit ads117x_exit(void)
117{
118 platform_driver_unregister(&ads117x_codec_driver);
119}
120module_exit(ads117x_exit);
121
122MODULE_DESCRIPTION("ASoC ads117x driver");
123MODULE_AUTHOR("Graeme Gregory");
124MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
new file mode 100644
index 000000000000..dbcf50ec9bd1
--- /dev/null
+++ b/sound/soc/codecs/ads117x.h
@@ -0,0 +1,13 @@
1/*
2 * ads117x.h -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12extern struct snd_soc_dai ads117x_dai;
13extern struct snd_soc_codec_device soc_codec_dev_ads117x;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 4d47bc4f7428..bdeb10dfd887 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <sound/core.h> 14#include <sound/core.h>
14#include <sound/soc.h> 15#include <sound/soc.h>
15#include <sound/initval.h> 16#include <sound/initval.h>
@@ -90,12 +91,10 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
90 if (reg >= codec->reg_cache_size) 91 if (reg >= codec->reg_cache_size)
91 return -EINVAL; 92 return -EINVAL;
92 93
93 reg &= AK4104_REG_MASK;
94 reg |= AK4104_WRITE;
95
96 /* only write to the hardware if value has changed */ 94 /* only write to the hardware if value has changed */
97 if (cache[reg] != value) { 95 if (cache[reg] != value) {
98 u8 tmp[2] = { reg, value }; 96 u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
97
99 if (spi_write(spi, tmp, sizeof(tmp))) { 98 if (spi_write(spi, tmp, sizeof(tmp))) {
100 dev_err(&spi->dev, "SPI write failed\n"); 99 dev_err(&spi->dev, "SPI write failed\n");
101 return -EIO; 100 return -EIO;
@@ -185,9 +184,7 @@ struct snd_soc_dai ak4104_dai = {
185 .stream_name = "Playback", 184 .stream_name = "Playback",
186 .channels_min = 2, 185 .channels_min = 2,
187 .channels_max = 2, 186 .channels_max = 2,
188 .rates = SNDRV_PCM_RATE_44100 | 187 .rates = SNDRV_PCM_RATE_8000_192000,
189 SNDRV_PCM_RATE_48000 |
190 SNDRV_PCM_RATE_32000,
191 .formats = SNDRV_PCM_FMTBIT_S16_LE | 188 .formats = SNDRV_PCM_FMTBIT_S16_LE |
192 SNDRV_PCM_FMTBIT_S24_3LE | 189 SNDRV_PCM_FMTBIT_S24_3LE |
193 SNDRV_PCM_FMTBIT_S24_LE 190 SNDRV_PCM_FMTBIT_S24_LE
@@ -313,14 +310,6 @@ static int ak4104_probe(struct platform_device *pdev)
313 return ret; 310 return ret;
314 } 311 }
315 312
316 /* Register the socdev */
317 ret = snd_soc_init_card(socdev);
318 if (ret < 0) {
319 dev_err(codec->dev, "failed to register card\n");
320 snd_soc_free_pcms(socdev);
321 return ret;
322 }
323
324 return 0; 313 return 0;
325} 314}
326 315
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 0abec0d29a96..352d1d08dbd9 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -294,7 +295,6 @@ static int ak4535_add_widgets(struct snd_soc_codec *codec)
294 295
295 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 296 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
296 297
297 snd_soc_dapm_new_widgets(codec);
298 return 0; 298 return 0;
299} 299}
300 300
@@ -485,17 +485,9 @@ static int ak4535_init(struct snd_soc_device *socdev)
485 snd_soc_add_controls(codec, ak4535_snd_controls, 485 snd_soc_add_controls(codec, ak4535_snd_controls,
486 ARRAY_SIZE(ak4535_snd_controls)); 486 ARRAY_SIZE(ak4535_snd_controls));
487 ak4535_add_widgets(codec); 487 ak4535_add_widgets(codec);
488 ret = snd_soc_init_card(socdev);
489 if (ret < 0) {
490 printk(KERN_ERR "ak4535: failed to register card\n");
491 goto card_err;
492 }
493 488
494 return ret; 489 return ret;
495 490
496card_err:
497 snd_soc_free_pcms(socdev);
498 snd_soc_dapm_free(socdev);
499pcm_err: 491pcm_err:
500 kfree(codec->reg_cache); 492 kfree(codec->reg_cache);
501 493
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index e057c7b578df..729859cf6ca8 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -29,6 +29,7 @@
29#include <linux/pm.h> 29#include <linux/pm.h>
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/slab.h>
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/pcm.h> 34#include <sound/pcm.h>
34#include <sound/pcm_params.h> 35#include <sound/pcm_params.h>
@@ -442,18 +443,9 @@ static int ak4642_probe(struct platform_device *pdev)
442 goto pcm_err; 443 goto pcm_err;
443 } 444 }
444 445
445 ret = snd_soc_init_card(socdev);
446 if (ret < 0) {
447 printk(KERN_ERR "ak4642: failed to register card\n");
448 goto card_err;
449 }
450
451 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 446 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
452 return ret; 447 return ret;
453 448
454card_err:
455 snd_soc_free_pcms(socdev);
456 snd_soc_dapm_free(socdev);
457pcm_err: 449pcm_err:
458 return ret; 450 return ret;
459 451
@@ -479,7 +471,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
479 471
480static int __init ak4642_modinit(void) 472static int __init ak4642_modinit(void)
481{ 473{
482 int ret; 474 int ret = 0;
483#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 475#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
484 ret = i2c_add_driver(&ak4642_i2c_driver); 476 ret = i2c_add_driver(&ak4642_i2c_driver);
485#endif 477#endif
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
new file mode 100644
index 000000000000..926797a014c7
--- /dev/null
+++ b/sound/soc/codecs/ak4671.c
@@ -0,0 +1,816 @@
1/*
2 * ak4671.c -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/delay.h>
18#include <linux/slab.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/initval.h>
22#include <sound/tlv.h>
23
24#include "ak4671.h"
25
26static struct snd_soc_codec *ak4671_codec;
27
28/* codec private data */
29struct ak4671_priv {
30 struct snd_soc_codec codec;
31 u8 reg_cache[AK4671_CACHEREGNUM];
32};
33
34/* ak4671 register cache & default register settings */
35static const u8 ak4671_reg[AK4671_CACHEREGNUM] = {
36 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
37 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */
38 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */
39 0x02, /* AK4671_FORMAT_SELECT (0x03) */
40 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
41 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */
42 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
43 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
44 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
45 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
46 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
47 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
48 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
49 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
50 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
51 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
52 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
53 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
54 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
55 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
56 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
57 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
58 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */
59 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */
60 0x02, /* AK4671_MODE_CONTROL1 (0x18) */
61 0x01, /* AK4671_MODE_CONTROL2 (0x19) */
62 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
63 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
64 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
65 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
66 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
67 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
68 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
69 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
70 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */
71 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */
72 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */
73 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */
74 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */
75 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */
76 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
77 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
78 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
79 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
80 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
81 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
82 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
83 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
84 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
85 0x00, /* this register not used */
86 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */
87 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */
88 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */
89 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */
90 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */
91 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */
92 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */
93 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */
94 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */
95 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */
96 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */
97 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */
98 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */
99 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */
100 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */
101 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */
102 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */
103 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */
104 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */
105 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */
106 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */
107 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */
108 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */
109 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */
110 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */
111 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */
112 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */
113 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */
114 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */
115 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */
116 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
117 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
118 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
119 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */
120 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */
121 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */
122 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
123 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
124 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
125 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
126 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */
127};
128
129/*
130 * LOUT1/ROUT1 output volume control:
131 * from -24 to 6 dB in 6 dB steps (mute instead of -30 dB)
132 */
133static DECLARE_TLV_DB_SCALE(out1_tlv, -3000, 600, 1);
134
135/*
136 * LOUT2/ROUT2 output volume control:
137 * from -33 to 6 dB in 3 dB steps (mute instead of -33 dB)
138 */
139static DECLARE_TLV_DB_SCALE(out2_tlv, -3300, 300, 1);
140
141/*
142 * LOUT3/ROUT3 output volume control:
143 * from -6 to 3 dB in 3 dB steps
144 */
145static DECLARE_TLV_DB_SCALE(out3_tlv, -600, 300, 0);
146
147/*
148 * Mic amp gain control:
149 * from -15 to 30 dB in 3 dB steps
150 * REVISIT: The actual min value(0x01) is -12 dB and the reg value 0x00 is not
151 * available
152 */
153static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -1500, 300, 0);
154
155static const struct snd_kcontrol_new ak4671_snd_controls[] = {
156 /* Common playback gain controls */
157 SOC_SINGLE_TLV("Line Output1 Playback Volume",
158 AK4671_OUTPUT_VOLUME_CONTROL, 0, 0x6, 0, out1_tlv),
159 SOC_SINGLE_TLV("Headphone Output2 Playback Volume",
160 AK4671_OUTPUT_VOLUME_CONTROL, 4, 0xd, 0, out2_tlv),
161 SOC_SINGLE_TLV("Line Output3 Playback Volume",
162 AK4671_LOUT3_POWER_MANAGERMENT, 6, 0x3, 0, out3_tlv),
163
164 /* Common capture gain controls */
165 SOC_DOUBLE_TLV("Mic Amp Capture Volume",
166 AK4671_MIC_AMP_GAIN, 0, 4, 0xf, 0, mic_amp_tlv),
167};
168
169/* event handlers */
170static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
171 struct snd_kcontrol *kcontrol, int event)
172{
173 struct snd_soc_codec *codec = w->codec;
174 u8 reg;
175
176 switch (event) {
177 case SND_SOC_DAPM_POST_PMU:
178 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
179 reg |= AK4671_MUTEN;
180 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
181 break;
182 case SND_SOC_DAPM_PRE_PMD:
183 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
184 reg &= ~AK4671_MUTEN;
185 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
186 break;
187 }
188
189 return 0;
190}
191
192/* Output Mixers */
193static const struct snd_kcontrol_new ak4671_lout1_mixer_controls[] = {
194 SOC_DAPM_SINGLE("DACL", AK4671_LOUT1_SIGNAL_SELECT, 0, 1, 0),
195 SOC_DAPM_SINGLE("LINL1", AK4671_LOUT1_SIGNAL_SELECT, 1, 1, 0),
196 SOC_DAPM_SINGLE("LINL2", AK4671_LOUT1_SIGNAL_SELECT, 2, 1, 0),
197 SOC_DAPM_SINGLE("LINL3", AK4671_LOUT1_SIGNAL_SELECT, 3, 1, 0),
198 SOC_DAPM_SINGLE("LINL4", AK4671_LOUT1_SIGNAL_SELECT, 4, 1, 0),
199 SOC_DAPM_SINGLE("LOOPL", AK4671_LOUT1_SIGNAL_SELECT, 5, 1, 0),
200};
201
202static const struct snd_kcontrol_new ak4671_rout1_mixer_controls[] = {
203 SOC_DAPM_SINGLE("DACR", AK4671_ROUT1_SIGNAL_SELECT, 0, 1, 0),
204 SOC_DAPM_SINGLE("RINR1", AK4671_ROUT1_SIGNAL_SELECT, 1, 1, 0),
205 SOC_DAPM_SINGLE("RINR2", AK4671_ROUT1_SIGNAL_SELECT, 2, 1, 0),
206 SOC_DAPM_SINGLE("RINR3", AK4671_ROUT1_SIGNAL_SELECT, 3, 1, 0),
207 SOC_DAPM_SINGLE("RINR4", AK4671_ROUT1_SIGNAL_SELECT, 4, 1, 0),
208 SOC_DAPM_SINGLE("LOOPR", AK4671_ROUT1_SIGNAL_SELECT, 5, 1, 0),
209};
210
211static const struct snd_kcontrol_new ak4671_lout2_mixer_controls[] = {
212 SOC_DAPM_SINGLE("DACHL", AK4671_LOUT2_SIGNAL_SELECT, 0, 1, 0),
213 SOC_DAPM_SINGLE("LINH1", AK4671_LOUT2_SIGNAL_SELECT, 1, 1, 0),
214 SOC_DAPM_SINGLE("LINH2", AK4671_LOUT2_SIGNAL_SELECT, 2, 1, 0),
215 SOC_DAPM_SINGLE("LINH3", AK4671_LOUT2_SIGNAL_SELECT, 3, 1, 0),
216 SOC_DAPM_SINGLE("LINH4", AK4671_LOUT2_SIGNAL_SELECT, 4, 1, 0),
217 SOC_DAPM_SINGLE("LOOPHL", AK4671_LOUT2_SIGNAL_SELECT, 5, 1, 0),
218};
219
220static const struct snd_kcontrol_new ak4671_rout2_mixer_controls[] = {
221 SOC_DAPM_SINGLE("DACHR", AK4671_ROUT2_SIGNAL_SELECT, 0, 1, 0),
222 SOC_DAPM_SINGLE("RINH1", AK4671_ROUT2_SIGNAL_SELECT, 1, 1, 0),
223 SOC_DAPM_SINGLE("RINH2", AK4671_ROUT2_SIGNAL_SELECT, 2, 1, 0),
224 SOC_DAPM_SINGLE("RINH3", AK4671_ROUT2_SIGNAL_SELECT, 3, 1, 0),
225 SOC_DAPM_SINGLE("RINH4", AK4671_ROUT2_SIGNAL_SELECT, 4, 1, 0),
226 SOC_DAPM_SINGLE("LOOPHR", AK4671_ROUT2_SIGNAL_SELECT, 5, 1, 0),
227};
228
229static const struct snd_kcontrol_new ak4671_lout3_mixer_controls[] = {
230 SOC_DAPM_SINGLE("DACSL", AK4671_LOUT3_SIGNAL_SELECT, 0, 1, 0),
231 SOC_DAPM_SINGLE("LINS1", AK4671_LOUT3_SIGNAL_SELECT, 1, 1, 0),
232 SOC_DAPM_SINGLE("LINS2", AK4671_LOUT3_SIGNAL_SELECT, 2, 1, 0),
233 SOC_DAPM_SINGLE("LINS3", AK4671_LOUT3_SIGNAL_SELECT, 3, 1, 0),
234 SOC_DAPM_SINGLE("LINS4", AK4671_LOUT3_SIGNAL_SELECT, 4, 1, 0),
235 SOC_DAPM_SINGLE("LOOPSL", AK4671_LOUT3_SIGNAL_SELECT, 5, 1, 0),
236};
237
238static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
239 SOC_DAPM_SINGLE("DACSR", AK4671_ROUT3_SIGNAL_SELECT, 0, 1, 0),
240 SOC_DAPM_SINGLE("RINS1", AK4671_ROUT3_SIGNAL_SELECT, 1, 1, 0),
241 SOC_DAPM_SINGLE("RINS2", AK4671_ROUT3_SIGNAL_SELECT, 2, 1, 0),
242 SOC_DAPM_SINGLE("RINS3", AK4671_ROUT3_SIGNAL_SELECT, 3, 1, 0),
243 SOC_DAPM_SINGLE("RINS4", AK4671_ROUT3_SIGNAL_SELECT, 4, 1, 0),
244 SOC_DAPM_SINGLE("LOOPSR", AK4671_ROUT3_SIGNAL_SELECT, 5, 1, 0),
245};
246
247/* Input MUXs */
248static const char *ak4671_lin_mux_texts[] =
249 {"LIN1", "LIN2", "LIN3", "LIN4"};
250static const struct soc_enum ak4671_lin_mux_enum =
251 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0,
252 ARRAY_SIZE(ak4671_lin_mux_texts),
253 ak4671_lin_mux_texts);
254static const struct snd_kcontrol_new ak4671_lin_mux_control =
255 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
256
257static const char *ak4671_rin_mux_texts[] =
258 {"RIN1", "RIN2", "RIN3", "RIN4"};
259static const struct soc_enum ak4671_rin_mux_enum =
260 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2,
261 ARRAY_SIZE(ak4671_rin_mux_texts),
262 ak4671_rin_mux_texts);
263static const struct snd_kcontrol_new ak4671_rin_mux_control =
264 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
265
266static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
267 /* Inputs */
268 SND_SOC_DAPM_INPUT("LIN1"),
269 SND_SOC_DAPM_INPUT("RIN1"),
270 SND_SOC_DAPM_INPUT("LIN2"),
271 SND_SOC_DAPM_INPUT("RIN2"),
272 SND_SOC_DAPM_INPUT("LIN3"),
273 SND_SOC_DAPM_INPUT("RIN3"),
274 SND_SOC_DAPM_INPUT("LIN4"),
275 SND_SOC_DAPM_INPUT("RIN4"),
276
277 /* Outputs */
278 SND_SOC_DAPM_OUTPUT("LOUT1"),
279 SND_SOC_DAPM_OUTPUT("ROUT1"),
280 SND_SOC_DAPM_OUTPUT("LOUT2"),
281 SND_SOC_DAPM_OUTPUT("ROUT2"),
282 SND_SOC_DAPM_OUTPUT("LOUT3"),
283 SND_SOC_DAPM_OUTPUT("ROUT3"),
284
285 /* DAC */
286 SND_SOC_DAPM_DAC("DAC Left", "Left HiFi Playback",
287 AK4671_AD_DA_POWER_MANAGEMENT, 6, 0),
288 SND_SOC_DAPM_DAC("DAC Right", "Right HiFi Playback",
289 AK4671_AD_DA_POWER_MANAGEMENT, 7, 0),
290
291 /* ADC */
292 SND_SOC_DAPM_ADC("ADC Left", "Left HiFi Capture",
293 AK4671_AD_DA_POWER_MANAGEMENT, 4, 0),
294 SND_SOC_DAPM_ADC("ADC Right", "Right HiFi Capture",
295 AK4671_AD_DA_POWER_MANAGEMENT, 5, 0),
296
297 /* PGA */
298 SND_SOC_DAPM_PGA("LOUT2 Mix Amp",
299 AK4671_LOUT2_POWER_MANAGERMENT, 5, 0, NULL, 0),
300 SND_SOC_DAPM_PGA("ROUT2 Mix Amp",
301 AK4671_LOUT2_POWER_MANAGERMENT, 6, 0, NULL, 0),
302
303 SND_SOC_DAPM_PGA("LIN1 Mixing Circuit",
304 AK4671_MIXING_POWER_MANAGEMENT1, 0, 0, NULL, 0),
305 SND_SOC_DAPM_PGA("RIN1 Mixing Circuit",
306 AK4671_MIXING_POWER_MANAGEMENT1, 1, 0, NULL, 0),
307 SND_SOC_DAPM_PGA("LIN2 Mixing Circuit",
308 AK4671_MIXING_POWER_MANAGEMENT1, 2, 0, NULL, 0),
309 SND_SOC_DAPM_PGA("RIN2 Mixing Circuit",
310 AK4671_MIXING_POWER_MANAGEMENT1, 3, 0, NULL, 0),
311 SND_SOC_DAPM_PGA("LIN3 Mixing Circuit",
312 AK4671_MIXING_POWER_MANAGEMENT1, 4, 0, NULL, 0),
313 SND_SOC_DAPM_PGA("RIN3 Mixing Circuit",
314 AK4671_MIXING_POWER_MANAGEMENT1, 5, 0, NULL, 0),
315 SND_SOC_DAPM_PGA("LIN4 Mixing Circuit",
316 AK4671_MIXING_POWER_MANAGEMENT1, 6, 0, NULL, 0),
317 SND_SOC_DAPM_PGA("RIN4 Mixing Circuit",
318 AK4671_MIXING_POWER_MANAGEMENT1, 7, 0, NULL, 0),
319
320 /* Output Mixers */
321 SND_SOC_DAPM_MIXER("LOUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 0, 0,
322 &ak4671_lout1_mixer_controls[0],
323 ARRAY_SIZE(ak4671_lout1_mixer_controls)),
324 SND_SOC_DAPM_MIXER("ROUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 1, 0,
325 &ak4671_rout1_mixer_controls[0],
326 ARRAY_SIZE(ak4671_rout1_mixer_controls)),
327 SND_SOC_DAPM_MIXER_E("LOUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
328 0, 0, &ak4671_lout2_mixer_controls[0],
329 ARRAY_SIZE(ak4671_lout2_mixer_controls),
330 ak4671_out2_event,
331 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
332 SND_SOC_DAPM_MIXER_E("ROUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
333 1, 0, &ak4671_rout2_mixer_controls[0],
334 ARRAY_SIZE(ak4671_rout2_mixer_controls),
335 ak4671_out2_event,
336 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
337 SND_SOC_DAPM_MIXER("LOUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 0, 0,
338 &ak4671_lout3_mixer_controls[0],
339 ARRAY_SIZE(ak4671_lout3_mixer_controls)),
340 SND_SOC_DAPM_MIXER("ROUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 1, 0,
341 &ak4671_rout3_mixer_controls[0],
342 ARRAY_SIZE(ak4671_rout3_mixer_controls)),
343
344 /* Input MUXs */
345 SND_SOC_DAPM_MUX("LIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 2, 0,
346 &ak4671_lin_mux_control),
347 SND_SOC_DAPM_MUX("RIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 3, 0,
348 &ak4671_rin_mux_control),
349
350 /* Mic Power */
351 SND_SOC_DAPM_MICBIAS("Mic Bias", AK4671_AD_DA_POWER_MANAGEMENT, 1, 0),
352
353 /* Supply */
354 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
355};
356
357static const struct snd_soc_dapm_route intercon[] = {
358 {"DAC Left", "NULL", "PMPLL"},
359 {"DAC Right", "NULL", "PMPLL"},
360 {"ADC Left", "NULL", "PMPLL"},
361 {"ADC Right", "NULL", "PMPLL"},
362
363 /* Outputs */
364 {"LOUT1", "NULL", "LOUT1 Mixer"},
365 {"ROUT1", "NULL", "ROUT1 Mixer"},
366 {"LOUT2", "NULL", "LOUT2 Mix Amp"},
367 {"ROUT2", "NULL", "ROUT2 Mix Amp"},
368 {"LOUT3", "NULL", "LOUT3 Mixer"},
369 {"ROUT3", "NULL", "ROUT3 Mixer"},
370
371 {"LOUT1 Mixer", "DACL", "DAC Left"},
372 {"ROUT1 Mixer", "DACR", "DAC Right"},
373 {"LOUT2 Mixer", "DACHL", "DAC Left"},
374 {"ROUT2 Mixer", "DACHR", "DAC Right"},
375 {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"},
376 {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"},
377 {"LOUT3 Mixer", "DACSL", "DAC Left"},
378 {"ROUT3 Mixer", "DACSR", "DAC Right"},
379
380 /* Inputs */
381 {"LIN MUX", "LIN1", "LIN1"},
382 {"LIN MUX", "LIN2", "LIN2"},
383 {"LIN MUX", "LIN3", "LIN3"},
384 {"LIN MUX", "LIN4", "LIN4"},
385
386 {"RIN MUX", "RIN1", "RIN1"},
387 {"RIN MUX", "RIN2", "RIN2"},
388 {"RIN MUX", "RIN3", "RIN3"},
389 {"RIN MUX", "RIN4", "RIN4"},
390
391 {"LIN1", NULL, "Mic Bias"},
392 {"RIN1", NULL, "Mic Bias"},
393 {"LIN2", NULL, "Mic Bias"},
394 {"RIN2", NULL, "Mic Bias"},
395
396 {"ADC Left", "NULL", "LIN MUX"},
397 {"ADC Right", "NULL", "RIN MUX"},
398
399 /* Analog Loops */
400 {"LIN1 Mixing Circuit", "NULL", "LIN1"},
401 {"RIN1 Mixing Circuit", "NULL", "RIN1"},
402 {"LIN2 Mixing Circuit", "NULL", "LIN2"},
403 {"RIN2 Mixing Circuit", "NULL", "RIN2"},
404 {"LIN3 Mixing Circuit", "NULL", "LIN3"},
405 {"RIN3 Mixing Circuit", "NULL", "RIN3"},
406 {"LIN4 Mixing Circuit", "NULL", "LIN4"},
407 {"RIN4 Mixing Circuit", "NULL", "RIN4"},
408
409 {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
410 {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
411 {"LOUT2 Mixer", "LINH1", "LIN1 Mixing Circuit"},
412 {"ROUT2 Mixer", "RINH1", "RIN1 Mixing Circuit"},
413 {"LOUT3 Mixer", "LINS1", "LIN1 Mixing Circuit"},
414 {"ROUT3 Mixer", "RINS1", "RIN1 Mixing Circuit"},
415
416 {"LOUT1 Mixer", "LINL2", "LIN2 Mixing Circuit"},
417 {"ROUT1 Mixer", "RINR2", "RIN2 Mixing Circuit"},
418 {"LOUT2 Mixer", "LINH2", "LIN2 Mixing Circuit"},
419 {"ROUT2 Mixer", "RINH2", "RIN2 Mixing Circuit"},
420 {"LOUT3 Mixer", "LINS2", "LIN2 Mixing Circuit"},
421 {"ROUT3 Mixer", "RINS2", "RIN2 Mixing Circuit"},
422
423 {"LOUT1 Mixer", "LINL3", "LIN3 Mixing Circuit"},
424 {"ROUT1 Mixer", "RINR3", "RIN3 Mixing Circuit"},
425 {"LOUT2 Mixer", "LINH3", "LIN3 Mixing Circuit"},
426 {"ROUT2 Mixer", "RINH3", "RIN3 Mixing Circuit"},
427 {"LOUT3 Mixer", "LINS3", "LIN3 Mixing Circuit"},
428 {"ROUT3 Mixer", "RINS3", "RIN3 Mixing Circuit"},
429
430 {"LOUT1 Mixer", "LINL4", "LIN4 Mixing Circuit"},
431 {"ROUT1 Mixer", "RINR4", "RIN4 Mixing Circuit"},
432 {"LOUT2 Mixer", "LINH4", "LIN4 Mixing Circuit"},
433 {"ROUT2 Mixer", "RINH4", "RIN4 Mixing Circuit"},
434 {"LOUT3 Mixer", "LINS4", "LIN4 Mixing Circuit"},
435 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
436};
437
438static int ak4671_add_widgets(struct snd_soc_codec *codec)
439{
440 snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
441 ARRAY_SIZE(ak4671_dapm_widgets));
442
443 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
444
445 return 0;
446}
447
448static int ak4671_hw_params(struct snd_pcm_substream *substream,
449 struct snd_pcm_hw_params *params,
450 struct snd_soc_dai *dai)
451{
452 struct snd_soc_codec *codec = dai->codec;
453 u8 fs;
454
455 fs = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
456 fs &= ~AK4671_FS;
457
458 switch (params_rate(params)) {
459 case 8000:
460 fs |= AK4671_FS_8KHZ;
461 break;
462 case 12000:
463 fs |= AK4671_FS_12KHZ;
464 break;
465 case 16000:
466 fs |= AK4671_FS_16KHZ;
467 break;
468 case 24000:
469 fs |= AK4671_FS_24KHZ;
470 break;
471 case 11025:
472 fs |= AK4671_FS_11_025KHZ;
473 break;
474 case 22050:
475 fs |= AK4671_FS_22_05KHZ;
476 break;
477 case 32000:
478 fs |= AK4671_FS_32KHZ;
479 break;
480 case 44100:
481 fs |= AK4671_FS_44_1KHZ;
482 break;
483 case 48000:
484 fs |= AK4671_FS_48KHZ;
485 break;
486 default:
487 return -EINVAL;
488 }
489
490 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, fs);
491
492 return 0;
493}
494
495static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
496 unsigned int freq, int dir)
497{
498 struct snd_soc_codec *codec = dai->codec;
499 u8 pll;
500
501 pll = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
502 pll &= ~AK4671_PLL;
503
504 switch (freq) {
505 case 11289600:
506 pll |= AK4671_PLL_11_2896MHZ;
507 break;
508 case 12000000:
509 pll |= AK4671_PLL_12MHZ;
510 break;
511 case 12288000:
512 pll |= AK4671_PLL_12_288MHZ;
513 break;
514 case 13000000:
515 pll |= AK4671_PLL_13MHZ;
516 break;
517 case 13500000:
518 pll |= AK4671_PLL_13_5MHZ;
519 break;
520 case 19200000:
521 pll |= AK4671_PLL_19_2MHZ;
522 break;
523 case 24000000:
524 pll |= AK4671_PLL_24MHZ;
525 break;
526 case 26000000:
527 pll |= AK4671_PLL_26MHZ;
528 break;
529 case 27000000:
530 pll |= AK4671_PLL_27MHZ;
531 break;
532 default:
533 return -EINVAL;
534 }
535
536 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, pll);
537
538 return 0;
539}
540
541static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
542{
543 struct snd_soc_codec *codec = dai->codec;
544 u8 mode;
545 u8 format;
546
547 /* set master/slave audio interface */
548 mode = snd_soc_read(codec, AK4671_PLL_MODE_SELECT1);
549
550 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
551 case SND_SOC_DAIFMT_CBM_CFM:
552 mode |= AK4671_M_S;
553 break;
554 case SND_SOC_DAIFMT_CBM_CFS:
555 mode &= ~(AK4671_M_S);
556 break;
557 default:
558 return -EINVAL;
559 }
560
561 /* interface format */
562 format = snd_soc_read(codec, AK4671_FORMAT_SELECT);
563 format &= ~AK4671_DIF;
564
565 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
566 case SND_SOC_DAIFMT_I2S:
567 format |= AK4671_DIF_I2S_MODE;
568 break;
569 case SND_SOC_DAIFMT_LEFT_J:
570 format |= AK4671_DIF_MSB_MODE;
571 break;
572 case SND_SOC_DAIFMT_DSP_A:
573 format |= AK4671_DIF_DSP_MODE;
574 format |= AK4671_BCKP;
575 format |= AK4671_MSBS;
576 break;
577 default:
578 return -EINVAL;
579 }
580
581 /* set mode and format */
582 snd_soc_write(codec, AK4671_PLL_MODE_SELECT1, mode);
583 snd_soc_write(codec, AK4671_FORMAT_SELECT, format);
584
585 return 0;
586}
587
588static int ak4671_set_bias_level(struct snd_soc_codec *codec,
589 enum snd_soc_bias_level level)
590{
591 u8 reg;
592
593 switch (level) {
594 case SND_SOC_BIAS_ON:
595 case SND_SOC_BIAS_PREPARE:
596 case SND_SOC_BIAS_STANDBY:
597 reg = snd_soc_read(codec, AK4671_AD_DA_POWER_MANAGEMENT);
598 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT,
599 reg | AK4671_PMVCM);
600 break;
601 case SND_SOC_BIAS_OFF:
602 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
603 break;
604 }
605 codec->bias_level = level;
606 return 0;
607}
608
609#define AK4671_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
610 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
611 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
612 SNDRV_PCM_RATE_48000)
613
614#define AK4671_FORMATS SNDRV_PCM_FMTBIT_S16_LE
615
616static struct snd_soc_dai_ops ak4671_dai_ops = {
617 .hw_params = ak4671_hw_params,
618 .set_sysclk = ak4671_set_dai_sysclk,
619 .set_fmt = ak4671_set_dai_fmt,
620};
621
622struct snd_soc_dai ak4671_dai = {
623 .name = "AK4671",
624 .playback = {
625 .stream_name = "Playback",
626 .channels_min = 1,
627 .channels_max = 2,
628 .rates = AK4671_RATES,
629 .formats = AK4671_FORMATS,},
630 .capture = {
631 .stream_name = "Capture",
632 .channels_min = 1,
633 .channels_max = 2,
634 .rates = AK4671_RATES,
635 .formats = AK4671_FORMATS,},
636 .ops = &ak4671_dai_ops,
637};
638EXPORT_SYMBOL_GPL(ak4671_dai);
639
640static int ak4671_probe(struct platform_device *pdev)
641{
642 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
643 struct snd_soc_codec *codec;
644 int ret = 0;
645
646 if (ak4671_codec == NULL) {
647 dev_err(&pdev->dev, "Codec device not registered\n");
648 return -ENODEV;
649 }
650
651 socdev->card->codec = ak4671_codec;
652 codec = ak4671_codec;
653
654 /* register pcms */
655 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
656 if (ret < 0) {
657 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
658 goto pcm_err;
659 }
660
661 snd_soc_add_controls(codec, ak4671_snd_controls,
662 ARRAY_SIZE(ak4671_snd_controls));
663 ak4671_add_widgets(codec);
664
665 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
666
667 return ret;
668
669pcm_err:
670 return ret;
671}
672
673static int ak4671_remove(struct platform_device *pdev)
674{
675 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
676
677 snd_soc_free_pcms(socdev);
678 snd_soc_dapm_free(socdev);
679
680 return 0;
681}
682
683struct snd_soc_codec_device soc_codec_dev_ak4671 = {
684 .probe = ak4671_probe,
685 .remove = ak4671_remove,
686};
687EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
688
689static int ak4671_register(struct ak4671_priv *ak4671,
690 enum snd_soc_control_type control)
691{
692 int ret;
693 struct snd_soc_codec *codec = &ak4671->codec;
694
695 if (ak4671_codec) {
696 dev_err(codec->dev, "Another AK4671 is registered\n");
697 ret = -EINVAL;
698 goto err;
699 }
700
701 mutex_init(&codec->mutex);
702 INIT_LIST_HEAD(&codec->dapm_widgets);
703 INIT_LIST_HEAD(&codec->dapm_paths);
704
705 codec->private_data = ak4671;
706 codec->name = "AK4671";
707 codec->owner = THIS_MODULE;
708 codec->bias_level = SND_SOC_BIAS_OFF;
709 codec->set_bias_level = ak4671_set_bias_level;
710 codec->dai = &ak4671_dai;
711 codec->num_dai = 1;
712 codec->reg_cache_size = AK4671_CACHEREGNUM;
713 codec->reg_cache = &ak4671->reg_cache;
714
715 memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
716
717 ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
718 if (ret < 0) {
719 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
720 goto err;
721 }
722
723 ak4671_dai.dev = codec->dev;
724 ak4671_codec = codec;
725
726 ret = snd_soc_register_codec(codec);
727 if (ret != 0) {
728 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
729 goto err;
730 }
731
732 ret = snd_soc_register_dai(&ak4671_dai);
733 if (ret != 0) {
734 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
735 goto err_codec;
736 }
737
738 return 0;
739
740err_codec:
741 snd_soc_unregister_codec(codec);
742err:
743 kfree(ak4671);
744 return ret;
745}
746
747static void ak4671_unregister(struct ak4671_priv *ak4671)
748{
749 ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
750 snd_soc_unregister_dai(&ak4671_dai);
751 snd_soc_unregister_codec(&ak4671->codec);
752 kfree(ak4671);
753 ak4671_codec = NULL;
754}
755
756static int __devinit ak4671_i2c_probe(struct i2c_client *client,
757 const struct i2c_device_id *id)
758{
759 struct ak4671_priv *ak4671;
760 struct snd_soc_codec *codec;
761
762 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
763 if (ak4671 == NULL)
764 return -ENOMEM;
765
766 codec = &ak4671->codec;
767 codec->hw_write = (hw_write_t)i2c_master_send;
768
769 i2c_set_clientdata(client, ak4671);
770 codec->control_data = client;
771
772 codec->dev = &client->dev;
773
774 return ak4671_register(ak4671, SND_SOC_I2C);
775}
776
777static __devexit int ak4671_i2c_remove(struct i2c_client *client)
778{
779 struct ak4671_priv *ak4671 = i2c_get_clientdata(client);
780
781 ak4671_unregister(ak4671);
782
783 return 0;
784}
785
786static const struct i2c_device_id ak4671_i2c_id[] = {
787 { "ak4671", 0 },
788 { }
789};
790MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
791
792static struct i2c_driver ak4671_i2c_driver = {
793 .driver = {
794 .name = "ak4671",
795 .owner = THIS_MODULE,
796 },
797 .probe = ak4671_i2c_probe,
798 .remove = __devexit_p(ak4671_i2c_remove),
799 .id_table = ak4671_i2c_id,
800};
801
802static int __init ak4671_modinit(void)
803{
804 return i2c_add_driver(&ak4671_i2c_driver);
805}
806module_init(ak4671_modinit);
807
808static void __exit ak4671_exit(void)
809{
810 i2c_del_driver(&ak4671_i2c_driver);
811}
812module_exit(ak4671_exit);
813
814MODULE_DESCRIPTION("ASoC AK4671 codec driver");
815MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
816MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
new file mode 100644
index 000000000000..e2fad964e88b
--- /dev/null
+++ b/sound/soc/codecs/ak4671.h
@@ -0,0 +1,156 @@
1/*
2 * ak4671.h -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef _AK4671_H
15#define _AK4671_H
16
17#define AK4671_AD_DA_POWER_MANAGEMENT 0x00
18#define AK4671_PLL_MODE_SELECT0 0x01
19#define AK4671_PLL_MODE_SELECT1 0x02
20#define AK4671_FORMAT_SELECT 0x03
21#define AK4671_MIC_SIGNAL_SELECT 0x04
22#define AK4671_MIC_AMP_GAIN 0x05
23#define AK4671_MIXING_POWER_MANAGEMENT0 0x06
24#define AK4671_MIXING_POWER_MANAGEMENT1 0x07
25#define AK4671_OUTPUT_VOLUME_CONTROL 0x08
26#define AK4671_LOUT1_SIGNAL_SELECT 0x09
27#define AK4671_ROUT1_SIGNAL_SELECT 0x0a
28#define AK4671_LOUT2_SIGNAL_SELECT 0x0b
29#define AK4671_ROUT2_SIGNAL_SELECT 0x0c
30#define AK4671_LOUT3_SIGNAL_SELECT 0x0d
31#define AK4671_ROUT3_SIGNAL_SELECT 0x0e
32#define AK4671_LOUT1_POWER_MANAGERMENT 0x0f
33#define AK4671_LOUT2_POWER_MANAGERMENT 0x10
34#define AK4671_LOUT3_POWER_MANAGERMENT 0x11
35#define AK4671_LCH_INPUT_VOLUME_CONTROL 0x12
36#define AK4671_RCH_INPUT_VOLUME_CONTROL 0x13
37#define AK4671_ALC_REFERENCE_SELECT 0x14
38#define AK4671_DIGITAL_MIXING_CONTROL 0x15
39#define AK4671_ALC_TIMER_SELECT 0x16
40#define AK4671_ALC_MODE_CONTROL 0x17
41#define AK4671_MODE_CONTROL1 0x18
42#define AK4671_MODE_CONTROL2 0x19
43#define AK4671_LCH_OUTPUT_VOLUME_CONTROL 0x1a
44#define AK4671_RCH_OUTPUT_VOLUME_CONTROL 0x1b
45#define AK4671_SIDETONE_A_CONTROL 0x1c
46#define AK4671_DIGITAL_FILTER_SELECT 0x1d
47#define AK4671_FIL3_COEFFICIENT0 0x1e
48#define AK4671_FIL3_COEFFICIENT1 0x1f
49#define AK4671_FIL3_COEFFICIENT2 0x20
50#define AK4671_FIL3_COEFFICIENT3 0x21
51#define AK4671_EQ_COEFFICIENT0 0x22
52#define AK4671_EQ_COEFFICIENT1 0x23
53#define AK4671_EQ_COEFFICIENT2 0x24
54#define AK4671_EQ_COEFFICIENT3 0x25
55#define AK4671_EQ_COEFFICIENT4 0x26
56#define AK4671_EQ_COEFFICIENT5 0x27
57#define AK4671_FIL1_COEFFICIENT0 0x28
58#define AK4671_FIL1_COEFFICIENT1 0x29
59#define AK4671_FIL1_COEFFICIENT2 0x2a
60#define AK4671_FIL1_COEFFICIENT3 0x2b
61#define AK4671_FIL2_COEFFICIENT0 0x2c
62#define AK4671_FIL2_COEFFICIENT1 0x2d
63#define AK4671_FIL2_COEFFICIENT2 0x2e
64#define AK4671_FIL2_COEFFICIENT3 0x2f
65#define AK4671_DIGITAL_FILTER_SELECT2 0x30
66#define AK4671_E1_COEFFICIENT0 0x32
67#define AK4671_E1_COEFFICIENT1 0x33
68#define AK4671_E1_COEFFICIENT2 0x34
69#define AK4671_E1_COEFFICIENT3 0x35
70#define AK4671_E1_COEFFICIENT4 0x36
71#define AK4671_E1_COEFFICIENT5 0x37
72#define AK4671_E2_COEFFICIENT0 0x38
73#define AK4671_E2_COEFFICIENT1 0x39
74#define AK4671_E2_COEFFICIENT2 0x3a
75#define AK4671_E2_COEFFICIENT3 0x3b
76#define AK4671_E2_COEFFICIENT4 0x3c
77#define AK4671_E2_COEFFICIENT5 0x3d
78#define AK4671_E3_COEFFICIENT0 0x3e
79#define AK4671_E3_COEFFICIENT1 0x3f
80#define AK4671_E3_COEFFICIENT2 0x40
81#define AK4671_E3_COEFFICIENT3 0x41
82#define AK4671_E3_COEFFICIENT4 0x42
83#define AK4671_E3_COEFFICIENT5 0x43
84#define AK4671_E4_COEFFICIENT0 0x44
85#define AK4671_E4_COEFFICIENT1 0x45
86#define AK4671_E4_COEFFICIENT2 0x46
87#define AK4671_E4_COEFFICIENT3 0x47
88#define AK4671_E4_COEFFICIENT4 0x48
89#define AK4671_E4_COEFFICIENT5 0x49
90#define AK4671_E5_COEFFICIENT0 0x4a
91#define AK4671_E5_COEFFICIENT1 0x4b
92#define AK4671_E5_COEFFICIENT2 0x4c
93#define AK4671_E5_COEFFICIENT3 0x4d
94#define AK4671_E5_COEFFICIENT4 0x4e
95#define AK4671_E5_COEFFICIENT5 0x4f
96#define AK4671_EQ_CONTROL_250HZ_100HZ 0x50
97#define AK4671_EQ_CONTROL_3500HZ_1KHZ 0x51
98#define AK4671_EQ_CONTRO_10KHZ 0x52
99#define AK4671_PCM_IF_CONTROL0 0x53
100#define AK4671_PCM_IF_CONTROL1 0x54
101#define AK4671_PCM_IF_CONTROL2 0x55
102#define AK4671_DIGITAL_VOLUME_B_CONTROL 0x56
103#define AK4671_DIGITAL_VOLUME_C_CONTROL 0x57
104#define AK4671_SIDETONE_VOLUME_CONTROL 0x58
105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
106#define AK4671_SAR_ADC_CONTROL 0x5a
107
108#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
109
110/* Bitfield Definitions */
111
112/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
113#define AK4671_PMVCM 0x01
114
115/* AK4671_PLL_MODE_SELECT0 (0x01) Fields */
116#define AK4671_PLL 0x0f
117#define AK4671_PLL_11_2896MHZ (4 << 0)
118#define AK4671_PLL_12_288MHZ (5 << 0)
119#define AK4671_PLL_12MHZ (6 << 0)
120#define AK4671_PLL_24MHZ (7 << 0)
121#define AK4671_PLL_19_2MHZ (8 << 0)
122#define AK4671_PLL_13_5MHZ (12 << 0)
123#define AK4671_PLL_27MHZ (13 << 0)
124#define AK4671_PLL_13MHZ (14 << 0)
125#define AK4671_PLL_26MHZ (15 << 0)
126#define AK4671_FS 0xf0
127#define AK4671_FS_8KHZ (0 << 4)
128#define AK4671_FS_12KHZ (1 << 4)
129#define AK4671_FS_16KHZ (2 << 4)
130#define AK4671_FS_24KHZ (3 << 4)
131#define AK4671_FS_11_025KHZ (5 << 4)
132#define AK4671_FS_22_05KHZ (7 << 4)
133#define AK4671_FS_32KHZ (10 << 4)
134#define AK4671_FS_48KHZ (11 << 4)
135#define AK4671_FS_44_1KHZ (15 << 4)
136
137/* AK4671_PLL_MODE_SELECT1 (0x02) Fields */
138#define AK4671_PMPLL 0x01
139#define AK4671_M_S 0x02
140
141/* AK4671_FORMAT_SELECT (0x03) Fields */
142#define AK4671_DIF 0x03
143#define AK4671_DIF_DSP_MODE (0 << 0)
144#define AK4671_DIF_MSB_MODE (2 << 0)
145#define AK4671_DIF_I2S_MODE (3 << 0)
146#define AK4671_BCKP 0x04
147#define AK4671_MSBS 0x08
148#define AK4671_SDOD 0x10
149
150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
151#define AK4671_MUTEN 0x04
152
153extern struct snd_soc_dai ak4671_dai;
154extern struct snd_soc_codec_device soc_codec_dev_ak4671;
155
156#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ca1e24a8f12a..81a62d198b70 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -23,11 +23,13 @@
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/slab.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/soc.h> 28#include <sound/soc.h>
28#include <sound/initval.h> 29#include <sound/initval.h>
29#include <linux/i2c.h> 30#include <linux/i2c.h>
30#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/regulator/consumer.h>
31 33
32#include "cs4270.h" 34#include "cs4270.h"
33 35
@@ -106,6 +108,10 @@
106#define CS4270_MUTE_DAC_A 0x01 108#define CS4270_MUTE_DAC_A 0x01
107#define CS4270_MUTE_DAC_B 0x02 109#define CS4270_MUTE_DAC_B 0x02
108 110
111static const char *supply_names[] = {
112 "va", "vd", "vlc"
113};
114
109/* Private data for the CS4270 */ 115/* Private data for the CS4270 */
110struct cs4270_private { 116struct cs4270_private {
111 struct snd_soc_codec codec; 117 struct snd_soc_codec codec;
@@ -114,6 +120,9 @@ struct cs4270_private {
114 unsigned int mode; /* The mode (I2S or left-justified) */ 120 unsigned int mode; /* The mode (I2S or left-justified) */
115 unsigned int slave_mode; 121 unsigned int slave_mode;
116 unsigned int manual_mute; 122 unsigned int manual_mute;
123
124 /* power domain regulators */
125 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
117}; 126};
118 127
119/** 128/**
@@ -192,6 +201,11 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
192 * This function must be called by the machine driver's 'startup' function, 201 * 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 202 * otherwise the list of supported sample rates will not be available in
194 * time for ALSA. 203 * time for ALSA.
204 *
205 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
206 * theoretically possible sample rates to be enabled. Call it again with a
207 * proper value set one the external clock is set (most probably you would do
208 * that from a machine's driver 'hw_param' hook.
195 */ 209 */
196static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, 210static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
197 int clk_id, unsigned int freq, int dir) 211 int clk_id, unsigned int freq, int dir)
@@ -205,20 +219,27 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
205 219
206 cs4270->mclk = freq; 220 cs4270->mclk = freq;
207 221
208 for (i = 0; i < NUM_MCLK_RATIOS; i++) { 222 if (cs4270->mclk) {
209 unsigned int rate = freq / cs4270_mode_ratios[i].ratio; 223 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
210 rates |= snd_pcm_rate_to_rate_bit(rate); 224 unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
211 if (rate < rate_min) 225 rates |= snd_pcm_rate_to_rate_bit(rate);
212 rate_min = rate; 226 if (rate < rate_min)
213 if (rate > rate_max) 227 rate_min = rate;
214 rate_max = rate; 228 if (rate > rate_max)
215 } 229 rate_max = rate;
216 /* FIXME: soc should support a rate list */ 230 }
217 rates &= ~SNDRV_PCM_RATE_KNOT; 231 /* FIXME: soc should support a rate list */
232 rates &= ~SNDRV_PCM_RATE_KNOT;
218 233
219 if (!rates) { 234 if (!rates) {
220 dev_err(codec->dev, "could not find a valid sample rate\n"); 235 dev_err(codec->dev, "could not find a valid sample rate\n");
221 return -EINVAL; 236 return -EINVAL;
237 }
238 } else {
239 /* enable all possible rates */
240 rates = SNDRV_PCM_RATE_8000_192000;
241 rate_min = 8000;
242 rate_max = 192000;
222 } 243 }
223 244
224 codec_dai->playback.rates = rates; 245 codec_dai->playback.rates = rates;
@@ -520,6 +541,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0), 541 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0), 542 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), 543 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
544 SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
523 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), 545 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
524 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), 546 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
525 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1), 547 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
@@ -578,7 +600,8 @@ static int cs4270_probe(struct platform_device *pdev)
578{ 600{
579 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
580 struct snd_soc_codec *codec = cs4270_codec; 602 struct snd_soc_codec *codec = cs4270_codec;
581 int ret; 603 struct cs4270_private *cs4270 = codec->private_data;
604 int i, ret;
582 605
583 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 606 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
584 socdev->card->codec = codec; 607 socdev->card->codec = codec;
@@ -598,15 +621,26 @@ static int cs4270_probe(struct platform_device *pdev)
598 goto error_free_pcms; 621 goto error_free_pcms;
599 } 622 }
600 623
601 /* And finally, register the socdev */ 624 /* get the power supply regulators */
602 ret = snd_soc_init_card(socdev); 625 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
603 if (ret < 0) { 626 cs4270->supplies[i].supply = supply_names[i];
604 dev_err(codec->dev, "failed to register card\n"); 627
628 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
629 cs4270->supplies);
630 if (ret < 0)
605 goto error_free_pcms; 631 goto error_free_pcms;
606 } 632
633 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
634 cs4270->supplies);
635 if (ret < 0)
636 goto error_free_regulators;
607 637
608 return 0; 638 return 0;
609 639
640error_free_regulators:
641 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
642 cs4270->supplies);
643
610error_free_pcms: 644error_free_pcms:
611 snd_soc_free_pcms(socdev); 645 snd_soc_free_pcms(socdev);
612 646
@@ -622,8 +656,12 @@ error_free_pcms:
622static int cs4270_remove(struct platform_device *pdev) 656static int cs4270_remove(struct platform_device *pdev)
623{ 657{
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 658 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
659 struct snd_soc_codec *codec = cs4270_codec;
660 struct cs4270_private *cs4270 = codec->private_data;
625 661
626 snd_soc_free_pcms(socdev); 662 snd_soc_free_pcms(socdev);
663 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
664 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
627 665
628 return 0; 666 return 0;
629}; 667};
@@ -802,36 +840,36 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
802 * and all registers are written back to the hardware when resuming. 840 * and all registers are written back to the hardware when resuming.
803 */ 841 */
804 842
805static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg) 843static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
806{ 844{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client); 845 struct snd_soc_codec *codec = cs4270_codec;
808 struct snd_soc_codec *codec = &cs4270->codec; 846 struct cs4270_private *cs4270 = codec->private_data;
809 847 int reg, ret;
810 return snd_soc_suspend_device(codec->dev);
811}
812 848
813static int cs4270_i2c_resume(struct i2c_client *client) 849 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
814{ 850 if (reg < 0)
815 struct cs4270_private *cs4270 = i2c_get_clientdata(client); 851 return reg;
816 struct snd_soc_codec *codec = &cs4270->codec;
817 852
818 return snd_soc_resume_device(codec->dev); 853 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
819} 854 if (ret < 0)
855 return ret;
820 856
821static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 857 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
822{ 858 cs4270->supplies);
823 struct snd_soc_codec *codec = cs4270_codec;
824 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
825 859
826 return snd_soc_write(codec, CS4270_PWRCTL, reg); 860 return 0;
827} 861}
828 862
829static int cs4270_soc_resume(struct platform_device *pdev) 863static int cs4270_soc_resume(struct platform_device *pdev)
830{ 864{
831 struct snd_soc_codec *codec = cs4270_codec; 865 struct snd_soc_codec *codec = cs4270_codec;
866 struct cs4270_private *cs4270 = codec->private_data;
832 struct i2c_client *i2c_client = codec->control_data; 867 struct i2c_client *i2c_client = codec->control_data;
833 int reg; 868 int reg;
834 869
870 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
871 cs4270->supplies);
872
835 /* In case the device was put to hard reset during sleep, we need to 873 /* In case the device was put to hard reset during sleep, we need to
836 * wait 500ns here before any I2C communication. */ 874 * wait 500ns here before any I2C communication. */
837 ndelay(500); 875 ndelay(500);
@@ -853,8 +891,6 @@ static int cs4270_soc_resume(struct platform_device *pdev)
853 return snd_soc_write(codec, CS4270_PWRCTL, reg); 891 return snd_soc_write(codec, CS4270_PWRCTL, reg);
854} 892}
855#else 893#else
856#define cs4270_i2c_suspend NULL
857#define cs4270_i2c_resume NULL
858#define cs4270_soc_suspend NULL 894#define cs4270_soc_suspend NULL
859#define cs4270_soc_resume NULL 895#define cs4270_soc_resume NULL
860#endif /* CONFIG_PM */ 896#endif /* CONFIG_PM */
@@ -873,8 +909,6 @@ static struct i2c_driver cs4270_i2c_driver = {
873 .id_table = cs4270_id, 909 .id_table = cs4270_id,
874 .probe = cs4270_i2c_probe, 910 .probe = cs4270_i2c_probe,
875 .remove = cs4270_i2c_remove, 911 .remove = cs4270_i2c_remove,
876 .suspend = cs4270_i2c_suspend,
877 .resume = cs4270_i2c_resume,
878}; 912};
879 913
880/* 914/*
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 38eac9c866e1..9f169c477108 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/tty.h> 16#include <linux/tty.h>
17#include <linux/slab.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/initval.h> 20#include <sound/initval.h>
@@ -93,7 +94,6 @@ static int cx20442_add_widgets(struct snd_soc_codec *codec)
93 snd_soc_dapm_add_routes(codec, cx20442_audio_map, 94 snd_soc_dapm_add_routes(codec, cx20442_audio_map,
94 ARRAY_SIZE(cx20442_audio_map)); 95 ARRAY_SIZE(cx20442_audio_map));
95 96
96 snd_soc_dapm_new_widgets(codec);
97 return 0; 97 return 0;
98} 98}
99 99
@@ -355,17 +355,6 @@ static int cx20442_codec_probe(struct platform_device *pdev)
355 355
356 cx20442_add_widgets(codec); 356 cx20442_add_widgets(codec);
357 357
358 ret = snd_soc_init_card(socdev);
359 if (ret < 0) {
360 dev_err(&pdev->dev, "failed to register card\n");
361 goto card_err;
362 }
363
364 return ret;
365
366card_err:
367 snd_soc_free_pcms(socdev);
368 snd_soc_dapm_free(socdev);
369pcm_err: 358pcm_err:
370 return ret; 359 return ret;
371} 360}
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
new file mode 100644
index 000000000000..366daf1d044e
--- /dev/null
+++ b/sound/soc/codecs/da7210.c
@@ -0,0 +1,590 @@
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 <linux/slab.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/tlv.h>
33#include <sound/initval.h>
34#include <asm/div64.h>
35
36#include "da7210.h"
37
38/* DA7210 register space */
39#define DA7210_STATUS 0x02
40#define DA7210_STARTUP1 0x03
41#define DA7210_MIC_L 0x07
42#define DA7210_MIC_R 0x08
43#define DA7210_INMIX_L 0x0D
44#define DA7210_INMIX_R 0x0E
45#define DA7210_ADC_HPF 0x0F
46#define DA7210_ADC 0x10
47#define DA7210_DAC_HPF 0x14
48#define DA7210_DAC_L 0x15
49#define DA7210_DAC_R 0x16
50#define DA7210_DAC_SEL 0x17
51#define DA7210_OUTMIX_L 0x1C
52#define DA7210_OUTMIX_R 0x1D
53#define DA7210_HP_L_VOL 0x21
54#define DA7210_HP_R_VOL 0x22
55#define DA7210_HP_CFG 0x23
56#define DA7210_DAI_SRC_SEL 0x25
57#define DA7210_DAI_CFG1 0x26
58#define DA7210_DAI_CFG3 0x28
59#define DA7210_PLL_DIV3 0x2B
60#define DA7210_PLL 0x2C
61
62/* STARTUP1 bit fields */
63#define DA7210_SC_MST_EN (1 << 0)
64
65/* MIC_L bit fields */
66#define DA7210_MICBIAS_EN (1 << 6)
67#define DA7210_MIC_L_EN (1 << 7)
68
69/* MIC_R bit fields */
70#define DA7210_MIC_R_EN (1 << 7)
71
72/* INMIX_L bit fields */
73#define DA7210_IN_L_EN (1 << 7)
74
75/* INMIX_R bit fields */
76#define DA7210_IN_R_EN (1 << 7)
77
78/* ADC_HPF bit fields */
79#define DA7210_ADC_VOICE_EN (1 << 7)
80
81/* ADC bit fields */
82#define DA7210_ADC_L_EN (1 << 3)
83#define DA7210_ADC_R_EN (1 << 7)
84
85/* DAC_HPF fields */
86#define DA7210_DAC_VOICE_EN (1 << 7)
87
88/* DAC_SEL bit fields */
89#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
90#define DA7210_DAC_L_EN (1 << 3)
91#define DA7210_DAC_R_SRC_DAI_R (5 << 4)
92#define DA7210_DAC_R_EN (1 << 7)
93
94/* OUTMIX_L bit fields */
95#define DA7210_OUT_L_EN (1 << 7)
96
97/* OUTMIX_R bit fields */
98#define DA7210_OUT_R_EN (1 << 7)
99
100/* HP_CFG bit fields */
101#define DA7210_HP_2CAP_MODE (1 << 1)
102#define DA7210_HP_SENSE_EN (1 << 2)
103#define DA7210_HP_L_EN (1 << 3)
104#define DA7210_HP_MODE (1 << 6)
105#define DA7210_HP_R_EN (1 << 7)
106
107/* DAI_SRC_SEL bit fields */
108#define DA7210_DAI_OUT_L_SRC (6 << 0)
109#define DA7210_DAI_OUT_R_SRC (7 << 4)
110
111/* DAI_CFG1 bit fields */
112#define DA7210_DAI_WORD_S16_LE (0 << 0)
113#define DA7210_DAI_WORD_S24_LE (2 << 0)
114#define DA7210_DAI_FLEN_64BIT (1 << 2)
115#define DA7210_DAI_MODE_MASTER (1 << 7)
116
117/* DAI_CFG3 bit fields */
118#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
119#define DA7210_DAI_OE (1 << 3)
120#define DA7210_DAI_EN (1 << 7)
121
122/*PLL_DIV3 bit fields */
123#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
124#define DA7210_PLL_BYP (1 << 6)
125
126/* PLL bit fields */
127#define DA7210_PLL_FS_48000 (11 << 0)
128
129#define DA7210_VERSION "0.0.1"
130
131/* Codec private data */
132struct da7210_priv {
133 struct snd_soc_codec codec;
134};
135
136static struct snd_soc_codec *da7210_codec;
137
138/*
139 * Register cache
140 */
141static const u8 da7210_reg[] = {
142 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */
144 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */
145 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */
146 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */
147 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */
148 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */
149 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */
158 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */
159 0x00, /* R88 */
160};
161
162/*
163 * Read da7210 register cache
164 */
165static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
166{
167 u8 *cache = codec->reg_cache;
168 BUG_ON(reg > ARRAY_SIZE(da7210_reg));
169 return cache[reg];
170}
171
172/*
173 * Write to the da7210 register space
174 */
175static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
176{
177 u8 *cache = codec->reg_cache;
178 u8 data[2];
179
180 BUG_ON(codec->volatile_register);
181
182 data[0] = reg & 0xff;
183 data[1] = value & 0xff;
184
185 if (reg >= codec->reg_cache_size)
186 return -EIO;
187
188 if (2 != codec->hw_write(codec->control_data, data, 2))
189 return -EIO;
190
191 cache[reg] = value;
192 return 0;
193}
194
195/*
196 * Read from the da7210 register space.
197 */
198static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg)
199{
200 if (DA7210_STATUS == reg)
201 return i2c_smbus_read_byte_data(codec->control_data, reg);
202
203 return da7210_read_reg_cache(codec, reg);
204}
205
206static int da7210_startup(struct snd_pcm_substream *substream,
207 struct snd_soc_dai *dai)
208{
209 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
210 struct snd_soc_codec *codec = dai->codec;
211
212 if (is_play) {
213 /* PlayBack Volume 40 */
214 snd_soc_update_bits(codec, DA7210_HP_L_VOL, 0x3F, 40);
215 snd_soc_update_bits(codec, DA7210_HP_R_VOL, 0x3F, 40);
216
217 /* Enable Out */
218 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
219 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
220
221 } else {
222 /* Volume 7 */
223 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
224 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
225
226 /* Enable Mic */
227 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
228 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
229 }
230
231 return 0;
232}
233
234/*
235 * Set PCM DAI word length.
236 */
237static int da7210_hw_params(struct snd_pcm_substream *substream,
238 struct snd_pcm_hw_params *params,
239 struct snd_soc_dai *dai)
240{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct snd_soc_device *socdev = rtd->socdev;
243 struct snd_soc_codec *codec = socdev->card->codec;
244 u32 dai_cfg1;
245 u32 reg, mask;
246
247 /* set DAI source to Left and Right ADC */
248 da7210_write(codec, DA7210_DAI_SRC_SEL,
249 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
250
251 /* Enable DAI */
252 da7210_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
253
254 dai_cfg1 = 0xFC & da7210_read(codec, DA7210_DAI_CFG1);
255
256 switch (params_format(params)) {
257 case SNDRV_PCM_FORMAT_S16_LE:
258 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
259 break;
260 case SNDRV_PCM_FORMAT_S24_LE:
261 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
262 break;
263 default:
264 return -EINVAL;
265 }
266
267 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
268
269 /* FIXME
270 *
271 * It support 48K only now
272 */
273 switch (params_rate(params)) {
274 case 48000:
275 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
276 reg = DA7210_DAC_HPF;
277 mask = DA7210_DAC_VOICE_EN;
278 } else {
279 reg = DA7210_ADC_HPF;
280 mask = DA7210_ADC_VOICE_EN;
281 }
282 break;
283 default:
284 return -EINVAL;
285 }
286
287 snd_soc_update_bits(codec, reg, mask, 0);
288
289 return 0;
290}
291
292/*
293 * Set DAI mode and Format
294 */
295static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
296{
297 struct snd_soc_codec *codec = codec_dai->codec;
298 u32 dai_cfg1;
299 u32 dai_cfg3;
300
301 dai_cfg1 = 0x7f & da7210_read(codec, DA7210_DAI_CFG1);
302 dai_cfg3 = 0xfc & da7210_read(codec, DA7210_DAI_CFG3);
303
304 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
305 case SND_SOC_DAIFMT_CBM_CFM:
306 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
307 break;
308 default:
309 return -EINVAL;
310 }
311
312 /* FIXME
313 *
314 * It support I2S only now
315 */
316 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
317 case SND_SOC_DAIFMT_I2S:
318 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
319 break;
320 default:
321 return -EINVAL;
322 }
323
324 /* FIXME
325 *
326 * It support 64bit data transmission only now
327 */
328 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
329
330 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
331 da7210_write(codec, DA7210_DAI_CFG3, dai_cfg3);
332
333 return 0;
334}
335
336#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
337
338/* DAI operations */
339static struct snd_soc_dai_ops da7210_dai_ops = {
340 .startup = da7210_startup,
341 .hw_params = da7210_hw_params,
342 .set_fmt = da7210_set_dai_fmt,
343};
344
345struct snd_soc_dai da7210_dai = {
346 .name = "DA7210 IIS",
347 .id = 0,
348 /* playback capabilities */
349 .playback = {
350 .stream_name = "Playback",
351 .channels_min = 1,
352 .channels_max = 2,
353 .rates = SNDRV_PCM_RATE_8000_96000,
354 .formats = DA7210_FORMATS,
355 },
356 /* capture capabilities */
357 .capture = {
358 .stream_name = "Capture",
359 .channels_min = 1,
360 .channels_max = 2,
361 .rates = SNDRV_PCM_RATE_8000_96000,
362 .formats = DA7210_FORMATS,
363 },
364 .ops = &da7210_dai_ops,
365};
366EXPORT_SYMBOL_GPL(da7210_dai);
367
368/*
369 * Initialize the DA7210 driver
370 * register the mixer and dsp interfaces with the kernel
371 */
372static int da7210_init(struct da7210_priv *da7210)
373{
374 struct snd_soc_codec *codec = &da7210->codec;
375 int ret = 0;
376
377 if (da7210_codec) {
378 dev_err(codec->dev, "Another da7210 is registered\n");
379 return -EINVAL;
380 }
381
382 mutex_init(&codec->mutex);
383 INIT_LIST_HEAD(&codec->dapm_widgets);
384 INIT_LIST_HEAD(&codec->dapm_paths);
385
386 codec->private_data = da7210;
387 codec->name = "DA7210";
388 codec->owner = THIS_MODULE;
389 codec->read = da7210_read;
390 codec->write = da7210_write;
391 codec->dai = &da7210_dai;
392 codec->num_dai = 1;
393 codec->hw_write = (hw_write_t)i2c_master_send;
394 codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
395 codec->reg_cache = kmemdup(da7210_reg,
396 sizeof(da7210_reg), GFP_KERNEL);
397
398 if (!codec->reg_cache)
399 return -ENOMEM;
400
401 da7210_dai.dev = codec->dev;
402 da7210_codec = codec;
403
404 ret = snd_soc_register_codec(codec);
405 if (ret) {
406 dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
407 goto init_err;
408 }
409
410 ret = snd_soc_register_dai(&da7210_dai);
411 if (ret) {
412 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
413 goto init_err;
414 }
415
416 /* FIXME
417 *
418 * This driver use fixed value here
419 */
420
421 /*
422 * ADC settings
423 */
424
425 /* Enable Left & Right MIC PGA and Mic Bias */
426 da7210_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
427 da7210_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
428
429 /* Enable Left and Right input PGA */
430 da7210_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
431 da7210_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
432
433 /* Enable Left and Right ADC */
434 da7210_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
435
436 /*
437 * DAC settings
438 */
439
440 /* Enable Left and Right DAC */
441 da7210_write(codec, DA7210_DAC_SEL,
442 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
443 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
444
445 /* Enable Left and Right out PGA */
446 da7210_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
447 da7210_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
448
449 /* Enable Left and Right HeadPhone PGA */
450 da7210_write(codec, DA7210_HP_CFG,
451 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
452 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
453
454 /* Diable PLL and bypass it */
455 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
456
457 /* Bypass PLL and set MCLK freq rang to 10-20MHz */
458 da7210_write(codec, DA7210_PLL_DIV3,
459 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
460
461 /* Activate all enabled subsystem */
462 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
463
464 return ret;
465
466init_err:
467 kfree(codec->reg_cache);
468 codec->reg_cache = NULL;
469
470 return ret;
471
472}
473
474#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
475static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
476 const struct i2c_device_id *id)
477{
478 struct da7210_priv *da7210;
479 struct snd_soc_codec *codec;
480 int ret;
481
482 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
483 if (!da7210)
484 return -ENOMEM;
485
486 codec = &da7210->codec;
487 codec->dev = &i2c->dev;
488
489 i2c_set_clientdata(i2c, da7210);
490 codec->control_data = i2c;
491
492 ret = da7210_init(da7210);
493 if (ret < 0)
494 pr_err("Failed to initialise da7210 audio codec\n");
495
496 return ret;
497}
498
499static int __devexit da7210_i2c_remove(struct i2c_client *client)
500{
501 struct da7210_priv *da7210 = i2c_get_clientdata(client);
502
503 snd_soc_unregister_dai(&da7210_dai);
504 kfree(da7210->codec.reg_cache);
505 kfree(da7210);
506 da7210_codec = NULL;
507
508 return 0;
509}
510
511static const struct i2c_device_id da7210_i2c_id[] = {
512 { "da7210", 0 },
513 { }
514};
515MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
516
517/* I2C codec control layer */
518static struct i2c_driver da7210_i2c_driver = {
519 .driver = {
520 .name = "DA7210 I2C Codec",
521 .owner = THIS_MODULE,
522 },
523 .probe = da7210_i2c_probe,
524 .remove = __devexit_p(da7210_i2c_remove),
525 .id_table = da7210_i2c_id,
526};
527#endif
528
529static int da7210_probe(struct platform_device *pdev)
530{
531 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
532 struct snd_soc_codec *codec;
533 int ret;
534
535 if (!da7210_codec) {
536 dev_err(&pdev->dev, "Codec device not registered\n");
537 return -ENODEV;
538 }
539
540 socdev->card->codec = da7210_codec;
541 codec = da7210_codec;
542
543 /* Register pcms */
544 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
545 if (ret < 0)
546 goto pcm_err;
547
548 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
549
550pcm_err:
551 return ret;
552}
553
554static int da7210_remove(struct platform_device *pdev)
555{
556 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
557
558 snd_soc_free_pcms(socdev);
559 snd_soc_dapm_free(socdev);
560
561 return 0;
562}
563
564struct snd_soc_codec_device soc_codec_dev_da7210 = {
565 .probe = da7210_probe,
566 .remove = da7210_remove,
567};
568EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
569
570static int __init da7210_modinit(void)
571{
572 int ret = 0;
573#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
574 ret = i2c_add_driver(&da7210_i2c_driver);
575#endif
576 return ret;
577}
578module_init(da7210_modinit);
579
580static void __exit da7210_exit(void)
581{
582#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
583 i2c_del_driver(&da7210_i2c_driver);
584#endif
585}
586module_exit(da7210_exit);
587
588MODULE_DESCRIPTION("ASoC DA7210 driver");
589MODULE_AUTHOR("David Chen, Kuninori Morimoto");
590MODULE_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/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 5cda9e6b5a74..5a5f187a2657 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/gpio.h> 21#include <linux/gpio.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/initval.h> 25#include <sound/initval.h>
@@ -90,13 +91,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
90 goto pcm_err; 91 goto pcm_err;
91 } 92 }
92 93
93 /* Register Card. */
94 ret = snd_soc_init_card(socdev);
95 if (ret < 0) {
96 printk(KERN_ERR "pcm3008: failed to register card\n");
97 goto card_err;
98 }
99
100 /* DEM1 DEM0 DE-EMPHASIS_MODE 94 /* DEM1 DEM0 DE-EMPHASIS_MODE
101 * Low Low De-emphasis 44.1 kHz ON 95 * Low Low De-emphasis 44.1 kHz ON
102 * Low High De-emphasis OFF 96 * Low High De-emphasis OFF
@@ -136,8 +130,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
136 130
137gpio_err: 131gpio_err:
138 pcm3008_gpio_free(setup); 132 pcm3008_gpio_free(setup);
139card_err:
140 snd_soc_free_pcms(socdev);
141pcm_err: 133pcm_err:
142 kfree(socdev->card->codec); 134 kfree(socdev->card->codec);
143 135
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index c550750c79c0..29d0906a924a 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -33,6 +33,7 @@
33#include <linux/pm.h> 33#include <linux/pm.h>
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/platform_device.h> 35#include <linux/platform_device.h>
36#include <linux/slab.h>
36#include <sound/core.h> 37#include <sound/core.h>
37#include <sound/pcm.h> 38#include <sound/pcm.h>
38#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
@@ -210,7 +211,6 @@ static int ssm2602_add_widgets(struct snd_soc_codec *codec)
210 211
211 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn)); 212 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
212 213
213 snd_soc_dapm_new_widgets(codec);
214 return 0; 214 return 0;
215} 215}
216 216
@@ -613,17 +613,9 @@ static int ssm2602_init(struct snd_soc_device *socdev)
613 snd_soc_add_controls(codec, ssm2602_snd_controls, 613 snd_soc_add_controls(codec, ssm2602_snd_controls,
614 ARRAY_SIZE(ssm2602_snd_controls)); 614 ARRAY_SIZE(ssm2602_snd_controls));
615 ssm2602_add_widgets(codec); 615 ssm2602_add_widgets(codec);
616 ret = snd_soc_init_card(socdev);
617 if (ret < 0) {
618 pr_err("ssm2602: failed to register card\n");
619 goto card_err;
620 }
621 616
622 return ret; 617 return ret;
623 618
624card_err:
625 snd_soc_free_pcms(socdev);
626 snd_soc_dapm_free(socdev);
627pcm_err: 619pcm_err:
628 kfree(codec->reg_cache); 620 kfree(codec->reg_cache);
629 return ret; 621 return ret;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index befc6488c39a..3293629dcb3b 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/slab.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/device.h> 20#include <linux/device.h>
20#include <sound/core.h> 21#include <sound/core.h>
@@ -191,6 +192,7 @@ static int ac97_analog_prepare(struct snd_pcm_substream *substream,
191 vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); 192 vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
192 193
193 vra |= 0x1; /* enable variable rate audio */ 194 vra |= 0x1; /* enable variable rate audio */
195 vra &= ~0x4; /* disable SPDIF output */
194 196
195 stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); 197 stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
196 198
@@ -221,22 +223,6 @@ static int ac97_digital_prepare(struct snd_pcm_substream *substream,
221 return stac9766_ac97_write(codec, reg, runtime->rate); 223 return stac9766_ac97_write(codec, reg, runtime->rate);
222} 224}
223 225
224static int ac97_digital_trigger(struct snd_pcm_substream *substream,
225 int cmd, struct snd_soc_dai *dai)
226{
227 struct snd_soc_codec *codec = dai->codec;
228 unsigned short vra;
229
230 switch (cmd) {
231 case SNDRV_PCM_TRIGGER_STOP:
232 vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
233 vra &= !0x04;
234 stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
235 break;
236 }
237 return 0;
238}
239
240static int stac9766_set_bias_level(struct snd_soc_codec *codec, 226static int stac9766_set_bias_level(struct snd_soc_codec *codec,
241 enum snd_soc_bias_level level) 227 enum snd_soc_bias_level level)
242{ 228{
@@ -315,7 +301,6 @@ static struct snd_soc_dai_ops stac9766_dai_ops_analog = {
315 301
316static struct snd_soc_dai_ops stac9766_dai_ops_digital = { 302static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
317 .prepare = ac97_digital_prepare, 303 .prepare = ac97_digital_prepare,
318 .trigger = ac97_digital_trigger,
319}; 304};
320 305
321struct snd_soc_dai stac9766_dai[] = { 306struct snd_soc_dai stac9766_dai[] = {
@@ -418,9 +403,6 @@ static int stac9766_codec_probe(struct platform_device *pdev)
418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls, 403 snd_soc_add_controls(codec, stac9766_snd_ac97_controls,
419 ARRAY_SIZE(stac9766_snd_ac97_controls)); 404 ARRAY_SIZE(stac9766_snd_ac97_controls));
420 405
421 ret = snd_soc_init_card(socdev);
422 if (ret < 0)
423 goto reset_err;
424 return 0; 406 return 0;
425 407
426reset_err: 408reset_err:
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 90a0264f7538..776b79cde904 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -25,6 +25,7 @@
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/slab.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -85,7 +86,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
85 * of data into val 86 * of data into val
86 */ 87 */
87 88
88 if ((reg < 0 || reg > 9) && (reg != 15)) { 89 if (reg > 9 && reg != 15) {
89 printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg); 90 printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
90 return -1; 91 return -1;
91 } 92 }
@@ -395,7 +396,6 @@ static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
395 /* set up audio path interconnects */ 396 /* set up audio path interconnects */
396 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 397 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
397 398
398 snd_soc_dapm_new_widgets(codec);
399 return 0; 399 return 0;
400} 400}
401 401
@@ -628,7 +628,7 @@ static int tlv320aic23_resume(struct platform_device *pdev)
628 u16 reg; 628 u16 reg;
629 629
630 /* Sync reg_cache with the hardware */ 630 /* Sync reg_cache with the hardware */
631 for (reg = 0; reg < TLV320AIC23_RESET; reg++) { 631 for (reg = 0; reg <= TLV320AIC23_ACTIVE; reg++) {
632 u16 val = tlv320aic23_read_reg_cache(codec, reg); 632 u16 val = tlv320aic23_read_reg_cache(codec, reg);
633 tlv320aic23_write(codec, reg, val); 633 tlv320aic23_write(codec, reg, val);
634 } 634 }
@@ -706,17 +706,9 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
706 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 706 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
707 ARRAY_SIZE(tlv320aic23_snd_controls)); 707 ARRAY_SIZE(tlv320aic23_snd_controls));
708 tlv320aic23_add_widgets(codec); 708 tlv320aic23_add_widgets(codec);
709 ret = snd_soc_init_card(socdev);
710 if (ret < 0) {
711 printk(KERN_ERR "tlv320aic23: failed to register card\n");
712 goto card_err;
713 }
714 709
715 return ret; 710 return ret;
716 711
717card_err:
718 snd_soc_free_pcms(socdev);
719 snd_soc_dapm_free(socdev);
720pcm_err: 712pcm_err:
721 kfree(codec->reg_cache); 713 kfree(codec->reg_cache);
722 return ret; 714 return ret;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 3387d9e736ea..b5b7d6a03844 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/sysfs.h> 14#include <linux/sysfs.h>
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <linux/slab.h>
16#include <sound/core.h> 17#include <sound/core.h>
17#include <sound/pcm.h> 18#include <sound/pcm.h>
18#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
@@ -356,18 +357,7 @@ static int aic26_probe(struct platform_device *pdev)
356 ARRAY_SIZE(aic26_snd_controls)); 357 ARRAY_SIZE(aic26_snd_controls));
357 WARN_ON(err < 0); 358 WARN_ON(err < 0);
358 359
359 /* CODEC is setup, we can register the card now */
360 dev_dbg(&pdev->dev, "Registering card\n");
361 ret = snd_soc_init_card(socdev);
362 if (ret < 0) {
363 dev_err(&pdev->dev, "aic26: failed to register card\n");
364 goto card_err;
365 }
366 return 0; 360 return 0;
367
368 card_err:
369 snd_soc_free_pcms(socdev);
370 return ret;
371} 361}
372 362
373static int aic26_remove(struct platform_device *pdev) 363static int aic26_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 3395cf945d56..4a6d56c3fed9 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -39,6 +39,7 @@
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/slab.h>
42#include <sound/core.h> 43#include <sound/core.h>
43#include <sound/pcm.h> 44#include <sound/pcm.h>
44#include <sound/pcm_params.h> 45#include <sound/pcm_params.h>
@@ -753,7 +754,6 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
753 /* set up audio path interconnects */ 754 /* set up audio path interconnects */
754 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 755 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
755 756
756 snd_soc_dapm_new_widgets(codec);
757 return 0; 757 return 0;
758} 758}
759 759
@@ -766,9 +766,10 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
766 struct snd_soc_codec *codec = socdev->card->codec; 766 struct snd_soc_codec *codec = socdev->card->codec;
767 struct aic3x_priv *aic3x = codec->private_data; 767 struct aic3x_priv *aic3x = codec->private_data;
768 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 768 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
769 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 769 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
770 u16 pll_d = 1; 770 u16 d, pll_d = 1;
771 u8 reg; 771 u8 reg;
772 int clk;
772 773
773 /* select data word length */ 774 /* select data word length */
774 data = 775 data =
@@ -834,48 +835,70 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
834 if (bypass_pll) 835 if (bypass_pll)
835 return 0; 836 return 0;
836 837
837 /* Use PLL 838 /* Use PLL, compute apropriate setup for j, d, r and p, the closest
838 * find an apropriate setup for j, d, r and p by iterating over 839 * one wins the game. Try with d==0 first, next with d!=0.
839 * p and r - j and d are calculated for each fraction. 840 * Constraints for j are according to the datasheet.
840 * Up to 128 values are probed, the closest one wins the game.
841 * The sysclk is divided by 1000 to prevent integer overflows. 841 * The sysclk is divided by 1000 to prevent integer overflows.
842 */ 842 */
843
843 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000); 844 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
844 845
845 for (r = 1; r <= 16; r++) 846 for (r = 1; r <= 16; r++)
846 for (p = 1; p <= 8; p++) { 847 for (p = 1; p <= 8; p++) {
847 int clk, tmp = (codec_clk * pll_r * 10) / pll_p; 848 for (j = 4; j <= 55; j++) {
848 u8 j = tmp / 10000; 849 /* This is actually 1000*((j+(d/10000))*r)/p
849 u16 d = tmp % 10000; 850 * The term had to be converted to get
851 * rid of the division by 10000; d = 0 here
852 */
853 int tmp_clk = (1000 * j * r) / p;
854
855 /* Check whether this values get closer than
856 * the best ones we had before
857 */
858 if (abs(codec_clk - tmp_clk) <
859 abs(codec_clk - last_clk)) {
860 pll_j = j; pll_d = 0;
861 pll_r = r; pll_p = p;
862 last_clk = tmp_clk;
863 }
864
865 /* Early exit for exact matches */
866 if (tmp_clk == codec_clk)
867 goto found;
868 }
869 }
850 870
851 if (j > 63) 871 /* try with d != 0 */
852 continue; 872 for (p = 1; p <= 8; p++) {
873 j = codec_clk * p / 1000;
853 874
854 if (d != 0 && aic3x->sysclk < 10000000) 875 if (j < 4 || j > 11)
855 continue; 876 continue;
856 877
857 /* This is actually 1000 * ((j + (d/10000)) * r) / p 878 /* do not use codec_clk here since we'd loose precision */
858 * The term had to be converted to get rid of the 879 d = ((2048 * p * fsref) - j * aic3x->sysclk)
859 * division by 10000 */ 880 * 100 / (aic3x->sysclk/100);
860 clk = ((10000 * j * r) + (d * r)) / (10 * p);
861 881
862 /* check whether this values get closer than the best 882 clk = (10000 * j + d) / (10 * p);
863 * ones we had before */
864 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
865 pll_j = j; pll_d = d; pll_r = r; pll_p = p;
866 last_clk = clk;
867 }
868 883
869 /* Early exit for exact matches */ 884 /* check whether this values get closer than the best
870 if (clk == codec_clk) 885 * ones we had before */
871 break; 886 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
887 pll_j = j; pll_d = d; pll_r = 1; pll_p = p;
888 last_clk = clk;
872 } 889 }
873 890
891 /* Early exit for exact matches */
892 if (clk == codec_clk)
893 goto found;
894 }
895
874 if (last_clk == 0) { 896 if (last_clk == 0) {
875 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__); 897 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
876 return -EINVAL; 898 return -EINVAL;
877 } 899 }
878 900
901found:
879 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 902 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
880 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); 903 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT));
881 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT); 904 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT);
@@ -1405,18 +1428,8 @@ static int aic3x_probe(struct platform_device *pdev)
1405 1428
1406 aic3x_add_widgets(codec); 1429 aic3x_add_widgets(codec);
1407 1430
1408 ret = snd_soc_init_card(socdev);
1409 if (ret < 0) {
1410 printk(KERN_ERR "aic3x: failed to register card\n");
1411 goto card_err;
1412 }
1413
1414 return ret; 1431 return ret;
1415 1432
1416card_err:
1417 snd_soc_free_pcms(socdev);
1418 snd_soc_dapm_free(socdev);
1419
1420pcm_err: 1433pcm_err:
1421 kfree(codec->reg_cache); 1434 kfree(codec->reg_cache);
1422 return ret; 1435 return ret;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
new file mode 100644
index 000000000000..d1e0e81ef30c
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -0,0 +1,1423 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
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 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/pm.h>
29#include <linux/i2c.h>
30#include <linux/platform_device.h>
31#include <linux/interrupt.h>
32#include <linux/gpio.h>
33#include <linux/regulator/consumer.h>
34#include <linux/slab.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/tlv320dac33-plat.h>
44#include "tlv320dac33.h"
45
46#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words,
47 * 6144 stereo */
48#define DAC33_BUFFER_SIZE_SAMPLES 6144
49
50#define NSAMPLE_MAX 5700
51
52#define LATENCY_TIME_MS 20
53
54static struct snd_soc_codec *tlv320dac33_codec;
55
56enum dac33_state {
57 DAC33_IDLE = 0,
58 DAC33_PREFILL,
59 DAC33_PLAYBACK,
60 DAC33_FLUSH,
61};
62
63enum dac33_fifo_modes {
64 DAC33_FIFO_BYPASS = 0,
65 DAC33_FIFO_MODE1,
66 DAC33_FIFO_MODE7,
67 DAC33_FIFO_LAST_MODE,
68};
69
70#define DAC33_NUM_SUPPLIES 3
71static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
72 "AVDD",
73 "DVDD",
74 "IOVDD",
75};
76
77struct tlv320dac33_priv {
78 struct mutex mutex;
79 struct workqueue_struct *dac33_wq;
80 struct work_struct work;
81 struct snd_soc_codec codec;
82 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
83 int power_gpio;
84 int chip_power;
85 int irq;
86 unsigned int refclk;
87
88 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
89 unsigned int nsample_min; /* nsample should not be lower than
90 * this */
91 unsigned int nsample_max; /* nsample should not be higher than
92 * this */
93 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
94 unsigned int nsample; /* burst read amount from host */
95 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
96
97 enum dac33_state state;
98};
99
100static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
1010x00, 0x00, 0x00, 0x00, /* 0x00 - 0x03 */
1020x00, 0x00, 0x00, 0x00, /* 0x04 - 0x07 */
1030x00, 0x00, 0x00, 0x00, /* 0x08 - 0x0b */
1040x00, 0x00, 0x00, 0x00, /* 0x0c - 0x0f */
1050x00, 0x00, 0x00, 0x00, /* 0x10 - 0x13 */
1060x00, 0x00, 0x00, 0x00, /* 0x14 - 0x17 */
1070x00, 0x00, 0x00, 0x00, /* 0x18 - 0x1b */
1080x00, 0x00, 0x00, 0x00, /* 0x1c - 0x1f */
1090x00, 0x00, 0x00, 0x00, /* 0x20 - 0x23 */
1100x00, 0x00, 0x00, 0x00, /* 0x24 - 0x27 */
1110x00, 0x00, 0x00, 0x00, /* 0x28 - 0x2b */
1120x00, 0x00, 0x00, 0x80, /* 0x2c - 0x2f */
1130x80, 0x00, 0x00, 0x00, /* 0x30 - 0x33 */
1140x00, 0x00, 0x00, 0x00, /* 0x34 - 0x37 */
1150x00, 0x00, /* 0x38 - 0x39 */
116/* Registers 0x3a - 0x3f are reserved */
117 0x00, 0x00, /* 0x3a - 0x3b */
1180x00, 0x00, 0x00, 0x00, /* 0x3c - 0x3f */
119
1200x00, 0x00, 0x00, 0x00, /* 0x40 - 0x43 */
1210x00, 0x80, /* 0x44 - 0x45 */
122/* Registers 0x46 - 0x47 are reserved */
123 0x80, 0x80, /* 0x46 - 0x47 */
124
1250x80, 0x00, 0x00, /* 0x48 - 0x4a */
126/* Registers 0x4b - 0x7c are reserved */
127 0x00, /* 0x4b */
1280x00, 0x00, 0x00, 0x00, /* 0x4c - 0x4f */
1290x00, 0x00, 0x00, 0x00, /* 0x50 - 0x53 */
1300x00, 0x00, 0x00, 0x00, /* 0x54 - 0x57 */
1310x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5b */
1320x00, 0x00, 0x00, 0x00, /* 0x5c - 0x5f */
1330x00, 0x00, 0x00, 0x00, /* 0x60 - 0x63 */
1340x00, 0x00, 0x00, 0x00, /* 0x64 - 0x67 */
1350x00, 0x00, 0x00, 0x00, /* 0x68 - 0x6b */
1360x00, 0x00, 0x00, 0x00, /* 0x6c - 0x6f */
1370x00, 0x00, 0x00, 0x00, /* 0x70 - 0x73 */
1380x00, 0x00, 0x00, 0x00, /* 0x74 - 0x77 */
1390x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7b */
1400x00, /* 0x7c */
141
142 0xda, 0x33, 0x03, /* 0x7d - 0x7f */
143};
144
145/* Register read and write */
146static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
147 unsigned reg)
148{
149 u8 *cache = codec->reg_cache;
150 if (reg >= DAC33_CACHEREGNUM)
151 return 0;
152
153 return cache[reg];
154}
155
156static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
157 u8 reg, u8 value)
158{
159 u8 *cache = codec->reg_cache;
160 if (reg >= DAC33_CACHEREGNUM)
161 return;
162
163 cache[reg] = value;
164}
165
166static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
167 u8 *value)
168{
169 struct tlv320dac33_priv *dac33 = codec->private_data;
170 int val;
171
172 *value = reg & 0xff;
173
174 /* If powered off, return the cached value */
175 if (dac33->chip_power) {
176 val = i2c_smbus_read_byte_data(codec->control_data, value[0]);
177 if (val < 0) {
178 dev_err(codec->dev, "Read failed (%d)\n", val);
179 value[0] = dac33_read_reg_cache(codec, reg);
180 } else {
181 value[0] = val;
182 dac33_write_reg_cache(codec, reg, val);
183 }
184 } else {
185 value[0] = dac33_read_reg_cache(codec, reg);
186 }
187
188 return 0;
189}
190
191static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
192 unsigned int value)
193{
194 struct tlv320dac33_priv *dac33 = codec->private_data;
195 u8 data[2];
196 int ret = 0;
197
198 /*
199 * data is
200 * D15..D8 dac33 register offset
201 * D7...D0 register data
202 */
203 data[0] = reg & 0xff;
204 data[1] = value & 0xff;
205
206 dac33_write_reg_cache(codec, data[0], data[1]);
207 if (dac33->chip_power) {
208 ret = codec->hw_write(codec->control_data, data, 2);
209 if (ret != 2)
210 dev_err(codec->dev, "Write failed (%d)\n", ret);
211 else
212 ret = 0;
213 }
214
215 return ret;
216}
217
218static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
219 unsigned int value)
220{
221 struct tlv320dac33_priv *dac33 = codec->private_data;
222 int ret;
223
224 mutex_lock(&dac33->mutex);
225 ret = dac33_write(codec, reg, value);
226 mutex_unlock(&dac33->mutex);
227
228 return ret;
229}
230
231#define DAC33_I2C_ADDR_AUTOINC 0x80
232static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
233 unsigned int value)
234{
235 struct tlv320dac33_priv *dac33 = codec->private_data;
236 u8 data[3];
237 int ret = 0;
238
239 /*
240 * data is
241 * D23..D16 dac33 register offset
242 * D15..D8 register data MSB
243 * D7...D0 register data LSB
244 */
245 data[0] = reg & 0xff;
246 data[1] = (value >> 8) & 0xff;
247 data[2] = value & 0xff;
248
249 dac33_write_reg_cache(codec, data[0], data[1]);
250 dac33_write_reg_cache(codec, data[0] + 1, data[2]);
251
252 if (dac33->chip_power) {
253 /* We need to set autoincrement mode for 16 bit writes */
254 data[0] |= DAC33_I2C_ADDR_AUTOINC;
255 ret = codec->hw_write(codec->control_data, data, 3);
256 if (ret != 3)
257 dev_err(codec->dev, "Write failed (%d)\n", ret);
258 else
259 ret = 0;
260 }
261
262 return ret;
263}
264
265static void dac33_restore_regs(struct snd_soc_codec *codec)
266{
267 struct tlv320dac33_priv *dac33 = codec->private_data;
268 u8 *cache = codec->reg_cache;
269 u8 data[2];
270 int i, ret;
271
272 if (!dac33->chip_power)
273 return;
274
275 for (i = DAC33_PWR_CTRL; i <= DAC33_INTP_CTRL_B; i++) {
276 data[0] = i;
277 data[1] = cache[i];
278 /* Skip the read only registers */
279 if ((i >= DAC33_INT_OSC_STATUS &&
280 i <= DAC33_INT_OSC_FREQ_RAT_READ_B) ||
281 (i >= DAC33_FIFO_WPTR_MSB && i <= DAC33_FIFO_IRQ_FLAG) ||
282 i == DAC33_DAC_STATUS_FLAGS ||
283 i == DAC33_SRC_EST_REF_CLK_RATIO_A ||
284 i == DAC33_SRC_EST_REF_CLK_RATIO_B)
285 continue;
286 ret = codec->hw_write(codec->control_data, data, 2);
287 if (ret != 2)
288 dev_err(codec->dev, "Write failed (%d)\n", ret);
289 }
290 for (i = DAC33_LDAC_PWR_CTRL; i <= DAC33_LINEL_TO_LLO_VOL; i++) {
291 data[0] = i;
292 data[1] = cache[i];
293 ret = codec->hw_write(codec->control_data, data, 2);
294 if (ret != 2)
295 dev_err(codec->dev, "Write failed (%d)\n", ret);
296 }
297 for (i = DAC33_LINER_TO_RLO_VOL; i <= DAC33_OSC_TRIM; i++) {
298 data[0] = i;
299 data[1] = cache[i];
300 ret = codec->hw_write(codec->control_data, data, 2);
301 if (ret != 2)
302 dev_err(codec->dev, "Write failed (%d)\n", ret);
303 }
304}
305
306static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
307{
308 u8 reg;
309
310 reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
311 if (power)
312 reg |= DAC33_PDNALLB;
313 else
314 reg &= ~DAC33_PDNALLB;
315 dac33_write(codec, DAC33_PWR_CTRL, reg);
316}
317
318static int dac33_hard_power(struct snd_soc_codec *codec, int power)
319{
320 struct tlv320dac33_priv *dac33 = codec->private_data;
321 int ret;
322
323 mutex_lock(&dac33->mutex);
324 if (power) {
325 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
326 dac33->supplies);
327 if (ret != 0) {
328 dev_err(codec->dev,
329 "Failed to enable supplies: %d\n", ret);
330 goto exit;
331 }
332
333 if (dac33->power_gpio >= 0)
334 gpio_set_value(dac33->power_gpio, 1);
335
336 dac33->chip_power = 1;
337
338 /* Restore registers */
339 dac33_restore_regs(codec);
340
341 dac33_soft_power(codec, 1);
342 } else {
343 dac33_soft_power(codec, 0);
344 if (dac33->power_gpio >= 0)
345 gpio_set_value(dac33->power_gpio, 0);
346
347 ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
348 dac33->supplies);
349 if (ret != 0) {
350 dev_err(codec->dev,
351 "Failed to disable supplies: %d\n", ret);
352 goto exit;
353 }
354
355 dac33->chip_power = 0;
356 }
357
358exit:
359 mutex_unlock(&dac33->mutex);
360 return ret;
361}
362
363static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
364 struct snd_ctl_elem_value *ucontrol)
365{
366 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
367 struct tlv320dac33_priv *dac33 = codec->private_data;
368
369 ucontrol->value.integer.value[0] = dac33->nsample;
370
371 return 0;
372}
373
374static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol)
376{
377 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
378 struct tlv320dac33_priv *dac33 = codec->private_data;
379 int ret = 0;
380
381 if (dac33->nsample == ucontrol->value.integer.value[0])
382 return 0;
383
384 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
385 ucontrol->value.integer.value[0] > dac33->nsample_max)
386 ret = -EINVAL;
387 else
388 dac33->nsample = ucontrol->value.integer.value[0];
389
390 return ret;
391}
392
393static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
395{
396 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct tlv320dac33_priv *dac33 = codec->private_data;
398
399 ucontrol->value.integer.value[0] = dac33->fifo_mode;
400
401 return 0;
402}
403
404static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
405 struct snd_ctl_elem_value *ucontrol)
406{
407 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
408 struct tlv320dac33_priv *dac33 = codec->private_data;
409 int ret = 0;
410
411 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
412 return 0;
413 /* Do not allow changes while stream is running*/
414 if (codec->active)
415 return -EPERM;
416
417 if (ucontrol->value.integer.value[0] < 0 ||
418 ucontrol->value.integer.value[0] >= DAC33_FIFO_LAST_MODE)
419 ret = -EINVAL;
420 else
421 dac33->fifo_mode = ucontrol->value.integer.value[0];
422
423 return ret;
424}
425
426/* Codec operation modes */
427static const char *dac33_fifo_mode_texts[] = {
428 "Bypass", "Mode 1", "Mode 7"
429};
430
431static const struct soc_enum dac33_fifo_mode_enum =
432 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts),
433 dac33_fifo_mode_texts);
434
435/*
436 * DACL/R digital volume control:
437 * from 0 dB to -63.5 in 0.5 dB steps
438 * Need to be inverted later on:
439 * 0x00 == 0 dB
440 * 0x7f == -63.5 dB
441 */
442static DECLARE_TLV_DB_SCALE(dac_digivol_tlv, -6350, 50, 0);
443
444static const struct snd_kcontrol_new dac33_snd_controls[] = {
445 SOC_DOUBLE_R_TLV("DAC Digital Playback Volume",
446 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL,
447 0, 0x7f, 1, dac_digivol_tlv),
448 SOC_DOUBLE_R("DAC Digital Playback Switch",
449 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1),
450 SOC_DOUBLE_R("Line to Line Out Volume",
451 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
452};
453
454static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
455 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
456 dac33_get_nsample, dac33_set_nsample),
457 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
458 dac33_get_fifo_mode, dac33_set_fifo_mode),
459};
460
461/* Analog bypass */
462static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
463 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
464
465static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
466 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
467
468static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
469 SND_SOC_DAPM_OUTPUT("LEFT_LO"),
470 SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
471
472 SND_SOC_DAPM_INPUT("LINEL"),
473 SND_SOC_DAPM_INPUT("LINER"),
474
475 SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0),
476 SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0),
477
478 /* Analog bypass */
479 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
480 &dac33_dapm_abypassl_control),
481 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
482 &dac33_dapm_abypassr_control),
483
484 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power",
485 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
486 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
487 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
488};
489
490static const struct snd_soc_dapm_route audio_map[] = {
491 /* Analog bypass */
492 {"Analog Left Bypass", "Switch", "LINEL"},
493 {"Analog Right Bypass", "Switch", "LINER"},
494
495 {"Output Left Amp Power", NULL, "DACL"},
496 {"Output Right Amp Power", NULL, "DACR"},
497
498 {"Output Left Amp Power", NULL, "Analog Left Bypass"},
499 {"Output Right Amp Power", NULL, "Analog Right Bypass"},
500
501 /* output */
502 {"LEFT_LO", NULL, "Output Left Amp Power"},
503 {"RIGHT_LO", NULL, "Output Right Amp Power"},
504};
505
506static int dac33_add_widgets(struct snd_soc_codec *codec)
507{
508 snd_soc_dapm_new_controls(codec, dac33_dapm_widgets,
509 ARRAY_SIZE(dac33_dapm_widgets));
510
511 /* set up audio path interconnects */
512 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
513
514 return 0;
515}
516
517static int dac33_set_bias_level(struct snd_soc_codec *codec,
518 enum snd_soc_bias_level level)
519{
520 int ret;
521
522 switch (level) {
523 case SND_SOC_BIAS_ON:
524 dac33_soft_power(codec, 1);
525 break;
526 case SND_SOC_BIAS_PREPARE:
527 break;
528 case SND_SOC_BIAS_STANDBY:
529 if (codec->bias_level == SND_SOC_BIAS_OFF) {
530 ret = dac33_hard_power(codec, 1);
531 if (ret != 0)
532 return ret;
533 }
534
535 dac33_soft_power(codec, 0);
536 break;
537 case SND_SOC_BIAS_OFF:
538 ret = dac33_hard_power(codec, 0);
539 if (ret != 0)
540 return ret;
541
542 break;
543 }
544 codec->bias_level = level;
545
546 return 0;
547}
548
549static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
550{
551 struct snd_soc_codec *codec;
552
553 codec = &dac33->codec;
554
555 switch (dac33->fifo_mode) {
556 case DAC33_FIFO_MODE1:
557 dac33_write16(codec, DAC33_NSAMPLE_MSB,
558 DAC33_THRREG(dac33->nsample));
559 dac33_write16(codec, DAC33_PREFILL_MSB,
560 DAC33_THRREG(dac33->alarm_threshold));
561 break;
562 case DAC33_FIFO_MODE7:
563 dac33_write16(codec, DAC33_PREFILL_MSB,
564 DAC33_THRREG(10));
565 break;
566 default:
567 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
568 dac33->fifo_mode);
569 break;
570 }
571}
572
573static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
574{
575 struct snd_soc_codec *codec;
576
577 codec = &dac33->codec;
578
579 switch (dac33->fifo_mode) {
580 case DAC33_FIFO_MODE1:
581 dac33_write16(codec, DAC33_NSAMPLE_MSB,
582 DAC33_THRREG(dac33->nsample));
583 break;
584 case DAC33_FIFO_MODE7:
585 /* At the moment we are not using interrupts in mode7 */
586 break;
587 default:
588 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
589 dac33->fifo_mode);
590 break;
591 }
592}
593
594static void dac33_work(struct work_struct *work)
595{
596 struct snd_soc_codec *codec;
597 struct tlv320dac33_priv *dac33;
598 u8 reg;
599
600 dac33 = container_of(work, struct tlv320dac33_priv, work);
601 codec = &dac33->codec;
602
603 mutex_lock(&dac33->mutex);
604 switch (dac33->state) {
605 case DAC33_PREFILL:
606 dac33->state = DAC33_PLAYBACK;
607 dac33_prefill_handler(dac33);
608 break;
609 case DAC33_PLAYBACK:
610 dac33_playback_handler(dac33);
611 break;
612 case DAC33_IDLE:
613 break;
614 case DAC33_FLUSH:
615 dac33->state = DAC33_IDLE;
616 /* Mask all interrupts from dac33 */
617 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
618
619 /* flush fifo */
620 reg = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
621 reg |= DAC33_FIFOFLUSH;
622 dac33_write(codec, DAC33_FIFO_CTRL_A, reg);
623 break;
624 }
625 mutex_unlock(&dac33->mutex);
626}
627
628static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
629{
630 struct snd_soc_codec *codec = dev;
631 struct tlv320dac33_priv *dac33 = codec->private_data;
632
633 queue_work(dac33->dac33_wq, &dac33->work);
634
635 return IRQ_HANDLED;
636}
637
638static void dac33_shutdown(struct snd_pcm_substream *substream,
639 struct snd_soc_dai *dai)
640{
641 struct snd_soc_pcm_runtime *rtd = substream->private_data;
642 struct snd_soc_device *socdev = rtd->socdev;
643 struct snd_soc_codec *codec = socdev->card->codec;
644 struct tlv320dac33_priv *dac33 = codec->private_data;
645 unsigned int pwr_ctrl;
646
647 /* Stop pending workqueue */
648 if (dac33->fifo_mode)
649 cancel_work_sync(&dac33->work);
650
651 mutex_lock(&dac33->mutex);
652 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
653 pwr_ctrl &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
654 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
655 mutex_unlock(&dac33->mutex);
656}
657
658static void dac33_oscwait(struct snd_soc_codec *codec)
659{
660 int timeout = 20;
661 u8 reg;
662
663 do {
664 msleep(1);
665 dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
666 } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
667 if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
668 dev_err(codec->dev,
669 "internal oscillator calibration failed\n");
670}
671
672static int dac33_hw_params(struct snd_pcm_substream *substream,
673 struct snd_pcm_hw_params *params,
674 struct snd_soc_dai *dai)
675{
676 struct snd_soc_pcm_runtime *rtd = substream->private_data;
677 struct snd_soc_device *socdev = rtd->socdev;
678 struct snd_soc_codec *codec = socdev->card->codec;
679
680 /* Check parameters for validity */
681 switch (params_rate(params)) {
682 case 44100:
683 case 48000:
684 break;
685 default:
686 dev_err(codec->dev, "unsupported rate %d\n",
687 params_rate(params));
688 return -EINVAL;
689 }
690
691 switch (params_format(params)) {
692 case SNDRV_PCM_FORMAT_S16_LE:
693 break;
694 default:
695 dev_err(codec->dev, "unsupported format %d\n",
696 params_format(params));
697 return -EINVAL;
698 }
699
700 return 0;
701}
702
703#define CALC_OSCSET(rate, refclk) ( \
704 ((((rate * 10000) / refclk) * 4096) + 7000) / 10000)
705#define CALC_RATIOSET(rate, refclk) ( \
706 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
707
708/*
709 * tlv320dac33 is strict on the sequence of the register writes, if the register
710 * writes happens in different order, than dac33 might end up in unknown state.
711 * Use the known, working sequence of register writes to initialize the dac33.
712 */
713static int dac33_prepare_chip(struct snd_pcm_substream *substream)
714{
715 struct snd_soc_pcm_runtime *rtd = substream->private_data;
716 struct snd_soc_device *socdev = rtd->socdev;
717 struct snd_soc_codec *codec = socdev->card->codec;
718 struct tlv320dac33_priv *dac33 = codec->private_data;
719 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
720 u8 aictrl_a, aictrl_b, fifoctrl_a;
721
722 switch (substream->runtime->rate) {
723 case 44100:
724 case 48000:
725 oscset = CALC_OSCSET(substream->runtime->rate, dac33->refclk);
726 ratioset = CALC_RATIOSET(substream->runtime->rate,
727 dac33->refclk);
728 break;
729 default:
730 dev_err(codec->dev, "unsupported rate %d\n",
731 substream->runtime->rate);
732 return -EINVAL;
733 }
734
735
736 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
737 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
738 /* Read FIFO control A, and clear FIFO flush bit */
739 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
740 fifoctrl_a &= ~DAC33_FIFOFLUSH;
741
742 fifoctrl_a &= ~DAC33_WIDTH;
743 switch (substream->runtime->format) {
744 case SNDRV_PCM_FORMAT_S16_LE:
745 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
746 fifoctrl_a |= DAC33_WIDTH;
747 break;
748 default:
749 dev_err(codec->dev, "unsupported format %d\n",
750 substream->runtime->format);
751 return -EINVAL;
752 }
753
754 mutex_lock(&dac33->mutex);
755 dac33_soft_power(codec, 1);
756
757 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
758 dac33_write(codec, DAC33_INT_OSC_CTRL, reg_tmp);
759
760 /* Write registers 0x08 and 0x09 (MSB, LSB) */
761 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
762
763 /* calib time: 128 is a nice number ;) */
764 dac33_write(codec, DAC33_CALIB_TIME, 128);
765
766 /* adjustment treshold & step */
767 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
768 DAC33_ADJSTEP(1));
769
770 /* div=4 / gain=1 / div */
771 dac33_write(codec, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
772
773 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
774 pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
775 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
776
777 dac33_oscwait(codec);
778
779 if (dac33->fifo_mode) {
780 /* Generic for all FIFO modes */
781 /* 50-51 : ASRC Control registers */
782 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
783 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
784
785 /* Write registers 0x34 and 0x35 (MSB, LSB) */
786 dac33_write16(codec, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
787
788 /* Set interrupts to high active */
789 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
790 } else {
791 /* FIFO bypass mode */
792 /* 50-51 : ASRC Control registers */
793 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
794 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
795 }
796
797 /* Interrupt behaviour configuration */
798 switch (dac33->fifo_mode) {
799 case DAC33_FIFO_MODE1:
800 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
801 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
802 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
803 break;
804 case DAC33_FIFO_MODE7:
805 /* Disable all interrupts */
806 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
807 break;
808 default:
809 /* in FIFO bypass mode, the interrupts are not used */
810 break;
811 }
812
813 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
814
815 switch (dac33->fifo_mode) {
816 case DAC33_FIFO_MODE1:
817 /*
818 * For mode1:
819 * Disable the FIFO bypass (Enable the use of FIFO)
820 * Select nSample mode
821 * BCLK is only running when data is needed by DAC33
822 */
823 fifoctrl_a &= ~DAC33_FBYPAS;
824 fifoctrl_a &= ~DAC33_FAUTO;
825 aictrl_b &= ~DAC33_BCLKON;
826 break;
827 case DAC33_FIFO_MODE7:
828 /*
829 * For mode1:
830 * Disable the FIFO bypass (Enable the use of FIFO)
831 * Select Threshold mode
832 * BCLK is only running when data is needed by DAC33
833 */
834 fifoctrl_a &= ~DAC33_FBYPAS;
835 fifoctrl_a |= DAC33_FAUTO;
836 aictrl_b &= ~DAC33_BCLKON;
837 break;
838 default:
839 /*
840 * For FIFO bypass mode:
841 * Enable the FIFO bypass (Disable the FIFO use)
842 * Set the BCLK as continous
843 */
844 fifoctrl_a |= DAC33_FBYPAS;
845 aictrl_b |= DAC33_BCLKON;
846 break;
847 }
848
849 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
850 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
851 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
852
853 /*
854 * BCLK divide ratio
855 * 0: 1.5
856 * 1: 1
857 * 2: 2
858 * ...
859 * 254: 254
860 * 255: 255
861 */
862 if (dac33->fifo_mode)
863 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
864 dac33->burst_bclkdiv);
865 else
866 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
867
868 switch (dac33->fifo_mode) {
869 case DAC33_FIFO_MODE1:
870 dac33_write16(codec, DAC33_ATHR_MSB,
871 DAC33_THRREG(dac33->alarm_threshold));
872 break;
873 case DAC33_FIFO_MODE7:
874 /*
875 * Configure the threshold levels, and leave 10 sample space
876 * at the bottom, and also at the top of the FIFO
877 */
878 dac33_write16(codec, DAC33_UTHR_MSB,
879 DAC33_THRREG(DAC33_BUFFER_SIZE_SAMPLES - 10));
880 dac33_write16(codec, DAC33_LTHR_MSB,
881 DAC33_THRREG(10));
882 break;
883 default:
884 break;
885 }
886
887 mutex_unlock(&dac33->mutex);
888
889 return 0;
890}
891
892static void dac33_calculate_times(struct snd_pcm_substream *substream)
893{
894 struct snd_soc_pcm_runtime *rtd = substream->private_data;
895 struct snd_soc_device *socdev = rtd->socdev;
896 struct snd_soc_codec *codec = socdev->card->codec;
897 struct tlv320dac33_priv *dac33 = codec->private_data;
898 unsigned int nsample_limit;
899
900 /* Number of samples (16bit, stereo) in one period */
901 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
902
903 /* Number of samples (16bit, stereo) in ALSA buffer */
904 dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
905 /* Subtract one period from the total */
906 dac33->nsample_max -= dac33->nsample_min;
907
908 /* Number of samples for LATENCY_TIME_MS / 2 */
909 dac33->alarm_threshold = substream->runtime->rate /
910 (1000 / (LATENCY_TIME_MS / 2));
911
912 /* Find and fix up the lowest nsmaple limit */
913 nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
914
915 if (dac33->nsample_min < nsample_limit)
916 dac33->nsample_min = nsample_limit;
917
918 if (dac33->nsample < dac33->nsample_min)
919 dac33->nsample = dac33->nsample_min;
920
921 /*
922 * Find and fix up the highest nsmaple limit
923 * In order to not overflow the DAC33 buffer substract the
924 * alarm_threshold value from the size of the DAC33 buffer
925 */
926 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
927
928 if (dac33->nsample_max > nsample_limit)
929 dac33->nsample_max = nsample_limit;
930
931 if (dac33->nsample > dac33->nsample_max)
932 dac33->nsample = dac33->nsample_max;
933}
934
935static int dac33_pcm_prepare(struct snd_pcm_substream *substream,
936 struct snd_soc_dai *dai)
937{
938 dac33_calculate_times(substream);
939 dac33_prepare_chip(substream);
940
941 return 0;
942}
943
944static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
945 struct snd_soc_dai *dai)
946{
947 struct snd_soc_pcm_runtime *rtd = substream->private_data;
948 struct snd_soc_device *socdev = rtd->socdev;
949 struct snd_soc_codec *codec = socdev->card->codec;
950 struct tlv320dac33_priv *dac33 = codec->private_data;
951 int ret = 0;
952
953 switch (cmd) {
954 case SNDRV_PCM_TRIGGER_START:
955 case SNDRV_PCM_TRIGGER_RESUME:
956 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
957 if (dac33->fifo_mode) {
958 dac33->state = DAC33_PREFILL;
959 queue_work(dac33->dac33_wq, &dac33->work);
960 }
961 break;
962 case SNDRV_PCM_TRIGGER_STOP:
963 case SNDRV_PCM_TRIGGER_SUSPEND:
964 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
965 if (dac33->fifo_mode) {
966 dac33->state = DAC33_FLUSH;
967 queue_work(dac33->dac33_wq, &dac33->work);
968 }
969 break;
970 default:
971 ret = -EINVAL;
972 }
973
974 return ret;
975}
976
977static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
978 int clk_id, unsigned int freq, int dir)
979{
980 struct snd_soc_codec *codec = codec_dai->codec;
981 struct tlv320dac33_priv *dac33 = codec->private_data;
982 u8 ioc_reg, asrcb_reg;
983
984 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
985 asrcb_reg = dac33_read_reg_cache(codec, DAC33_ASRC_CTRL_B);
986 switch (clk_id) {
987 case TLV320DAC33_MCLK:
988 ioc_reg |= DAC33_REFSEL;
989 asrcb_reg |= DAC33_SRCREFSEL;
990 break;
991 case TLV320DAC33_SLEEPCLK:
992 ioc_reg &= ~DAC33_REFSEL;
993 asrcb_reg &= ~DAC33_SRCREFSEL;
994 break;
995 default:
996 dev_err(codec->dev, "Invalid clock ID (%d)\n", clk_id);
997 break;
998 }
999 dac33->refclk = freq;
1000
1001 dac33_write_reg_cache(codec, DAC33_INT_OSC_CTRL, ioc_reg);
1002 dac33_write_reg_cache(codec, DAC33_ASRC_CTRL_B, asrcb_reg);
1003
1004 return 0;
1005}
1006
1007static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1008 unsigned int fmt)
1009{
1010 struct snd_soc_codec *codec = codec_dai->codec;
1011 struct tlv320dac33_priv *dac33 = codec->private_data;
1012 u8 aictrl_a, aictrl_b;
1013
1014 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
1015 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
1016 /* set master/slave audio interface */
1017 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1018 case SND_SOC_DAIFMT_CBM_CFM:
1019 /* Codec Master */
1020 aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK);
1021 break;
1022 case SND_SOC_DAIFMT_CBS_CFS:
1023 /* Codec Slave */
1024 if (dac33->fifo_mode) {
1025 dev_err(codec->dev, "FIFO mode requires master mode\n");
1026 return -EINVAL;
1027 } else
1028 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
1029 break;
1030 default:
1031 return -EINVAL;
1032 }
1033
1034 aictrl_a &= ~DAC33_AFMT_MASK;
1035 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1036 case SND_SOC_DAIFMT_I2S:
1037 aictrl_a |= DAC33_AFMT_I2S;
1038 break;
1039 case SND_SOC_DAIFMT_DSP_A:
1040 aictrl_a |= DAC33_AFMT_DSP;
1041 aictrl_b &= ~DAC33_DATA_DELAY_MASK;
1042 aictrl_b |= DAC33_DATA_DELAY(0);
1043 break;
1044 case SND_SOC_DAIFMT_RIGHT_J:
1045 aictrl_a |= DAC33_AFMT_RIGHT_J;
1046 break;
1047 case SND_SOC_DAIFMT_LEFT_J:
1048 aictrl_a |= DAC33_AFMT_LEFT_J;
1049 break;
1050 default:
1051 dev_err(codec->dev, "Unsupported format (%u)\n",
1052 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1053 return -EINVAL;
1054 }
1055
1056 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
1057 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
1058
1059 return 0;
1060}
1061
1062static void dac33_init_chip(struct snd_soc_codec *codec)
1063{
1064 /* 44-46: DAC Control Registers */
1065 /* A : DAC sample rate Fsref/1.5 */
1066 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
1067 /* B : DAC src=normal, not muted */
1068 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
1069 DAC33_DACSRCL_LEFT);
1070 /* C : (defaults) */
1071 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
1072
1073 /* 64-65 : L&R DAC power control
1074 Line In -> OUT 1V/V Gain, DAC -> OUT 4V/V Gain*/
1075 dac33_write(codec, DAC33_LDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1076 dac33_write(codec, DAC33_RDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1077
1078 /* 73 : volume soft stepping control,
1079 clock source = internal osc (?) */
1080 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
1081
1082 /* 66 : LOP/LOM Modes */
1083 dac33_write(codec, DAC33_OUT_AMP_CM_CTRL, 0xff);
1084
1085 /* 68 : LOM inverted from LOP */
1086 dac33_write(codec, DAC33_OUT_AMP_CTRL, (3<<2));
1087
1088 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
1089}
1090
1091static int dac33_soc_probe(struct platform_device *pdev)
1092{
1093 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1094 struct snd_soc_codec *codec;
1095 struct tlv320dac33_priv *dac33;
1096 int ret = 0;
1097
1098 BUG_ON(!tlv320dac33_codec);
1099
1100 codec = tlv320dac33_codec;
1101 socdev->card->codec = codec;
1102 dac33 = codec->private_data;
1103
1104 /* Power up the codec */
1105 dac33_hard_power(codec, 1);
1106 /* Set default configuration */
1107 dac33_init_chip(codec);
1108
1109 /* register pcms */
1110 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1111 if (ret < 0) {
1112 dev_err(codec->dev, "failed to create pcms\n");
1113 goto pcm_err;
1114 }
1115
1116 snd_soc_add_controls(codec, dac33_snd_controls,
1117 ARRAY_SIZE(dac33_snd_controls));
1118 /* Only add the nSample controls, if we have valid IRQ number */
1119 if (dac33->irq >= 0)
1120 snd_soc_add_controls(codec, dac33_nsample_snd_controls,
1121 ARRAY_SIZE(dac33_nsample_snd_controls));
1122
1123 dac33_add_widgets(codec);
1124
1125 /* power on device */
1126 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1127
1128 /* Bias level configuration has enabled regulator an extra time */
1129 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1130
1131 return 0;
1132
1133pcm_err:
1134 dac33_hard_power(codec, 0);
1135 return ret;
1136}
1137
1138static int dac33_soc_remove(struct platform_device *pdev)
1139{
1140 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1141 struct snd_soc_codec *codec = socdev->card->codec;
1142
1143 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1144
1145 snd_soc_free_pcms(socdev);
1146 snd_soc_dapm_free(socdev);
1147
1148 return 0;
1149}
1150
1151static int dac33_soc_suspend(struct platform_device *pdev, pm_message_t state)
1152{
1153 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1154 struct snd_soc_codec *codec = socdev->card->codec;
1155
1156 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1157
1158 return 0;
1159}
1160
1161static int dac33_soc_resume(struct platform_device *pdev)
1162{
1163 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1164 struct snd_soc_codec *codec = socdev->card->codec;
1165
1166 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1167 dac33_set_bias_level(codec, codec->suspend_bias_level);
1168
1169 return 0;
1170}
1171
1172struct snd_soc_codec_device soc_codec_dev_tlv320dac33 = {
1173 .probe = dac33_soc_probe,
1174 .remove = dac33_soc_remove,
1175 .suspend = dac33_soc_suspend,
1176 .resume = dac33_soc_resume,
1177};
1178EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1179
1180#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
1181 SNDRV_PCM_RATE_48000)
1182#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1183
1184static struct snd_soc_dai_ops dac33_dai_ops = {
1185 .shutdown = dac33_shutdown,
1186 .hw_params = dac33_hw_params,
1187 .prepare = dac33_pcm_prepare,
1188 .trigger = dac33_pcm_trigger,
1189 .set_sysclk = dac33_set_dai_sysclk,
1190 .set_fmt = dac33_set_dai_fmt,
1191};
1192
1193struct snd_soc_dai dac33_dai = {
1194 .name = "tlv320dac33",
1195 .playback = {
1196 .stream_name = "Playback",
1197 .channels_min = 2,
1198 .channels_max = 2,
1199 .rates = DAC33_RATES,
1200 .formats = DAC33_FORMATS,},
1201 .ops = &dac33_dai_ops,
1202};
1203EXPORT_SYMBOL_GPL(dac33_dai);
1204
1205static int __devinit dac33_i2c_probe(struct i2c_client *client,
1206 const struct i2c_device_id *id)
1207{
1208 struct tlv320dac33_platform_data *pdata;
1209 struct tlv320dac33_priv *dac33;
1210 struct snd_soc_codec *codec;
1211 int ret, i;
1212
1213 if (client->dev.platform_data == NULL) {
1214 dev_err(&client->dev, "Platform data not set\n");
1215 return -ENODEV;
1216 }
1217 pdata = client->dev.platform_data;
1218
1219 dac33 = kzalloc(sizeof(struct tlv320dac33_priv), GFP_KERNEL);
1220 if (dac33 == NULL)
1221 return -ENOMEM;
1222
1223 codec = &dac33->codec;
1224 codec->private_data = dac33;
1225 codec->control_data = client;
1226
1227 mutex_init(&codec->mutex);
1228 mutex_init(&dac33->mutex);
1229 INIT_LIST_HEAD(&codec->dapm_widgets);
1230 INIT_LIST_HEAD(&codec->dapm_paths);
1231
1232 codec->name = "tlv320dac33";
1233 codec->owner = THIS_MODULE;
1234 codec->read = dac33_read_reg_cache;
1235 codec->write = dac33_write_locked;
1236 codec->hw_write = (hw_write_t) i2c_master_send;
1237 codec->bias_level = SND_SOC_BIAS_OFF;
1238 codec->set_bias_level = dac33_set_bias_level;
1239 codec->dai = &dac33_dai;
1240 codec->num_dai = 1;
1241 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
1242 codec->reg_cache = kmemdup(dac33_reg, ARRAY_SIZE(dac33_reg),
1243 GFP_KERNEL);
1244 if (codec->reg_cache == NULL) {
1245 ret = -ENOMEM;
1246 goto error_reg;
1247 }
1248
1249 i2c_set_clientdata(client, dac33);
1250
1251 dac33->power_gpio = pdata->power_gpio;
1252 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1253 dac33->irq = client->irq;
1254 dac33->nsample = NSAMPLE_MAX;
1255 /* Disable FIFO use by default */
1256 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1257
1258 tlv320dac33_codec = codec;
1259
1260 codec->dev = &client->dev;
1261 dac33_dai.dev = codec->dev;
1262
1263 /* Check if the reset GPIO number is valid and request it */
1264 if (dac33->power_gpio >= 0) {
1265 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
1266 if (ret < 0) {
1267 dev_err(codec->dev,
1268 "Failed to request reset GPIO (%d)\n",
1269 dac33->power_gpio);
1270 snd_soc_unregister_dai(&dac33_dai);
1271 snd_soc_unregister_codec(codec);
1272 goto error_gpio;
1273 }
1274 gpio_direction_output(dac33->power_gpio, 0);
1275 } else {
1276 dac33->chip_power = 1;
1277 }
1278
1279 /* Check if the IRQ number is valid and request it */
1280 if (dac33->irq >= 0) {
1281 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1282 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1283 codec->name, codec);
1284 if (ret < 0) {
1285 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1286 dac33->irq, ret);
1287 dac33->irq = -1;
1288 }
1289 if (dac33->irq != -1) {
1290 /* Setup work queue */
1291 dac33->dac33_wq =
1292 create_singlethread_workqueue("tlv320dac33");
1293 if (dac33->dac33_wq == NULL) {
1294 free_irq(dac33->irq, &dac33->codec);
1295 ret = -ENOMEM;
1296 goto error_wq;
1297 }
1298
1299 INIT_WORK(&dac33->work, dac33_work);
1300 }
1301 }
1302
1303 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
1304 dac33->supplies[i].supply = dac33_supply_names[i];
1305
1306 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(dac33->supplies),
1307 dac33->supplies);
1308
1309 if (ret != 0) {
1310 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1311 goto err_get;
1312 }
1313
1314 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
1315 dac33->supplies);
1316 if (ret != 0) {
1317 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1318 goto err_enable;
1319 }
1320
1321 ret = snd_soc_register_codec(codec);
1322 if (ret != 0) {
1323 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1324 goto error_codec;
1325 }
1326
1327 ret = snd_soc_register_dai(&dac33_dai);
1328 if (ret != 0) {
1329 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1330 snd_soc_unregister_codec(codec);
1331 goto error_codec;
1332 }
1333
1334 /* Shut down the codec for now */
1335 dac33_hard_power(codec, 0);
1336
1337 return ret;
1338
1339error_codec:
1340 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1341err_enable:
1342 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1343err_get:
1344 if (dac33->irq >= 0) {
1345 free_irq(dac33->irq, &dac33->codec);
1346 destroy_workqueue(dac33->dac33_wq);
1347 }
1348error_wq:
1349 if (dac33->power_gpio >= 0)
1350 gpio_free(dac33->power_gpio);
1351error_gpio:
1352 kfree(codec->reg_cache);
1353error_reg:
1354 tlv320dac33_codec = NULL;
1355 kfree(dac33);
1356
1357 return ret;
1358}
1359
1360static int __devexit dac33_i2c_remove(struct i2c_client *client)
1361{
1362 struct tlv320dac33_priv *dac33;
1363
1364 dac33 = i2c_get_clientdata(client);
1365 dac33_hard_power(&dac33->codec, 0);
1366
1367 if (dac33->power_gpio >= 0)
1368 gpio_free(dac33->power_gpio);
1369 if (dac33->irq >= 0)
1370 free_irq(dac33->irq, &dac33->codec);
1371
1372 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1373
1374 destroy_workqueue(dac33->dac33_wq);
1375 snd_soc_unregister_dai(&dac33_dai);
1376 snd_soc_unregister_codec(&dac33->codec);
1377 kfree(dac33->codec.reg_cache);
1378 kfree(dac33);
1379 tlv320dac33_codec = NULL;
1380
1381 return 0;
1382}
1383
1384static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1385 {
1386 .name = "tlv320dac33",
1387 .driver_data = 0,
1388 },
1389 { },
1390};
1391
1392static struct i2c_driver tlv320dac33_i2c_driver = {
1393 .driver = {
1394 .name = "tlv320dac33",
1395 .owner = THIS_MODULE,
1396 },
1397 .probe = dac33_i2c_probe,
1398 .remove = __devexit_p(dac33_i2c_remove),
1399 .id_table = tlv320dac33_i2c_id,
1400};
1401
1402static int __init dac33_module_init(void)
1403{
1404 int r;
1405 r = i2c_add_driver(&tlv320dac33_i2c_driver);
1406 if (r < 0) {
1407 printk(KERN_ERR "DAC33: driver registration failed\n");
1408 return r;
1409 }
1410 return 0;
1411}
1412module_init(dac33_module_init);
1413
1414static void __exit dac33_module_exit(void)
1415{
1416 i2c_del_driver(&tlv320dac33_i2c_driver);
1417}
1418module_exit(dac33_module_exit);
1419
1420
1421MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1422MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
1423MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
new file mode 100644
index 000000000000..eb8ae07f0bd2
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -0,0 +1,267 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
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 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TLV320DAC33_H
25#define __TLV320DAC33_H
26
27#define DAC33_PAGE_SELECT 0x00
28#define DAC33_PWR_CTRL 0x01
29#define DAC33_PLL_CTRL_A 0x02
30#define DAC33_PLL_CTRL_B 0x03
31#define DAC33_PLL_CTRL_C 0x04
32#define DAC33_PLL_CTRL_D 0x05
33#define DAC33_PLL_CTRL_E 0x06
34#define DAC33_INT_OSC_CTRL 0x07
35#define DAC33_INT_OSC_FREQ_RAT_A 0x08
36#define DAC33_INT_OSC_FREQ_RAT_B 0x09
37#define DAC33_INT_OSC_DAC_RATIO_SET 0x0A
38#define DAC33_CALIB_TIME 0x0B
39#define DAC33_INT_OSC_CTRL_B 0x0C
40#define DAC33_INT_OSC_CTRL_C 0x0D
41#define DAC33_INT_OSC_STATUS 0x0E
42#define DAC33_INT_OSC_DAC_RATIO_READ 0x0F
43#define DAC33_INT_OSC_FREQ_RAT_READ_A 0x10
44#define DAC33_INT_OSC_FREQ_RAT_READ_B 0x11
45#define DAC33_SER_AUDIOIF_CTRL_A 0x12
46#define DAC33_SER_AUDIOIF_CTRL_B 0x13
47#define DAC33_SER_AUDIOIF_CTRL_C 0x14
48#define DAC33_FIFO_CTRL_A 0x15
49#define DAC33_UTHR_MSB 0x16
50#define DAC33_UTHR_LSB 0x17
51#define DAC33_ATHR_MSB 0x18
52#define DAC33_ATHR_LSB 0x19
53#define DAC33_LTHR_MSB 0x1A
54#define DAC33_LTHR_LSB 0x1B
55#define DAC33_PREFILL_MSB 0x1C
56#define DAC33_PREFILL_LSB 0x1D
57#define DAC33_NSAMPLE_MSB 0x1E
58#define DAC33_NSAMPLE_LSB 0x1F
59#define DAC33_FIFO_WPTR_MSB 0x20
60#define DAC33_FIFO_WPTR_LSB 0x21
61#define DAC33_FIFO_RPTR_MSB 0x22
62#define DAC33_FIFO_RPTR_LSB 0x23
63#define DAC33_FIFO_DEPTH_MSB 0x24
64#define DAC33_FIFO_DEPTH_LSB 0x25
65#define DAC33_SAMPLES_REMAINING_MSB 0x26
66#define DAC33_SAMPLES_REMAINING_LSB 0x27
67#define DAC33_FIFO_IRQ_FLAG 0x28
68#define DAC33_FIFO_IRQ_MASK 0x29
69#define DAC33_FIFO_IRQ_MODE_A 0x2A
70#define DAC33_FIFO_IRQ_MODE_B 0x2B
71#define DAC33_DAC_CTRL_A 0x2C
72#define DAC33_DAC_CTRL_B 0x2D
73#define DAC33_DAC_CTRL_C 0x2E
74#define DAC33_LDAC_DIG_VOL_CTRL 0x2F
75#define DAC33_RDAC_DIG_VOL_CTRL 0x30
76#define DAC33_DAC_STATUS_FLAGS 0x31
77#define DAC33_ASRC_CTRL_A 0x32
78#define DAC33_ASRC_CTRL_B 0x33
79#define DAC33_SRC_REF_CLK_RATIO_A 0x34
80#define DAC33_SRC_REF_CLK_RATIO_B 0x35
81#define DAC33_SRC_EST_REF_CLK_RATIO_A 0x36
82#define DAC33_SRC_EST_REF_CLK_RATIO_B 0x37
83#define DAC33_INTP_CTRL_A 0x38
84#define DAC33_INTP_CTRL_B 0x39
85/* Registers 0x3A - 0x3F Reserved */
86#define DAC33_LDAC_PWR_CTRL 0x40
87#define DAC33_RDAC_PWR_CTRL 0x41
88#define DAC33_OUT_AMP_CM_CTRL 0x42
89#define DAC33_OUT_AMP_PWR_CTRL 0x43
90#define DAC33_OUT_AMP_CTRL 0x44
91#define DAC33_LINEL_TO_LLO_VOL 0x45
92/* Registers 0x45 - 0x47 Reserved */
93#define DAC33_LINER_TO_RLO_VOL 0x48
94#define DAC33_ANA_VOL_SOFT_STEP_CTRL 0x49
95#define DAC33_OSC_TRIM 0x4A
96/* Registers 0x4B - 0x7C Reserved */
97#define DAC33_DEVICE_ID_MSB 0x7D
98#define DAC33_DEVICE_ID_LSB 0x7E
99#define DAC33_DEVICE_REV_ID 0x7F
100
101#define DAC33_CACHEREGNUM 128
102
103/* Bit definitions */
104
105/* DAC33_PWR_CTRL (0x01) */
106#define DAC33_DACRPDNB (0x01 << 0)
107#define DAC33_DACLPDNB (0x01 << 1)
108#define DAC33_OSCPDNB (0x01 << 2)
109#define DAC33_PLLPDNB (0x01 << 3)
110#define DAC33_PDNALLB (0x01 << 4)
111#define DAC33_SOFT_RESET (0x01 << 7)
112
113/* DAC33_INT_OSC_CTRL (0x07) */
114#define DAC33_REFSEL (0x01 << 1)
115
116/* DAC33_INT_OSC_CTRL_B (0x0C) */
117#define DAC33_ADJSTEP(x) (x << 0)
118#define DAC33_ADJTHRSHLD(x) (x << 4)
119
120/* DAC33_INT_OSC_CTRL_C (0x0D) */
121#define DAC33_REFDIV(x) (x << 4)
122
123/* DAC33_INT_OSC_STATUS (0x0E) */
124#define DAC33_OSCSTATUS_IDLE_CALIB (0x00)
125#define DAC33_OSCSTATUS_NORMAL (0x01)
126#define DAC33_OSCSTATUS_ADJUSTMENT (0x03)
127#define DAC33_OSCSTATUS_NOT_USED (0x02)
128
129/* DAC33_SER_AUDIOIF_CTRL_A (0x12) */
130#define DAC33_MSWCLK (0x01 << 0)
131#define DAC33_MSBCLK (0x01 << 1)
132#define DAC33_AFMT_MASK (0x03 << 2)
133#define DAC33_AFMT_I2S (0x00 << 2)
134#define DAC33_AFMT_DSP (0x01 << 2)
135#define DAC33_AFMT_RIGHT_J (0x02 << 2)
136#define DAC33_AFMT_LEFT_J (0x03 << 2)
137#define DAC33_WLEN_MASK (0x03 << 4)
138#define DAC33_WLEN_16 (0x00 << 4)
139#define DAC33_WLEN_20 (0x01 << 4)
140#define DAC33_WLEN_24 (0x02 << 4)
141#define DAC33_WLEN_32 (0x03 << 4)
142#define DAC33_NCYCL_MASK (0x03 << 6)
143#define DAC33_NCYCL_16 (0x00 << 6)
144#define DAC33_NCYCL_20 (0x01 << 6)
145#define DAC33_NCYCL_24 (0x02 << 6)
146#define DAC33_NCYCL_32 (0x03 << 6)
147
148/* DAC33_SER_AUDIOIF_CTRL_B (0x13) */
149#define DAC33_DATA_DELAY_MASK (0x03 << 2)
150#define DAC33_DATA_DELAY(x) (x << 2)
151#define DAC33_BCLKON (0x01 << 5)
152
153/* DAC33_FIFO_CTRL_A (0x15) */
154#define DAC33_WIDTH (0x01 << 0)
155#define DAC33_FBYPAS (0x01 << 1)
156#define DAC33_FAUTO (0x01 << 2)
157#define DAC33_FIFOFLUSH (0x01 << 3)
158
159/*
160 * UTHR, ATHR, LTHR, PREFILL, NSAMPLE (0x16 - 0x1F)
161 * 13-bit values
162*/
163#define DAC33_THRREG(x) (((x) & 0x1FFF) << 3)
164
165/* DAC33_FIFO_IRQ_MASK (0x29) */
166#define DAC33_MNS (0x01 << 0)
167#define DAC33_MPS (0x01 << 1)
168#define DAC33_MAT (0x01 << 2)
169#define DAC33_MLT (0x01 << 3)
170#define DAC33_MUT (0x01 << 4)
171#define DAC33_MUF (0x01 << 5)
172#define DAC33_MOF (0x01 << 6)
173
174#define DAC33_FIFO_IRQ_MODE_MASK (0x03)
175#define DAC33_FIFO_IRQ_MODE_RISING (0x00)
176#define DAC33_FIFO_IRQ_MODE_FALLING (0x01)
177#define DAC33_FIFO_IRQ_MODE_LEVEL (0x02)
178#define DAC33_FIFO_IRQ_MODE_EDGE (0x03)
179
180/* DAC33_FIFO_IRQ_MODE_A (0x2A) */
181#define DAC33_UTM(x) (x << 0)
182#define DAC33_UFM(x) (x << 2)
183#define DAC33_OFM(x) (x << 4)
184
185/* DAC33_FIFO_IRQ_MODE_B (0x2B) */
186#define DAC33_NSM(x) (x << 0)
187#define DAC33_PSM(x) (x << 2)
188#define DAC33_ATM(x) (x << 4)
189#define DAC33_LTM(x) (x << 6)
190
191/* DAC33_DAC_CTRL_A (0x2C) */
192#define DAC33_DACRATE(x) (x << 0)
193#define DAC33_DACDUAL (0x01 << 4)
194#define DAC33_DACLKSEL_MASK (0x03 << 5)
195#define DAC33_DACLKSEL_INTSOC (0x00 << 5)
196#define DAC33_DACLKSEL_PLL (0x01 << 5)
197#define DAC33_DACLKSEL_MCLK (0x02 << 5)
198#define DAC33_DACLKSEL_BCLK (0x03 << 5)
199
200/* DAC33_DAC_CTRL_B (0x2D) */
201#define DAC33_DACSRCR_MASK (0x03 << 0)
202#define DAC33_DACSRCR_MUTE (0x00 << 0)
203#define DAC33_DACSRCR_RIGHT (0x01 << 0)
204#define DAC33_DACSRCR_LEFT (0x02 << 0)
205#define DAC33_DACSRCR_MONOMIX (0x03 << 0)
206#define DAC33_DACSRCL_MASK (0x03 << 2)
207#define DAC33_DACSRCL_MUTE (0x00 << 2)
208#define DAC33_DACSRCL_LEFT (0x01 << 2)
209#define DAC33_DACSRCL_RIGHT (0x02 << 2)
210#define DAC33_DACSRCL_MONOMIX (0x03 << 2)
211#define DAC33_DVOLSTEP_MASK (0x03 << 4)
212#define DAC33_DVOLSTEP_SS_PERFS (0x00 << 4)
213#define DAC33_DVOLSTEP_SS_PER2FS (0x01 << 4)
214#define DAC33_DVOLSTEP_SS_DISABLED (0x02 << 4)
215#define DAC33_DVOLCTRL_MASK (0x03 << 6)
216#define DAC33_DVOLCTRL_LR_INDEPENDENT1 (0x00 << 6)
217#define DAC33_DVOLCTRL_LR_RIGHT_CONTROL (0x01 << 6)
218#define DAC33_DVOLCTRL_LR_LEFT_CONTROL (0x02 << 6)
219#define DAC33_DVOLCTRL_LR_INDEPENDENT2 (0x03 << 6)
220
221/* DAC33_DAC_CTRL_C (0x2E) */
222#define DAC33_DEEMENR (0x01 << 0)
223#define DAC33_EFFENR (0x01 << 1)
224#define DAC33_DEEMENL (0x01 << 2)
225#define DAC33_EFFENL (0x01 << 3)
226#define DAC33_EN3D (0x01 << 4)
227#define DAC33_RESYNMUTE (0x01 << 5)
228#define DAC33_RESYNEN (0x01 << 6)
229
230/* DAC33_ASRC_CTRL_A (0x32) */
231#define DAC33_SRCBYP (0x01 << 0)
232#define DAC33_SRCLKSEL_MASK (0x03 << 1)
233#define DAC33_SRCLKSEL_INTSOC (0x00 << 1)
234#define DAC33_SRCLKSEL_PLL (0x01 << 1)
235#define DAC33_SRCLKSEL_MCLK (0x02 << 1)
236#define DAC33_SRCLKSEL_BCLK (0x03 << 1)
237#define DAC33_SRCLKDIV(x) (x << 3)
238
239/* DAC33_ASRC_CTRL_B (0x33) */
240#define DAC33_SRCSETUP(x) (x << 0)
241#define DAC33_SRCREFSEL (0x01 << 4)
242#define DAC33_SRCREFDIV(x) (x << 5)
243
244/* DAC33_INTP_CTRL_A (0x38) */
245#define DAC33_INTPSEL (0x01 << 0)
246#define DAC33_INTPM_MASK (0x03 << 1)
247#define DAC33_INTPM_ALOW_OPENDRAIN (0x00 << 1)
248#define DAC33_INTPM_ALOW (0x01 << 1)
249#define DAC33_INTPM_AHIGH (0x02 << 1)
250
251/* DAC33_LDAC_PWR_CTRL (0x40) */
252/* DAC33_RDAC_PWR_CTRL (0x41) */
253#define DAC33_DACLRNUM (0x01 << 2)
254#define DAC33_LROUT_GAIN(x) (x << 0)
255
256/* DAC33_ANA_VOL_SOFT_STEP_CTRL (0x49) */
257#define DAC33_VOLCLKSEL (0x01 << 0)
258#define DAC33_VOLCLKEN (0x01 << 1)
259#define DAC33_VOLBYPASS (0x01 << 2)
260
261#define TLV320DAC33_MCLK 0
262#define TLV320DAC33_SLEEPCLK 1
263
264extern struct snd_soc_dai dac33_dai;
265extern struct snd_soc_codec_device soc_codec_dev_tlv320dac33;
266
267#endif /* __TLV320DAC33_H */
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
new file mode 100644
index 000000000000..569ad8758a84
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -0,0 +1,531 @@
1/*
2 * ALSA SoC Texas Instruments TPA6130A2 headset stereo amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/device.h>
26#include <linux/i2c.h>
27#include <linux/gpio.h>
28#include <linux/regulator/consumer.h>
29#include <linux/slab.h>
30#include <sound/tpa6130a2-plat.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h>
34
35#include "tpa6130a2.h"
36
37static struct i2c_client *tpa6130a2_client;
38
39#define TPA6130A2_NUM_SUPPLIES 2
40static const char *tpa6130a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
41 "CPVSS",
42 "Vdd",
43};
44
45static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
46 "HPVdd",
47 "AVdd",
48};
49
50/* This struct is used to save the context */
51struct tpa6130a2_data {
52 struct mutex mutex;
53 unsigned char regs[TPA6130A2_CACHEREGNUM];
54 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES];
55 int power_gpio;
56 unsigned char power_state;
57};
58
59static int tpa6130a2_i2c_read(int reg)
60{
61 struct tpa6130a2_data *data;
62 int val;
63
64 BUG_ON(tpa6130a2_client == NULL);
65 data = i2c_get_clientdata(tpa6130a2_client);
66
67 /* If powered off, return the cached value */
68 if (data->power_state) {
69 val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
70 if (val < 0)
71 dev_err(&tpa6130a2_client->dev, "Read failed\n");
72 else
73 data->regs[reg] = val;
74 } else {
75 val = data->regs[reg];
76 }
77
78 return val;
79}
80
81static int tpa6130a2_i2c_write(int reg, u8 value)
82{
83 struct tpa6130a2_data *data;
84 int val = 0;
85
86 BUG_ON(tpa6130a2_client == NULL);
87 data = i2c_get_clientdata(tpa6130a2_client);
88
89 if (data->power_state) {
90 val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
91 if (val < 0)
92 dev_err(&tpa6130a2_client->dev, "Write failed\n");
93 }
94
95 /* Either powered on or off, we save the context */
96 data->regs[reg] = value;
97
98 return val;
99}
100
101static u8 tpa6130a2_read(int reg)
102{
103 struct tpa6130a2_data *data;
104
105 BUG_ON(tpa6130a2_client == NULL);
106 data = i2c_get_clientdata(tpa6130a2_client);
107
108 return data->regs[reg];
109}
110
111static void tpa6130a2_initialize(void)
112{
113 struct tpa6130a2_data *data;
114 int i;
115
116 BUG_ON(tpa6130a2_client == NULL);
117 data = i2c_get_clientdata(tpa6130a2_client);
118
119 for (i = 1; i < TPA6130A2_REG_VERSION; i++)
120 tpa6130a2_i2c_write(i, data->regs[i]);
121}
122
123static int tpa6130a2_power(int power)
124{
125 struct tpa6130a2_data *data;
126 u8 val;
127 int ret;
128
129 BUG_ON(tpa6130a2_client == NULL);
130 data = i2c_get_clientdata(tpa6130a2_client);
131
132 mutex_lock(&data->mutex);
133 if (power) {
134 /* Power on */
135 if (data->power_gpio >= 0)
136 gpio_set_value(data->power_gpio, 1);
137
138 ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies),
139 data->supplies);
140 if (ret != 0) {
141 dev_err(&tpa6130a2_client->dev,
142 "Failed to enable supplies: %d\n", ret);
143 goto exit;
144 }
145
146 data->power_state = 1;
147 tpa6130a2_initialize();
148
149 /* Clear SWS */
150 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
151 val &= ~TPA6130A2_SWS;
152 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
153 } else {
154 /* set SWS */
155 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
156 val |= TPA6130A2_SWS;
157 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
158
159 /* Power off */
160 if (data->power_gpio >= 0)
161 gpio_set_value(data->power_gpio, 0);
162
163 ret = regulator_bulk_disable(ARRAY_SIZE(data->supplies),
164 data->supplies);
165 if (ret != 0) {
166 dev_err(&tpa6130a2_client->dev,
167 "Failed to disable supplies: %d\n", ret);
168 goto exit;
169 }
170
171 data->power_state = 0;
172 }
173
174exit:
175 mutex_unlock(&data->mutex);
176 return ret;
177}
178
179static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
181{
182 struct soc_mixer_control *mc =
183 (struct soc_mixer_control *)kcontrol->private_value;
184 struct tpa6130a2_data *data;
185 unsigned int reg = mc->reg;
186 unsigned int shift = mc->shift;
187 unsigned int mask = mc->max;
188 unsigned int invert = mc->invert;
189
190 BUG_ON(tpa6130a2_client == NULL);
191 data = i2c_get_clientdata(tpa6130a2_client);
192
193 mutex_lock(&data->mutex);
194
195 ucontrol->value.integer.value[0] =
196 (tpa6130a2_read(reg) >> shift) & mask;
197
198 if (invert)
199 ucontrol->value.integer.value[0] =
200 mask - ucontrol->value.integer.value[0];
201
202 mutex_unlock(&data->mutex);
203 return 0;
204}
205
206static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol)
208{
209 struct soc_mixer_control *mc =
210 (struct soc_mixer_control *)kcontrol->private_value;
211 struct tpa6130a2_data *data;
212 unsigned int reg = mc->reg;
213 unsigned int shift = mc->shift;
214 unsigned int mask = mc->max;
215 unsigned int invert = mc->invert;
216 unsigned int val = (ucontrol->value.integer.value[0] & mask);
217 unsigned int val_reg;
218
219 BUG_ON(tpa6130a2_client == NULL);
220 data = i2c_get_clientdata(tpa6130a2_client);
221
222 if (invert)
223 val = mask - val;
224
225 mutex_lock(&data->mutex);
226
227 val_reg = tpa6130a2_read(reg);
228 if (((val_reg >> shift) & mask) == val) {
229 mutex_unlock(&data->mutex);
230 return 0;
231 }
232
233 val_reg &= ~(mask << shift);
234 val_reg |= val << shift;
235 tpa6130a2_i2c_write(reg, val_reg);
236
237 mutex_unlock(&data->mutex);
238
239 return 1;
240}
241
242/*
243 * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
244 * down in gain.
245 */
246static const unsigned int tpa6130_tlv[] = {
247 TLV_DB_RANGE_HEAD(10),
248 0, 1, TLV_DB_SCALE_ITEM(-5950, 600, 0),
249 2, 3, TLV_DB_SCALE_ITEM(-5000, 250, 0),
250 4, 5, TLV_DB_SCALE_ITEM(-4550, 160, 0),
251 6, 7, TLV_DB_SCALE_ITEM(-4140, 190, 0),
252 8, 9, TLV_DB_SCALE_ITEM(-3650, 120, 0),
253 10, 11, TLV_DB_SCALE_ITEM(-3330, 160, 0),
254 12, 13, TLV_DB_SCALE_ITEM(-3040, 180, 0),
255 14, 20, TLV_DB_SCALE_ITEM(-2710, 110, 0),
256 21, 37, TLV_DB_SCALE_ITEM(-1960, 74, 0),
257 38, 63, TLV_DB_SCALE_ITEM(-720, 45, 0),
258};
259
260static const struct snd_kcontrol_new tpa6130a2_controls[] = {
261 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
262 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
263 tpa6130a2_get_reg, tpa6130a2_set_reg,
264 tpa6130_tlv),
265};
266
267/*
268 * Enable or disable channel (left or right)
269 * The bit number for mute and amplifier are the same per channel:
270 * bit 6: Right channel
271 * bit 7: Left channel
272 * in both registers.
273 */
274static void tpa6130a2_channel_enable(u8 channel, int enable)
275{
276 u8 val;
277
278 if (enable) {
279 /* Enable channel */
280 /* Enable amplifier */
281 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
282 val |= channel;
283 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
284
285 /* Unmute channel */
286 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
287 val &= ~channel;
288 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
289 } else {
290 /* Disable channel */
291 /* Mute channel */
292 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
293 val |= channel;
294 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
295
296 /* Disable amplifier */
297 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
298 val &= ~channel;
299 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
300 }
301}
302
303static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w,
304 struct snd_kcontrol *kcontrol, int event)
305{
306 switch (event) {
307 case SND_SOC_DAPM_POST_PMU:
308 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1);
309 break;
310 case SND_SOC_DAPM_POST_PMD:
311 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0);
312 break;
313 }
314 return 0;
315}
316
317static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
318 struct snd_kcontrol *kcontrol, int event)
319{
320 switch (event) {
321 case SND_SOC_DAPM_POST_PMU:
322 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1);
323 break;
324 case SND_SOC_DAPM_POST_PMD:
325 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0);
326 break;
327 }
328 return 0;
329}
330
331static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
332 struct snd_kcontrol *kcontrol, int event)
333{
334 int ret = 0;
335
336 switch (event) {
337 case SND_SOC_DAPM_POST_PMU:
338 ret = tpa6130a2_power(1);
339 break;
340 case SND_SOC_DAPM_POST_PMD:
341 ret = tpa6130a2_power(0);
342 break;
343 }
344 return ret;
345}
346
347static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
348 SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM,
349 0, 0, NULL, 0, tpa6130a2_left_event,
350 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
351 SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM,
352 0, 0, NULL, 0, tpa6130a2_right_event,
353 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
354 SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM,
355 0, 0, tpa6130a2_supply_event,
356 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
357 /* Outputs */
358 SND_SOC_DAPM_HP("TPA6130A2 Headphone Left", NULL),
359 SND_SOC_DAPM_HP("TPA6130A2 Headphone Right", NULL),
360};
361
362static const struct snd_soc_dapm_route audio_map[] = {
363 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"},
364 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"},
365
366 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"},
367 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"},
368};
369
370int tpa6130a2_add_controls(struct snd_soc_codec *codec)
371{
372 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
373 ARRAY_SIZE(tpa6130a2_dapm_widgets));
374
375 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
376
377 return snd_soc_add_controls(codec, tpa6130a2_controls,
378 ARRAY_SIZE(tpa6130a2_controls));
379
380}
381EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
382
383static int __devinit tpa6130a2_probe(struct i2c_client *client,
384 const struct i2c_device_id *id)
385{
386 struct device *dev;
387 struct tpa6130a2_data *data;
388 struct tpa6130a2_platform_data *pdata;
389 int i, ret;
390
391 dev = &client->dev;
392
393 if (client->dev.platform_data == NULL) {
394 dev_err(dev, "Platform data not set\n");
395 dump_stack();
396 return -ENODEV;
397 }
398
399 data = kzalloc(sizeof(*data), GFP_KERNEL);
400 if (data == NULL) {
401 dev_err(dev, "Can not allocate memory\n");
402 return -ENOMEM;
403 }
404
405 tpa6130a2_client = client;
406
407 i2c_set_clientdata(tpa6130a2_client, data);
408
409 pdata = client->dev.platform_data;
410 data->power_gpio = pdata->power_gpio;
411
412 mutex_init(&data->mutex);
413
414 /* Set default register values */
415 data->regs[TPA6130A2_REG_CONTROL] = TPA6130A2_SWS;
416 data->regs[TPA6130A2_REG_VOL_MUTE] = TPA6130A2_MUTE_R |
417 TPA6130A2_MUTE_L;
418
419 if (data->power_gpio >= 0) {
420 ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
421 if (ret < 0) {
422 dev_err(dev, "Failed to request power GPIO (%d)\n",
423 data->power_gpio);
424 goto err_gpio;
425 }
426 gpio_direction_output(data->power_gpio, 0);
427 }
428
429 switch (pdata->id) {
430 case TPA6130A2:
431 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
432 data->supplies[i].supply = tpa6130a2_supply_names[i];
433 break;
434 case TPA6140A2:
435 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
436 data->supplies[i].supply = tpa6140a2_supply_names[i];;
437 break;
438 default:
439 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
440 pdata->id);
441 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
442 data->supplies[i].supply = tpa6130a2_supply_names[i];
443 }
444
445 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
446 data->supplies);
447 if (ret != 0) {
448 dev_err(dev, "Failed to request supplies: %d\n", ret);
449 goto err_regulator;
450 }
451
452 ret = tpa6130a2_power(1);
453 if (ret != 0)
454 goto err_power;
455
456
457 /* Read version */
458 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
459 TPA6130A2_VERSION_MASK;
460 if ((ret != 1) && (ret != 2))
461 dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
462
463 /* Disable the chip */
464 ret = tpa6130a2_power(0);
465 if (ret != 0)
466 goto err_power;
467
468 return 0;
469
470err_power:
471 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
472err_regulator:
473 if (data->power_gpio >= 0)
474 gpio_free(data->power_gpio);
475err_gpio:
476 kfree(data);
477 i2c_set_clientdata(tpa6130a2_client, NULL);
478 tpa6130a2_client = NULL;
479
480 return ret;
481}
482
483static int __devexit tpa6130a2_remove(struct i2c_client *client)
484{
485 struct tpa6130a2_data *data = i2c_get_clientdata(client);
486
487 tpa6130a2_power(0);
488
489 if (data->power_gpio >= 0)
490 gpio_free(data->power_gpio);
491
492 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
493
494 kfree(data);
495 tpa6130a2_client = NULL;
496
497 return 0;
498}
499
500static const struct i2c_device_id tpa6130a2_id[] = {
501 { "tpa6130a2", 0 },
502 { }
503};
504MODULE_DEVICE_TABLE(i2c, tpa6130a2_id);
505
506static struct i2c_driver tpa6130a2_i2c_driver = {
507 .driver = {
508 .name = "tpa6130a2",
509 .owner = THIS_MODULE,
510 },
511 .probe = tpa6130a2_probe,
512 .remove = __devexit_p(tpa6130a2_remove),
513 .id_table = tpa6130a2_id,
514};
515
516static int __init tpa6130a2_init(void)
517{
518 return i2c_add_driver(&tpa6130a2_i2c_driver);
519}
520
521static void __exit tpa6130a2_exit(void)
522{
523 i2c_del_driver(&tpa6130a2_i2c_driver);
524}
525
526MODULE_AUTHOR("Peter Ujfalusi");
527MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
528MODULE_LICENSE("GPL");
529
530module_init(tpa6130a2_init);
531module_exit(tpa6130a2_exit);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
new file mode 100644
index 000000000000..57e867fd86d1
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -0,0 +1,61 @@
1/*
2 * ALSA SoC TPA6130A2 amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TPA6130A2_H__
25#define __TPA6130A2_H__
26
27/* Register addresses */
28#define TPA6130A2_REG_CONTROL 0x01
29#define TPA6130A2_REG_VOL_MUTE 0x02
30#define TPA6130A2_REG_OUT_IMPEDANCE 0x03
31#define TPA6130A2_REG_VERSION 0x04
32
33#define TPA6130A2_CACHEREGNUM (TPA6130A2_REG_VERSION + 1)
34
35/* Register bits */
36/* TPA6130A2_REG_CONTROL (0x01) */
37#define TPA6130A2_SWS (0x01 << 0)
38#define TPA6130A2_TERMAL (0x01 << 1)
39#define TPA6130A2_MODE(x) (x << 4)
40#define TPA6130A2_MODE_STEREO (0x00)
41#define TPA6130A2_MODE_DUAL_MONO (0x01)
42#define TPA6130A2_MODE_BRIDGE (0x02)
43#define TPA6130A2_MODE_MASK (0x03)
44#define TPA6130A2_HP_EN_R (0x01 << 6)
45#define TPA6130A2_HP_EN_L (0x01 << 7)
46
47/* TPA6130A2_REG_VOL_MUTE (0x02) */
48#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
49#define TPA6130A2_MUTE_R (0x01 << 6)
50#define TPA6130A2_MUTE_L (0x01 << 7)
51
52/* TPA6130A2_REG_OUT_IMPEDANCE (0x03) */
53#define TPA6130A2_HIZ_R (0x01 << 0)
54#define TPA6130A2_HIZ_L (0x01 << 1)
55
56/* TPA6130A2_REG_VERSION (0x04) */
57#define TPA6130A2_VERSION_MASK (0x0f)
58
59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
60
61#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 4df7c6c61c76..520ffd6536c3 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -26,7 +26,8 @@
26#include <linux/pm.h> 26#include <linux/pm.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/i2c/twl4030.h> 29#include <linux/i2c/twl.h>
30#include <linux/slab.h>
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
32#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
@@ -55,7 +56,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
55 0x0c, /* REG_ATXR1PGA (0xB) */ 56 0x0c, /* REG_ATXR1PGA (0xB) */
56 0x00, /* REG_AVTXL2PGA (0xC) */ 57 0x00, /* REG_AVTXL2PGA (0xC) */
57 0x00, /* REG_AVTXR2PGA (0xD) */ 58 0x00, /* REG_AVTXR2PGA (0xD) */
58 0x01, /* REG_AUDIO_IF (0xE) */ 59 0x00, /* REG_AUDIO_IF (0xE) */
59 0x00, /* REG_VOICE_IF (0xF) */ 60 0x00, /* REG_VOICE_IF (0xF) */
60 0x00, /* REG_ARXR1PGA (0x10) */ 61 0x00, /* REG_ARXR1PGA (0x10) */
61 0x00, /* REG_ARXL1PGA (0x11) */ 62 0x00, /* REG_ARXL1PGA (0x11) */
@@ -64,19 +65,19 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
64 0x00, /* REG_VRXPGA (0x14) */ 65 0x00, /* REG_VRXPGA (0x14) */
65 0x00, /* REG_VSTPGA (0x15) */ 66 0x00, /* REG_VSTPGA (0x15) */
66 0x00, /* REG_VRX2ARXPGA (0x16) */ 67 0x00, /* REG_VRX2ARXPGA (0x16) */
67 0x0c, /* REG_AVDAC_CTL (0x17) */ 68 0x00, /* REG_AVDAC_CTL (0x17) */
68 0x00, /* REG_ARX2VTXPGA (0x18) */ 69 0x00, /* REG_ARX2VTXPGA (0x18) */
69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ 70 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ 71 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
71 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */ 72 0x4a, /* REG_ARXL2_APGA_CTL (0x1B) */
72 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */ 73 0x4a, /* REG_ARXR2_APGA_CTL (0x1C) */
73 0x00, /* REG_ATX2ARXPGA (0x1D) */ 74 0x00, /* REG_ATX2ARXPGA (0x1D) */
74 0x00, /* REG_BT_IF (0x1E) */ 75 0x00, /* REG_BT_IF (0x1E) */
75 0x00, /* REG_BTPGA (0x1F) */ 76 0x00, /* REG_BTPGA (0x1F) */
76 0x00, /* REG_BTSTPGA (0x20) */ 77 0x00, /* REG_BTSTPGA (0x20) */
77 0x00, /* REG_EAR_CTL (0x21) */ 78 0x00, /* REG_EAR_CTL (0x21) */
78 0x24, /* REG_HS_SEL (0x22) */ 79 0x00, /* REG_HS_SEL (0x22) */
79 0x0a, /* REG_HS_GAIN_SET (0x23) */ 80 0x00, /* REG_HS_GAIN_SET (0x23) */
80 0x00, /* REG_HS_POPN_SET (0x24) */ 81 0x00, /* REG_HS_POPN_SET (0x24) */
81 0x00, /* REG_PREDL_CTL (0x25) */ 82 0x00, /* REG_PREDL_CTL (0x25) */
82 0x00, /* REG_PREDR_CTL (0x26) */ 83 0x00, /* REG_PREDR_CTL (0x26) */
@@ -99,7 +100,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ 100 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ 101 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ 102 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
102 0x16, /* REG_APLL_CTL (0x3A) */ 103 0x06, /* REG_APLL_CTL (0x3A) */
103 0x00, /* REG_DTMF_CTL (0x3B) */ 104 0x00, /* REG_DTMF_CTL (0x3B) */
104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ 105 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ 106 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
@@ -120,9 +121,10 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
120 121
121/* codec private data */ 122/* codec private data */
122struct twl4030_priv { 123struct twl4030_priv {
123 unsigned int bypass_state; 124 struct snd_soc_codec codec;
125
124 unsigned int codec_powered; 126 unsigned int codec_powered;
125 unsigned int codec_muted; 127 unsigned int apll_enabled;
126 128
127 struct snd_pcm_substream *master_substream; 129 struct snd_pcm_substream *master_substream;
128 struct snd_pcm_substream *slave_substream; 130 struct snd_pcm_substream *slave_substream;
@@ -174,7 +176,7 @@ static int twl4030_write(struct snd_soc_codec *codec,
174{ 176{
175 twl4030_write_reg_cache(codec, reg, value); 177 twl4030_write_reg_cache(codec, reg, value);
176 if (likely(reg < TWL4030_REG_SW_SHADOW)) 178 if (likely(reg < TWL4030_REG_SW_SHADOW))
177 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, 179 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value,
178 reg); 180 reg);
179 else 181 else
180 return 0; 182 return 0;
@@ -183,19 +185,20 @@ static int twl4030_write(struct snd_soc_codec *codec,
183static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 185static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
184{ 186{
185 struct twl4030_priv *twl4030 = codec->private_data; 187 struct twl4030_priv *twl4030 = codec->private_data;
186 u8 mode; 188 int mode;
187 189
188 if (enable == twl4030->codec_powered) 190 if (enable == twl4030->codec_powered)
189 return; 191 return;
190 192
191 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
192 if (enable) 193 if (enable)
193 mode |= TWL4030_CODECPDZ; 194 mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
194 else 195 else
195 mode &= ~TWL4030_CODECPDZ; 196 mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
196 197
197 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); 198 if (mode >= 0) {
198 twl4030->codec_powered = enable; 199 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
200 twl4030->codec_powered = enable;
201 }
199 202
200 /* REVISIT: this delay is present in TI sample drivers */ 203 /* REVISIT: this delay is present in TI sample drivers */
201 /* but there seems to be no TRM requirement for it */ 204 /* but there seems to be no TRM requirement for it */
@@ -212,31 +215,30 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
212 215
213 /* set all audio section registers to reasonable defaults */ 216 /* set all audio section registers to reasonable defaults */
214 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) 217 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
215 twl4030_write(codec, i, cache[i]); 218 if (i != TWL4030_REG_APLL_CTL)
219 twl4030_write(codec, i, cache[i]);
216 220
217} 221}
218 222
219static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) 223static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
220{ 224{
221 struct twl4030_priv *twl4030 = codec->private_data; 225 struct twl4030_priv *twl4030 = codec->private_data;
222 u8 reg_val; 226 int status;
223 227
224 if (mute == twl4030->codec_muted) 228 if (enable == twl4030->apll_enabled)
225 return; 229 return;
226 230
227 if (mute) { 231 if (enable)
228 /* Disable PLL */
229 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
230 reg_val &= ~TWL4030_APLL_EN;
231 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
232 } else {
233 /* Enable PLL */ 232 /* Enable PLL */
234 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 233 status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
235 reg_val |= TWL4030_APLL_EN; 234 else
236 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); 235 /* Disable PLL */
237 } 236 status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
237
238 if (status >= 0)
239 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
238 240
239 twl4030->codec_muted = mute; 241 twl4030->apll_enabled = enable;
240} 242}
241 243
242static void twl4030_power_up(struct snd_soc_codec *codec) 244static void twl4030_power_up(struct snd_soc_codec *codec)
@@ -260,7 +262,7 @@ static void twl4030_power_up(struct snd_soc_codec *codec)
260 do { 262 do {
261 /* this takes a little while, so don't slam i2c */ 263 /* this takes a little while, so don't slam i2c */
262 udelay(2000); 264 udelay(2000);
263 twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, 265 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
264 TWL4030_REG_ANAMICL); 266 TWL4030_REG_ANAMICL);
265 } while ((i++ < 100) && 267 } while ((i++ < 100) &&
266 ((byte & TWL4030_CNCL_OFFSET_START) == 268 ((byte & TWL4030_CNCL_OFFSET_START) ==
@@ -541,7 +543,7 @@ static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
541 break; \ 543 break; \
542 case SND_SOC_DAPM_POST_PMD: \ 544 case SND_SOC_DAPM_POST_PMD: \
543 reg_val = twl4030_read_reg_cache(w->codec, reg); \ 545 reg_val = twl4030_read_reg_cache(w->codec, reg); \
544 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ 546 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
545 reg_val & (~mask), \ 547 reg_val & (~mask), \
546 reg); \ 548 reg); \
547 break; \ 549 break; \
@@ -613,6 +615,27 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
613 return 0; 615 return 0;
614} 616}
615 617
618static int vibramux_event(struct snd_soc_dapm_widget *w,
619 struct snd_kcontrol *kcontrol, int event)
620{
621 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
622 return 0;
623}
624
625static int apll_event(struct snd_soc_dapm_widget *w,
626 struct snd_kcontrol *kcontrol, int event)
627{
628 switch (event) {
629 case SND_SOC_DAPM_PRE_PMU:
630 twl4030_apll_enable(w->codec, 1);
631 break;
632 case SND_SOC_DAPM_POST_PMD:
633 twl4030_apll_enable(w->codec, 0);
634 break;
635 }
636 return 0;
637}
638
616static void headset_ramp(struct snd_soc_codec *codec, int ramp) 639static void headset_ramp(struct snd_soc_codec *codec, int ramp)
617{ 640{
618 struct snd_soc_device *socdev = codec->socdev; 641 struct snd_soc_device *socdev = codec->socdev;
@@ -657,7 +680,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
657 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 680 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
658 twl4030->sysclk) + 1); 681 twl4030->sysclk) + 1);
659 /* Bypass the reg_cache to mute the headset */ 682 /* Bypass the reg_cache to mute the headset */
660 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 683 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
661 hs_gain & (~0x0f), 684 hs_gain & (~0x0f),
662 TWL4030_REG_HS_GAIN_SET); 685 TWL4030_REG_HS_GAIN_SET);
663 686
@@ -724,67 +747,6 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
724 return 0; 747 return 0;
725} 748}
726 749
727static int bypass_event(struct snd_soc_dapm_widget *w,
728 struct snd_kcontrol *kcontrol, int event)
729{
730 struct soc_mixer_control *m =
731 (struct soc_mixer_control *)w->kcontrols->private_value;
732 struct twl4030_priv *twl4030 = w->codec->private_data;
733 unsigned char reg, misc;
734
735 reg = twl4030_read_reg_cache(w->codec, m->reg);
736
737 /*
738 * bypass_state[0:3] - analog HiFi bypass
739 * bypass_state[4] - analog voice bypass
740 * bypass_state[5] - digital voice bypass
741 * bypass_state[6:7] - digital HiFi bypass
742 */
743 if (m->reg == TWL4030_REG_VSTPGA) {
744 /* Voice digital bypass */
745 if (reg)
746 twl4030->bypass_state |= (1 << 5);
747 else
748 twl4030->bypass_state &= ~(1 << 5);
749 } else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
750 /* Analog bypass */
751 if (reg & (1 << m->shift))
752 twl4030->bypass_state |=
753 (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
754 else
755 twl4030->bypass_state &=
756 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
757 } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
758 /* Analog voice bypass */
759 if (reg & (1 << m->shift))
760 twl4030->bypass_state |= (1 << 4);
761 else
762 twl4030->bypass_state &= ~(1 << 4);
763 } else {
764 /* Digital bypass */
765 if (reg & (0x7 << m->shift))
766 twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
767 else
768 twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
769 }
770
771 /* Enable master analog loopback mode if any analog switch is enabled*/
772 misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
773 if (twl4030->bypass_state & 0x1F)
774 misc |= TWL4030_FMLOOP_EN;
775 else
776 misc &= ~TWL4030_FMLOOP_EN;
777 twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
778
779 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
780 if (twl4030->bypass_state)
781 twl4030_codec_mute(w->codec, 0);
782 else
783 twl4030_codec_mute(w->codec, 1);
784 }
785 return 0;
786}
787
788/* 750/*
789 * Some of the gain controls in TWL (mostly those which are associated with 751 * Some of the gain controls in TWL (mostly those which are associated with
790 * the outputs) are implemented in an interesting way: 752 * the outputs) are implemented in an interesting way:
@@ -1192,32 +1154,28 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1192 SND_SOC_NOPM, 0, 0), 1154 SND_SOC_NOPM, 0, 0),
1193 1155
1194 /* Analog bypasses */ 1156 /* Analog bypasses */
1195 SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1157 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1196 &twl4030_dapm_abypassr1_control, bypass_event, 1158 &twl4030_dapm_abypassr1_control),
1197 SND_SOC_DAPM_POST_REG), 1159 SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1198 SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1160 &twl4030_dapm_abypassl1_control),
1199 &twl4030_dapm_abypassl1_control, 1161 SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1200 bypass_event, SND_SOC_DAPM_POST_REG), 1162 &twl4030_dapm_abypassr2_control),
1201 SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1163 SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1202 &twl4030_dapm_abypassr2_control, 1164 &twl4030_dapm_abypassl2_control),
1203 bypass_event, SND_SOC_DAPM_POST_REG), 1165 SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1204 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1166 &twl4030_dapm_abypassv_control),
1205 &twl4030_dapm_abypassl2_control, 1167
1206 bypass_event, SND_SOC_DAPM_POST_REG), 1168 /* Master analog loopback switch */
1207 SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0, 1169 SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
1208 &twl4030_dapm_abypassv_control, 1170 NULL, 0),
1209 bypass_event, SND_SOC_DAPM_POST_REG),
1210 1171
1211 /* Digital bypasses */ 1172 /* Digital bypasses */
1212 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, 1173 SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
1213 &twl4030_dapm_dbypassl_control, bypass_event, 1174 &twl4030_dapm_dbypassl_control),
1214 SND_SOC_DAPM_POST_REG), 1175 SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
1215 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, 1176 &twl4030_dapm_dbypassr_control),
1216 &twl4030_dapm_dbypassr_control, bypass_event, 1177 SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1217 SND_SOC_DAPM_POST_REG), 1178 &twl4030_dapm_dbypassv_control),
1218 SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1219 &twl4030_dapm_dbypassv_control, bypass_event,
1220 SND_SOC_DAPM_POST_REG),
1221 1179
1222 /* Digital mixers, power control for the physical DACs */ 1180 /* Digital mixers, power control for the physical DACs */
1223 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer", 1181 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
@@ -1243,6 +1201,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1243 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", 1201 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
1244 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0), 1202 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
1245 1203
1204 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1205 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1206
1207 SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0),
1208
1246 /* Output MIXER controls */ 1209 /* Output MIXER controls */
1247 /* Earpiece */ 1210 /* Earpiece */
1248 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1211 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
@@ -1308,8 +1271,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1308 0, 0, NULL, 0, handsfreerpga_event, 1271 0, 0, NULL, 0, handsfreerpga_event,
1309 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1272 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1310 /* Vibra */ 1273 /* Vibra */
1311 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, 1274 SND_SOC_DAPM_MUX_E("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1312 &twl4030_dapm_vibra_control), 1275 &twl4030_dapm_vibra_control, vibramux_event,
1276 SND_SOC_DAPM_PRE_PMU),
1313 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0, 1277 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
1314 &twl4030_dapm_vibrapath_control), 1278 &twl4030_dapm_vibrapath_control),
1315 1279
@@ -1369,6 +1333,18 @@ static const struct snd_soc_dapm_route intercon[] = {
1369 {"Digital R2 Playback Mixer", NULL, "DAC Right2"}, 1333 {"Digital R2 Playback Mixer", NULL, "DAC Right2"},
1370 {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, 1334 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1371 1335
1336 /* Supply for the digital part (APLL) */
1337 {"Digital R1 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital L1 Playback Mixer", NULL, "APLL Enable"},
1339 {"Digital R2 Playback Mixer", NULL, "APLL Enable"},
1340 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1341 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1342
1343 {"Digital R1 Playback Mixer", NULL, "AIF Enable"},
1344 {"Digital L1 Playback Mixer", NULL, "AIF Enable"},
1345 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1346 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1347
1372 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, 1348 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1373 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, 1349 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1374 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, 1350 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
@@ -1482,6 +1458,16 @@ static const struct snd_soc_dapm_route intercon[] = {
1482 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1458 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1483 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1459 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1484 1460
1461 {"ADC Virtual Left1", NULL, "APLL Enable"},
1462 {"ADC Virtual Right1", NULL, "APLL Enable"},
1463 {"ADC Virtual Left2", NULL, "APLL Enable"},
1464 {"ADC Virtual Right2", NULL, "APLL Enable"},
1465
1466 {"ADC Virtual Left1", NULL, "AIF Enable"},
1467 {"ADC Virtual Right1", NULL, "AIF Enable"},
1468 {"ADC Virtual Left2", NULL, "AIF Enable"},
1469 {"ADC Virtual Right2", NULL, "AIF Enable"},
1470
1485 /* Analog bypass routes */ 1471 /* Analog bypass routes */
1486 {"Right1 Analog Loopback", "Switch", "Analog Right"}, 1472 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1487 {"Left1 Analog Loopback", "Switch", "Analog Left"}, 1473 {"Left1 Analog Loopback", "Switch", "Analog Left"},
@@ -1489,6 +1475,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1489 {"Left2 Analog Loopback", "Switch", "Analog Left"}, 1475 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1490 {"Voice Analog Loopback", "Switch", "Analog Left"}, 1476 {"Voice Analog Loopback", "Switch", "Analog Left"},
1491 1477
1478 /* Supply for the Analog loopbacks */
1479 {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
1480 {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
1481 {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
1482 {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
1483 {"Voice Analog Loopback", NULL, "FM Loop Enable"},
1484
1492 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1485 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1493 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1486 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1494 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, 1487 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
@@ -1513,32 +1506,20 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec)
1513 1506
1514 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 1507 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
1515 1508
1516 snd_soc_dapm_new_widgets(codec);
1517 return 0; 1509 return 0;
1518} 1510}
1519 1511
1520static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1512static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1521 enum snd_soc_bias_level level) 1513 enum snd_soc_bias_level level)
1522{ 1514{
1523 struct twl4030_priv *twl4030 = codec->private_data;
1524
1525 switch (level) { 1515 switch (level) {
1526 case SND_SOC_BIAS_ON: 1516 case SND_SOC_BIAS_ON:
1527 twl4030_codec_mute(codec, 0);
1528 break; 1517 break;
1529 case SND_SOC_BIAS_PREPARE: 1518 case SND_SOC_BIAS_PREPARE:
1530 twl4030_power_up(codec);
1531 if (twl4030->bypass_state)
1532 twl4030_codec_mute(codec, 0);
1533 else
1534 twl4030_codec_mute(codec, 1);
1535 break; 1519 break;
1536 case SND_SOC_BIAS_STANDBY: 1520 case SND_SOC_BIAS_STANDBY:
1537 twl4030_power_up(codec); 1521 if (codec->bias_level == SND_SOC_BIAS_OFF)
1538 if (twl4030->bypass_state) 1522 twl4030_power_up(codec);
1539 twl4030_codec_mute(codec, 0);
1540 else
1541 twl4030_codec_mute(codec, 1);
1542 break; 1523 break;
1543 case SND_SOC_BIAS_OFF: 1524 case SND_SOC_BIAS_OFF:
1544 twl4030_power_down(codec); 1525 twl4030_power_down(codec);
@@ -1785,29 +1766,23 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1785{ 1766{
1786 struct snd_soc_codec *codec = codec_dai->codec; 1767 struct snd_soc_codec *codec = codec_dai->codec;
1787 struct twl4030_priv *twl4030 = codec->private_data; 1768 struct twl4030_priv *twl4030 = codec->private_data;
1788 u8 infreq;
1789 1769
1790 switch (freq) { 1770 switch (freq) {
1791 case 19200000: 1771 case 19200000:
1792 infreq = TWL4030_APLL_INFREQ_19200KHZ;
1793 twl4030->sysclk = 19200;
1794 break;
1795 case 26000000: 1772 case 26000000:
1796 infreq = TWL4030_APLL_INFREQ_26000KHZ;
1797 twl4030->sysclk = 26000;
1798 break;
1799 case 38400000: 1773 case 38400000:
1800 infreq = TWL4030_APLL_INFREQ_38400KHZ;
1801 twl4030->sysclk = 38400;
1802 break; 1774 break;
1803 default: 1775 default:
1804 printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n", 1776 dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq);
1805 freq);
1806 return -EINVAL; 1777 return -EINVAL;
1807 } 1778 }
1808 1779
1809 infreq |= TWL4030_APLL_EN; 1780 if ((freq / 1000) != twl4030->sysclk) {
1810 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq); 1781 dev_err(codec->dev,
1782 "Mismatch in APLL mclk: %u (configured: %u)\n",
1783 freq, twl4030->sysclk * 1000);
1784 return -EINVAL;
1785 }
1811 1786
1812 return 0; 1787 return 0;
1813} 1788}
@@ -1905,18 +1880,16 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1905 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1880 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1906 struct snd_soc_device *socdev = rtd->socdev; 1881 struct snd_soc_device *socdev = rtd->socdev;
1907 struct snd_soc_codec *codec = socdev->card->codec; 1882 struct snd_soc_codec *codec = socdev->card->codec;
1908 u8 infreq; 1883 struct twl4030_priv *twl4030 = codec->private_data;
1909 u8 mode; 1884 u8 mode;
1910 1885
1911 /* If the system master clock is not 26MHz, the voice PCM interface is 1886 /* If the system master clock is not 26MHz, the voice PCM interface is
1912 * not avilable. 1887 * not avilable.
1913 */ 1888 */
1914 infreq = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL) 1889 if (twl4030->sysclk != 26000) {
1915 & TWL4030_APLL_INFREQ; 1890 dev_err(codec->dev, "The board is configured for %u Hz, while"
1916 1891 "the Voice interface needs 26MHz APLL mclk\n",
1917 if (infreq != TWL4030_APLL_INFREQ_26000KHZ) { 1892 twl4030->sysclk * 1000);
1918 printk(KERN_ERR "TWL4030 voice startup: "
1919 "MCLK is not 26MHz, call set_sysclk() on init\n");
1920 return -EINVAL; 1893 return -EINVAL;
1921 } 1894 }
1922 1895
@@ -1989,21 +1962,19 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1989 int clk_id, unsigned int freq, int dir) 1962 int clk_id, unsigned int freq, int dir)
1990{ 1963{
1991 struct snd_soc_codec *codec = codec_dai->codec; 1964 struct snd_soc_codec *codec = codec_dai->codec;
1992 u8 infreq; 1965 struct twl4030_priv *twl4030 = codec->private_data;
1993 1966
1994 switch (freq) { 1967 if (freq != 26000000) {
1995 case 26000000: 1968 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
1996 infreq = TWL4030_APLL_INFREQ_26000KHZ; 1969 "interface needs 26MHz APLL mclk\n", freq);
1997 break; 1970 return -EINVAL;
1998 default: 1971 }
1999 printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n", 1972 if ((freq / 1000) != twl4030->sysclk) {
2000 freq); 1973 dev_err(codec->dev,
1974 "Mismatch in APLL mclk: %u (configured: %u)\n",
1975 freq, twl4030->sysclk * 1000);
2001 return -EINVAL; 1976 return -EINVAL;
2002 } 1977 }
2003
2004 infreq |= TWL4030_APLL_EN;
2005 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
2006
2007 return 0; 1978 return 0;
2008} 1979}
2009 1980
@@ -2121,7 +2092,7 @@ struct snd_soc_dai twl4030_dai[] = {
2121}; 2092};
2122EXPORT_SYMBOL_GPL(twl4030_dai); 2093EXPORT_SYMBOL_GPL(twl4030_dai);
2123 2094
2124static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) 2095static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state)
2125{ 2096{
2126 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2097 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2127 struct snd_soc_codec *codec = socdev->card->codec; 2098 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2131,7 +2102,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
2131 return 0; 2102 return 0;
2132} 2103}
2133 2104
2134static int twl4030_resume(struct platform_device *pdev) 2105static int twl4030_soc_resume(struct platform_device *pdev)
2135{ 2106{
2136 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2107 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2137 struct snd_soc_codec *codec = socdev->card->codec; 2108 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2141,147 +2112,182 @@ static int twl4030_resume(struct platform_device *pdev)
2141 return 0; 2112 return 0;
2142} 2113}
2143 2114
2144/* 2115static struct snd_soc_codec *twl4030_codec;
2145 * initialize the driver
2146 * register the mixer and dsp interfaces with the kernel
2147 */
2148 2116
2149static int twl4030_init(struct snd_soc_device *socdev) 2117static int twl4030_soc_probe(struct platform_device *pdev)
2150{ 2118{
2151 struct snd_soc_codec *codec = socdev->card->codec; 2119 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2152 struct twl4030_setup_data *setup = socdev->codec_data; 2120 struct twl4030_setup_data *setup = socdev->codec_data;
2153 struct twl4030_priv *twl4030 = codec->private_data; 2121 struct snd_soc_codec *codec;
2154 int ret = 0; 2122 struct twl4030_priv *twl4030;
2123 int ret;
2155 2124
2156 printk(KERN_INFO "TWL4030 Audio Codec init \n"); 2125 BUG_ON(!twl4030_codec);
2157 2126
2158 codec->name = "twl4030"; 2127 codec = twl4030_codec;
2159 codec->owner = THIS_MODULE; 2128 twl4030 = codec->private_data;
2160 codec->read = twl4030_read_reg_cache; 2129 socdev->card->codec = codec;
2161 codec->write = twl4030_write;
2162 codec->set_bias_level = twl4030_set_bias_level;
2163 codec->dai = twl4030_dai;
2164 codec->num_dai = ARRAY_SIZE(twl4030_dai),
2165 codec->reg_cache_size = sizeof(twl4030_reg);
2166 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2167 GFP_KERNEL);
2168 if (codec->reg_cache == NULL)
2169 return -ENOMEM;
2170 2130
2171 /* Configuration for headset ramp delay from setup data */ 2131 /* Configuration for headset ramp delay from setup data */
2172 if (setup) { 2132 if (setup) {
2173 unsigned char hs_pop; 2133 unsigned char hs_pop;
2174 2134
2175 if (setup->sysclk) 2135 if (setup->sysclk != twl4030->sysclk)
2176 twl4030->sysclk = setup->sysclk; 2136 dev_warn(&pdev->dev,
2177 else 2137 "Mismatch in APLL mclk: %u (configured: %u)\n",
2178 twl4030->sysclk = 26000; 2138 setup->sysclk, twl4030->sysclk);
2179 2139
2180 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 2140 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
2181 hs_pop &= ~TWL4030_RAMP_DELAY; 2141 hs_pop &= ~TWL4030_RAMP_DELAY;
2182 hs_pop |= (setup->ramp_delay_value << 2); 2142 hs_pop |= (setup->ramp_delay_value << 2);
2183 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 2143 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
2184 } else {
2185 twl4030->sysclk = 26000;
2186 } 2144 }
2187 2145
2188 /* register pcms */ 2146 /* register pcms */
2189 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2147 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2190 if (ret < 0) { 2148 if (ret < 0) {
2191 printk(KERN_ERR "twl4030: failed to create pcms\n"); 2149 dev_err(&pdev->dev, "failed to create pcms\n");
2192 goto pcm_err; 2150 return ret;
2193 } 2151 }
2194 2152
2195 twl4030_init_chip(codec);
2196
2197 /* power on device */
2198 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2199
2200 snd_soc_add_controls(codec, twl4030_snd_controls, 2153 snd_soc_add_controls(codec, twl4030_snd_controls,
2201 ARRAY_SIZE(twl4030_snd_controls)); 2154 ARRAY_SIZE(twl4030_snd_controls));
2202 twl4030_add_widgets(codec); 2155 twl4030_add_widgets(codec);
2203 2156
2204 ret = snd_soc_init_card(socdev); 2157 return 0;
2205 if (ret < 0) { 2158}
2206 printk(KERN_ERR "twl4030: failed to register card\n");
2207 goto card_err;
2208 }
2209 2159
2210 return ret; 2160static int twl4030_soc_remove(struct platform_device *pdev)
2161{
2162 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2163 struct snd_soc_codec *codec = socdev->card->codec;
2211 2164
2212card_err: 2165 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2213 snd_soc_free_pcms(socdev); 2166 snd_soc_free_pcms(socdev);
2214 snd_soc_dapm_free(socdev); 2167 snd_soc_dapm_free(socdev);
2215pcm_err:
2216 kfree(codec->reg_cache);
2217 return ret;
2218}
2219 2168
2220static struct snd_soc_device *twl4030_socdev; 2169 return 0;
2170}
2221 2171
2222static int twl4030_probe(struct platform_device *pdev) 2172static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2223{ 2173{
2224 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2174 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
2225 struct snd_soc_codec *codec; 2175 struct snd_soc_codec *codec;
2226 struct twl4030_priv *twl4030; 2176 struct twl4030_priv *twl4030;
2177 int ret;
2227 2178
2228 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 2179 if (!pdata) {
2229 if (codec == NULL) 2180 dev_err(&pdev->dev, "platform_data is missing\n");
2230 return -ENOMEM; 2181 return -EINVAL;
2182 }
2231 2183
2232 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2184 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2233 if (twl4030 == NULL) { 2185 if (twl4030 == NULL) {
2234 kfree(codec); 2186 dev_err(&pdev->dev, "Can not allocate memroy\n");
2235 return -ENOMEM; 2187 return -ENOMEM;
2236 } 2188 }
2237 2189
2190 codec = &twl4030->codec;
2238 codec->private_data = twl4030; 2191 codec->private_data = twl4030;
2239 socdev->card->codec = codec; 2192 codec->dev = &pdev->dev;
2193 twl4030_dai[0].dev = &pdev->dev;
2194 twl4030_dai[1].dev = &pdev->dev;
2195
2240 mutex_init(&codec->mutex); 2196 mutex_init(&codec->mutex);
2241 INIT_LIST_HEAD(&codec->dapm_widgets); 2197 INIT_LIST_HEAD(&codec->dapm_widgets);
2242 INIT_LIST_HEAD(&codec->dapm_paths); 2198 INIT_LIST_HEAD(&codec->dapm_paths);
2243 2199
2244 twl4030_socdev = socdev; 2200 codec->name = "twl4030";
2245 twl4030_init(socdev); 2201 codec->owner = THIS_MODULE;
2202 codec->read = twl4030_read_reg_cache;
2203 codec->write = twl4030_write;
2204 codec->set_bias_level = twl4030_set_bias_level;
2205 codec->dai = twl4030_dai;
2206 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2207 codec->reg_cache_size = sizeof(twl4030_reg);
2208 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2209 GFP_KERNEL);
2210 if (codec->reg_cache == NULL) {
2211 ret = -ENOMEM;
2212 goto error_cache;
2213 }
2214
2215 platform_set_drvdata(pdev, twl4030);
2216 twl4030_codec = codec;
2217
2218 /* Set the defaults, and power up the codec */
2219 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2220 twl4030_init_chip(codec);
2221 codec->bias_level = SND_SOC_BIAS_OFF;
2222 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2223
2224 ret = snd_soc_register_codec(codec);
2225 if (ret != 0) {
2226 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2227 goto error_codec;
2228 }
2229
2230 ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2231 if (ret != 0) {
2232 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
2233 snd_soc_unregister_codec(codec);
2234 goto error_codec;
2235 }
2246 2236
2247 return 0; 2237 return 0;
2238
2239error_codec:
2240 twl4030_power_down(codec);
2241 kfree(codec->reg_cache);
2242error_cache:
2243 kfree(twl4030);
2244 return ret;
2248} 2245}
2249 2246
2250static int twl4030_remove(struct platform_device *pdev) 2247static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2251{ 2248{
2252 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2249 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
2253 struct snd_soc_codec *codec = socdev->card->codec;
2254 2250
2255 printk(KERN_INFO "TWL4030 Audio Codec remove\n"); 2251 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2256 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2252 snd_soc_unregister_codec(&twl4030->codec);
2257 snd_soc_free_pcms(socdev); 2253 kfree(twl4030->codec.reg_cache);
2258 snd_soc_dapm_free(socdev); 2254 kfree(twl4030);
2259 kfree(codec->private_data);
2260 kfree(codec);
2261 2255
2256 twl4030_codec = NULL;
2262 return 0; 2257 return 0;
2263} 2258}
2264 2259
2265struct snd_soc_codec_device soc_codec_dev_twl4030 = { 2260MODULE_ALIAS("platform:twl4030_codec_audio");
2266 .probe = twl4030_probe, 2261
2267 .remove = twl4030_remove, 2262static struct platform_driver twl4030_codec_driver = {
2268 .suspend = twl4030_suspend, 2263 .probe = twl4030_codec_probe,
2269 .resume = twl4030_resume, 2264 .remove = __devexit_p(twl4030_codec_remove),
2265 .driver = {
2266 .name = "twl4030_codec_audio",
2267 .owner = THIS_MODULE,
2268 },
2270}; 2269};
2271EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2272 2270
2273static int __init twl4030_modinit(void) 2271static int __init twl4030_modinit(void)
2274{ 2272{
2275 return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2273 return platform_driver_register(&twl4030_codec_driver);
2276} 2274}
2277module_init(twl4030_modinit); 2275module_init(twl4030_modinit);
2278 2276
2279static void __exit twl4030_exit(void) 2277static void __exit twl4030_exit(void)
2280{ 2278{
2281 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2279 platform_driver_unregister(&twl4030_codec_driver);
2282} 2280}
2283module_exit(twl4030_exit); 2281module_exit(twl4030_exit);
2284 2282
2283struct snd_soc_codec_device soc_codec_dev_twl4030 = {
2284 .probe = twl4030_soc_probe,
2285 .remove = twl4030_soc_remove,
2286 .suspend = twl4030_soc_suspend,
2287 .resume = twl4030_soc_resume,
2288};
2289EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2290
2285MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); 2291MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2286MODULE_AUTHOR("Steve Sakoman"); 2292MODULE_AUTHOR("Steve Sakoman");
2287MODULE_LICENSE("GPL"); 2293MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 2b4bfa23f985..f206d242ca31 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -22,245 +22,13 @@
22#ifndef __TWL4030_AUDIO_H__ 22#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__ 23#define __TWL4030_AUDIO_H__
24 24
25#define TWL4030_REG_CODEC_MODE 0x1 25/* Register descriptions are here */
26#define TWL4030_REG_OPTION 0x2 26#include <linux/mfd/twl4030-codec.h>
27#define TWL4030_REG_UNKNOWN 0x3
28#define TWL4030_REG_MICBIAS_CTL 0x4
29#define TWL4030_REG_ANAMICL 0x5
30#define TWL4030_REG_ANAMICR 0x6
31#define TWL4030_REG_AVADC_CTL 0x7
32#define TWL4030_REG_ADCMICSEL 0x8
33#define TWL4030_REG_DIGMIXING 0x9
34#define TWL4030_REG_ATXL1PGA 0xA
35#define TWL4030_REG_ATXR1PGA 0xB
36#define TWL4030_REG_AVTXL2PGA 0xC
37#define TWL4030_REG_AVTXR2PGA 0xD
38#define TWL4030_REG_AUDIO_IF 0xE
39#define TWL4030_REG_VOICE_IF 0xF
40#define TWL4030_REG_ARXR1PGA 0x10
41#define TWL4030_REG_ARXL1PGA 0x11
42#define TWL4030_REG_ARXR2PGA 0x12
43#define TWL4030_REG_ARXL2PGA 0x13
44#define TWL4030_REG_VRXPGA 0x14
45#define TWL4030_REG_VSTPGA 0x15
46#define TWL4030_REG_VRX2ARXPGA 0x16
47#define TWL4030_REG_AVDAC_CTL 0x17
48#define TWL4030_REG_ARX2VTXPGA 0x18
49#define TWL4030_REG_ARXL1_APGA_CTL 0x19
50#define TWL4030_REG_ARXR1_APGA_CTL 0x1A
51#define TWL4030_REG_ARXL2_APGA_CTL 0x1B
52#define TWL4030_REG_ARXR2_APGA_CTL 0x1C
53#define TWL4030_REG_ATX2ARXPGA 0x1D
54#define TWL4030_REG_BT_IF 0x1E
55#define TWL4030_REG_BTPGA 0x1F
56#define TWL4030_REG_BTSTPGA 0x20
57#define TWL4030_REG_EAR_CTL 0x21
58#define TWL4030_REG_HS_SEL 0x22
59#define TWL4030_REG_HS_GAIN_SET 0x23
60#define TWL4030_REG_HS_POPN_SET 0x24
61#define TWL4030_REG_PREDL_CTL 0x25
62#define TWL4030_REG_PREDR_CTL 0x26
63#define TWL4030_REG_PRECKL_CTL 0x27
64#define TWL4030_REG_PRECKR_CTL 0x28
65#define TWL4030_REG_HFL_CTL 0x29
66#define TWL4030_REG_HFR_CTL 0x2A
67#define TWL4030_REG_ALC_CTL 0x2B
68#define TWL4030_REG_ALC_SET1 0x2C
69#define TWL4030_REG_ALC_SET2 0x2D
70#define TWL4030_REG_BOOST_CTL 0x2E
71#define TWL4030_REG_SOFTVOL_CTL 0x2F
72#define TWL4030_REG_DTMF_FREQSEL 0x30
73#define TWL4030_REG_DTMF_TONEXT1H 0x31
74#define TWL4030_REG_DTMF_TONEXT1L 0x32
75#define TWL4030_REG_DTMF_TONEXT2H 0x33
76#define TWL4030_REG_DTMF_TONEXT2L 0x34
77#define TWL4030_REG_DTMF_TONOFF 0x35
78#define TWL4030_REG_DTMF_WANONOFF 0x36
79#define TWL4030_REG_I2S_RX_SCRAMBLE_H 0x37
80#define TWL4030_REG_I2S_RX_SCRAMBLE_M 0x38
81#define TWL4030_REG_I2S_RX_SCRAMBLE_L 0x39
82#define TWL4030_REG_APLL_CTL 0x3A
83#define TWL4030_REG_DTMF_CTL 0x3B
84#define TWL4030_REG_DTMF_PGA_CTL2 0x3C
85#define TWL4030_REG_DTMF_PGA_CTL1 0x3D
86#define TWL4030_REG_MISC_SET_1 0x3E
87#define TWL4030_REG_PCMBTMUX 0x3F
88#define TWL4030_REG_RX_PATH_SEL 0x43
89#define TWL4030_REG_VDL_APGA_CTL 0x44
90#define TWL4030_REG_VIBRA_CTL 0x45
91#define TWL4030_REG_VIBRA_SET 0x46
92#define TWL4030_REG_VIBRA_PWM_SET 0x47
93#define TWL4030_REG_ANAMIC_GAIN 0x48
94#define TWL4030_REG_MISC_SET_2 0x49
95#define TWL4030_REG_SW_SHADOW 0x4A
96 27
28/* Shadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A
97#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
98 31
99/* Bitfield Definitions */
100
101/* TWL4030_CODEC_MODE (0x01) Fields */
102
103#define TWL4030_APLL_RATE 0xF0
104#define TWL4030_APLL_RATE_8000 0x00
105#define TWL4030_APLL_RATE_11025 0x10
106#define TWL4030_APLL_RATE_12000 0x20
107#define TWL4030_APLL_RATE_16000 0x40
108#define TWL4030_APLL_RATE_22050 0x50
109#define TWL4030_APLL_RATE_24000 0x60
110#define TWL4030_APLL_RATE_32000 0x80
111#define TWL4030_APLL_RATE_44100 0x90
112#define TWL4030_APLL_RATE_48000 0xA0
113#define TWL4030_APLL_RATE_96000 0xE0
114#define TWL4030_SEL_16K 0x08
115#define TWL4030_CODECPDZ 0x02
116#define TWL4030_OPT_MODE 0x01
117#define TWL4030_OPTION_1 (1 << 0)
118#define TWL4030_OPTION_2 (0 << 0)
119
120/* TWL4030_OPTION (0x02) Fields */
121
122#define TWL4030_ATXL1_EN (1 << 0)
123#define TWL4030_ATXR1_EN (1 << 1)
124#define TWL4030_ATXL2_VTXL_EN (1 << 2)
125#define TWL4030_ATXR2_VTXR_EN (1 << 3)
126#define TWL4030_ARXL1_VRX_EN (1 << 4)
127#define TWL4030_ARXR1_EN (1 << 5)
128#define TWL4030_ARXL2_EN (1 << 6)
129#define TWL4030_ARXR2_EN (1 << 7)
130
131/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
132
133#define TWL4030_MICBIAS2_CTL 0x40
134#define TWL4030_MICBIAS1_CTL 0x20
135#define TWL4030_HSMICBIAS_EN 0x04
136#define TWL4030_MICBIAS2_EN 0x02
137#define TWL4030_MICBIAS1_EN 0x01
138
139/* ANAMICL (0x05) Fields */
140
141#define TWL4030_CNCL_OFFSET_START 0x80
142#define TWL4030_OFFSET_CNCL_SEL 0x60
143#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
144#define TWL4030_OFFSET_CNCL_SEL_ARX2 0x20
145#define TWL4030_OFFSET_CNCL_SEL_VRX 0x40
146#define TWL4030_OFFSET_CNCL_SEL_ALL 0x60
147#define TWL4030_MICAMPL_EN 0x10
148#define TWL4030_CKMIC_EN 0x08
149#define TWL4030_AUXL_EN 0x04
150#define TWL4030_HSMIC_EN 0x02
151#define TWL4030_MAINMIC_EN 0x01
152
153/* ANAMICR (0x06) Fields */
154
155#define TWL4030_MICAMPR_EN 0x10
156#define TWL4030_AUXR_EN 0x04
157#define TWL4030_SUBMIC_EN 0x01
158
159/* AVADC_CTL (0x07) Fields */
160
161#define TWL4030_ADCL_EN 0x08
162#define TWL4030_AVADC_CLK_PRIORITY 0x04
163#define TWL4030_ADCR_EN 0x02
164
165/* TWL4030_REG_ADCMICSEL (0x08) Fields */
166
167#define TWL4030_DIGMIC1_EN 0x08
168#define TWL4030_TX2IN_SEL 0x04
169#define TWL4030_DIGMIC0_EN 0x02
170#define TWL4030_TX1IN_SEL 0x01
171
172/* AUDIO_IF (0x0E) Fields */
173
174#define TWL4030_AIF_SLAVE_EN 0x80
175#define TWL4030_DATA_WIDTH 0x60
176#define TWL4030_DATA_WIDTH_16S_16W 0x00
177#define TWL4030_DATA_WIDTH_32S_16W 0x40
178#define TWL4030_DATA_WIDTH_32S_24W 0x60
179#define TWL4030_AIF_FORMAT 0x18
180#define TWL4030_AIF_FORMAT_CODEC 0x00
181#define TWL4030_AIF_FORMAT_LEFT 0x08
182#define TWL4030_AIF_FORMAT_RIGHT 0x10
183#define TWL4030_AIF_FORMAT_TDM 0x18
184#define TWL4030_AIF_TRI_EN 0x04
185#define TWL4030_CLK256FS_EN 0x02
186#define TWL4030_AIF_EN 0x01
187
188/* VOICE_IF (0x0F) Fields */
189
190#define TWL4030_VIF_SLAVE_EN 0x80
191#define TWL4030_VIF_DIN_EN 0x40
192#define TWL4030_VIF_DOUT_EN 0x20
193#define TWL4030_VIF_SWAP 0x10
194#define TWL4030_VIF_FORMAT 0x08
195#define TWL4030_VIF_TRI_EN 0x04
196#define TWL4030_VIF_SUB_EN 0x02
197#define TWL4030_VIF_EN 0x01
198
199/* EAR_CTL (0x21) */
200#define TWL4030_EAR_GAIN 0x30
201
202/* HS_GAIN_SET (0x23) Fields */
203
204#define TWL4030_HSR_GAIN 0x0C
205#define TWL4030_HSR_GAIN_PWR_DOWN 0x00
206#define TWL4030_HSR_GAIN_PLUS_6DB 0x04
207#define TWL4030_HSR_GAIN_0DB 0x08
208#define TWL4030_HSR_GAIN_MINUS_6DB 0x0C
209#define TWL4030_HSL_GAIN 0x03
210#define TWL4030_HSL_GAIN_PWR_DOWN 0x00
211#define TWL4030_HSL_GAIN_PLUS_6DB 0x01
212#define TWL4030_HSL_GAIN_0DB 0x02
213#define TWL4030_HSL_GAIN_MINUS_6DB 0x03
214
215/* HS_POPN_SET (0x24) Fields */
216
217#define TWL4030_VMID_EN 0x40
218#define TWL4030_EXTMUTE 0x20
219#define TWL4030_RAMP_DELAY 0x1C
220#define TWL4030_RAMP_DELAY_20MS 0x00
221#define TWL4030_RAMP_DELAY_40MS 0x04
222#define TWL4030_RAMP_DELAY_81MS 0x08
223#define TWL4030_RAMP_DELAY_161MS 0x0C
224#define TWL4030_RAMP_DELAY_323MS 0x10
225#define TWL4030_RAMP_DELAY_645MS 0x14
226#define TWL4030_RAMP_DELAY_1291MS 0x18
227#define TWL4030_RAMP_DELAY_2581MS 0x1C
228#define TWL4030_RAMP_EN 0x02
229
230/* PREDL_CTL (0x25) */
231#define TWL4030_PREDL_GAIN 0x30
232
233/* PREDR_CTL (0x26) */
234#define TWL4030_PREDR_GAIN 0x30
235
236/* PRECKL_CTL (0x27) */
237#define TWL4030_PRECKL_GAIN 0x30
238
239/* PRECKR_CTL (0x28) */
240#define TWL4030_PRECKR_GAIN 0x30
241
242/* HFL_CTL (0x29, 0x2A) Fields */
243#define TWL4030_HF_CTL_HB_EN 0x04
244#define TWL4030_HF_CTL_LOOP_EN 0x08
245#define TWL4030_HF_CTL_RAMP_EN 0x10
246#define TWL4030_HF_CTL_REF_EN 0x20
247
248/* APLL_CTL (0x3A) Fields */
249
250#define TWL4030_APLL_EN 0x10
251#define TWL4030_APLL_INFREQ 0x0F
252#define TWL4030_APLL_INFREQ_19200KHZ 0x05
253#define TWL4030_APLL_INFREQ_26000KHZ 0x06
254#define TWL4030_APLL_INFREQ_38400KHZ 0x0F
255
256/* REG_MISC_SET_1 (0x3E) Fields */
257
258#define TWL4030_CLK64_EN 0x80
259#define TWL4030_SCRAMBLE_EN 0x40
260#define TWL4030_FMLOOP_EN 0x20
261#define TWL4030_SMOOTH_ANAVOL_EN 0x02
262#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
263
264/* TWL4030_REG_SW_SHADOW (0x4A) Fields */ 32/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
265#define TWL4030_HFL_EN 0x01 33#define TWL4030_HFL_EN 0x01
266#define TWL4030_HFR_EN 0x02 34#define TWL4030_HFR_EN 0x02
@@ -279,3 +47,5 @@ struct twl4030_setup_data {
279}; 47};
280 48
281#endif /* End of __TWL4030_AUDIO_H__ */ 49#endif /* End of __TWL4030_AUDIO_H__ */
50
51
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index c33b92edbded..a8dcd5a5bbcb 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -15,6 +15,7 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/slab.h>
18#include <sound/pcm.h> 19#include <sound/pcm.h>
19#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
20#include <sound/soc.h> 21#include <sound/soc.h>
@@ -101,7 +102,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value); 102 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
102 103
103 if (reg >= UDA134X_REGS_NUM) { 104 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %u", 105 printk(KERN_ERR "%s unknown register: reg: %u",
105 __func__, reg); 106 __func__, reg);
106 return -EINVAL; 107 return -EINVAL;
107 } 108 }
@@ -552,7 +553,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
552 ARRAY_SIZE(uda1341_snd_controls)); 553 ARRAY_SIZE(uda1341_snd_controls));
553 break; 554 break;
554 default: 555 default:
555 printk(KERN_ERR "%s unkown codec type: %d", 556 printk(KERN_ERR "%s unknown codec type: %d",
556 __func__, pd->model); 557 __func__, pd->model);
557 return -EINVAL; 558 return -EINVAL;
558 } 559 }
@@ -562,17 +563,8 @@ static int uda134x_soc_probe(struct platform_device *pdev)
562 goto pcm_err; 563 goto pcm_err;
563 } 564 }
564 565
565 ret = snd_soc_init_card(socdev);
566 if (ret < 0) {
567 printk(KERN_ERR "UDA134X: failed to register card\n");
568 goto card_err;
569 }
570
571 return 0; 566 return 0;
572 567
573card_err:
574 snd_soc_free_pcms(socdev);
575 snd_soc_dapm_free(socdev);
576pcm_err: 568pcm_err:
577 kfree(codec->reg_cache); 569 kfree(codec->reg_cache);
578reg_err: 570reg_err:
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 92ec03442154..9cd0a66b7663 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -137,7 +137,7 @@ static void uda1380_flush_work(struct work_struct *work)
137{ 137{
138 int bit, reg; 138 int bit, reg;
139 139
140 for_each_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { 140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
141 reg = 0x10 + bit; 141 reg = 0x10 + bit;
142 pr_debug("uda1380: flush reg %x val %x:\n", reg, 142 pr_debug("uda1380: flush reg %x val %x:\n", reg,
143 uda1380_read_reg_cache(uda1380_codec, reg)); 143 uda1380_read_reg_cache(uda1380_codec, reg));
@@ -378,7 +378,6 @@ static int uda1380_add_widgets(struct snd_soc_codec *codec)
378 378
379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
380 380
381 snd_soc_dapm_new_widgets(codec);
382 return 0; 381 return 0;
383} 382}
384 383
@@ -713,17 +712,9 @@ static int uda1380_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, uda1380_snd_controls, 712 snd_soc_add_controls(codec, uda1380_snd_controls,
714 ARRAY_SIZE(uda1380_snd_controls)); 713 ARRAY_SIZE(uda1380_snd_controls));
715 uda1380_add_widgets(codec); 714 uda1380_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 715
722 return ret; 716 return ret;
723 717
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 718pcm_err:
728 return ret; 719 return ret;
729} 720}
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
new file mode 100644
index 000000000000..002e289d1255
--- /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/kernel.h>
27#include <linux/init.h>
28#include <linux/firmware.h>
29#include <linux/delay.h>
30#include <linux/pm.h>
31#include <linux/i2c.h>
32#include <linux/platform_device.h>
33#include <linux/debugfs.h>
34#include <linux/slab.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/wm8350.c b/sound/soc/codecs/wm8350.c
index 593d5b9c9f03..2e0772f9c456 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/slab.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
@@ -800,7 +801,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
800 return ret; 801 return ret;
801 } 802 }
802 803
803 return snd_soc_dapm_new_widgets(codec); 804 return 0;
804} 805}
805 806
806static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai, 807static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
@@ -925,7 +926,7 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
925 iface |= 0x3 << 8; 926 iface |= 0x3 << 8;
926 break; 927 break;
927 case SND_SOC_DAIFMT_DSP_B: 928 case SND_SOC_DAIFMT_DSP_B:
928 iface |= 0x3 << 8; /* lg not sure which mode */ 929 iface |= 0x3 << 8 | WM8350_AIF_LRCLK_INV;
929 break; 930 break;
930 default: 931 default:
931 return -EINVAL; 932 return -EINVAL;
@@ -1101,7 +1102,7 @@ static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
1101} 1102}
1102 1103
1103static int wm8350_set_fll(struct snd_soc_dai *codec_dai, 1104static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1104 int pll_id, unsigned int freq_in, 1105 int pll_id, int source, unsigned int freq_in,
1105 unsigned int freq_out) 1106 unsigned int freq_out)
1106{ 1107{
1107 struct snd_soc_codec *codec = codec_dai->codec; 1108 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1340,15 +1341,16 @@ static int wm8350_resume(struct platform_device *pdev)
1340 return 0; 1341 return 0;
1341} 1342}
1342 1343
1343static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data) 1344static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1344{ 1345{
1345 struct wm8350_data *priv = data; 1346 struct wm8350_data *priv = data;
1347 struct wm8350 *wm8350 = priv->codec.control_data;
1346 u16 reg; 1348 u16 reg;
1347 int report; 1349 int report;
1348 int mask; 1350 int mask;
1349 struct wm8350_jack_data *jack = NULL; 1351 struct wm8350_jack_data *jack = NULL;
1350 1352
1351 switch (irq) { 1353 switch (irq - wm8350->irq_base) {
1352 case WM8350_IRQ_CODEC_JCK_DET_L: 1354 case WM8350_IRQ_CODEC_JCK_DET_L:
1353 jack = &priv->hpl; 1355 jack = &priv->hpl;
1354 mask = WM8350_JACK_L_LVL; 1356 mask = WM8350_JACK_L_LVL;
@@ -1365,7 +1367,7 @@ static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data)
1365 1367
1366 if (!jack->jack) { 1368 if (!jack->jack) {
1367 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); 1369 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n");
1368 return; 1370 return IRQ_NONE;
1369 } 1371 }
1370 1372
1371 /* Debounce */ 1373 /* Debounce */
@@ -1378,6 +1380,8 @@ static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data)
1378 report = 0; 1380 report = 0;
1379 1381
1380 snd_soc_jack_report(jack->jack, report, jack->report); 1382 snd_soc_jack_report(jack->jack, report, jack->report);
1383
1384 return IRQ_HANDLED;
1381} 1385}
1382 1386
1383/** 1387/**
@@ -1421,9 +1425,7 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1421 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); 1425 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
1422 1426
1423 /* Sync status */ 1427 /* Sync status */
1424 wm8350_hp_jack_handler(wm8350, irq, priv); 1428 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv);
1425
1426 wm8350_unmask_irq(wm8350, irq);
1427 1429
1428 return 0; 1430 return 0;
1429} 1431}
@@ -1482,12 +1484,16 @@ static int wm8350_probe(struct platform_device *pdev)
1482 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, 1484 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
1483 WM8350_OUT2_VU | WM8350_OUT2R_MUTE); 1485 WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
1484 1486
1485 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); 1487 /* Make sure jack detect is disabled to start off with */
1486 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); 1488 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1489 WM8350_JDL_ENA | WM8350_JDR_ENA);
1490
1487 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, 1491 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L,
1488 wm8350_hp_jack_handler, priv); 1492 wm8350_hp_jack_handler, 0, "Left jack detect",
1493 priv);
1489 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, 1494 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
1490 wm8350_hp_jack_handler, priv); 1495 wm8350_hp_jack_handler, 0, "Right jack detect",
1496 priv);
1491 1497
1492 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1498 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1493 if (ret < 0) { 1499 if (ret < 0) {
@@ -1501,18 +1507,7 @@ static int wm8350_probe(struct platform_device *pdev)
1501 1507
1502 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1508 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1503 1509
1504 ret = snd_soc_init_card(socdev);
1505 if (ret < 0) {
1506 dev_err(&pdev->dev, "failed to register card\n");
1507 goto card_err;
1508 }
1509
1510 return 0; 1510 return 0;
1511
1512card_err:
1513 snd_soc_free_pcms(socdev);
1514 snd_soc_dapm_free(socdev);
1515 return ret;
1516} 1511}
1517 1512
1518static int wm8350_remove(struct platform_device *pdev) 1513static int wm8350_remove(struct platform_device *pdev)
@@ -1527,10 +1522,8 @@ static int wm8350_remove(struct platform_device *pdev)
1527 WM8350_JDL_ENA | WM8350_JDR_ENA); 1522 WM8350_JDL_ENA | WM8350_JDR_ENA);
1528 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1523 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1529 1524
1530 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); 1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
1531 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); 1526 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
1532 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
1533 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
1534 1527
1535 priv->hpl.jack = NULL; 1528 priv->hpl.jack = NULL;
1536 priv->hpr.jack = NULL; 1529 priv->hpr.jack = NULL;
@@ -1680,21 +1673,6 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1680 return 0; 1673 return 0;
1681} 1674}
1682 1675
1683#ifdef CONFIG_PM
1684static int wm8350_codec_suspend(struct platform_device *pdev, pm_message_t m)
1685{
1686 return snd_soc_suspend_device(&pdev->dev);
1687}
1688
1689static int wm8350_codec_resume(struct platform_device *pdev)
1690{
1691 return snd_soc_resume_device(&pdev->dev);
1692}
1693#else
1694#define wm8350_codec_suspend NULL
1695#define wm8350_codec_resume NULL
1696#endif
1697
1698static struct platform_driver wm8350_codec_driver = { 1676static struct platform_driver wm8350_codec_driver = {
1699 .driver = { 1677 .driver = {
1700 .name = "wm8350-codec", 1678 .name = "wm8350-codec",
@@ -1702,8 +1680,6 @@ static struct platform_driver wm8350_codec_driver = {
1702 }, 1680 },
1703 .probe = wm8350_codec_probe, 1681 .probe = wm8350_codec_probe,
1704 .remove = __devexit_p(wm8350_codec_remove), 1682 .remove = __devexit_p(wm8350_codec_remove),
1705 .suspend = wm8350_codec_suspend,
1706 .resume = wm8350_codec_resume,
1707}; 1683};
1708 1684
1709static __init int wm8350_init(void) 1685static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index b9ef4d915221..6acc885cf9b7 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/slab.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/delay.h> 19#include <linux/delay.h>
19#include <linux/pm.h> 20#include <linux/pm.h>
@@ -915,7 +916,6 @@ static int wm8400_add_widgets(struct snd_soc_codec *codec)
915 916
916 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 917 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
917 918
918 snd_soc_dapm_new_widgets(codec);
919 return 0; 919 return 0;
920} 920}
921 921
@@ -1011,7 +1011,8 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
1011} 1011}
1012 1012
1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1014 unsigned int freq_in, unsigned int freq_out) 1014 int source, unsigned int freq_in,
1015 unsigned int freq_out)
1015{ 1016{
1016 struct snd_soc_codec *codec = codec_dai->codec; 1017 struct snd_soc_codec *codec = codec_dai->codec;
1017 struct wm8400_priv *wm8400 = codec->private_data; 1018 struct wm8400_priv *wm8400 = codec->private_data;
@@ -1399,17 +1400,6 @@ static int wm8400_probe(struct platform_device *pdev)
1399 wm8400_add_controls(codec); 1400 wm8400_add_controls(codec);
1400 wm8400_add_widgets(codec); 1401 wm8400_add_widgets(codec);
1401 1402
1402 ret = snd_soc_init_card(socdev);
1403 if (ret < 0) {
1404 dev_err(&pdev->dev, "failed to register card\n");
1405 goto card_err;
1406 }
1407
1408 return ret;
1409
1410card_err:
1411 snd_soc_free_pcms(socdev);
1412 snd_soc_dapm_free(socdev);
1413pcm_err: 1403pcm_err:
1414 return ret; 1404 return ret;
1415} 1405}
@@ -1558,21 +1548,6 @@ static int __exit wm8400_codec_remove(struct platform_device *dev)
1558 return 0; 1548 return 0;
1559} 1549}
1560 1550
1561#ifdef CONFIG_PM
1562static int wm8400_pdev_suspend(struct platform_device *pdev, pm_message_t msg)
1563{
1564 return snd_soc_suspend_device(&pdev->dev);
1565}
1566
1567static int wm8400_pdev_resume(struct platform_device *pdev)
1568{
1569 return snd_soc_resume_device(&pdev->dev);
1570}
1571#else
1572#define wm8400_pdev_suspend NULL
1573#define wm8400_pdev_resume NULL
1574#endif
1575
1576static struct platform_driver wm8400_codec_driver = { 1551static struct platform_driver wm8400_codec_driver = {
1577 .driver = { 1552 .driver = {
1578 .name = "wm8400-codec", 1553 .name = "wm8400-codec",
@@ -1580,8 +1555,6 @@ static struct platform_driver wm8400_codec_driver = {
1580 }, 1555 },
1581 .probe = wm8400_codec_probe, 1556 .probe = wm8400_codec_probe,
1582 .remove = __exit_p(wm8400_codec_remove), 1557 .remove = __exit_p(wm8400_codec_remove),
1583 .suspend = wm8400_pdev_suspend,
1584 .resume = wm8400_pdev_resume,
1585}; 1558};
1586 1559
1587static int __init wm8400_codec_init(void) 1560static int __init wm8400_codec_init(void)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 060d5d06ba95..9000b1d19afb 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -19,6 +19,7 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -219,7 +220,6 @@ static int wm8510_add_widgets(struct snd_soc_codec *codec)
219 220
220 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 221 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
221 222
222 snd_soc_dapm_new_widgets(codec);
223 return 0; 223 return 0;
224} 224}
225 225
@@ -271,8 +271,8 @@ static void pll_factors(unsigned int target, unsigned int source)
271 pll_div.k = K; 271 pll_div.k = K;
272} 272}
273 273
274static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, 274static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
275 int pll_id, unsigned int freq_in, unsigned int freq_out) 275 int source, unsigned int freq_in, unsigned int freq_out)
276{ 276{
277 struct snd_soc_codec *codec = codec_dai->codec; 277 struct snd_soc_codec *codec = codec_dai->codec;
278 u16 reg; 278 u16 reg;
@@ -425,23 +425,23 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
425 425
426 /* filter coefficient */ 426 /* filter coefficient */
427 switch (params_rate(params)) { 427 switch (params_rate(params)) {
428 case SNDRV_PCM_RATE_8000: 428 case 8000:
429 adn |= 0x5 << 1; 429 adn |= 0x5 << 1;
430 break; 430 break;
431 case SNDRV_PCM_RATE_11025: 431 case 11025:
432 adn |= 0x4 << 1; 432 adn |= 0x4 << 1;
433 break; 433 break;
434 case SNDRV_PCM_RATE_16000: 434 case 16000:
435 adn |= 0x3 << 1; 435 adn |= 0x3 << 1;
436 break; 436 break;
437 case SNDRV_PCM_RATE_22050: 437 case 22050:
438 adn |= 0x2 << 1; 438 adn |= 0x2 << 1;
439 break; 439 break;
440 case SNDRV_PCM_RATE_32000: 440 case 32000:
441 adn |= 0x1 << 1; 441 adn |= 0x1 << 1;
442 break; 442 break;
443 case SNDRV_PCM_RATE_44100: 443 case 44100:
444 case SNDRV_PCM_RATE_48000: 444 case 48000:
445 break; 445 break;
446 } 446 }
447 447
@@ -604,16 +604,9 @@ static int wm8510_init(struct snd_soc_device *socdev,
604 snd_soc_add_controls(codec, wm8510_snd_controls, 604 snd_soc_add_controls(codec, wm8510_snd_controls,
605 ARRAY_SIZE(wm8510_snd_controls)); 605 ARRAY_SIZE(wm8510_snd_controls));
606 wm8510_add_widgets(codec); 606 wm8510_add_widgets(codec);
607 ret = snd_soc_init_card(socdev); 607
608 if (ret < 0) {
609 printk(KERN_ERR "wm8510: failed to register card\n");
610 goto card_err;
611 }
612 return ret; 608 return ret;
613 609
614card_err:
615 snd_soc_free_pcms(socdev);
616 snd_soc_dapm_free(socdev);
617err: 610err:
618 kfree(codec->reg_cache); 611 kfree(codec->reg_cache);
619 return ret; 612 return ret;
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 25870a4652fb..19cd47293424 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -19,6 +19,7 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -117,7 +118,6 @@ static int wm8523_add_widgets(struct snd_soc_codec *codec)
117 118
118 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 119 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
119 120
120 snd_soc_dapm_new_widgets(codec);
121 return 0; 121 return 0;
122} 122}
123 123
@@ -448,17 +448,9 @@ static int wm8523_probe(struct platform_device *pdev)
448 snd_soc_add_controls(codec, wm8523_snd_controls, 448 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls)); 449 ARRAY_SIZE(wm8523_snd_controls));
450 wm8523_add_widgets(codec); 450 wm8523_add_widgets(codec);
451 ret = snd_soc_init_card(socdev);
452 if (ret < 0) {
453 dev_err(codec->dev, "failed to register card: %d\n", ret);
454 goto card_err;
455 }
456 451
457 return ret; 452 return ret;
458 453
459card_err:
460 snd_soc_free_pcms(socdev);
461 snd_soc_dapm_free(socdev);
462pcm_err: 454pcm_err:
463 return ret; 455 return ret;
464} 456}
@@ -638,21 +630,6 @@ static __devexit int wm8523_i2c_remove(struct i2c_client *client)
638 return 0; 630 return 0;
639} 631}
640 632
641#ifdef CONFIG_PM
642static int wm8523_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
643{
644 return snd_soc_suspend_device(&i2c->dev);
645}
646
647static int wm8523_i2c_resume(struct i2c_client *i2c)
648{
649 return snd_soc_resume_device(&i2c->dev);
650}
651#else
652#define wm8523_i2c_suspend NULL
653#define wm8523_i2c_resume NULL
654#endif
655
656static const struct i2c_device_id wm8523_i2c_id[] = { 633static const struct i2c_device_id wm8523_i2c_id[] = {
657 { "wm8523", 0 }, 634 { "wm8523", 0 },
658 { } 635 { }
@@ -666,8 +643,6 @@ static struct i2c_driver wm8523_i2c_driver = {
666 }, 643 },
667 .probe = wm8523_i2c_probe, 644 .probe = wm8523_i2c_probe,
668 .remove = __devexit_p(wm8523_i2c_remove), 645 .remove = __devexit_p(wm8523_i2c_remove),
669 .suspend = wm8523_i2c_suspend,
670 .resume = wm8523_i2c_resume,
671 .id_table = wm8523_i2c_id, 646 .id_table = wm8523_i2c_id,
672}; 647};
673#endif 648#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 6bded8c78150..8cc9042965eb 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -25,6 +25,7 @@
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <linux/slab.h>
28 29
29#include <sound/core.h> 30#include <sound/core.h>
30#include <sound/pcm.h> 31#include <sound/pcm.h>
@@ -315,7 +316,6 @@ static int wm8580_add_widgets(struct snd_soc_codec *codec)
315 316
316 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 317 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
317 318
318 snd_soc_dapm_new_widgets(codec);
319 return 0; 319 return 0;
320} 320}
321 321
@@ -407,8 +407,8 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
407 return 0; 407 return 0;
408} 408}
409 409
410static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, 410static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
411 int pll_id, unsigned int freq_in, unsigned int freq_out) 411 int source, unsigned int freq_in, unsigned int freq_out)
412{ 412{
413 int offset; 413 int offset;
414 struct snd_soc_codec *codec = codec_dai->codec; 414 struct snd_soc_codec *codec = codec_dai->codec;
@@ -800,17 +800,9 @@ static int wm8580_probe(struct platform_device *pdev)
800 snd_soc_add_controls(codec, wm8580_snd_controls, 800 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls)); 801 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec); 802 wm8580_add_widgets(codec);
803 ret = snd_soc_init_card(socdev);
804 if (ret < 0) {
805 dev_err(codec->dev, "failed to register card: %d\n", ret);
806 goto card_err;
807 }
808 803
809 return ret; 804 return ret;
810 805
811card_err:
812 snd_soc_free_pcms(socdev);
813 snd_soc_dapm_free(socdev);
814pcm_err: 806pcm_err:
815 return ret; 807 return ret;
816} 808}
@@ -961,21 +953,6 @@ static int wm8580_i2c_remove(struct i2c_client *client)
961 return 0; 953 return 0;
962} 954}
963 955
964#ifdef CONFIG_PM
965static int wm8580_i2c_suspend(struct i2c_client *client, pm_message_t msg)
966{
967 return snd_soc_suspend_device(&client->dev);
968}
969
970static int wm8580_i2c_resume(struct i2c_client *client)
971{
972 return snd_soc_resume_device(&client->dev);
973}
974#else
975#define wm8580_i2c_suspend NULL
976#define wm8580_i2c_resume NULL
977#endif
978
979static const struct i2c_device_id wm8580_i2c_id[] = { 956static const struct i2c_device_id wm8580_i2c_id[] = {
980 { "wm8580", 0 }, 957 { "wm8580", 0 },
981 { } 958 { }
@@ -989,8 +966,6 @@ static struct i2c_driver wm8580_i2c_driver = {
989 }, 966 },
990 .probe = wm8580_i2c_probe, 967 .probe = wm8580_i2c_probe,
991 .remove = wm8580_i2c_remove, 968 .remove = wm8580_i2c_remove,
992 .suspend = wm8580_i2c_suspend,
993 .resume = wm8580_i2c_resume,
994 .id_table = wm8580_i2c_id, 969 .id_table = wm8580_i2c_id,
995}; 970};
996#endif 971#endif
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
new file mode 100644
index 000000000000..8ca3812f2f2f
--- /dev/null
+++ b/sound/soc/codecs/wm8711.c
@@ -0,0 +1,634 @@
1/*
2 * wm8711.c -- WM8711 ALSA SoC Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.c by Richard Purdie
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.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 <linux/spi/spi.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/tlv.h>
30#include <sound/initval.h>
31
32#include "wm8711.h"
33
34static struct snd_soc_codec *wm8711_codec;
35
36/* codec private data */
37struct wm8711_priv {
38 struct snd_soc_codec codec;
39 u16 reg_cache[WM8711_CACHEREGNUM];
40 unsigned int sysclk;
41};
42
43/*
44 * wm8711 register cache
45 * We can't read the WM8711 register space when we are
46 * using 2 wire for device control, so we cache them instead.
47 * There is no point in caching the reset register
48 */
49static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
50 0x0079, 0x0079, 0x000a, 0x0008,
51 0x009f, 0x000a, 0x0000, 0x0000
52};
53
54#define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0)
55
56static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
57
58static const struct snd_kcontrol_new wm8711_snd_controls[] = {
59
60SOC_DOUBLE_R_TLV("Master Playback Volume", WM8711_LOUT1V, WM8711_ROUT1V,
61 0, 127, 0, out_tlv),
62SOC_DOUBLE_R("Master Playback ZC Switch", WM8711_LOUT1V, WM8711_ROUT1V,
63 7, 1, 0),
64
65};
66
67/* Output Mixer */
68static const struct snd_kcontrol_new wm8711_output_mixer_controls[] = {
69SOC_DAPM_SINGLE("Line Bypass Switch", WM8711_APANA, 3, 1, 0),
70SOC_DAPM_SINGLE("HiFi Playback Switch", WM8711_APANA, 4, 1, 0),
71};
72
73static const struct snd_soc_dapm_widget wm8711_dapm_widgets[] = {
74SND_SOC_DAPM_MIXER("Output Mixer", WM8711_PWR, 4, 1,
75 &wm8711_output_mixer_controls[0],
76 ARRAY_SIZE(wm8711_output_mixer_controls)),
77SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8711_PWR, 3, 1),
78SND_SOC_DAPM_OUTPUT("LOUT"),
79SND_SOC_DAPM_OUTPUT("LHPOUT"),
80SND_SOC_DAPM_OUTPUT("ROUT"),
81SND_SOC_DAPM_OUTPUT("RHPOUT"),
82};
83
84static const struct snd_soc_dapm_route intercon[] = {
85 /* output mixer */
86 {"Output Mixer", "Line Bypass Switch", "Line Input"},
87 {"Output Mixer", "HiFi Playback Switch", "DAC"},
88
89 /* outputs */
90 {"RHPOUT", NULL, "Output Mixer"},
91 {"ROUT", NULL, "Output Mixer"},
92 {"LHPOUT", NULL, "Output Mixer"},
93 {"LOUT", NULL, "Output Mixer"},
94};
95
96static int wm8711_add_widgets(struct snd_soc_codec *codec)
97{
98 snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets,
99 ARRAY_SIZE(wm8711_dapm_widgets));
100
101 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
102
103 return 0;
104}
105
106struct _coeff_div {
107 u32 mclk;
108 u32 rate;
109 u16 fs;
110 u8 sr:4;
111 u8 bosr:1;
112 u8 usb:1;
113};
114
115/* codec mclk clock divider coefficients */
116static const struct _coeff_div coeff_div[] = {
117 /* 48k */
118 {12288000, 48000, 256, 0x0, 0x0, 0x0},
119 {18432000, 48000, 384, 0x0, 0x1, 0x0},
120 {12000000, 48000, 250, 0x0, 0x0, 0x1},
121
122 /* 32k */
123 {12288000, 32000, 384, 0x6, 0x0, 0x0},
124 {18432000, 32000, 576, 0x6, 0x1, 0x0},
125 {12000000, 32000, 375, 0x6, 0x0, 0x1},
126
127 /* 8k */
128 {12288000, 8000, 1536, 0x3, 0x0, 0x0},
129 {18432000, 8000, 2304, 0x3, 0x1, 0x0},
130 {11289600, 8000, 1408, 0xb, 0x0, 0x0},
131 {16934400, 8000, 2112, 0xb, 0x1, 0x0},
132 {12000000, 8000, 1500, 0x3, 0x0, 0x1},
133
134 /* 96k */
135 {12288000, 96000, 128, 0x7, 0x0, 0x0},
136 {18432000, 96000, 192, 0x7, 0x1, 0x0},
137 {12000000, 96000, 125, 0x7, 0x0, 0x1},
138
139 /* 44.1k */
140 {11289600, 44100, 256, 0x8, 0x0, 0x0},
141 {16934400, 44100, 384, 0x8, 0x1, 0x0},
142 {12000000, 44100, 272, 0x8, 0x1, 0x1},
143
144 /* 88.2k */
145 {11289600, 88200, 128, 0xf, 0x0, 0x0},
146 {16934400, 88200, 192, 0xf, 0x1, 0x0},
147 {12000000, 88200, 136, 0xf, 0x1, 0x1},
148};
149
150static inline int get_coeff(int mclk, int rate)
151{
152 int i;
153
154 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
155 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
156 return i;
157 }
158 return 0;
159}
160
161static int wm8711_hw_params(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params,
163 struct snd_soc_dai *dai)
164{
165 struct snd_soc_codec *codec = dai->codec;
166 struct wm8711_priv *wm8711 = codec->private_data;
167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
168 int i = get_coeff(wm8711->sysclk, params_rate(params));
169 u16 srate = (coeff_div[i].sr << 2) |
170 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
171
172 snd_soc_write(codec, WM8711_SRATE, srate);
173
174 /* bit size */
175 switch (params_format(params)) {
176 case SNDRV_PCM_FORMAT_S16_LE:
177 break;
178 case SNDRV_PCM_FORMAT_S20_3LE:
179 iface |= 0x0004;
180 break;
181 case SNDRV_PCM_FORMAT_S24_LE:
182 iface |= 0x0008;
183 break;
184 }
185
186 snd_soc_write(codec, WM8711_IFACE, iface);
187 return 0;
188}
189
190static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
192{
193 struct snd_soc_codec *codec = dai->codec;
194
195 /* set active */
196 snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
197
198 return 0;
199}
200
201static void wm8711_shutdown(struct snd_pcm_substream *substream,
202 struct snd_soc_dai *dai)
203{
204 struct snd_soc_codec *codec = dai->codec;
205
206 /* deactivate */
207 if (!codec->active) {
208 udelay(50);
209 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
210 }
211}
212
213static int wm8711_mute(struct snd_soc_dai *dai, int mute)
214{
215 struct snd_soc_codec *codec = dai->codec;
216 u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
217
218 if (mute)
219 snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
220 else
221 snd_soc_write(codec, WM8711_APDIGI, mute_reg);
222
223 return 0;
224}
225
226static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
227 int clk_id, unsigned int freq, int dir)
228{
229 struct snd_soc_codec *codec = codec_dai->codec;
230 struct wm8711_priv *wm8711 = codec->private_data;
231
232 switch (freq) {
233 case 11289600:
234 case 12000000:
235 case 12288000:
236 case 16934400:
237 case 18432000:
238 wm8711->sysclk = freq;
239 return 0;
240 }
241 return -EINVAL;
242}
243
244static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
245 unsigned int fmt)
246{
247 struct snd_soc_codec *codec = codec_dai->codec;
248 u16 iface = 0;
249
250 /* set master/slave audio interface */
251 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
252 case SND_SOC_DAIFMT_CBM_CFM:
253 iface |= 0x0040;
254 break;
255 case SND_SOC_DAIFMT_CBS_CFS:
256 break;
257 default:
258 return -EINVAL;
259 }
260
261 /* interface format */
262 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
263 case SND_SOC_DAIFMT_I2S:
264 iface |= 0x0002;
265 break;
266 case SND_SOC_DAIFMT_RIGHT_J:
267 break;
268 case SND_SOC_DAIFMT_LEFT_J:
269 iface |= 0x0001;
270 break;
271 case SND_SOC_DAIFMT_DSP_A:
272 iface |= 0x0003;
273 break;
274 case SND_SOC_DAIFMT_DSP_B:
275 iface |= 0x0013;
276 break;
277 default:
278 return -EINVAL;
279 }
280
281 /* clock inversion */
282 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
283 case SND_SOC_DAIFMT_NB_NF:
284 break;
285 case SND_SOC_DAIFMT_IB_IF:
286 iface |= 0x0090;
287 break;
288 case SND_SOC_DAIFMT_IB_NF:
289 iface |= 0x0080;
290 break;
291 case SND_SOC_DAIFMT_NB_IF:
292 iface |= 0x0010;
293 break;
294 default:
295 return -EINVAL;
296 }
297
298 /* set iface */
299 snd_soc_write(codec, WM8711_IFACE, iface);
300 return 0;
301}
302
303
304static int wm8711_set_bias_level(struct snd_soc_codec *codec,
305 enum snd_soc_bias_level level)
306{
307 u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
308
309 switch (level) {
310 case SND_SOC_BIAS_ON:
311 snd_soc_write(codec, WM8711_PWR, reg);
312 break;
313 case SND_SOC_BIAS_PREPARE:
314 break;
315 case SND_SOC_BIAS_STANDBY:
316 snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
317 break;
318 case SND_SOC_BIAS_OFF:
319 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
320 snd_soc_write(codec, WM8711_PWR, 0xffff);
321 break;
322 }
323 codec->bias_level = level;
324 return 0;
325}
326
327#define WM8711_RATES SNDRV_PCM_RATE_8000_96000
328
329#define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
330 SNDRV_PCM_FMTBIT_S24_LE)
331
332static struct snd_soc_dai_ops wm8711_ops = {
333 .prepare = wm8711_pcm_prepare,
334 .hw_params = wm8711_hw_params,
335 .shutdown = wm8711_shutdown,
336 .digital_mute = wm8711_mute,
337 .set_sysclk = wm8711_set_dai_sysclk,
338 .set_fmt = wm8711_set_dai_fmt,
339};
340
341struct snd_soc_dai wm8711_dai = {
342 .name = "WM8711",
343 .playback = {
344 .stream_name = "Playback",
345 .channels_min = 1,
346 .channels_max = 2,
347 .rates = WM8711_RATES,
348 .formats = WM8711_FORMATS,
349 },
350 .ops = &wm8711_ops,
351};
352EXPORT_SYMBOL_GPL(wm8711_dai);
353
354static int wm8711_suspend(struct platform_device *pdev, pm_message_t state)
355{
356 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
357 struct snd_soc_codec *codec = socdev->card->codec;
358
359 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
360 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
361 return 0;
362}
363
364static int wm8711_resume(struct platform_device *pdev)
365{
366 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
367 struct snd_soc_codec *codec = socdev->card->codec;
368 int i;
369 u8 data[2];
370 u16 *cache = codec->reg_cache;
371
372 /* Sync reg_cache with the hardware */
373 for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) {
374 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
375 data[1] = cache[i] & 0x00ff;
376 codec->hw_write(codec->control_data, data, 2);
377 }
378 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
379 wm8711_set_bias_level(codec, codec->suspend_bias_level);
380 return 0;
381}
382
383static int wm8711_probe(struct platform_device *pdev)
384{
385 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
386 struct snd_soc_codec *codec;
387 int ret = 0;
388
389 if (wm8711_codec == NULL) {
390 dev_err(&pdev->dev, "Codec device not registered\n");
391 return -ENODEV;
392 }
393
394 socdev->card->codec = wm8711_codec;
395 codec = wm8711_codec;
396
397 /* register pcms */
398 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
399 if (ret < 0) {
400 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
401 goto pcm_err;
402 }
403
404 snd_soc_add_controls(codec, wm8711_snd_controls,
405 ARRAY_SIZE(wm8711_snd_controls));
406 wm8711_add_widgets(codec);
407
408 return ret;
409
410pcm_err:
411 return ret;
412}
413
414/* power down chip */
415static int wm8711_remove(struct platform_device *pdev)
416{
417 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
418
419 snd_soc_free_pcms(socdev);
420 snd_soc_dapm_free(socdev);
421
422 return 0;
423}
424
425struct snd_soc_codec_device soc_codec_dev_wm8711 = {
426 .probe = wm8711_probe,
427 .remove = wm8711_remove,
428 .suspend = wm8711_suspend,
429 .resume = wm8711_resume,
430};
431EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
432
433static int wm8711_register(struct wm8711_priv *wm8711,
434 enum snd_soc_control_type control)
435{
436 int ret;
437 struct snd_soc_codec *codec = &wm8711->codec;
438 u16 reg;
439
440 if (wm8711_codec) {
441 dev_err(codec->dev, "Another WM8711 is registered\n");
442 return -EINVAL;
443 }
444
445 mutex_init(&codec->mutex);
446 INIT_LIST_HEAD(&codec->dapm_widgets);
447 INIT_LIST_HEAD(&codec->dapm_paths);
448
449 codec->private_data = wm8711;
450 codec->name = "WM8711";
451 codec->owner = THIS_MODULE;
452 codec->bias_level = SND_SOC_BIAS_OFF;
453 codec->set_bias_level = wm8711_set_bias_level;
454 codec->dai = &wm8711_dai;
455 codec->num_dai = 1;
456 codec->reg_cache_size = WM8711_CACHEREGNUM;
457 codec->reg_cache = &wm8711->reg_cache;
458
459 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
460
461 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
462 if (ret < 0) {
463 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
464 goto err;
465 }
466
467 ret = wm8711_reset(codec);
468 if (ret < 0) {
469 dev_err(codec->dev, "Failed to issue reset\n");
470 goto err;
471 }
472
473 wm8711_dai.dev = codec->dev;
474
475 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
476
477 /* Latch the update bits */
478 reg = snd_soc_read(codec, WM8711_LOUT1V);
479 snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100);
480 reg = snd_soc_read(codec, WM8711_ROUT1V);
481 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
482
483 wm8711_codec = codec;
484
485 ret = snd_soc_register_codec(codec);
486 if (ret != 0) {
487 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
488 goto err;
489 }
490
491 ret = snd_soc_register_dai(&wm8711_dai);
492 if (ret != 0) {
493 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
494 goto err_codec;
495 }
496
497 return 0;
498
499err_codec:
500 snd_soc_unregister_codec(codec);
501err:
502 kfree(wm8711);
503 return ret;
504}
505
506static void wm8711_unregister(struct wm8711_priv *wm8711)
507{
508 wm8711_set_bias_level(&wm8711->codec, SND_SOC_BIAS_OFF);
509 snd_soc_unregister_dai(&wm8711_dai);
510 snd_soc_unregister_codec(&wm8711->codec);
511 kfree(wm8711);
512 wm8711_codec = NULL;
513}
514
515#if defined(CONFIG_SPI_MASTER)
516static int __devinit wm8711_spi_probe(struct spi_device *spi)
517{
518 struct snd_soc_codec *codec;
519 struct wm8711_priv *wm8711;
520
521 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
522 if (wm8711 == NULL)
523 return -ENOMEM;
524
525 codec = &wm8711->codec;
526 codec->control_data = spi;
527 codec->dev = &spi->dev;
528
529 dev_set_drvdata(&spi->dev, wm8711);
530
531 return wm8711_register(wm8711, SND_SOC_SPI);
532}
533
534static int __devexit wm8711_spi_remove(struct spi_device *spi)
535{
536 struct wm8711_priv *wm8711 = dev_get_drvdata(&spi->dev);
537
538 wm8711_unregister(wm8711);
539
540 return 0;
541}
542
543static struct spi_driver wm8711_spi_driver = {
544 .driver = {
545 .name = "wm8711",
546 .bus = &spi_bus_type,
547 .owner = THIS_MODULE,
548 },
549 .probe = wm8711_spi_probe,
550 .remove = __devexit_p(wm8711_spi_remove),
551};
552#endif /* CONFIG_SPI_MASTER */
553
554#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
555static __devinit int wm8711_i2c_probe(struct i2c_client *i2c,
556 const struct i2c_device_id *id)
557{
558 struct wm8711_priv *wm8711;
559 struct snd_soc_codec *codec;
560
561 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
562 if (wm8711 == NULL)
563 return -ENOMEM;
564
565 codec = &wm8711->codec;
566 codec->hw_write = (hw_write_t)i2c_master_send;
567
568 i2c_set_clientdata(i2c, wm8711);
569 codec->control_data = i2c;
570
571 codec->dev = &i2c->dev;
572
573 return wm8711_register(wm8711, SND_SOC_I2C);
574}
575
576static __devexit int wm8711_i2c_remove(struct i2c_client *client)
577{
578 struct wm8711_priv *wm8711 = i2c_get_clientdata(client);
579 wm8711_unregister(wm8711);
580 return 0;
581}
582
583static const struct i2c_device_id wm8711_i2c_id[] = {
584 { "wm8711", 0 },
585 { }
586};
587MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
588
589static struct i2c_driver wm8711_i2c_driver = {
590 .driver = {
591 .name = "WM8711 I2C Codec",
592 .owner = THIS_MODULE,
593 },
594 .probe = wm8711_i2c_probe,
595 .remove = __devexit_p(wm8711_i2c_remove),
596 .id_table = wm8711_i2c_id,
597};
598#endif
599
600static int __init wm8711_modinit(void)
601{
602 int ret;
603#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
604 ret = i2c_add_driver(&wm8711_i2c_driver);
605 if (ret != 0) {
606 printk(KERN_ERR "Failed to register WM8711 I2C driver: %d\n",
607 ret);
608 }
609#endif
610#if defined(CONFIG_SPI_MASTER)
611 ret = spi_register_driver(&wm8711_spi_driver);
612 if (ret != 0) {
613 printk(KERN_ERR "Failed to register WM8711 SPI driver: %d\n",
614 ret);
615 }
616#endif
617 return 0;
618}
619module_init(wm8711_modinit);
620
621static void __exit wm8711_exit(void)
622{
623#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
624 i2c_del_driver(&wm8711_i2c_driver);
625#endif
626#if defined(CONFIG_SPI_MASTER)
627 spi_unregister_driver(&wm8711_spi_driver);
628#endif
629}
630module_exit(wm8711_exit);
631
632MODULE_DESCRIPTION("ASoC WM8711 driver");
633MODULE_AUTHOR("Mike Arthur");
634MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8711.h b/sound/soc/codecs/wm8711.h
new file mode 100644
index 000000000000..381e84a43816
--- /dev/null
+++ b/sound/soc/codecs/wm8711.h
@@ -0,0 +1,42 @@
1/*
2 * wm8711.h -- WM8711 Soc Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _WM8711_H
16#define _WM8711_H
17
18/* WM8711 register space */
19
20#define WM8711_LOUT1V 0x02
21#define WM8711_ROUT1V 0x03
22#define WM8711_APANA 0x04
23#define WM8711_APDIGI 0x05
24#define WM8711_PWR 0x06
25#define WM8711_IFACE 0x07
26#define WM8711_SRATE 0x08
27#define WM8711_ACTIVE 0x09
28#define WM8711_RESET 0x0f
29
30#define WM8711_CACHEREGNUM 8
31
32#define WM8711_SYSCLK 0
33#define WM8711_DAI 0
34
35struct wm8711_setup_data {
36 unsigned short i2c_address;
37};
38
39extern struct snd_soc_dai wm8711_dai;
40extern struct snd_soc_codec_device soc_codec_dev_wm8711;
41
42#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
new file mode 100644
index 000000000000..1072621e93fd
--- /dev/null
+++ b/sound/soc/codecs/wm8727.c
@@ -0,0 +1,168 @@
1/*
2 * wm8727.c
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/device.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/ac97_codec.h>
23#include <sound/initval.h>
24#include <sound/soc.h>
25
26#include "wm8727.h"
27/*
28 * Note this is a simple chip with no configuration interface, sample rate is
29 * determined automatically by examining the Master clock and Bit clock ratios
30 */
31#define WM8727_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
32 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
33 SNDRV_PCM_RATE_192000)
34
35
36struct snd_soc_dai wm8727_dai = {
37 .name = "WM8727",
38 .playback = {
39 .stream_name = "Playback",
40 .channels_min = 2,
41 .channels_max = 2,
42 .rates = WM8727_RATES,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
44 },
45};
46EXPORT_SYMBOL_GPL(wm8727_dai);
47
48static struct snd_soc_codec *wm8727_codec;
49
50static int wm8727_soc_probe(struct platform_device *pdev)
51{
52 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
53 int ret = 0;
54
55 BUG_ON(!wm8727_codec);
56
57 socdev->card->codec = wm8727_codec;
58
59 /* register pcms */
60 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
61 if (ret < 0) {
62 printk(KERN_ERR "wm8727: failed to create pcms\n");
63 goto pcm_err;
64 }
65
66 return ret;
67
68pcm_err:
69 kfree(socdev->card->codec);
70 socdev->card->codec = NULL;
71 return ret;
72}
73
74static int wm8727_soc_remove(struct platform_device *pdev)
75{
76 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
77
78 snd_soc_free_pcms(socdev);
79
80 return 0;
81}
82
83struct snd_soc_codec_device soc_codec_dev_wm8727 = {
84 .probe = wm8727_soc_probe,
85 .remove = wm8727_soc_remove,
86};
87EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
88
89
90static __devinit int wm8727_platform_probe(struct platform_device *pdev)
91{
92 struct snd_soc_codec *codec;
93 int ret;
94
95 if (wm8727_codec) {
96 dev_err(&pdev->dev, "Another WM8727 is registered\n");
97 return -EBUSY;
98 }
99
100 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
101 if (codec == NULL)
102 return -ENOMEM;
103 wm8727_codec = codec;
104
105 platform_set_drvdata(pdev, codec);
106
107 mutex_init(&codec->mutex);
108 codec->dev = &pdev->dev;
109 codec->name = "WM8727";
110 codec->owner = THIS_MODULE;
111 codec->dai = &wm8727_dai;
112 codec->num_dai = 1;
113 INIT_LIST_HEAD(&codec->dapm_widgets);
114 INIT_LIST_HEAD(&codec->dapm_paths);
115
116 wm8727_dai.dev = &pdev->dev;
117
118 ret = snd_soc_register_codec(codec);
119 if (ret != 0) {
120 dev_err(&pdev->dev, "Failed to register CODEC: %d\n", ret);
121 goto err;
122 }
123
124 ret = snd_soc_register_dai(&wm8727_dai);
125 if (ret != 0) {
126 dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
127 goto err_codec;
128 }
129
130err_codec:
131 snd_soc_unregister_codec(codec);
132err:
133 kfree(codec);
134 return ret;
135}
136
137static int __devexit wm8727_platform_remove(struct platform_device *pdev)
138{
139 snd_soc_unregister_dai(&wm8727_dai);
140 snd_soc_unregister_codec(platform_get_drvdata(pdev));
141 return 0;
142}
143
144static struct platform_driver wm8727_codec_driver = {
145 .driver = {
146 .name = "wm8727-codec",
147 .owner = THIS_MODULE,
148 },
149
150 .probe = wm8727_platform_probe,
151 .remove = __devexit_p(wm8727_platform_remove),
152};
153
154static int __init wm8727_init(void)
155{
156 return platform_driver_register(&wm8727_codec_driver);
157}
158module_init(wm8727_init);
159
160static void __exit wm8727_exit(void)
161{
162 platform_driver_unregister(&wm8727_codec_driver);
163}
164module_exit(wm8727_exit);
165
166MODULE_DESCRIPTION("ASoC wm8727 driver");
167MODULE_AUTHOR("Neil Jones");
168MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8727.h b/sound/soc/codecs/wm8727.h
new file mode 100644
index 000000000000..ee19aa71bcdc
--- /dev/null
+++ b/sound/soc/codecs/wm8727.h
@@ -0,0 +1,21 @@
1/*
2 * wm8727.h
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#ifndef WM8727_H_
16#define WM8727_H_
17
18extern struct snd_soc_dai wm8727_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8727;
20
21#endif /* WM8727_H_ */
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 16e969a762c3..07adc375a706 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -18,6 +18,7 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -74,8 +75,6 @@ static int wm8728_add_widgets(struct snd_soc_codec *codec)
74 75
75 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 76 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
76 77
77 snd_soc_dapm_new_widgets(codec);
78
79 return 0; 78 return 0;
80} 79}
81 80
@@ -287,17 +286,9 @@ static int wm8728_init(struct snd_soc_device *socdev,
287 snd_soc_add_controls(codec, wm8728_snd_controls, 286 snd_soc_add_controls(codec, wm8728_snd_controls,
288 ARRAY_SIZE(wm8728_snd_controls)); 287 ARRAY_SIZE(wm8728_snd_controls));
289 wm8728_add_widgets(codec); 288 wm8728_add_widgets(codec);
290 ret = snd_soc_init_card(socdev);
291 if (ret < 0) {
292 printk(KERN_ERR "wm8728: failed to register card\n");
293 goto card_err;
294 }
295 289
296 return ret; 290 return ret;
297 291
298card_err:
299 snd_soc_free_pcms(socdev);
300 snd_soc_dapm_free(socdev);
301err: 292err:
302 kfree(codec->reg_cache); 293 kfree(codec->reg_cache);
303 return ret; 294 return ret;
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index d3fd4f28d96e..e7c6bf163185 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -18,7 +18,9 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/slab.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/regulator/consumer.h>
22#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
23#include <sound/core.h> 25#include <sound/core.h>
24#include <sound/pcm.h> 26#include <sound/pcm.h>
@@ -33,9 +35,18 @@
33static struct snd_soc_codec *wm8731_codec; 35static struct snd_soc_codec *wm8731_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8731; 36struct snd_soc_codec_device soc_codec_dev_wm8731;
35 37
38#define WM8731_NUM_SUPPLIES 4
39static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
40 "AVDD",
41 "HPVDD",
42 "DCVDD",
43 "DBVDD",
44};
45
36/* codec private data */ 46/* codec private data */
37struct wm8731_priv { 47struct wm8731_priv {
38 struct snd_soc_codec codec; 48 struct snd_soc_codec codec;
49 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
39 u16 reg_cache[WM8731_CACHEREGNUM]; 50 u16 reg_cache[WM8731_CACHEREGNUM];
40 unsigned int sysclk; 51 unsigned int sysclk;
41}; 52};
@@ -149,7 +160,6 @@ static int wm8731_add_widgets(struct snd_soc_codec *codec)
149 160
150 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 161 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
151 162
152 snd_soc_dapm_new_widgets(codec);
153 return 0; 163 return 0;
154} 164}
155 165
@@ -422,9 +432,12 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
422{ 432{
423 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 433 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
424 struct snd_soc_codec *codec = socdev->card->codec; 434 struct snd_soc_codec *codec = socdev->card->codec;
435 struct wm8731_priv *wm8731 = codec->private_data;
425 436
426 snd_soc_write(codec, WM8731_ACTIVE, 0x0); 437 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
427 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 438 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
439 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
440 wm8731->supplies);
428 return 0; 441 return 0;
429} 442}
430 443
@@ -432,18 +445,28 @@ static int wm8731_resume(struct platform_device *pdev)
432{ 445{
433 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 446 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
434 struct snd_soc_codec *codec = socdev->card->codec; 447 struct snd_soc_codec *codec = socdev->card->codec;
435 int i; 448 struct wm8731_priv *wm8731 = codec->private_data;
449 int i, ret;
436 u8 data[2]; 450 u8 data[2];
437 u16 *cache = codec->reg_cache; 451 u16 *cache = codec->reg_cache;
438 452
453 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
454 wm8731->supplies);
455 if (ret != 0)
456 return ret;
457
439 /* Sync reg_cache with the hardware */ 458 /* Sync reg_cache with the hardware */
440 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 459 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
460 if (cache[i] == wm8731_reg[i])
461 continue;
462
441 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 463 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
442 data[1] = cache[i] & 0x00ff; 464 data[1] = cache[i] & 0x00ff;
443 codec->hw_write(codec->control_data, data, 2); 465 codec->hw_write(codec->control_data, data, 2);
444 } 466 }
445 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 467 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
446 wm8731_set_bias_level(codec, codec->suspend_bias_level); 468 wm8731_set_bias_level(codec, codec->suspend_bias_level);
469
447 return 0; 470 return 0;
448} 471}
449#else 472#else
@@ -475,17 +498,9 @@ static int wm8731_probe(struct platform_device *pdev)
475 snd_soc_add_controls(codec, wm8731_snd_controls, 498 snd_soc_add_controls(codec, wm8731_snd_controls,
476 ARRAY_SIZE(wm8731_snd_controls)); 499 ARRAY_SIZE(wm8731_snd_controls));
477 wm8731_add_widgets(codec); 500 wm8731_add_widgets(codec);
478 ret = snd_soc_init_card(socdev);
479 if (ret < 0) {
480 dev_err(codec->dev, "failed to register card: %d\n", ret);
481 goto card_err;
482 }
483 501
484 return ret; 502 return ret;
485 503
486card_err:
487 snd_soc_free_pcms(socdev);
488 snd_soc_dapm_free(socdev);
489pcm_err: 504pcm_err:
490 return ret; 505 return ret;
491} 506}
@@ -512,7 +527,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
512static int wm8731_register(struct wm8731_priv *wm8731, 527static int wm8731_register(struct wm8731_priv *wm8731,
513 enum snd_soc_control_type control) 528 enum snd_soc_control_type control)
514{ 529{
515 int ret; 530 int ret, i;
516 struct snd_soc_codec *codec = &wm8731->codec; 531 struct snd_soc_codec *codec = &wm8731->codec;
517 532
518 if (wm8731_codec) { 533 if (wm8731_codec) {
@@ -543,10 +558,27 @@ static int wm8731_register(struct wm8731_priv *wm8731,
543 goto err; 558 goto err;
544 } 559 }
545 560
561 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
562 wm8731->supplies[i].supply = wm8731_supply_names[i];
563
564 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8731->supplies),
565 wm8731->supplies);
566 if (ret != 0) {
567 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
568 goto err;
569 }
570
571 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
572 wm8731->supplies);
573 if (ret != 0) {
574 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
575 goto err_regulator_get;
576 }
577
546 ret = wm8731_reset(codec); 578 ret = wm8731_reset(codec);
547 if (ret < 0) { 579 if (ret < 0) {
548 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 580 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
549 goto err; 581 goto err_regulator_enable;
550 } 582 }
551 583
552 wm8731_dai.dev = codec->dev; 584 wm8731_dai.dev = codec->dev;
@@ -567,7 +599,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
567 ret = snd_soc_register_codec(codec); 599 ret = snd_soc_register_codec(codec);
568 if (ret != 0) { 600 if (ret != 0) {
569 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 601 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
570 goto err; 602 goto err_regulator_enable;
571 } 603 }
572 604
573 ret = snd_soc_register_dai(&wm8731_dai); 605 ret = snd_soc_register_dai(&wm8731_dai);
@@ -581,6 +613,10 @@ static int wm8731_register(struct wm8731_priv *wm8731,
581 613
582err_codec: 614err_codec:
583 snd_soc_unregister_codec(codec); 615 snd_soc_unregister_codec(codec);
616err_regulator_enable:
617 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
618err_regulator_get:
619 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
584err: 620err:
585 kfree(wm8731); 621 kfree(wm8731);
586 return ret; 622 return ret;
@@ -591,6 +627,8 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
591 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 627 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
592 snd_soc_unregister_dai(&wm8731_dai); 628 snd_soc_unregister_dai(&wm8731_dai);
593 snd_soc_unregister_codec(&wm8731->codec); 629 snd_soc_unregister_codec(&wm8731->codec);
630 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
594 kfree(wm8731); 632 kfree(wm8731);
595 wm8731_codec = NULL; 633 wm8731_codec = NULL;
596} 634}
@@ -623,21 +661,6 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
623 return 0; 661 return 0;
624} 662}
625 663
626#ifdef CONFIG_PM
627static int wm8731_spi_suspend(struct spi_device *spi, pm_message_t msg)
628{
629 return snd_soc_suspend_device(&spi->dev);
630}
631
632static int wm8731_spi_resume(struct spi_device *spi)
633{
634 return snd_soc_resume_device(&spi->dev);
635}
636#else
637#define wm8731_spi_suspend NULL
638#define wm8731_spi_resume NULL
639#endif
640
641static struct spi_driver wm8731_spi_driver = { 664static struct spi_driver wm8731_spi_driver = {
642 .driver = { 665 .driver = {
643 .name = "wm8731", 666 .name = "wm8731",
@@ -645,8 +668,6 @@ static struct spi_driver wm8731_spi_driver = {
645 .owner = THIS_MODULE, 668 .owner = THIS_MODULE,
646 }, 669 },
647 .probe = wm8731_spi_probe, 670 .probe = wm8731_spi_probe,
648 .suspend = wm8731_spi_suspend,
649 .resume = wm8731_spi_resume,
650 .remove = __devexit_p(wm8731_spi_remove), 671 .remove = __devexit_p(wm8731_spi_remove),
651}; 672};
652#endif /* CONFIG_SPI_MASTER */ 673#endif /* CONFIG_SPI_MASTER */
@@ -679,21 +700,6 @@ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
679 return 0; 700 return 0;
680} 701}
681 702
682#ifdef CONFIG_PM
683static int wm8731_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
684{
685 return snd_soc_suspend_device(&i2c->dev);
686}
687
688static int wm8731_i2c_resume(struct i2c_client *i2c)
689{
690 return snd_soc_resume_device(&i2c->dev);
691}
692#else
693#define wm8731_i2c_suspend NULL
694#define wm8731_i2c_resume NULL
695#endif
696
697static const struct i2c_device_id wm8731_i2c_id[] = { 703static const struct i2c_device_id wm8731_i2c_id[] = {
698 { "wm8731", 0 }, 704 { "wm8731", 0 },
699 { } 705 { }
@@ -707,8 +713,6 @@ static struct i2c_driver wm8731_i2c_driver = {
707 }, 713 },
708 .probe = wm8731_i2c_probe, 714 .probe = wm8731_i2c_probe,
709 .remove = __devexit_p(wm8731_i2c_remove), 715 .remove = __devexit_p(wm8731_i2c_remove),
710 .suspend = wm8731_i2c_suspend,
711 .resume = wm8731_i2c_resume,
712 .id_table = wm8731_i2c_id, 716 .id_table = wm8731_i2c_id,
713}; 717};
714#endif 718#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 4ba1e7e93fb4..2916ed4d3844 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -20,6 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -403,7 +404,6 @@ static int wm8750_add_widgets(struct snd_soc_codec *codec)
403 404
404 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 405 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
405 406
406 snd_soc_dapm_new_widgets(codec);
407 return 0; 407 return 0;
408} 408}
409 409
@@ -772,16 +772,8 @@ static int wm8750_init(struct snd_soc_device *socdev,
772 snd_soc_add_controls(codec, wm8750_snd_controls, 772 snd_soc_add_controls(codec, wm8750_snd_controls,
773 ARRAY_SIZE(wm8750_snd_controls)); 773 ARRAY_SIZE(wm8750_snd_controls));
774 wm8750_add_widgets(codec); 774 wm8750_add_widgets(codec);
775 ret = snd_soc_init_card(socdev);
776 if (ret < 0) {
777 printk(KERN_ERR "wm8750: failed to register card\n");
778 goto card_err;
779 }
780 return ret; 775 return ret;
781 776
782card_err:
783 snd_soc_free_pcms(socdev);
784 snd_soc_dapm_free(socdev);
785err: 777err:
786 kfree(codec->reg_cache); 778 kfree(codec->reg_cache);
787 return ret; 779 return ret;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5ad677ce80da..613199a0f799 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -40,6 +40,7 @@
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/spi/spi.h> 42#include <linux/spi/spi.h>
43#include <linux/slab.h>
43#include <sound/core.h> 44#include <sound/core.h>
44#include <sound/pcm.h> 45#include <sound/pcm.h>
45#include <sound/pcm_params.h> 46#include <sound/pcm_params.h>
@@ -673,7 +674,6 @@ static int wm8753_add_widgets(struct snd_soc_codec *codec)
673 674
674 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 675 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
675 676
676 snd_soc_dapm_new_widgets(codec);
677 return 0; 677 return 0;
678} 678}
679 679
@@ -724,8 +724,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
724 pll_div->k = K; 724 pll_div->k = K;
725} 725}
726 726
727static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, 727static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
728 int pll_id, unsigned int freq_in, unsigned int freq_out) 728 int source, unsigned int freq_in, unsigned int freq_out)
729{ 729{
730 u16 reg, enable; 730 u16 reg, enable;
731 int offset; 731 int offset;
@@ -1508,10 +1508,6 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
1508 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1508 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1509 struct snd_soc_codec *codec = socdev->card->codec; 1509 struct snd_soc_codec *codec = socdev->card->codec;
1510 1510
1511 /* we only need to suspend if we are a valid card */
1512 if (!codec->card)
1513 return 0;
1514
1515 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1511 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1516 return 0; 1512 return 0;
1517} 1513}
@@ -1524,10 +1520,6 @@ static int wm8753_resume(struct platform_device *pdev)
1524 u8 data[2]; 1520 u8 data[2];
1525 u16 *cache = codec->reg_cache; 1521 u16 *cache = codec->reg_cache;
1526 1522
1527 /* we only need to resume if we are a valid card */
1528 if (!codec->card)
1529 return 0;
1530
1531 /* Sync reg_cache with the hardware */ 1523 /* Sync reg_cache with the hardware */
1532 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { 1524 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
1533 if (i + 1 == WM8753_RESET) 1525 if (i + 1 == WM8753_RESET)
@@ -1583,18 +1575,9 @@ static int wm8753_probe(struct platform_device *pdev)
1583 snd_soc_add_controls(codec, wm8753_snd_controls, 1575 snd_soc_add_controls(codec, wm8753_snd_controls,
1584 ARRAY_SIZE(wm8753_snd_controls)); 1576 ARRAY_SIZE(wm8753_snd_controls));
1585 wm8753_add_widgets(codec); 1577 wm8753_add_widgets(codec);
1586 ret = snd_soc_init_card(socdev);
1587 if (ret < 0) {
1588 printk(KERN_ERR "wm8753: failed to register card\n");
1589 goto card_err;
1590 }
1591 1578
1592 return 0; 1579 return 0;
1593 1580
1594card_err:
1595 snd_soc_free_pcms(socdev);
1596 snd_soc_dapm_free(socdev);
1597
1598pcm_err: 1581pcm_err:
1599 return ret; 1582 return ret;
1600} 1583}
@@ -1767,21 +1750,6 @@ static int wm8753_i2c_remove(struct i2c_client *client)
1767 return 0; 1750 return 0;
1768} 1751}
1769 1752
1770#ifdef CONFIG_PM
1771static int wm8753_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1772{
1773 return snd_soc_suspend_device(&client->dev);
1774}
1775
1776static int wm8753_i2c_resume(struct i2c_client *client)
1777{
1778 return snd_soc_resume_device(&client->dev);
1779}
1780#else
1781#define wm8753_i2c_suspend NULL
1782#define wm8753_i2c_resume NULL
1783#endif
1784
1785static const struct i2c_device_id wm8753_i2c_id[] = { 1753static const struct i2c_device_id wm8753_i2c_id[] = {
1786 { "wm8753", 0 }, 1754 { "wm8753", 0 },
1787 { } 1755 { }
@@ -1795,8 +1763,6 @@ static struct i2c_driver wm8753_i2c_driver = {
1795 }, 1763 },
1796 .probe = wm8753_i2c_probe, 1764 .probe = wm8753_i2c_probe,
1797 .remove = wm8753_i2c_remove, 1765 .remove = wm8753_i2c_remove,
1798 .suspend = wm8753_i2c_suspend,
1799 .resume = wm8753_i2c_resume,
1800 .id_table = wm8753_i2c_id, 1766 .id_table = wm8753_i2c_id,
1801}; 1767};
1802#endif 1768#endif
@@ -1852,22 +1818,6 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1852 return 0; 1818 return 0;
1853} 1819}
1854 1820
1855#ifdef CONFIG_PM
1856static int wm8753_spi_suspend(struct spi_device *spi, pm_message_t msg)
1857{
1858 return snd_soc_suspend_device(&spi->dev);
1859}
1860
1861static int wm8753_spi_resume(struct spi_device *spi)
1862{
1863 return snd_soc_resume_device(&spi->dev);
1864}
1865
1866#else
1867#define wm8753_spi_suspend NULL
1868#define wm8753_spi_resume NULL
1869#endif
1870
1871static struct spi_driver wm8753_spi_driver = { 1821static struct spi_driver wm8753_spi_driver = {
1872 .driver = { 1822 .driver = {
1873 .name = "wm8753", 1823 .name = "wm8753",
@@ -1876,8 +1826,6 @@ static struct spi_driver wm8753_spi_driver = {
1876 }, 1826 },
1877 .probe = wm8753_spi_probe, 1827 .probe = wm8753_spi_probe,
1878 .remove = __devexit_p(wm8753_spi_remove), 1828 .remove = __devexit_p(wm8753_spi_remove),
1879 .suspend = wm8753_spi_suspend,
1880 .resume = wm8753_spi_resume,
1881}; 1829};
1882#endif 1830#endif
1883 1831
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index a9829aa26e53..60b1b3e1094b 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -20,6 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -406,6 +407,8 @@ static int wm8776_resume(struct platform_device *pdev)
406 407
407 /* Sync reg_cache with the hardware */ 408 /* Sync reg_cache with the hardware */
408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) { 409 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
410 if (cache[i] == wm8776_reg[i])
411 continue;
409 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 412 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
410 data[1] = cache[i] & 0x00ff; 413 data[1] = cache[i] & 0x00ff;
411 codec->hw_write(codec->control_data, data, 2); 414 codec->hw_write(codec->control_data, data, 2);
@@ -447,17 +450,8 @@ static int wm8776_probe(struct platform_device *pdev)
447 ARRAY_SIZE(wm8776_dapm_widgets)); 450 ARRAY_SIZE(wm8776_dapm_widgets));
448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 451 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
449 452
450 ret = snd_soc_init_card(socdev);
451 if (ret < 0) {
452 dev_err(codec->dev, "failed to register card: %d\n", ret);
453 goto card_err;
454 }
455
456 return ret; 453 return ret;
457 454
458card_err:
459 snd_soc_free_pcms(socdev);
460 snd_soc_dapm_free(socdev);
461pcm_err: 455pcm_err:
462 return ret; 456 return ret;
463} 457}
@@ -616,21 +610,6 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi)
616 return 0; 610 return 0;
617} 611}
618 612
619#ifdef CONFIG_PM
620static int wm8776_spi_suspend(struct spi_device *spi, pm_message_t msg)
621{
622 return snd_soc_suspend_device(&spi->dev);
623}
624
625static int wm8776_spi_resume(struct spi_device *spi)
626{
627 return snd_soc_resume_device(&spi->dev);
628}
629#else
630#define wm8776_spi_suspend NULL
631#define wm8776_spi_resume NULL
632#endif
633
634static struct spi_driver wm8776_spi_driver = { 613static struct spi_driver wm8776_spi_driver = {
635 .driver = { 614 .driver = {
636 .name = "wm8776", 615 .name = "wm8776",
@@ -638,8 +617,6 @@ static struct spi_driver wm8776_spi_driver = {
638 .owner = THIS_MODULE, 617 .owner = THIS_MODULE,
639 }, 618 },
640 .probe = wm8776_spi_probe, 619 .probe = wm8776_spi_probe,
641 .suspend = wm8776_spi_suspend,
642 .resume = wm8776_spi_resume,
643 .remove = __devexit_p(wm8776_spi_remove), 620 .remove = __devexit_p(wm8776_spi_remove),
644}; 621};
645#endif /* CONFIG_SPI_MASTER */ 622#endif /* CONFIG_SPI_MASTER */
@@ -673,21 +650,6 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client)
673 return 0; 650 return 0;
674} 651}
675 652
676#ifdef CONFIG_PM
677static int wm8776_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
678{
679 return snd_soc_suspend_device(&i2c->dev);
680}
681
682static int wm8776_i2c_resume(struct i2c_client *i2c)
683{
684 return snd_soc_resume_device(&i2c->dev);
685}
686#else
687#define wm8776_i2c_suspend NULL
688#define wm8776_i2c_resume NULL
689#endif
690
691static const struct i2c_device_id wm8776_i2c_id[] = { 653static const struct i2c_device_id wm8776_i2c_id[] = {
692 { "wm8776", 0 }, 654 { "wm8776", 0 },
693 { } 655 { }
@@ -701,8 +663,6 @@ static struct i2c_driver wm8776_i2c_driver = {
701 }, 663 },
702 .probe = wm8776_i2c_probe, 664 .probe = wm8776_i2c_probe,
703 .remove = __devexit_p(wm8776_i2c_remove), 665 .remove = __devexit_p(wm8776_i2c_remove),
704 .suspend = wm8776_i2c_suspend,
705 .resume = wm8776_i2c_resume,
706 .id_table = wm8776_i2c_id, 666 .id_table = wm8776_i2c_id,
707}; 667};
708#endif 668#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5e9c855c0036..b7fd96adac64 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -24,6 +24,7 @@
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/slab.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/pcm.h> 29#include <sound/pcm.h>
29#include <sound/pcm_params.h> 30#include <sound/pcm_params.h>
@@ -199,7 +200,7 @@ static void wm8900_reset(struct snd_soc_codec *codec)
199 snd_soc_write(codec, WM8900_REG_RESET, 0); 200 snd_soc_write(codec, WM8900_REG_RESET, 0);
200 201
201 memcpy(codec->reg_cache, wm8900_reg_defaults, 202 memcpy(codec->reg_cache, wm8900_reg_defaults,
202 sizeof(codec->reg_cache)); 203 sizeof(wm8900_reg_defaults));
203} 204}
204 205
205static int wm8900_hp_event(struct snd_soc_dapm_widget *w, 206static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
@@ -618,8 +619,6 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
618 619
619 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 620 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
620 621
621 snd_soc_dapm_new_widgets(codec);
622
623 return 0; 622 return 0;
624} 623}
625 624
@@ -814,8 +813,8 @@ reenable:
814 return 0; 813 return 0;
815} 814}
816 815
817static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, 816static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
818 int pll_id, unsigned int freq_in, unsigned int freq_out) 817 int source, unsigned int freq_in, unsigned int freq_out)
819{ 818{
820 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out); 819 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
821} 820}
@@ -1312,21 +1311,6 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1312 return 0; 1311 return 0;
1313} 1312}
1314 1313
1315#ifdef CONFIG_PM
1316static int wm8900_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1317{
1318 return snd_soc_suspend_device(&client->dev);
1319}
1320
1321static int wm8900_i2c_resume(struct i2c_client *client)
1322{
1323 return snd_soc_resume_device(&client->dev);
1324}
1325#else
1326#define wm8900_i2c_suspend NULL
1327#define wm8900_i2c_resume NULL
1328#endif
1329
1330static const struct i2c_device_id wm8900_i2c_id[] = { 1314static const struct i2c_device_id wm8900_i2c_id[] = {
1331 { "wm8900", 0 }, 1315 { "wm8900", 0 },
1332 { } 1316 { }
@@ -1340,8 +1324,6 @@ static struct i2c_driver wm8900_i2c_driver = {
1340 }, 1324 },
1341 .probe = wm8900_i2c_probe, 1325 .probe = wm8900_i2c_probe,
1342 .remove = __devexit_p(wm8900_i2c_remove), 1326 .remove = __devexit_p(wm8900_i2c_remove),
1343 .suspend = wm8900_i2c_suspend,
1344 .resume = wm8900_i2c_resume,
1345 .id_table = wm8900_i2c_id, 1327 .id_table = wm8900_i2c_id,
1346}; 1328};
1347 1329
@@ -1370,17 +1352,6 @@ static int wm8900_probe(struct platform_device *pdev)
1370 ARRAY_SIZE(wm8900_snd_controls)); 1352 ARRAY_SIZE(wm8900_snd_controls));
1371 wm8900_add_widgets(codec); 1353 wm8900_add_widgets(codec);
1372 1354
1373 ret = snd_soc_init_card(socdev);
1374 if (ret < 0) {
1375 dev_err(&pdev->dev, "Failed to register card\n");
1376 goto card_err;
1377 }
1378
1379 return ret;
1380
1381card_err:
1382 snd_soc_free_pcms(socdev);
1383 snd_soc_dapm_free(socdev);
1384pcm_err: 1355pcm_err:
1385 return ret; 1356 return ret;
1386} 1357}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fe1307b500cf..fa5f99fde68b 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -23,6 +23,7 @@
23#include <linux/pm.h> 23#include <linux/pm.h>
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/slab.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
28#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
@@ -607,7 +608,7 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
607SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), 608SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
608SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), 609SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
609SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), 610SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
610SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1, 611SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1,
611 drc_tlv_thresh), 612 drc_tlv_thresh),
612SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp), 613SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
613SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min), 614SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
@@ -617,11 +618,11 @@ SOC_ENUM("DRC Decay Rate", drc_decay),
617SOC_ENUM("DRC FF Delay", drc_ff_delay), 618SOC_ENUM("DRC FF Delay", drc_ff_delay),
618SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0), 619SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
619SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0), 620SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
620SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max), 621SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
621SOC_ENUM("DRC QR Decay Rate", drc_qr_decay), 622SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
622SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0), 623SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
623SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0), 624SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
624SOC_ENUM("DRC Smoothing Threashold", drc_smoothing), 625SOC_ENUM("DRC Smoothing Threshold", drc_smoothing),
625SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), 626SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
626 627
627SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, 628SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
@@ -919,8 +920,6 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
919 920
920 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 921 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
921 922
922 snd_soc_dapm_new_widgets(codec);
923
924 return 0; 923 return 0;
925} 924}
926 925
@@ -1506,7 +1505,7 @@ static int wm8903_resume(struct platform_device *pdev)
1506 struct i2c_client *i2c = codec->control_data; 1505 struct i2c_client *i2c = codec->control_data;
1507 int i; 1506 int i;
1508 u16 *reg_cache = codec->reg_cache; 1507 u16 *reg_cache = codec->reg_cache;
1509 u16 *tmp_cache = kmemdup(codec->reg_cache, sizeof(wm8903_reg_defaults), 1508 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
1510 GFP_KERNEL); 1509 GFP_KERNEL);
1511 1510
1512 /* Bring the codec back up to standby first to minimise pop/clicks */ 1511 /* Bring the codec back up to standby first to minimise pop/clicks */
@@ -1518,6 +1517,7 @@ static int wm8903_resume(struct platform_device *pdev)
1518 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++) 1517 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
1519 if (tmp_cache[i] != reg_cache[i]) 1518 if (tmp_cache[i] != reg_cache[i])
1520 snd_soc_write(codec, i, tmp_cache[i]); 1519 snd_soc_write(codec, i, tmp_cache[i]);
1520 kfree(tmp_cache);
1521 } else { 1521 } else {
1522 dev_err(&i2c->dev, "Failed to allocate temporary cache\n"); 1522 dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
1523 } 1523 }
@@ -1655,21 +1655,6 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1655 return 0; 1655 return 0;
1656} 1656}
1657 1657
1658#ifdef CONFIG_PM
1659static int wm8903_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1660{
1661 return snd_soc_suspend_device(&client->dev);
1662}
1663
1664static int wm8903_i2c_resume(struct i2c_client *client)
1665{
1666 return snd_soc_resume_device(&client->dev);
1667}
1668#else
1669#define wm8903_i2c_suspend NULL
1670#define wm8903_i2c_resume NULL
1671#endif
1672
1673/* i2c codec control layer */ 1658/* i2c codec control layer */
1674static const struct i2c_device_id wm8903_i2c_id[] = { 1659static const struct i2c_device_id wm8903_i2c_id[] = {
1675 { "wm8903", 0 }, 1660 { "wm8903", 0 },
@@ -1684,8 +1669,6 @@ static struct i2c_driver wm8903_i2c_driver = {
1684 }, 1669 },
1685 .probe = wm8903_i2c_probe, 1670 .probe = wm8903_i2c_probe,
1686 .remove = __devexit_p(wm8903_i2c_remove), 1671 .remove = __devexit_p(wm8903_i2c_remove),
1687 .suspend = wm8903_i2c_suspend,
1688 .resume = wm8903_i2c_resume,
1689 .id_table = wm8903_i2c_id, 1672 .id_table = wm8903_i2c_id,
1690}; 1673};
1691 1674
@@ -1712,17 +1695,8 @@ static int wm8903_probe(struct platform_device *pdev)
1712 ARRAY_SIZE(wm8903_snd_controls)); 1695 ARRAY_SIZE(wm8903_snd_controls));
1713 wm8903_add_widgets(socdev->card->codec); 1696 wm8903_add_widgets(socdev->card->codec);
1714 1697
1715 ret = snd_soc_init_card(socdev);
1716 if (ret < 0) {
1717 dev_err(&pdev->dev, "wm8903: failed to register card\n");
1718 goto card_err;
1719 }
1720
1721 return ret; 1698 return ret;
1722 1699
1723card_err:
1724 snd_soc_free_pcms(socdev);
1725 snd_soc_dapm_free(socdev);
1726err: 1700err:
1727 return ret; 1701 return ret;
1728} 1702}
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
new file mode 100644
index 000000000000..c6f0abcc5711
--- /dev/null
+++ b/sound/soc/codecs/wm8904.c
@@ -0,0 +1,2657 @@
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 <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <sound/wm8904.h>
31
32#include "wm8904.h"
33
34static struct snd_soc_codec *wm8904_codec;
35struct snd_soc_codec_device soc_codec_dev_wm8904;
36
37enum wm8904_type {
38 WM8904,
39 WM8912,
40};
41
42#define WM8904_NUM_DCS_CHANNELS 4
43
44#define WM8904_NUM_SUPPLIES 5
45static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
46 "DCVDD",
47 "DBVDD",
48 "AVDD",
49 "CPVDD",
50 "MICVDD",
51};
52
53/* codec private data */
54struct wm8904_priv {
55 struct snd_soc_codec codec;
56 u16 reg_cache[WM8904_MAX_REGISTER + 1];
57
58 enum wm8904_type devtype;
59
60 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
61
62 struct wm8904_pdata *pdata;
63
64 int deemph;
65
66 /* Platform provided DRC configuration */
67 const char **drc_texts;
68 int drc_cfg;
69 struct soc_enum drc_enum;
70
71 /* Platform provided ReTune mobile configuration */
72 int num_retune_mobile_texts;
73 const char **retune_mobile_texts;
74 int retune_mobile_cfg;
75 struct soc_enum retune_mobile_enum;
76
77 /* FLL setup */
78 int fll_src;
79 int fll_fref;
80 int fll_fout;
81
82 /* Clocking configuration */
83 unsigned int mclk_rate;
84 int sysclk_src;
85 unsigned int sysclk_rate;
86
87 int tdm_width;
88 int tdm_slots;
89 int bclk;
90 int fs;
91
92 /* DC servo configuration - cached offset values */
93 int dcs_state[WM8904_NUM_DCS_CHANNELS];
94};
95
96static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = {
97 0x8904, /* R0 - SW Reset and ID */
98 0x0000, /* R1 - Revision */
99 0x0000, /* R2 */
100 0x0000, /* R3 */
101 0x0018, /* R4 - Bias Control 0 */
102 0x0000, /* R5 - VMID Control 0 */
103 0x0000, /* R6 - Mic Bias Control 0 */
104 0x0000, /* R7 - Mic Bias Control 1 */
105 0x0001, /* R8 - Analogue DAC 0 */
106 0x9696, /* R9 - mic Filter Control */
107 0x0001, /* R10 - Analogue ADC 0 */
108 0x0000, /* R11 */
109 0x0000, /* R12 - Power Management 0 */
110 0x0000, /* R13 */
111 0x0000, /* R14 - Power Management 2 */
112 0x0000, /* R15 - Power Management 3 */
113 0x0000, /* R16 */
114 0x0000, /* R17 */
115 0x0000, /* R18 - Power Management 6 */
116 0x0000, /* R19 */
117 0x945E, /* R20 - Clock Rates 0 */
118 0x0C05, /* R21 - Clock Rates 1 */
119 0x0006, /* R22 - Clock Rates 2 */
120 0x0000, /* R23 */
121 0x0050, /* R24 - Audio Interface 0 */
122 0x000A, /* R25 - Audio Interface 1 */
123 0x00E4, /* R26 - Audio Interface 2 */
124 0x0040, /* R27 - Audio Interface 3 */
125 0x0000, /* R28 */
126 0x0000, /* R29 */
127 0x00C0, /* R30 - DAC Digital Volume Left */
128 0x00C0, /* R31 - DAC Digital Volume Right */
129 0x0000, /* R32 - DAC Digital 0 */
130 0x0008, /* R33 - DAC Digital 1 */
131 0x0000, /* R34 */
132 0x0000, /* R35 */
133 0x00C0, /* R36 - ADC Digital Volume Left */
134 0x00C0, /* R37 - ADC Digital Volume Right */
135 0x0010, /* R38 - ADC Digital 0 */
136 0x0000, /* R39 - Digital Microphone 0 */
137 0x01AF, /* R40 - DRC 0 */
138 0x3248, /* R41 - DRC 1 */
139 0x0000, /* R42 - DRC 2 */
140 0x0000, /* R43 - DRC 3 */
141 0x0085, /* R44 - Analogue Left Input 0 */
142 0x0085, /* R45 - Analogue Right Input 0 */
143 0x0044, /* R46 - Analogue Left Input 1 */
144 0x0044, /* R47 - Analogue Right Input 1 */
145 0x0000, /* R48 */
146 0x0000, /* R49 */
147 0x0000, /* R50 */
148 0x0000, /* R51 */
149 0x0000, /* R52 */
150 0x0000, /* R53 */
151 0x0000, /* R54 */
152 0x0000, /* R55 */
153 0x0000, /* R56 */
154 0x002D, /* R57 - Analogue OUT1 Left */
155 0x002D, /* R58 - Analogue OUT1 Right */
156 0x0039, /* R59 - Analogue OUT2 Left */
157 0x0039, /* R60 - Analogue OUT2 Right */
158 0x0000, /* R61 - Analogue OUT12 ZC */
159 0x0000, /* R62 */
160 0x0000, /* R63 */
161 0x0000, /* R64 */
162 0x0000, /* R65 */
163 0x0000, /* R66 */
164 0x0000, /* R67 - DC Servo 0 */
165 0x0000, /* R68 - DC Servo 1 */
166 0xAAAA, /* R69 - DC Servo 2 */
167 0x0000, /* R70 */
168 0xAAAA, /* R71 - DC Servo 4 */
169 0xAAAA, /* R72 - DC Servo 5 */
170 0x0000, /* R73 - DC Servo 6 */
171 0x0000, /* R74 - DC Servo 7 */
172 0x0000, /* R75 - DC Servo 8 */
173 0x0000, /* R76 - DC Servo 9 */
174 0x0000, /* R77 - DC Servo Readback 0 */
175 0x0000, /* R78 */
176 0x0000, /* R79 */
177 0x0000, /* R80 */
178 0x0000, /* R81 */
179 0x0000, /* R82 */
180 0x0000, /* R83 */
181 0x0000, /* R84 */
182 0x0000, /* R85 */
183 0x0000, /* R86 */
184 0x0000, /* R87 */
185 0x0000, /* R88 */
186 0x0000, /* R89 */
187 0x0000, /* R90 - Analogue HP 0 */
188 0x0000, /* R91 */
189 0x0000, /* R92 */
190 0x0000, /* R93 */
191 0x0000, /* R94 - Analogue Lineout 0 */
192 0x0000, /* R95 */
193 0x0000, /* R96 */
194 0x0000, /* R97 */
195 0x0000, /* R98 - Charge Pump 0 */
196 0x0000, /* R99 */
197 0x0000, /* R100 */
198 0x0000, /* R101 */
199 0x0000, /* R102 */
200 0x0000, /* R103 */
201 0x0004, /* R104 - Class W 0 */
202 0x0000, /* R105 */
203 0x0000, /* R106 */
204 0x0000, /* R107 */
205 0x0000, /* R108 - Write Sequencer 0 */
206 0x0000, /* R109 - Write Sequencer 1 */
207 0x0000, /* R110 - Write Sequencer 2 */
208 0x0000, /* R111 - Write Sequencer 3 */
209 0x0000, /* R112 - Write Sequencer 4 */
210 0x0000, /* R113 */
211 0x0000, /* R114 */
212 0x0000, /* R115 */
213 0x0000, /* R116 - FLL Control 1 */
214 0x0007, /* R117 - FLL Control 2 */
215 0x0000, /* R118 - FLL Control 3 */
216 0x2EE0, /* R119 - FLL Control 4 */
217 0x0004, /* R120 - FLL Control 5 */
218 0x0014, /* R121 - GPIO Control 1 */
219 0x0010, /* R122 - GPIO Control 2 */
220 0x0010, /* R123 - GPIO Control 3 */
221 0x0000, /* R124 - GPIO Control 4 */
222 0x0000, /* R125 */
223 0x0000, /* R126 - Digital Pulls */
224 0x0000, /* R127 - Interrupt Status */
225 0xFFFF, /* R128 - Interrupt Status Mask */
226 0x0000, /* R129 - Interrupt Polarity */
227 0x0000, /* R130 - Interrupt Debounce */
228 0x0000, /* R131 */
229 0x0000, /* R132 */
230 0x0000, /* R133 */
231 0x0000, /* R134 - EQ1 */
232 0x000C, /* R135 - EQ2 */
233 0x000C, /* R136 - EQ3 */
234 0x000C, /* R137 - EQ4 */
235 0x000C, /* R138 - EQ5 */
236 0x000C, /* R139 - EQ6 */
237 0x0FCA, /* R140 - EQ7 */
238 0x0400, /* R141 - EQ8 */
239 0x00D8, /* R142 - EQ9 */
240 0x1EB5, /* R143 - EQ10 */
241 0xF145, /* R144 - EQ11 */
242 0x0B75, /* R145 - EQ12 */
243 0x01C5, /* R146 - EQ13 */
244 0x1C58, /* R147 - EQ14 */
245 0xF373, /* R148 - EQ15 */
246 0x0A54, /* R149 - EQ16 */
247 0x0558, /* R150 - EQ17 */
248 0x168E, /* R151 - EQ18 */
249 0xF829, /* R152 - EQ19 */
250 0x07AD, /* R153 - EQ20 */
251 0x1103, /* R154 - EQ21 */
252 0x0564, /* R155 - EQ22 */
253 0x0559, /* R156 - EQ23 */
254 0x4000, /* R157 - EQ24 */
255 0x0000, /* R158 */
256 0x0000, /* R159 */
257 0x0000, /* R160 */
258 0x0000, /* R161 - Control Interface Test 1 */
259 0x0000, /* R162 */
260 0x0000, /* R163 */
261 0x0000, /* R164 */
262 0x0000, /* R165 */
263 0x0000, /* R166 */
264 0x0000, /* R167 */
265 0x0000, /* R168 */
266 0x0000, /* R169 */
267 0x0000, /* R170 */
268 0x0000, /* R171 */
269 0x0000, /* R172 */
270 0x0000, /* R173 */
271 0x0000, /* R174 */
272 0x0000, /* R175 */
273 0x0000, /* R176 */
274 0x0000, /* R177 */
275 0x0000, /* R178 */
276 0x0000, /* R179 */
277 0x0000, /* R180 */
278 0x0000, /* R181 */
279 0x0000, /* R182 */
280 0x0000, /* R183 */
281 0x0000, /* R184 */
282 0x0000, /* R185 */
283 0x0000, /* R186 */
284 0x0000, /* R187 */
285 0x0000, /* R188 */
286 0x0000, /* R189 */
287 0x0000, /* R190 */
288 0x0000, /* R191 */
289 0x0000, /* R192 */
290 0x0000, /* R193 */
291 0x0000, /* R194 */
292 0x0000, /* R195 */
293 0x0000, /* R196 */
294 0x0000, /* R197 */
295 0x0000, /* R198 */
296 0x0000, /* R199 */
297 0x0000, /* R200 */
298 0x0000, /* R201 */
299 0x0000, /* R202 */
300 0x0000, /* R203 */
301 0x0000, /* R204 - Analogue Output Bias 0 */
302 0x0000, /* R205 */
303 0x0000, /* R206 */
304 0x0000, /* R207 */
305 0x0000, /* R208 */
306 0x0000, /* R209 */
307 0x0000, /* R210 */
308 0x0000, /* R211 */
309 0x0000, /* R212 */
310 0x0000, /* R213 */
311 0x0000, /* R214 */
312 0x0000, /* R215 */
313 0x0000, /* R216 */
314 0x0000, /* R217 */
315 0x0000, /* R218 */
316 0x0000, /* R219 */
317 0x0000, /* R220 */
318 0x0000, /* R221 */
319 0x0000, /* R222 */
320 0x0000, /* R223 */
321 0x0000, /* R224 */
322 0x0000, /* R225 */
323 0x0000, /* R226 */
324 0x0000, /* R227 */
325 0x0000, /* R228 */
326 0x0000, /* R229 */
327 0x0000, /* R230 */
328 0x0000, /* R231 */
329 0x0000, /* R232 */
330 0x0000, /* R233 */
331 0x0000, /* R234 */
332 0x0000, /* R235 */
333 0x0000, /* R236 */
334 0x0000, /* R237 */
335 0x0000, /* R238 */
336 0x0000, /* R239 */
337 0x0000, /* R240 */
338 0x0000, /* R241 */
339 0x0000, /* R242 */
340 0x0000, /* R243 */
341 0x0000, /* R244 */
342 0x0000, /* R245 */
343 0x0000, /* R246 */
344 0x0000, /* R247 - FLL NCO Test 0 */
345 0x0019, /* R248 - FLL NCO Test 1 */
346};
347
348static struct {
349 int readable;
350 int writable;
351 int vol;
352} wm8904_access[] = {
353 { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */
354 { 0x0000, 0x0000, 0 }, /* R1 - Revision */
355 { 0x0000, 0x0000, 0 }, /* R2 */
356 { 0x0000, 0x0000, 0 }, /* R3 */
357 { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */
358 { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */
359 { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */
360 { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */
361 { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */
362 { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */
363 { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */
364 { 0x0000, 0x0000, 0 }, /* R11 */
365 { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */
366 { 0x0000, 0x0000, 0 }, /* R13 */
367 { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */
368 { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */
369 { 0x0000, 0x0000, 0 }, /* R16 */
370 { 0x0000, 0x0000, 0 }, /* R17 */
371 { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */
372 { 0x0000, 0x0000, 0 }, /* R19 */
373 { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */
374 { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */
375 { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */
376 { 0x0000, 0x0000, 0 }, /* R23 */
377 { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */
378 { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */
379 { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */
380 { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */
381 { 0x0000, 0x0000, 0 }, /* R28 */
382 { 0x0000, 0x0000, 0 }, /* R29 */
383 { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */
384 { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */
385 { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */
386 { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */
387 { 0x0000, 0x0000, 0 }, /* R34 */
388 { 0x0000, 0x0000, 0 }, /* R35 */
389 { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */
390 { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */
391 { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */
392 { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */
393 { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */
394 { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */
395 { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */
396 { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */
397 { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */
398 { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */
399 { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */
400 { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */
401 { 0x0000, 0x0000, 0 }, /* R48 */
402 { 0x0000, 0x0000, 0 }, /* R49 */
403 { 0x0000, 0x0000, 0 }, /* R50 */
404 { 0x0000, 0x0000, 0 }, /* R51 */
405 { 0x0000, 0x0000, 0 }, /* R52 */
406 { 0x0000, 0x0000, 0 }, /* R53 */
407 { 0x0000, 0x0000, 0 }, /* R54 */
408 { 0x0000, 0x0000, 0 }, /* R55 */
409 { 0x0000, 0x0000, 0 }, /* R56 */
410 { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */
411 { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */
412 { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */
413 { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */
414 { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */
415 { 0x0000, 0x0000, 0 }, /* R62 */
416 { 0x0000, 0x0000, 0 }, /* R63 */
417 { 0x0000, 0x0000, 0 }, /* R64 */
418 { 0x0000, 0x0000, 0 }, /* R65 */
419 { 0x0000, 0x0000, 0 }, /* R66 */
420 { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */
421 { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */
422 { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */
423 { 0x0000, 0x0000, 0 }, /* R70 */
424 { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */
425 { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */
426 { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */
427 { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */
428 { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */
429 { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */
430 { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */
431 { 0x0000, 0x0000, 0 }, /* R78 */
432 { 0x0000, 0x0000, 0 }, /* R79 */
433 { 0x0000, 0x0000, 0 }, /* R80 */
434 { 0x0000, 0x0000, 0 }, /* R81 */
435 { 0x0000, 0x0000, 0 }, /* R82 */
436 { 0x0000, 0x0000, 0 }, /* R83 */
437 { 0x0000, 0x0000, 0 }, /* R84 */
438 { 0x0000, 0x0000, 0 }, /* R85 */
439 { 0x0000, 0x0000, 0 }, /* R86 */
440 { 0x0000, 0x0000, 0 }, /* R87 */
441 { 0x0000, 0x0000, 0 }, /* R88 */
442 { 0x0000, 0x0000, 0 }, /* R89 */
443 { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */
444 { 0x0000, 0x0000, 0 }, /* R91 */
445 { 0x0000, 0x0000, 0 }, /* R92 */
446 { 0x0000, 0x0000, 0 }, /* R93 */
447 { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */
448 { 0x0000, 0x0000, 0 }, /* R95 */
449 { 0x0000, 0x0000, 0 }, /* R96 */
450 { 0x0000, 0x0000, 0 }, /* R97 */
451 { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */
452 { 0x0000, 0x0000, 0 }, /* R99 */
453 { 0x0000, 0x0000, 0 }, /* R100 */
454 { 0x0000, 0x0000, 0 }, /* R101 */
455 { 0x0000, 0x0000, 0 }, /* R102 */
456 { 0x0000, 0x0000, 0 }, /* R103 */
457 { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
458 { 0x0000, 0x0000, 0 }, /* R105 */
459 { 0x0000, 0x0000, 0 }, /* R106 */
460 { 0x0000, 0x0000, 0 }, /* R107 */
461 { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
462 { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
463 { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
464 { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
465 { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
466 { 0x0000, 0x0000, 0 }, /* R113 */
467 { 0x0000, 0x0000, 0 }, /* R114 */
468 { 0x0000, 0x0000, 0 }, /* R115 */
469 { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
470 { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
471 { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
472 { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
473 { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
474 { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
475 { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
476 { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
477 { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
478 { 0x0000, 0x0000, 0 }, /* R125 */
479 { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
480 { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
481 { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
482 { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
483 { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
484 { 0x0000, 0x0000, 0 }, /* R131 */
485 { 0x0000, 0x0000, 0 }, /* R132 */
486 { 0x0000, 0x0000, 0 }, /* R133 */
487 { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
488 { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
489 { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
490 { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
491 { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
492 { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
493 { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
494 { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
495 { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
496 { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
497 { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
498 { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
499 { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
500 { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
501 { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
502 { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
503 { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
504 { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
505 { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
506 { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
507 { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
508 { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
509 { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
510 { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
511 { 0x0000, 0x0000, 0 }, /* R158 */
512 { 0x0000, 0x0000, 0 }, /* R159 */
513 { 0x0000, 0x0000, 0 }, /* R160 */
514 { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
515 { 0x0000, 0x0000, 0 }, /* R162 */
516 { 0x0000, 0x0000, 0 }, /* R163 */
517 { 0x0000, 0x0000, 0 }, /* R164 */
518 { 0x0000, 0x0000, 0 }, /* R165 */
519 { 0x0000, 0x0000, 0 }, /* R166 */
520 { 0x0000, 0x0000, 0 }, /* R167 */
521 { 0x0000, 0x0000, 0 }, /* R168 */
522 { 0x0000, 0x0000, 0 }, /* R169 */
523 { 0x0000, 0x0000, 0 }, /* R170 */
524 { 0x0000, 0x0000, 0 }, /* R171 */
525 { 0x0000, 0x0000, 0 }, /* R172 */
526 { 0x0000, 0x0000, 0 }, /* R173 */
527 { 0x0000, 0x0000, 0 }, /* R174 */
528 { 0x0000, 0x0000, 0 }, /* R175 */
529 { 0x0000, 0x0000, 0 }, /* R176 */
530 { 0x0000, 0x0000, 0 }, /* R177 */
531 { 0x0000, 0x0000, 0 }, /* R178 */
532 { 0x0000, 0x0000, 0 }, /* R179 */
533 { 0x0000, 0x0000, 0 }, /* R180 */
534 { 0x0000, 0x0000, 0 }, /* R181 */
535 { 0x0000, 0x0000, 0 }, /* R182 */
536 { 0x0000, 0x0000, 0 }, /* R183 */
537 { 0x0000, 0x0000, 0 }, /* R184 */
538 { 0x0000, 0x0000, 0 }, /* R185 */
539 { 0x0000, 0x0000, 0 }, /* R186 */
540 { 0x0000, 0x0000, 0 }, /* R187 */
541 { 0x0000, 0x0000, 0 }, /* R188 */
542 { 0x0000, 0x0000, 0 }, /* R189 */
543 { 0x0000, 0x0000, 0 }, /* R190 */
544 { 0x0000, 0x0000, 0 }, /* R191 */
545 { 0x0000, 0x0000, 0 }, /* R192 */
546 { 0x0000, 0x0000, 0 }, /* R193 */
547 { 0x0000, 0x0000, 0 }, /* R194 */
548 { 0x0000, 0x0000, 0 }, /* R195 */
549 { 0x0000, 0x0000, 0 }, /* R196 */
550 { 0x0000, 0x0000, 0 }, /* R197 */
551 { 0x0000, 0x0000, 0 }, /* R198 */
552 { 0x0000, 0x0000, 0 }, /* R199 */
553 { 0x0000, 0x0000, 0 }, /* R200 */
554 { 0x0000, 0x0000, 0 }, /* R201 */
555 { 0x0000, 0x0000, 0 }, /* R202 */
556 { 0x0000, 0x0000, 0 }, /* R203 */
557 { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
558 { 0x0000, 0x0000, 0 }, /* R205 */
559 { 0x0000, 0x0000, 0 }, /* R206 */
560 { 0x0000, 0x0000, 0 }, /* R207 */
561 { 0x0000, 0x0000, 0 }, /* R208 */
562 { 0x0000, 0x0000, 0 }, /* R209 */
563 { 0x0000, 0x0000, 0 }, /* R210 */
564 { 0x0000, 0x0000, 0 }, /* R211 */
565 { 0x0000, 0x0000, 0 }, /* R212 */
566 { 0x0000, 0x0000, 0 }, /* R213 */
567 { 0x0000, 0x0000, 0 }, /* R214 */
568 { 0x0000, 0x0000, 0 }, /* R215 */
569 { 0x0000, 0x0000, 0 }, /* R216 */
570 { 0x0000, 0x0000, 0 }, /* R217 */
571 { 0x0000, 0x0000, 0 }, /* R218 */
572 { 0x0000, 0x0000, 0 }, /* R219 */
573 { 0x0000, 0x0000, 0 }, /* R220 */
574 { 0x0000, 0x0000, 0 }, /* R221 */
575 { 0x0000, 0x0000, 0 }, /* R222 */
576 { 0x0000, 0x0000, 0 }, /* R223 */
577 { 0x0000, 0x0000, 0 }, /* R224 */
578 { 0x0000, 0x0000, 0 }, /* R225 */
579 { 0x0000, 0x0000, 0 }, /* R226 */
580 { 0x0000, 0x0000, 0 }, /* R227 */
581 { 0x0000, 0x0000, 0 }, /* R228 */
582 { 0x0000, 0x0000, 0 }, /* R229 */
583 { 0x0000, 0x0000, 0 }, /* R230 */
584 { 0x0000, 0x0000, 0 }, /* R231 */
585 { 0x0000, 0x0000, 0 }, /* R232 */
586 { 0x0000, 0x0000, 0 }, /* R233 */
587 { 0x0000, 0x0000, 0 }, /* R234 */
588 { 0x0000, 0x0000, 0 }, /* R235 */
589 { 0x0000, 0x0000, 0 }, /* R236 */
590 { 0x0000, 0x0000, 0 }, /* R237 */
591 { 0x0000, 0x0000, 0 }, /* R238 */
592 { 0x0000, 0x0000, 0 }, /* R239 */
593 { 0x0000, 0x0000, 0 }, /* R240 */
594 { 0x0000, 0x0000, 0 }, /* R241 */
595 { 0x0000, 0x0000, 0 }, /* R242 */
596 { 0x0000, 0x0000, 0 }, /* R243 */
597 { 0x0000, 0x0000, 0 }, /* R244 */
598 { 0x0000, 0x0000, 0 }, /* R245 */
599 { 0x0000, 0x0000, 0 }, /* R246 */
600 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
601 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
602};
603
604static int wm8904_volatile_register(unsigned int reg)
605{
606 return wm8904_access[reg].vol;
607}
608
609static int wm8904_reset(struct snd_soc_codec *codec)
610{
611 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
612}
613
614static int wm8904_configure_clocking(struct snd_soc_codec *codec)
615{
616 struct wm8904_priv *wm8904 = codec->private_data;
617 unsigned int clock0, clock2, rate;
618
619 /* Gate the clock while we're updating to avoid misclocking */
620 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
621 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
622 WM8904_SYSCLK_SRC, 0);
623
624 /* This should be done on init() for bypass paths */
625 switch (wm8904->sysclk_src) {
626 case WM8904_CLK_MCLK:
627 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
628
629 clock2 &= ~WM8904_SYSCLK_SRC;
630 rate = wm8904->mclk_rate;
631
632 /* Ensure the FLL is stopped */
633 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
634 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
635 break;
636
637 case WM8904_CLK_FLL:
638 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
639 wm8904->fll_fout);
640
641 clock2 |= WM8904_SYSCLK_SRC;
642 rate = wm8904->fll_fout;
643 break;
644
645 default:
646 dev_err(codec->dev, "System clock not configured\n");
647 return -EINVAL;
648 }
649
650 /* SYSCLK shouldn't be over 13.5MHz */
651 if (rate > 13500000) {
652 clock0 = WM8904_MCLK_DIV;
653 wm8904->sysclk_rate = rate / 2;
654 } else {
655 clock0 = 0;
656 wm8904->sysclk_rate = rate;
657 }
658
659 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
660 clock0);
661
662 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
663 WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2);
664
665 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
666
667 return 0;
668}
669
670static void wm8904_set_drc(struct snd_soc_codec *codec)
671{
672 struct wm8904_priv *wm8904 = codec->private_data;
673 struct wm8904_pdata *pdata = wm8904->pdata;
674 int save, i;
675
676 /* Save any enables; the configuration should clear them. */
677 save = snd_soc_read(codec, WM8904_DRC_0);
678
679 for (i = 0; i < WM8904_DRC_REGS; i++)
680 snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff,
681 pdata->drc_cfgs[wm8904->drc_cfg].regs[i]);
682
683 /* Reenable the DRC */
684 snd_soc_update_bits(codec, WM8904_DRC_0,
685 WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save);
686}
687
688static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol)
690{
691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
692 struct wm8904_priv *wm8904 = codec->private_data;
693 struct wm8904_pdata *pdata = wm8904->pdata;
694 int value = ucontrol->value.integer.value[0];
695
696 if (value >= pdata->num_drc_cfgs)
697 return -EINVAL;
698
699 wm8904->drc_cfg = value;
700
701 wm8904_set_drc(codec);
702
703 return 0;
704}
705
706static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
707 struct snd_ctl_elem_value *ucontrol)
708{
709 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
710 struct wm8904_priv *wm8904 = codec->private_data;
711
712 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
713
714 return 0;
715}
716
717static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
718{
719 struct wm8904_priv *wm8904 = codec->private_data;
720 struct wm8904_pdata *pdata = wm8904->pdata;
721 int best, best_val, save, i, cfg;
722
723 if (!pdata || !wm8904->num_retune_mobile_texts)
724 return;
725
726 /* Find the version of the currently selected configuration
727 * with the nearest sample rate. */
728 cfg = wm8904->retune_mobile_cfg;
729 best = 0;
730 best_val = INT_MAX;
731 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
732 if (strcmp(pdata->retune_mobile_cfgs[i].name,
733 wm8904->retune_mobile_texts[cfg]) == 0 &&
734 abs(pdata->retune_mobile_cfgs[i].rate
735 - wm8904->fs) < best_val) {
736 best = i;
737 best_val = abs(pdata->retune_mobile_cfgs[i].rate
738 - wm8904->fs);
739 }
740 }
741
742 dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
743 pdata->retune_mobile_cfgs[best].name,
744 pdata->retune_mobile_cfgs[best].rate,
745 wm8904->fs);
746
747 /* The EQ will be disabled while reconfiguring it, remember the
748 * current configuration.
749 */
750 save = snd_soc_read(codec, WM8904_EQ1);
751
752 for (i = 0; i < WM8904_EQ_REGS; i++)
753 snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff,
754 pdata->retune_mobile_cfgs[best].regs[i]);
755
756 snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save);
757}
758
759static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
760 struct snd_ctl_elem_value *ucontrol)
761{
762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
763 struct wm8904_priv *wm8904 = codec->private_data;
764 struct wm8904_pdata *pdata = wm8904->pdata;
765 int value = ucontrol->value.integer.value[0];
766
767 if (value >= pdata->num_retune_mobile_cfgs)
768 return -EINVAL;
769
770 wm8904->retune_mobile_cfg = value;
771
772 wm8904_set_retune_mobile(codec);
773
774 return 0;
775}
776
777static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
778 struct snd_ctl_elem_value *ucontrol)
779{
780 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
781 struct wm8904_priv *wm8904 = codec->private_data;
782
783 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
784
785 return 0;
786}
787
788static int deemph_settings[] = { 0, 32000, 44100, 48000 };
789
790static int wm8904_set_deemph(struct snd_soc_codec *codec)
791{
792 struct wm8904_priv *wm8904 = codec->private_data;
793 int val, i, best;
794
795 /* If we're using deemphasis select the nearest available sample
796 * rate.
797 */
798 if (wm8904->deemph) {
799 best = 1;
800 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
801 if (abs(deemph_settings[i] - wm8904->fs) <
802 abs(deemph_settings[best] - wm8904->fs))
803 best = i;
804 }
805
806 val = best << WM8904_DEEMPH_SHIFT;
807 } else {
808 val = 0;
809 }
810
811 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
812
813 return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
814 WM8904_DEEMPH_MASK, val);
815}
816
817static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
818 struct snd_ctl_elem_value *ucontrol)
819{
820 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
821 struct wm8904_priv *wm8904 = codec->private_data;
822
823 return wm8904->deemph;
824}
825
826static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol)
828{
829 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
830 struct wm8904_priv *wm8904 = codec->private_data;
831 int deemph = ucontrol->value.enumerated.item[0];
832
833 if (deemph > 1)
834 return -EINVAL;
835
836 wm8904->deemph = deemph;
837
838 return wm8904_set_deemph(codec);
839}
840
841static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
842static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
843static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
844static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
845static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
846
847static const char *input_mode_text[] = {
848 "Single-Ended", "Differential Line", "Differential Mic"
849};
850
851static const struct soc_enum lin_mode =
852 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
853
854static const struct soc_enum rin_mode =
855 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
856
857static const char *hpf_mode_text[] = {
858 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
859};
860
861static const struct soc_enum hpf_mode =
862 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
863
864static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
865SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
866 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
867
868SOC_ENUM("Left Caputure Mode", lin_mode),
869SOC_ENUM("Right Capture Mode", rin_mode),
870
871/* No TLV since it depends on mode */
872SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
873 WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
874SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
875 WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0),
876
877SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
878SOC_ENUM("High Pass Filter Mode", hpf_mode),
879
880SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0),
881};
882
883static const char *drc_path_text[] = {
884 "ADC", "DAC"
885};
886
887static const struct soc_enum drc_path =
888 SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text);
889
890static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = {
891SOC_SINGLE_TLV("Digital Playback Boost Volume",
892 WM8904_AUDIO_INTERFACE_0, 9, 3, 0, dac_boost_tlv),
893SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8904_DAC_DIGITAL_VOLUME_LEFT,
894 WM8904_DAC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
895
896SOC_DOUBLE_R_TLV("Headphone Volume", WM8904_ANALOGUE_OUT1_LEFT,
897 WM8904_ANALOGUE_OUT1_RIGHT, 0, 63, 0, out_tlv),
898SOC_DOUBLE_R("Headphone Switch", WM8904_ANALOGUE_OUT1_LEFT,
899 WM8904_ANALOGUE_OUT1_RIGHT, 8, 1, 1),
900SOC_DOUBLE_R("Headphone ZC Switch", WM8904_ANALOGUE_OUT1_LEFT,
901 WM8904_ANALOGUE_OUT1_RIGHT, 6, 1, 0),
902
903SOC_DOUBLE_R_TLV("Line Output Volume", WM8904_ANALOGUE_OUT2_LEFT,
904 WM8904_ANALOGUE_OUT2_RIGHT, 0, 63, 0, out_tlv),
905SOC_DOUBLE_R("Line Output Switch", WM8904_ANALOGUE_OUT2_LEFT,
906 WM8904_ANALOGUE_OUT2_RIGHT, 8, 1, 1),
907SOC_DOUBLE_R("Line Output ZC Switch", WM8904_ANALOGUE_OUT2_LEFT,
908 WM8904_ANALOGUE_OUT2_RIGHT, 6, 1, 0),
909
910SOC_SINGLE("EQ Switch", WM8904_EQ1, 0, 1, 0),
911SOC_SINGLE("DRC Switch", WM8904_DRC_0, 15, 1, 0),
912SOC_ENUM("DRC Path", drc_path),
913SOC_SINGLE("DAC OSRx2 Switch", WM8904_DAC_DIGITAL_1, 6, 1, 0),
914SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
915 wm8904_get_deemph, wm8904_put_deemph),
916};
917
918static const struct snd_kcontrol_new wm8904_snd_controls[] = {
919SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8904_DAC_DIGITAL_0, 4, 8, 15, 0,
920 sidetone_tlv),
921};
922
923static const struct snd_kcontrol_new wm8904_eq_controls[] = {
924SOC_SINGLE_TLV("EQ1 Volume", WM8904_EQ2, 0, 24, 0, eq_tlv),
925SOC_SINGLE_TLV("EQ2 Volume", WM8904_EQ3, 0, 24, 0, eq_tlv),
926SOC_SINGLE_TLV("EQ3 Volume", WM8904_EQ4, 0, 24, 0, eq_tlv),
927SOC_SINGLE_TLV("EQ4 Volume", WM8904_EQ5, 0, 24, 0, eq_tlv),
928SOC_SINGLE_TLV("EQ5 Volume", WM8904_EQ6, 0, 24, 0, eq_tlv),
929};
930
931static int cp_event(struct snd_soc_dapm_widget *w,
932 struct snd_kcontrol *kcontrol, int event)
933{
934 BUG_ON(event != SND_SOC_DAPM_POST_PMU);
935
936 /* Maximum startup time */
937 udelay(500);
938
939 return 0;
940}
941
942static int sysclk_event(struct snd_soc_dapm_widget *w,
943 struct snd_kcontrol *kcontrol, int event)
944{
945 struct snd_soc_codec *codec = w->codec;
946 struct wm8904_priv *wm8904 = codec->private_data;
947
948 switch (event) {
949 case SND_SOC_DAPM_PRE_PMU:
950 /* If we're using the FLL then we only start it when
951 * required; we assume that the configuration has been
952 * done previously and all we need to do is kick it
953 * off.
954 */
955 switch (wm8904->sysclk_src) {
956 case WM8904_CLK_FLL:
957 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
958 WM8904_FLL_OSC_ENA,
959 WM8904_FLL_OSC_ENA);
960
961 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
962 WM8904_FLL_ENA,
963 WM8904_FLL_ENA);
964 break;
965
966 default:
967 break;
968 }
969 break;
970
971 case SND_SOC_DAPM_POST_PMD:
972 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
973 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
974 break;
975 }
976
977 return 0;
978}
979
980static int out_pga_event(struct snd_soc_dapm_widget *w,
981 struct snd_kcontrol *kcontrol, int event)
982{
983 struct snd_soc_codec *codec = w->codec;
984 struct wm8904_priv *wm8904 = codec->private_data;
985 int reg, val;
986 int dcs_mask;
987 int dcs_l, dcs_r;
988 int dcs_l_reg, dcs_r_reg;
989 int timeout;
990 int pwr_reg;
991
992 /* This code is shared between HP and LINEOUT; we do all our
993 * power management in stereo pairs to avoid latency issues so
994 * we reuse shift to identify which rather than strcmp() the
995 * name. */
996 reg = w->shift;
997
998 switch (reg) {
999 case WM8904_ANALOGUE_HP_0:
1000 pwr_reg = WM8904_POWER_MANAGEMENT_2;
1001 dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
1002 dcs_r_reg = WM8904_DC_SERVO_8;
1003 dcs_l_reg = WM8904_DC_SERVO_9;
1004 dcs_l = 0;
1005 dcs_r = 1;
1006 break;
1007 case WM8904_ANALOGUE_LINEOUT_0:
1008 pwr_reg = WM8904_POWER_MANAGEMENT_3;
1009 dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
1010 dcs_r_reg = WM8904_DC_SERVO_6;
1011 dcs_l_reg = WM8904_DC_SERVO_7;
1012 dcs_l = 2;
1013 dcs_r = 3;
1014 break;
1015 default:
1016 BUG();
1017 return -EINVAL;
1018 }
1019
1020 switch (event) {
1021 case SND_SOC_DAPM_PRE_PMU:
1022 /* Power on the PGAs */
1023 snd_soc_update_bits(codec, pwr_reg,
1024 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1025 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA);
1026
1027 /* Power on the amplifier */
1028 snd_soc_update_bits(codec, reg,
1029 WM8904_HPL_ENA | WM8904_HPR_ENA,
1030 WM8904_HPL_ENA | WM8904_HPR_ENA);
1031
1032
1033 /* Enable the first stage */
1034 snd_soc_update_bits(codec, reg,
1035 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
1036 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);
1037
1038 /* Power up the DC servo */
1039 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1040 dcs_mask, dcs_mask);
1041
1042 /* Either calibrate the DC servo or restore cached state
1043 * if we have that.
1044 */
1045 if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
1046 dev_dbg(codec->dev, "Restoring DC servo state\n");
1047
1048 snd_soc_write(codec, dcs_l_reg,
1049 wm8904->dcs_state[dcs_l]);
1050 snd_soc_write(codec, dcs_r_reg,
1051 wm8904->dcs_state[dcs_r]);
1052
1053 snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);
1054
1055 timeout = 20;
1056 } else {
1057 dev_dbg(codec->dev, "Calibrating DC servo\n");
1058
1059 snd_soc_write(codec, WM8904_DC_SERVO_1,
1060 dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);
1061
1062 timeout = 500;
1063 }
1064
1065 /* Wait for DC servo to complete */
1066 dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
1067 do {
1068 val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
1069 if ((val & dcs_mask) == dcs_mask)
1070 break;
1071
1072 msleep(1);
1073 } while (--timeout);
1074
1075 if ((val & dcs_mask) != dcs_mask)
1076 dev_warn(codec->dev, "DC servo timed out\n");
1077 else
1078 dev_dbg(codec->dev, "DC servo ready\n");
1079
1080 /* Enable the output stage */
1081 snd_soc_update_bits(codec, reg,
1082 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1083 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
1084 break;
1085
1086 case SND_SOC_DAPM_POST_PMU:
1087 /* Unshort the output itself */
1088 snd_soc_update_bits(codec, reg,
1089 WM8904_HPL_RMV_SHORT |
1090 WM8904_HPR_RMV_SHORT,
1091 WM8904_HPL_RMV_SHORT |
1092 WM8904_HPR_RMV_SHORT);
1093
1094 break;
1095
1096 case SND_SOC_DAPM_PRE_PMD:
1097 /* Short the output */
1098 snd_soc_update_bits(codec, reg,
1099 WM8904_HPL_RMV_SHORT |
1100 WM8904_HPR_RMV_SHORT, 0);
1101 break;
1102
1103 case SND_SOC_DAPM_POST_PMD:
1104 /* Cache the DC servo configuration; this will be
1105 * invalidated if we change the configuration. */
1106 wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg);
1107 wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg);
1108
1109 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1110 dcs_mask, 0);
1111
1112 /* Disable the amplifier input and output stages */
1113 snd_soc_update_bits(codec, reg,
1114 WM8904_HPL_ENA | WM8904_HPR_ENA |
1115 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY |
1116 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1117 0);
1118
1119 /* PGAs too */
1120 snd_soc_update_bits(codec, pwr_reg,
1121 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1122 0);
1123 break;
1124 }
1125
1126 return 0;
1127}
1128
1129static const char *lin_text[] = {
1130 "IN1L", "IN2L", "IN3L"
1131};
1132
1133static const struct soc_enum lin_enum =
1134 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text);
1135
1136static const struct snd_kcontrol_new lin_mux =
1137 SOC_DAPM_ENUM("Left Capture Mux", lin_enum);
1138
1139static const struct soc_enum lin_inv_enum =
1140 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text);
1141
1142static const struct snd_kcontrol_new lin_inv_mux =
1143 SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
1144
1145static const char *rin_text[] = {
1146 "IN1R", "IN2R", "IN3R"
1147};
1148
1149static const struct soc_enum rin_enum =
1150 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text);
1151
1152static const struct snd_kcontrol_new rin_mux =
1153 SOC_DAPM_ENUM("Right Capture Mux", rin_enum);
1154
1155static const struct soc_enum rin_inv_enum =
1156 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text);
1157
1158static const struct snd_kcontrol_new rin_inv_mux =
1159 SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
1160
1161static const char *aif_text[] = {
1162 "Left", "Right"
1163};
1164
1165static const struct soc_enum aifoutl_enum =
1166 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text);
1167
1168static const struct snd_kcontrol_new aifoutl_mux =
1169 SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
1170
1171static const struct soc_enum aifoutr_enum =
1172 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text);
1173
1174static const struct snd_kcontrol_new aifoutr_mux =
1175 SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
1176
1177static const struct soc_enum aifinl_enum =
1178 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text);
1179
1180static const struct snd_kcontrol_new aifinl_mux =
1181 SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
1182
1183static const struct soc_enum aifinr_enum =
1184 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text);
1185
1186static const struct snd_kcontrol_new aifinr_mux =
1187 SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
1188
1189static const struct snd_soc_dapm_widget wm8904_core_dapm_widgets[] = {
1190SND_SOC_DAPM_SUPPLY("SYSCLK", WM8904_CLOCK_RATES_2, 2, 0, sysclk_event,
1191 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1192SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8904_CLOCK_RATES_2, 1, 0, NULL, 0),
1193SND_SOC_DAPM_SUPPLY("TOCLK", WM8904_CLOCK_RATES_2, 0, 0, NULL, 0),
1194};
1195
1196static const struct snd_soc_dapm_widget wm8904_adc_dapm_widgets[] = {
1197SND_SOC_DAPM_INPUT("IN1L"),
1198SND_SOC_DAPM_INPUT("IN1R"),
1199SND_SOC_DAPM_INPUT("IN2L"),
1200SND_SOC_DAPM_INPUT("IN2R"),
1201SND_SOC_DAPM_INPUT("IN3L"),
1202SND_SOC_DAPM_INPUT("IN3R"),
1203
1204SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0),
1205
1206SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
1207SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1208 &lin_inv_mux),
1209SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
1210SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1211 &rin_inv_mux),
1212
1213SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
1214 NULL, 0),
1215SND_SOC_DAPM_PGA("Right Capture PGA", WM8904_POWER_MANAGEMENT_0, 0, 0,
1216 NULL, 0),
1217
1218SND_SOC_DAPM_ADC("ADCL", NULL, WM8904_POWER_MANAGEMENT_6, 1, 0),
1219SND_SOC_DAPM_ADC("ADCR", NULL, WM8904_POWER_MANAGEMENT_6, 0, 0),
1220
1221SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
1222SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
1223
1224SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
1225SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
1226};
1227
1228static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = {
1229SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
1230SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
1231
1232SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
1233SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
1234
1235SND_SOC_DAPM_DAC("DACL", NULL, WM8904_POWER_MANAGEMENT_6, 3, 0),
1236SND_SOC_DAPM_DAC("DACR", NULL, WM8904_POWER_MANAGEMENT_6, 2, 0),
1237
1238SND_SOC_DAPM_SUPPLY("Charge pump", WM8904_CHARGE_PUMP_0, 0, 0, cp_event,
1239 SND_SOC_DAPM_POST_PMU),
1240
1241SND_SOC_DAPM_PGA("HPL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1242SND_SOC_DAPM_PGA("HPR PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1243
1244SND_SOC_DAPM_PGA("LINEL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1245SND_SOC_DAPM_PGA("LINER PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1246
1247SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM, WM8904_ANALOGUE_HP_0,
1248 0, NULL, 0, out_pga_event,
1249 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1250 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1251SND_SOC_DAPM_PGA_E("Line Output", SND_SOC_NOPM, WM8904_ANALOGUE_LINEOUT_0,
1252 0, NULL, 0, out_pga_event,
1253 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1254 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1255
1256SND_SOC_DAPM_OUTPUT("HPOUTL"),
1257SND_SOC_DAPM_OUTPUT("HPOUTR"),
1258SND_SOC_DAPM_OUTPUT("LINEOUTL"),
1259SND_SOC_DAPM_OUTPUT("LINEOUTR"),
1260};
1261
1262static const char *out_mux_text[] = {
1263 "DAC", "Bypass"
1264};
1265
1266static const struct soc_enum hpl_enum =
1267 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text);
1268
1269static const struct snd_kcontrol_new hpl_mux =
1270 SOC_DAPM_ENUM("HPL Mux", hpl_enum);
1271
1272static const struct soc_enum hpr_enum =
1273 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text);
1274
1275static const struct snd_kcontrol_new hpr_mux =
1276 SOC_DAPM_ENUM("HPR Mux", hpr_enum);
1277
1278static const struct soc_enum linel_enum =
1279 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text);
1280
1281static const struct snd_kcontrol_new linel_mux =
1282 SOC_DAPM_ENUM("LINEL Mux", linel_enum);
1283
1284static const struct soc_enum liner_enum =
1285 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text);
1286
1287static const struct snd_kcontrol_new liner_mux =
1288 SOC_DAPM_ENUM("LINEL Mux", liner_enum);
1289
1290static const char *sidetone_text[] = {
1291 "None", "Left", "Right"
1292};
1293
1294static const struct soc_enum dacl_sidetone_enum =
1295 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text);
1296
1297static const struct snd_kcontrol_new dacl_sidetone_mux =
1298 SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum);
1299
1300static const struct soc_enum dacr_sidetone_enum =
1301 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text);
1302
1303static const struct snd_kcontrol_new dacr_sidetone_mux =
1304 SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum);
1305
1306static const struct snd_soc_dapm_widget wm8904_dapm_widgets[] = {
1307SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0),
1308SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1309SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1310
1311SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &dacl_sidetone_mux),
1312SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &dacr_sidetone_mux),
1313
1314SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1315SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1316SND_SOC_DAPM_MUX("LINEL Mux", SND_SOC_NOPM, 0, 0, &linel_mux),
1317SND_SOC_DAPM_MUX("LINER Mux", SND_SOC_NOPM, 0, 0, &liner_mux),
1318};
1319
1320static const struct snd_soc_dapm_route core_intercon[] = {
1321 { "CLK_DSP", NULL, "SYSCLK" },
1322 { "TOCLK", NULL, "SYSCLK" },
1323};
1324
1325static const struct snd_soc_dapm_route adc_intercon[] = {
1326 { "Left Capture Mux", "IN1L", "IN1L" },
1327 { "Left Capture Mux", "IN2L", "IN2L" },
1328 { "Left Capture Mux", "IN3L", "IN3L" },
1329
1330 { "Left Capture Inverting Mux", "IN1L", "IN1L" },
1331 { "Left Capture Inverting Mux", "IN2L", "IN2L" },
1332 { "Left Capture Inverting Mux", "IN3L", "IN3L" },
1333
1334 { "Right Capture Mux", "IN1R", "IN1R" },
1335 { "Right Capture Mux", "IN2R", "IN2R" },
1336 { "Right Capture Mux", "IN3R", "IN3R" },
1337
1338 { "Right Capture Inverting Mux", "IN1R", "IN1R" },
1339 { "Right Capture Inverting Mux", "IN2R", "IN2R" },
1340 { "Right Capture Inverting Mux", "IN3R", "IN3R" },
1341
1342 { "Left Capture PGA", NULL, "Left Capture Mux" },
1343 { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
1344
1345 { "Right Capture PGA", NULL, "Right Capture Mux" },
1346 { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
1347
1348 { "AIFOUTL", "Left", "ADCL" },
1349 { "AIFOUTL", "Right", "ADCR" },
1350 { "AIFOUTR", "Left", "ADCL" },
1351 { "AIFOUTR", "Right", "ADCR" },
1352
1353 { "ADCL", NULL, "CLK_DSP" },
1354 { "ADCL", NULL, "Left Capture PGA" },
1355
1356 { "ADCR", NULL, "CLK_DSP" },
1357 { "ADCR", NULL, "Right Capture PGA" },
1358};
1359
1360static const struct snd_soc_dapm_route dac_intercon[] = {
1361 { "DACL", "Right", "AIFINR" },
1362 { "DACL", "Left", "AIFINL" },
1363 { "DACL", NULL, "CLK_DSP" },
1364
1365 { "DACR", "Right", "AIFINR" },
1366 { "DACR", "Left", "AIFINL" },
1367 { "DACR", NULL, "CLK_DSP" },
1368
1369 { "Charge pump", NULL, "SYSCLK" },
1370
1371 { "Headphone Output", NULL, "HPL PGA" },
1372 { "Headphone Output", NULL, "HPR PGA" },
1373 { "Headphone Output", NULL, "Charge pump" },
1374 { "Headphone Output", NULL, "TOCLK" },
1375
1376 { "Line Output", NULL, "LINEL PGA" },
1377 { "Line Output", NULL, "LINER PGA" },
1378 { "Line Output", NULL, "Charge pump" },
1379 { "Line Output", NULL, "TOCLK" },
1380
1381 { "HPOUTL", NULL, "Headphone Output" },
1382 { "HPOUTR", NULL, "Headphone Output" },
1383
1384 { "LINEOUTL", NULL, "Line Output" },
1385 { "LINEOUTR", NULL, "Line Output" },
1386};
1387
1388static const struct snd_soc_dapm_route wm8904_intercon[] = {
1389 { "Left Sidetone", "Left", "ADCL" },
1390 { "Left Sidetone", "Right", "ADCR" },
1391 { "DACL", NULL, "Left Sidetone" },
1392
1393 { "Right Sidetone", "Left", "ADCL" },
1394 { "Right Sidetone", "Right", "ADCR" },
1395 { "DACR", NULL, "Right Sidetone" },
1396
1397 { "Left Bypass", NULL, "Class G" },
1398 { "Left Bypass", NULL, "Left Capture PGA" },
1399
1400 { "Right Bypass", NULL, "Class G" },
1401 { "Right Bypass", NULL, "Right Capture PGA" },
1402
1403 { "HPL Mux", "DAC", "DACL" },
1404 { "HPL Mux", "Bypass", "Left Bypass" },
1405
1406 { "HPR Mux", "DAC", "DACR" },
1407 { "HPR Mux", "Bypass", "Right Bypass" },
1408
1409 { "LINEL Mux", "DAC", "DACL" },
1410 { "LINEL Mux", "Bypass", "Left Bypass" },
1411
1412 { "LINER Mux", "DAC", "DACR" },
1413 { "LINER Mux", "Bypass", "Right Bypass" },
1414
1415 { "HPL PGA", NULL, "HPL Mux" },
1416 { "HPR PGA", NULL, "HPR Mux" },
1417
1418 { "LINEL PGA", NULL, "LINEL Mux" },
1419 { "LINER PGA", NULL, "LINER Mux" },
1420};
1421
1422static const struct snd_soc_dapm_route wm8912_intercon[] = {
1423 { "HPL PGA", NULL, "DACL" },
1424 { "HPR PGA", NULL, "DACR" },
1425
1426 { "LINEL PGA", NULL, "DACL" },
1427 { "LINER PGA", NULL, "DACR" },
1428};
1429
1430static int wm8904_add_widgets(struct snd_soc_codec *codec)
1431{
1432 struct wm8904_priv *wm8904 = codec->private_data;
1433
1434 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1435 ARRAY_SIZE(wm8904_core_dapm_widgets));
1436 snd_soc_dapm_add_routes(codec, core_intercon,
1437 ARRAY_SIZE(core_intercon));
1438
1439 switch (wm8904->devtype) {
1440 case WM8904:
1441 snd_soc_add_controls(codec, wm8904_adc_snd_controls,
1442 ARRAY_SIZE(wm8904_adc_snd_controls));
1443 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1444 ARRAY_SIZE(wm8904_dac_snd_controls));
1445 snd_soc_add_controls(codec, wm8904_snd_controls,
1446 ARRAY_SIZE(wm8904_snd_controls));
1447
1448 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
1449 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1450 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1451 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1452 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
1453 ARRAY_SIZE(wm8904_dapm_widgets));
1454
1455 snd_soc_dapm_add_routes(codec, core_intercon,
1456 ARRAY_SIZE(core_intercon));
1457 snd_soc_dapm_add_routes(codec, adc_intercon,
1458 ARRAY_SIZE(adc_intercon));
1459 snd_soc_dapm_add_routes(codec, dac_intercon,
1460 ARRAY_SIZE(dac_intercon));
1461 snd_soc_dapm_add_routes(codec, wm8904_intercon,
1462 ARRAY_SIZE(wm8904_intercon));
1463 break;
1464
1465 case WM8912:
1466 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1467 ARRAY_SIZE(wm8904_dac_snd_controls));
1468
1469 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1470 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1471
1472 snd_soc_dapm_add_routes(codec, dac_intercon,
1473 ARRAY_SIZE(dac_intercon));
1474 snd_soc_dapm_add_routes(codec, wm8912_intercon,
1475 ARRAY_SIZE(wm8912_intercon));
1476 break;
1477 }
1478
1479 snd_soc_dapm_new_widgets(codec);
1480 return 0;
1481}
1482
1483static struct {
1484 int ratio;
1485 unsigned int clk_sys_rate;
1486} clk_sys_rates[] = {
1487 { 64, 0 },
1488 { 128, 1 },
1489 { 192, 2 },
1490 { 256, 3 },
1491 { 384, 4 },
1492 { 512, 5 },
1493 { 786, 6 },
1494 { 1024, 7 },
1495 { 1408, 8 },
1496 { 1536, 9 },
1497};
1498
1499static struct {
1500 int rate;
1501 int sample_rate;
1502} sample_rates[] = {
1503 { 8000, 0 },
1504 { 11025, 1 },
1505 { 12000, 1 },
1506 { 16000, 2 },
1507 { 22050, 3 },
1508 { 24000, 3 },
1509 { 32000, 4 },
1510 { 44100, 5 },
1511 { 48000, 5 },
1512};
1513
1514static struct {
1515 int div; /* *10 due to .5s */
1516 int bclk_div;
1517} bclk_divs[] = {
1518 { 10, 0 },
1519 { 15, 1 },
1520 { 20, 2 },
1521 { 30, 3 },
1522 { 40, 4 },
1523 { 50, 5 },
1524 { 55, 6 },
1525 { 60, 7 },
1526 { 80, 8 },
1527 { 100, 9 },
1528 { 110, 10 },
1529 { 120, 11 },
1530 { 160, 12 },
1531 { 200, 13 },
1532 { 220, 14 },
1533 { 240, 16 },
1534 { 200, 17 },
1535 { 320, 18 },
1536 { 440, 19 },
1537 { 480, 20 },
1538};
1539
1540
1541static int wm8904_hw_params(struct snd_pcm_substream *substream,
1542 struct snd_pcm_hw_params *params,
1543 struct snd_soc_dai *dai)
1544{
1545 struct snd_soc_codec *codec = dai->codec;
1546 struct wm8904_priv *wm8904 = codec->private_data;
1547 int ret, i, best, best_val, cur_val;
1548 unsigned int aif1 = 0;
1549 unsigned int aif2 = 0;
1550 unsigned int aif3 = 0;
1551 unsigned int clock1 = 0;
1552 unsigned int dac_digital1 = 0;
1553
1554 /* What BCLK do we need? */
1555 wm8904->fs = params_rate(params);
1556 if (wm8904->tdm_slots) {
1557 dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
1558 wm8904->tdm_slots, wm8904->tdm_width);
1559 wm8904->bclk = snd_soc_calc_bclk(wm8904->fs,
1560 wm8904->tdm_width, 2,
1561 wm8904->tdm_slots);
1562 } else {
1563 wm8904->bclk = snd_soc_params_to_bclk(params);
1564 }
1565
1566 switch (params_format(params)) {
1567 case SNDRV_PCM_FORMAT_S16_LE:
1568 break;
1569 case SNDRV_PCM_FORMAT_S20_3LE:
1570 aif1 |= 0x40;
1571 break;
1572 case SNDRV_PCM_FORMAT_S24_LE:
1573 aif1 |= 0x80;
1574 break;
1575 case SNDRV_PCM_FORMAT_S32_LE:
1576 aif1 |= 0xc0;
1577 break;
1578 default:
1579 return -EINVAL;
1580 }
1581
1582
1583 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk);
1584
1585 ret = wm8904_configure_clocking(codec);
1586 if (ret != 0)
1587 return ret;
1588
1589 /* Select nearest CLK_SYS_RATE */
1590 best = 0;
1591 best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio)
1592 - wm8904->fs);
1593 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1594 cur_val = abs((wm8904->sysclk_rate /
1595 clk_sys_rates[i].ratio) - wm8904->fs);;
1596 if (cur_val < best_val) {
1597 best = i;
1598 best_val = cur_val;
1599 }
1600 }
1601 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1602 clk_sys_rates[best].ratio);
1603 clock1 |= (clk_sys_rates[best].clk_sys_rate
1604 << WM8904_CLK_SYS_RATE_SHIFT);
1605
1606 /* SAMPLE_RATE */
1607 best = 0;
1608 best_val = abs(wm8904->fs - sample_rates[0].rate);
1609 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1610 /* Closest match */
1611 cur_val = abs(wm8904->fs - sample_rates[i].rate);
1612 if (cur_val < best_val) {
1613 best = i;
1614 best_val = cur_val;
1615 }
1616 }
1617 dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
1618 sample_rates[best].rate);
1619 clock1 |= (sample_rates[best].sample_rate
1620 << WM8904_SAMPLE_RATE_SHIFT);
1621
1622 /* Enable sloping stopband filter for low sample rates */
1623 if (wm8904->fs <= 24000)
1624 dac_digital1 |= WM8904_DAC_SB_FILT;
1625
1626 /* BCLK_DIV */
1627 best = 0;
1628 best_val = INT_MAX;
1629 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1630 cur_val = ((wm8904->sysclk_rate * 10) / bclk_divs[i].div)
1631 - wm8904->bclk;
1632 if (cur_val < 0) /* Table is sorted */
1633 break;
1634 if (cur_val < best_val) {
1635 best = i;
1636 best_val = cur_val;
1637 }
1638 }
1639 wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div;
1640 dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
1641 bclk_divs[best].div, wm8904->bclk);
1642 aif2 |= bclk_divs[best].bclk_div;
1643
1644 /* LRCLK is a simple fraction of BCLK */
1645 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
1646 aif3 |= wm8904->bclk / wm8904->fs;
1647
1648 /* Apply the settings */
1649 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
1650 WM8904_DAC_SB_FILT, dac_digital1);
1651 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1652 WM8904_AIF_WL_MASK, aif1);
1653 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2,
1654 WM8904_BCLK_DIV_MASK, aif2);
1655 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1656 WM8904_LRCLK_RATE_MASK, aif3);
1657 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1,
1658 WM8904_SAMPLE_RATE_MASK |
1659 WM8904_CLK_SYS_RATE_MASK, clock1);
1660
1661 /* Update filters for the new settings */
1662 wm8904_set_retune_mobile(codec);
1663 wm8904_set_deemph(codec);
1664
1665 return 0;
1666}
1667
1668
1669static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1670 unsigned int freq, int dir)
1671{
1672 struct snd_soc_codec *codec = dai->codec;
1673 struct wm8904_priv *priv = codec->private_data;
1674
1675 switch (clk_id) {
1676 case WM8904_CLK_MCLK:
1677 priv->sysclk_src = clk_id;
1678 priv->mclk_rate = freq;
1679 break;
1680
1681 case WM8904_CLK_FLL:
1682 priv->sysclk_src = clk_id;
1683 break;
1684
1685 default:
1686 return -EINVAL;
1687 }
1688
1689 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1690
1691 wm8904_configure_clocking(codec);
1692
1693 return 0;
1694}
1695
1696static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1697{
1698 struct snd_soc_codec *codec = dai->codec;
1699 unsigned int aif1 = 0;
1700 unsigned int aif3 = 0;
1701
1702 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1703 case SND_SOC_DAIFMT_CBS_CFS:
1704 break;
1705 case SND_SOC_DAIFMT_CBS_CFM:
1706 aif3 |= WM8904_LRCLK_DIR;
1707 break;
1708 case SND_SOC_DAIFMT_CBM_CFS:
1709 aif1 |= WM8904_BCLK_DIR;
1710 break;
1711 case SND_SOC_DAIFMT_CBM_CFM:
1712 aif1 |= WM8904_BCLK_DIR;
1713 aif3 |= WM8904_LRCLK_DIR;
1714 break;
1715 default:
1716 return -EINVAL;
1717 }
1718
1719 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1720 case SND_SOC_DAIFMT_DSP_B:
1721 aif1 |= WM8904_AIF_LRCLK_INV;
1722 case SND_SOC_DAIFMT_DSP_A:
1723 aif1 |= 0x3;
1724 break;
1725 case SND_SOC_DAIFMT_I2S:
1726 aif1 |= 0x2;
1727 break;
1728 case SND_SOC_DAIFMT_RIGHT_J:
1729 break;
1730 case SND_SOC_DAIFMT_LEFT_J:
1731 aif1 |= 0x1;
1732 break;
1733 default:
1734 return -EINVAL;
1735 }
1736
1737 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1738 case SND_SOC_DAIFMT_DSP_A:
1739 case SND_SOC_DAIFMT_DSP_B:
1740 /* frame inversion not valid for DSP modes */
1741 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1742 case SND_SOC_DAIFMT_NB_NF:
1743 break;
1744 case SND_SOC_DAIFMT_IB_NF:
1745 aif1 |= WM8904_AIF_BCLK_INV;
1746 break;
1747 default:
1748 return -EINVAL;
1749 }
1750 break;
1751
1752 case SND_SOC_DAIFMT_I2S:
1753 case SND_SOC_DAIFMT_RIGHT_J:
1754 case SND_SOC_DAIFMT_LEFT_J:
1755 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1756 case SND_SOC_DAIFMT_NB_NF:
1757 break;
1758 case SND_SOC_DAIFMT_IB_IF:
1759 aif1 |= WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV;
1760 break;
1761 case SND_SOC_DAIFMT_IB_NF:
1762 aif1 |= WM8904_AIF_BCLK_INV;
1763 break;
1764 case SND_SOC_DAIFMT_NB_IF:
1765 aif1 |= WM8904_AIF_LRCLK_INV;
1766 break;
1767 default:
1768 return -EINVAL;
1769 }
1770 break;
1771 default:
1772 return -EINVAL;
1773 }
1774
1775 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1776 WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV |
1777 WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1);
1778 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1779 WM8904_LRCLK_DIR, aif3);
1780
1781 return 0;
1782}
1783
1784
1785static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1786 unsigned int rx_mask, int slots, int slot_width)
1787{
1788 struct snd_soc_codec *codec = dai->codec;
1789 struct wm8904_priv *wm8904 = codec->private_data;
1790 int aif1 = 0;
1791
1792 /* Don't need to validate anything if we're turning off TDM */
1793 if (slots == 0)
1794 goto out;
1795
1796 /* Note that we allow configurations we can't handle ourselves -
1797 * for example, we can generate clocks for slots 2 and up even if
1798 * we can't use those slots ourselves.
1799 */
1800 aif1 |= WM8904_AIFADC_TDM | WM8904_AIFDAC_TDM;
1801
1802 switch (rx_mask) {
1803 case 3:
1804 break;
1805 case 0xc:
1806 aif1 |= WM8904_AIFADC_TDM_CHAN;
1807 break;
1808 default:
1809 return -EINVAL;
1810 }
1811
1812
1813 switch (tx_mask) {
1814 case 3:
1815 break;
1816 case 0xc:
1817 aif1 |= WM8904_AIFDAC_TDM_CHAN;
1818 break;
1819 default:
1820 return -EINVAL;
1821 }
1822
1823out:
1824 wm8904->tdm_width = slot_width;
1825 wm8904->tdm_slots = slots / 2;
1826
1827 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1828 WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN |
1829 WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1);
1830
1831 return 0;
1832}
1833
1834struct _fll_div {
1835 u16 fll_fratio;
1836 u16 fll_outdiv;
1837 u16 fll_clk_ref_div;
1838 u16 n;
1839 u16 k;
1840};
1841
1842/* The size in bits of the FLL divide multiplied by 10
1843 * to allow rounding later */
1844#define FIXED_FLL_SIZE ((1 << 16) * 10)
1845
1846static struct {
1847 unsigned int min;
1848 unsigned int max;
1849 u16 fll_fratio;
1850 int ratio;
1851} fll_fratios[] = {
1852 { 0, 64000, 4, 16 },
1853 { 64000, 128000, 3, 8 },
1854 { 128000, 256000, 2, 4 },
1855 { 256000, 1000000, 1, 2 },
1856 { 1000000, 13500000, 0, 1 },
1857};
1858
1859static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1860 unsigned int Fout)
1861{
1862 u64 Kpart;
1863 unsigned int K, Ndiv, Nmod, target;
1864 unsigned int div;
1865 int i;
1866
1867 /* Fref must be <=13.5MHz */
1868 div = 1;
1869 fll_div->fll_clk_ref_div = 0;
1870 while ((Fref / div) > 13500000) {
1871 div *= 2;
1872 fll_div->fll_clk_ref_div++;
1873
1874 if (div > 8) {
1875 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1876 Fref);
1877 return -EINVAL;
1878 }
1879 }
1880
1881 pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
1882
1883 /* Apply the division for our remaining calculations */
1884 Fref /= div;
1885
1886 /* Fvco should be 90-100MHz; don't check the upper bound */
1887 div = 4;
1888 while (Fout * div < 90000000) {
1889 div++;
1890 if (div > 64) {
1891 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1892 Fout);
1893 return -EINVAL;
1894 }
1895 }
1896 target = Fout * div;
1897 fll_div->fll_outdiv = div - 1;
1898
1899 pr_debug("Fvco=%dHz\n", target);
1900
1901 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1902 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1903 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1904 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1905 target /= fll_fratios[i].ratio;
1906 break;
1907 }
1908 }
1909 if (i == ARRAY_SIZE(fll_fratios)) {
1910 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1911 return -EINVAL;
1912 }
1913
1914 /* Now, calculate N.K */
1915 Ndiv = target / Fref;
1916
1917 fll_div->n = Ndiv;
1918 Nmod = target % Fref;
1919 pr_debug("Nmod=%d\n", Nmod);
1920
1921 /* Calculate fractional part - scale up so we can round. */
1922 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1923
1924 do_div(Kpart, Fref);
1925
1926 K = Kpart & 0xFFFFFFFF;
1927
1928 if ((K % 10) >= 5)
1929 K += 5;
1930
1931 /* Move down to proper range now rounding is done */
1932 fll_div->k = K / 10;
1933
1934 pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
1935 fll_div->n, fll_div->k,
1936 fll_div->fll_fratio, fll_div->fll_outdiv,
1937 fll_div->fll_clk_ref_div);
1938
1939 return 0;
1940}
1941
1942static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1943 unsigned int Fref, unsigned int Fout)
1944{
1945 struct snd_soc_codec *codec = dai->codec;
1946 struct wm8904_priv *wm8904 = codec->private_data;
1947 struct _fll_div fll_div;
1948 int ret, val;
1949 int clock2, fll1;
1950
1951 /* Any change? */
1952 if (source == wm8904->fll_src && Fref == wm8904->fll_fref &&
1953 Fout == wm8904->fll_fout)
1954 return 0;
1955
1956 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
1957
1958 if (Fout == 0) {
1959 dev_dbg(codec->dev, "FLL disabled\n");
1960
1961 wm8904->fll_fref = 0;
1962 wm8904->fll_fout = 0;
1963
1964 /* Gate SYSCLK to avoid glitches */
1965 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
1966 WM8904_CLK_SYS_ENA, 0);
1967
1968 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1969 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
1970
1971 goto out;
1972 }
1973
1974 /* Validate the FLL ID */
1975 switch (source) {
1976 case WM8904_FLL_MCLK:
1977 case WM8904_FLL_LRCLK:
1978 case WM8904_FLL_BCLK:
1979 ret = fll_factors(&fll_div, Fref, Fout);
1980 if (ret != 0)
1981 return ret;
1982 break;
1983
1984 case WM8904_FLL_FREE_RUNNING:
1985 dev_dbg(codec->dev, "Using free running FLL\n");
1986 /* Force 12MHz and output/4 for now */
1987 Fout = 12000000;
1988 Fref = 12000000;
1989
1990 memset(&fll_div, 0, sizeof(fll_div));
1991 fll_div.fll_outdiv = 3;
1992 break;
1993
1994 default:
1995 dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
1996 return -EINVAL;
1997 }
1998
1999 /* Save current state then disable the FLL and SYSCLK to avoid
2000 * misclocking */
2001 fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1);
2002 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2003 WM8904_CLK_SYS_ENA, 0);
2004 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2005 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
2006
2007 /* Unlock forced oscilator control to switch it on/off */
2008 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2009 WM8904_USER_KEY, WM8904_USER_KEY);
2010
2011 if (fll_id == WM8904_FLL_FREE_RUNNING) {
2012 val = WM8904_FLL_FRC_NCO;
2013 } else {
2014 val = 0;
2015 }
2016
2017 snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
2018 val);
2019 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2020 WM8904_USER_KEY, 0);
2021
2022 switch (fll_id) {
2023 case WM8904_FLL_MCLK:
2024 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2025 WM8904_FLL_CLK_REF_SRC_MASK, 0);
2026 break;
2027
2028 case WM8904_FLL_LRCLK:
2029 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2030 WM8904_FLL_CLK_REF_SRC_MASK, 1);
2031 break;
2032
2033 case WM8904_FLL_BCLK:
2034 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2035 WM8904_FLL_CLK_REF_SRC_MASK, 2);
2036 break;
2037 }
2038
2039 if (fll_div.k)
2040 val = WM8904_FLL_FRACN_ENA;
2041 else
2042 val = 0;
2043 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2044 WM8904_FLL_FRACN_ENA, val);
2045
2046 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2,
2047 WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK,
2048 (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) |
2049 (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT));
2050
2051 snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k);
2052
2053 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
2054 fll_div.n << WM8904_FLL_N_SHIFT);
2055
2056 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2057 WM8904_FLL_CLK_REF_DIV_MASK,
2058 fll_div.fll_clk_ref_div
2059 << WM8904_FLL_CLK_REF_DIV_SHIFT);
2060
2061 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2062
2063 wm8904->fll_fref = Fref;
2064 wm8904->fll_fout = Fout;
2065 wm8904->fll_src = source;
2066
2067 /* Enable the FLL if it was previously active */
2068 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2069 WM8904_FLL_OSC_ENA, fll1);
2070 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2071 WM8904_FLL_ENA, fll1);
2072
2073out:
2074 /* Reenable SYSCLK if it was previously active */
2075 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2076 WM8904_CLK_SYS_ENA, clock2);
2077
2078 return 0;
2079}
2080
2081static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2082{
2083 struct snd_soc_codec *codec = codec_dai->codec;
2084 int val;
2085
2086 if (mute)
2087 val = WM8904_DAC_MUTE;
2088 else
2089 val = 0;
2090
2091 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
2092
2093 return 0;
2094}
2095
2096static void wm8904_sync_cache(struct snd_soc_codec *codec)
2097{
2098 struct wm8904_priv *wm8904 = codec->private_data;
2099 int i;
2100
2101 if (!codec->cache_sync)
2102 return;
2103
2104 codec->cache_only = 0;
2105
2106 /* Sync back cached values if they're different from the
2107 * hardware default.
2108 */
2109 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
2110 if (!wm8904_access[i].writable)
2111 continue;
2112
2113 if (wm8904->reg_cache[i] == wm8904_reg[i])
2114 continue;
2115
2116 snd_soc_write(codec, i, wm8904->reg_cache[i]);
2117 }
2118
2119 codec->cache_sync = 0;
2120}
2121
2122static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2123 enum snd_soc_bias_level level)
2124{
2125 struct wm8904_priv *wm8904 = codec->private_data;
2126 int ret;
2127
2128 switch (level) {
2129 case SND_SOC_BIAS_ON:
2130 break;
2131
2132 case SND_SOC_BIAS_PREPARE:
2133 /* VMID resistance 2*50k */
2134 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2135 WM8904_VMID_RES_MASK,
2136 0x1 << WM8904_VMID_RES_SHIFT);
2137
2138 /* Normal bias current */
2139 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2140 WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT);
2141 break;
2142
2143 case SND_SOC_BIAS_STANDBY:
2144 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2145 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2146 wm8904->supplies);
2147 if (ret != 0) {
2148 dev_err(codec->dev,
2149 "Failed to enable supplies: %d\n",
2150 ret);
2151 return ret;
2152 }
2153
2154 wm8904_sync_cache(codec);
2155
2156 /* Enable bias */
2157 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2158 WM8904_BIAS_ENA, WM8904_BIAS_ENA);
2159
2160 /* Enable VMID, VMID buffering, 2*5k resistance */
2161 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2162 WM8904_VMID_ENA |
2163 WM8904_VMID_RES_MASK,
2164 WM8904_VMID_ENA |
2165 0x3 << WM8904_VMID_RES_SHIFT);
2166
2167 /* Let VMID ramp */
2168 msleep(1);
2169 }
2170
2171 /* Maintain VMID with 2*250k */
2172 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2173 WM8904_VMID_RES_MASK,
2174 0x2 << WM8904_VMID_RES_SHIFT);
2175
2176 /* Bias current *0.5 */
2177 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2178 WM8904_ISEL_MASK, 0);
2179 break;
2180
2181 case SND_SOC_BIAS_OFF:
2182 /* Turn off VMID */
2183 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2184 WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0);
2185
2186 /* Stop bias generation */
2187 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2188 WM8904_BIAS_ENA, 0);
2189
2190#ifdef CONFIG_REGULATOR
2191 /* Post 2.6.34 we will be able to get a callback when
2192 * the regulators are disabled which we can use but
2193 * for now just assume that the power will be cut if
2194 * the regulator API is in use.
2195 */
2196 codec->cache_sync = 1;
2197#endif
2198
2199 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
2200 wm8904->supplies);
2201 break;
2202 }
2203 codec->bias_level = level;
2204 return 0;
2205}
2206
2207#define WM8904_RATES SNDRV_PCM_RATE_8000_96000
2208
2209#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2210 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2211
2212static struct snd_soc_dai_ops wm8904_dai_ops = {
2213 .set_sysclk = wm8904_set_sysclk,
2214 .set_fmt = wm8904_set_fmt,
2215 .set_tdm_slot = wm8904_set_tdm_slot,
2216 .set_pll = wm8904_set_fll,
2217 .hw_params = wm8904_hw_params,
2218 .digital_mute = wm8904_digital_mute,
2219};
2220
2221struct snd_soc_dai wm8904_dai = {
2222 .name = "WM8904",
2223 .playback = {
2224 .stream_name = "Playback",
2225 .channels_min = 2,
2226 .channels_max = 2,
2227 .rates = WM8904_RATES,
2228 .formats = WM8904_FORMATS,
2229 },
2230 .capture = {
2231 .stream_name = "Capture",
2232 .channels_min = 2,
2233 .channels_max = 2,
2234 .rates = WM8904_RATES,
2235 .formats = WM8904_FORMATS,
2236 },
2237 .ops = &wm8904_dai_ops,
2238 .symmetric_rates = 1,
2239};
2240EXPORT_SYMBOL_GPL(wm8904_dai);
2241
2242#ifdef CONFIG_PM
2243static int wm8904_suspend(struct platform_device *pdev, pm_message_t state)
2244{
2245 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2246 struct snd_soc_codec *codec = socdev->card->codec;
2247
2248 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2249
2250 return 0;
2251}
2252
2253static int wm8904_resume(struct platform_device *pdev)
2254{
2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2256 struct snd_soc_codec *codec = socdev->card->codec;
2257
2258 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2259
2260 return 0;
2261}
2262#else
2263#define wm8904_suspend NULL
2264#define wm8904_resume NULL
2265#endif
2266
2267static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2268{
2269 struct snd_soc_codec *codec = &wm8904->codec;
2270 struct wm8904_pdata *pdata = wm8904->pdata;
2271 struct snd_kcontrol_new control =
2272 SOC_ENUM_EXT("EQ Mode",
2273 wm8904->retune_mobile_enum,
2274 wm8904_get_retune_mobile_enum,
2275 wm8904_put_retune_mobile_enum);
2276 int ret, i, j;
2277 const char **t;
2278
2279 /* We need an array of texts for the enum API but the number
2280 * of texts is likely to be less than the number of
2281 * configurations due to the sample rate dependency of the
2282 * configurations. */
2283 wm8904->num_retune_mobile_texts = 0;
2284 wm8904->retune_mobile_texts = NULL;
2285 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2286 for (j = 0; j < wm8904->num_retune_mobile_texts; j++) {
2287 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2288 wm8904->retune_mobile_texts[j]) == 0)
2289 break;
2290 }
2291
2292 if (j != wm8904->num_retune_mobile_texts)
2293 continue;
2294
2295 /* Expand the array... */
2296 t = krealloc(wm8904->retune_mobile_texts,
2297 sizeof(char *) *
2298 (wm8904->num_retune_mobile_texts + 1),
2299 GFP_KERNEL);
2300 if (t == NULL)
2301 continue;
2302
2303 /* ...store the new entry... */
2304 t[wm8904->num_retune_mobile_texts] =
2305 pdata->retune_mobile_cfgs[i].name;
2306
2307 /* ...and remember the new version. */
2308 wm8904->num_retune_mobile_texts++;
2309 wm8904->retune_mobile_texts = t;
2310 }
2311
2312 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2313 wm8904->num_retune_mobile_texts);
2314
2315 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2316 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2317
2318 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2319 if (ret != 0)
2320 dev_err(wm8904->codec.dev,
2321 "Failed to add ReTune Mobile control: %d\n", ret);
2322}
2323
2324static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2325{
2326 struct snd_soc_codec *codec = &wm8904->codec;
2327 struct wm8904_pdata *pdata = wm8904->pdata;
2328 int ret, i;
2329
2330 if (!pdata) {
2331 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2332 ARRAY_SIZE(wm8904_eq_controls));
2333 return;
2334 }
2335
2336 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
2337
2338 if (pdata->num_drc_cfgs) {
2339 struct snd_kcontrol_new control =
2340 SOC_ENUM_EXT("DRC Mode", wm8904->drc_enum,
2341 wm8904_get_drc_enum, wm8904_put_drc_enum);
2342
2343 /* We need an array of texts for the enum API */
2344 wm8904->drc_texts = kmalloc(sizeof(char *)
2345 * pdata->num_drc_cfgs, GFP_KERNEL);
2346 if (!wm8904->drc_texts) {
2347 dev_err(wm8904->codec.dev,
2348 "Failed to allocate %d DRC config texts\n",
2349 pdata->num_drc_cfgs);
2350 return;
2351 }
2352
2353 for (i = 0; i < pdata->num_drc_cfgs; i++)
2354 wm8904->drc_texts[i] = pdata->drc_cfgs[i].name;
2355
2356 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2357 wm8904->drc_enum.texts = wm8904->drc_texts;
2358
2359 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2360 if (ret != 0)
2361 dev_err(wm8904->codec.dev,
2362 "Failed to add DRC mode control: %d\n", ret);
2363
2364 wm8904_set_drc(codec);
2365 }
2366
2367 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2368 pdata->num_retune_mobile_cfgs);
2369
2370 if (pdata->num_retune_mobile_cfgs)
2371 wm8904_handle_retune_mobile_pdata(wm8904);
2372 else
2373 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2374 ARRAY_SIZE(wm8904_eq_controls));
2375}
2376
2377static int wm8904_probe(struct platform_device *pdev)
2378{
2379 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2380 struct snd_soc_codec *codec;
2381 int ret = 0;
2382
2383 if (wm8904_codec == NULL) {
2384 dev_err(&pdev->dev, "Codec device not registered\n");
2385 return -ENODEV;
2386 }
2387
2388 socdev->card->codec = wm8904_codec;
2389 codec = wm8904_codec;
2390
2391 /* register pcms */
2392 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2393 if (ret < 0) {
2394 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2395 goto pcm_err;
2396 }
2397
2398 wm8904_handle_pdata(codec->private_data);
2399
2400 wm8904_add_widgets(codec);
2401
2402 return ret;
2403
2404pcm_err:
2405 return ret;
2406}
2407
2408static int wm8904_remove(struct platform_device *pdev)
2409{
2410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2411
2412 snd_soc_free_pcms(socdev);
2413 snd_soc_dapm_free(socdev);
2414
2415 return 0;
2416}
2417
2418struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2419 .probe = wm8904_probe,
2420 .remove = wm8904_remove,
2421 .suspend = wm8904_suspend,
2422 .resume = wm8904_resume,
2423};
2424EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2425
2426static int wm8904_register(struct wm8904_priv *wm8904,
2427 enum snd_soc_control_type control)
2428{
2429 int ret;
2430 struct snd_soc_codec *codec = &wm8904->codec;
2431 int i;
2432
2433 if (wm8904_codec) {
2434 dev_err(codec->dev, "Another WM8904 is registered\n");
2435 return -EINVAL;
2436 }
2437
2438 mutex_init(&codec->mutex);
2439 INIT_LIST_HEAD(&codec->dapm_widgets);
2440 INIT_LIST_HEAD(&codec->dapm_paths);
2441
2442 codec->private_data = wm8904;
2443 codec->name = "WM8904";
2444 codec->owner = THIS_MODULE;
2445 codec->bias_level = SND_SOC_BIAS_OFF;
2446 codec->set_bias_level = wm8904_set_bias_level;
2447 codec->dai = &wm8904_dai;
2448 codec->num_dai = 1;
2449 codec->reg_cache_size = WM8904_MAX_REGISTER;
2450 codec->reg_cache = &wm8904->reg_cache;
2451 codec->volatile_register = wm8904_volatile_register;
2452 codec->cache_sync = 1;
2453 codec->idle_bias_off = 1;
2454
2455 switch (wm8904->devtype) {
2456 case WM8904:
2457 break;
2458 case WM8912:
2459 memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture));
2460 break;
2461 default:
2462 dev_err(codec->dev, "Unknown device type %d\n",
2463 wm8904->devtype);
2464 return -EINVAL;
2465 }
2466
2467 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
2468
2469 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2470 if (ret != 0) {
2471 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2472 goto err;
2473 }
2474
2475 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2476 wm8904->supplies[i].supply = wm8904_supply_names[i];
2477
2478 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
2479 wm8904->supplies);
2480 if (ret != 0) {
2481 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2482 goto err;
2483 }
2484
2485 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2486 wm8904->supplies);
2487 if (ret != 0) {
2488 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2489 goto err_get;
2490 }
2491
2492 ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
2493 if (ret < 0) {
2494 dev_err(codec->dev, "Failed to read ID register\n");
2495 goto err_enable;
2496 }
2497 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) {
2498 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2499 ret = -EINVAL;
2500 goto err_enable;
2501 }
2502
2503 ret = snd_soc_read(codec, WM8904_REVISION);
2504 if (ret < 0) {
2505 dev_err(codec->dev, "Failed to read device revision: %d\n",
2506 ret);
2507 goto err_enable;
2508 }
2509 dev_info(codec->dev, "revision %c\n", ret + 'A');
2510
2511 ret = wm8904_reset(codec);
2512 if (ret < 0) {
2513 dev_err(codec->dev, "Failed to issue reset\n");
2514 goto err_enable;
2515 }
2516
2517 wm8904_dai.dev = codec->dev;
2518
2519 /* Change some default settings - latch VU and enable ZC */
2520 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
2521 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
2522 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
2523 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
2524 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
2525 WM8904_HPOUTLZC;
2526 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
2527 WM8904_HPOUTRZC;
2528 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
2529 WM8904_LINEOUTLZC;
2530 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
2531 WM8904_LINEOUTRZC;
2532 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
2533
2534 /* Set Class W by default - this will be managed by the Class
2535 * G widget at runtime where bypass paths are available.
2536 */
2537 wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
2538
2539 /* Use normal bias source */
2540 wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
2541
2542 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2543
2544 /* Bias level configuration will have done an extra enable */
2545 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2546
2547 wm8904_codec = codec;
2548
2549 ret = snd_soc_register_codec(codec);
2550 if (ret != 0) {
2551 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2552 return ret;
2553 }
2554
2555 ret = snd_soc_register_dai(&wm8904_dai);
2556 if (ret != 0) {
2557 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2558 snd_soc_unregister_codec(codec);
2559 return ret;
2560 }
2561
2562 return 0;
2563
2564err_enable:
2565 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2566err_get:
2567 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2568err:
2569 kfree(wm8904);
2570 return ret;
2571}
2572
2573static void wm8904_unregister(struct wm8904_priv *wm8904)
2574{
2575 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF);
2576 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2577 snd_soc_unregister_dai(&wm8904_dai);
2578 snd_soc_unregister_codec(&wm8904->codec);
2579 kfree(wm8904);
2580 wm8904_codec = NULL;
2581}
2582
2583#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2584static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2585 const struct i2c_device_id *id)
2586{
2587 struct wm8904_priv *wm8904;
2588 struct snd_soc_codec *codec;
2589
2590 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2591 if (wm8904 == NULL)
2592 return -ENOMEM;
2593
2594 codec = &wm8904->codec;
2595 codec->hw_write = (hw_write_t)i2c_master_send;
2596
2597 wm8904->devtype = id->driver_data;
2598
2599 i2c_set_clientdata(i2c, wm8904);
2600 codec->control_data = i2c;
2601 wm8904->pdata = i2c->dev.platform_data;
2602
2603 codec->dev = &i2c->dev;
2604
2605 return wm8904_register(wm8904, SND_SOC_I2C);
2606}
2607
2608static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2609{
2610 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2611 wm8904_unregister(wm8904);
2612 return 0;
2613}
2614
2615static const struct i2c_device_id wm8904_i2c_id[] = {
2616 { "wm8904", WM8904 },
2617 { "wm8912", WM8912 },
2618 { }
2619};
2620MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2621
2622static struct i2c_driver wm8904_i2c_driver = {
2623 .driver = {
2624 .name = "WM8904",
2625 .owner = THIS_MODULE,
2626 },
2627 .probe = wm8904_i2c_probe,
2628 .remove = __devexit_p(wm8904_i2c_remove),
2629 .id_table = wm8904_i2c_id,
2630};
2631#endif
2632
2633static int __init wm8904_modinit(void)
2634{
2635 int ret;
2636#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2637 ret = i2c_add_driver(&wm8904_i2c_driver);
2638 if (ret != 0) {
2639 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n",
2640 ret);
2641 }
2642#endif
2643 return 0;
2644}
2645module_init(wm8904_modinit);
2646
2647static void __exit wm8904_exit(void)
2648{
2649#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2650 i2c_del_driver(&wm8904_i2c_driver);
2651#endif
2652}
2653module_exit(wm8904_exit);
2654
2655MODULE_DESCRIPTION("ASoC WM8904 driver");
2656MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2657MODULE_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/wm8940.c b/sound/soc/codecs/wm8940.c
index 1ef2454c5205..0c04b476487f 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -30,6 +30,7 @@
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/spi/spi.h> 32#include <linux/spi/spi.h>
33#include <linux/slab.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>
@@ -298,7 +299,6 @@ static int wm8940_add_widgets(struct snd_soc_codec *codec)
298 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 299 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
299 if (ret) 300 if (ret)
300 goto error_ret; 301 goto error_ret;
301 ret = snd_soc_dapm_new_widgets(codec);
302 302
303error_ret: 303error_ret:
304 return ret; 304 return ret;
@@ -379,23 +379,23 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
379 iface |= (1 << 9); 379 iface |= (1 << 9);
380 380
381 switch (params_rate(params)) { 381 switch (params_rate(params)) {
382 case SNDRV_PCM_RATE_8000: 382 case 8000:
383 addcntrl |= (0x5 << 1); 383 addcntrl |= (0x5 << 1);
384 break; 384 break;
385 case SNDRV_PCM_RATE_11025: 385 case 11025:
386 addcntrl |= (0x4 << 1); 386 addcntrl |= (0x4 << 1);
387 break; 387 break;
388 case SNDRV_PCM_RATE_16000: 388 case 16000:
389 addcntrl |= (0x3 << 1); 389 addcntrl |= (0x3 << 1);
390 break; 390 break;
391 case SNDRV_PCM_RATE_22050: 391 case 22050:
392 addcntrl |= (0x2 << 1); 392 addcntrl |= (0x2 << 1);
393 break; 393 break;
394 case SNDRV_PCM_RATE_32000: 394 case 32000:
395 addcntrl |= (0x1 << 1); 395 addcntrl |= (0x1 << 1);
396 break; 396 break;
397 case SNDRV_PCM_RATE_44100: 397 case 44100:
398 case SNDRV_PCM_RATE_48000: 398 case 48000:
399 break; 399 break;
400 } 400 }
401 ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl); 401 ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
@@ -536,8 +536,8 @@ static void pll_factors(unsigned int target, unsigned int source)
536} 536}
537 537
538/* Untested at the moment */ 538/* Untested at the moment */
539static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, 539static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
540 int pll_id, unsigned int freq_in, unsigned int freq_out) 540 int source, unsigned int freq_in, unsigned int freq_out)
541{ 541{
542 struct snd_soc_codec *codec = codec_dai->codec; 542 struct snd_soc_codec *codec = codec_dai->codec;
543 u16 reg; 543 u16 reg;
@@ -731,12 +731,6 @@ static int wm8940_probe(struct platform_device *pdev)
731 if (ret) 731 if (ret)
732 goto error_free_pcms; 732 goto error_free_pcms;
733 733
734 ret = snd_soc_init_card(socdev);
735 if (ret < 0) {
736 dev_err(codec->dev, "failed to register card: %d\n", ret);
737 goto error_free_pcms;
738 }
739
740 return ret; 734 return ret;
741 735
742error_free_pcms: 736error_free_pcms:
@@ -877,21 +871,6 @@ static int __devexit wm8940_i2c_remove(struct i2c_client *client)
877 return 0; 871 return 0;
878} 872}
879 873
880#ifdef CONFIG_PM
881static int wm8940_i2c_suspend(struct i2c_client *client, pm_message_t msg)
882{
883 return snd_soc_suspend_device(&client->dev);
884}
885
886static int wm8940_i2c_resume(struct i2c_client *client)
887{
888 return snd_soc_resume_device(&client->dev);
889}
890#else
891#define wm8940_i2c_suspend NULL
892#define wm8940_i2c_resume NULL
893#endif
894
895static const struct i2c_device_id wm8940_i2c_id[] = { 874static const struct i2c_device_id wm8940_i2c_id[] = {
896 { "wm8940", 0 }, 875 { "wm8940", 0 },
897 { } 876 { }
@@ -905,8 +884,6 @@ static struct i2c_driver wm8940_i2c_driver = {
905 }, 884 },
906 .probe = wm8940_i2c_probe, 885 .probe = wm8940_i2c_probe,
907 .remove = __devexit_p(wm8940_i2c_remove), 886 .remove = __devexit_p(wm8940_i2c_remove),
908 .suspend = wm8940_i2c_suspend,
909 .resume = wm8940_i2c_resume,
910 .id_table = wm8940_i2c_id, 887 .id_table = wm8940_i2c_id,
911}; 888};
912 889
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
new file mode 100644
index 000000000000..c8d7a809af4d
--- /dev/null
+++ b/sound/soc/codecs/wm8955.c
@@ -0,0 +1,1152 @@
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 <linux/slab.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/wm8955.h>
30
31#include "wm8955.h"
32
33static struct snd_soc_codec *wm8955_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8955;
35
36#define WM8955_NUM_SUPPLIES 4
37static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
38 "DCVDD",
39 "DBVDD",
40 "HPVDD",
41 "AVDD",
42};
43
44/* codec private data */
45struct wm8955_priv {
46 struct snd_soc_codec codec;
47 u16 reg_cache[WM8955_MAX_REGISTER + 1];
48
49 unsigned int mclk_rate;
50
51 int deemph;
52 int fs;
53
54 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
55
56 struct wm8955_pdata *pdata;
57};
58
59static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
60 0x0000, /* R0 */
61 0x0000, /* R1 */
62 0x0079, /* R2 - LOUT1 volume */
63 0x0079, /* R3 - ROUT1 volume */
64 0x0000, /* R4 */
65 0x0008, /* R5 - DAC Control */
66 0x0000, /* R6 */
67 0x000A, /* R7 - Audio Interface */
68 0x0000, /* R8 - Sample Rate */
69 0x0000, /* R9 */
70 0x00FF, /* R10 - Left DAC volume */
71 0x00FF, /* R11 - Right DAC volume */
72 0x000F, /* R12 - Bass control */
73 0x000F, /* R13 - Treble control */
74 0x0000, /* R14 */
75 0x0000, /* R15 - Reset */
76 0x0000, /* R16 */
77 0x0000, /* R17 */
78 0x0000, /* R18 */
79 0x0000, /* R19 */
80 0x0000, /* R20 */
81 0x0000, /* R21 */
82 0x0000, /* R22 */
83 0x00C1, /* R23 - Additional control (1) */
84 0x0000, /* R24 - Additional control (2) */
85 0x0000, /* R25 - Power Management (1) */
86 0x0000, /* R26 - Power Management (2) */
87 0x0000, /* R27 - Additional Control (3) */
88 0x0000, /* R28 */
89 0x0000, /* R29 */
90 0x0000, /* R30 */
91 0x0000, /* R31 */
92 0x0000, /* R32 */
93 0x0000, /* R33 */
94 0x0050, /* R34 - Left out Mix (1) */
95 0x0050, /* R35 - Left out Mix (2) */
96 0x0050, /* R36 - Right out Mix (1) */
97 0x0050, /* R37 - Right Out Mix (2) */
98 0x0050, /* R38 - Mono out Mix (1) */
99 0x0050, /* R39 - Mono out Mix (2) */
100 0x0079, /* R40 - LOUT2 volume */
101 0x0079, /* R41 - ROUT2 volume */
102 0x0079, /* R42 - MONOOUT volume */
103 0x0000, /* R43 - Clocking / PLL */
104 0x0103, /* R44 - PLL Control 1 */
105 0x0024, /* R45 - PLL Control 2 */
106 0x01BA, /* R46 - PLL Control 3 */
107 0x0000, /* R47 */
108 0x0000, /* R48 */
109 0x0000, /* R49 */
110 0x0000, /* R50 */
111 0x0000, /* R51 */
112 0x0000, /* R52 */
113 0x0000, /* R53 */
114 0x0000, /* R54 */
115 0x0000, /* R55 */
116 0x0000, /* R56 */
117 0x0000, /* R57 */
118 0x0000, /* R58 */
119 0x0000, /* R59 - PLL Control 4 */
120};
121
122static int wm8955_reset(struct snd_soc_codec *codec)
123{
124 return snd_soc_write(codec, WM8955_RESET, 0);
125}
126
127struct pll_factors {
128 int n;
129 int k;
130 int outdiv;
131};
132
133/* The size in bits of the FLL divide multiplied by 10
134 * to allow rounding later */
135#define FIXED_FLL_SIZE ((1 << 22) * 10)
136
137static int wm8995_pll_factors(struct device *dev,
138 int Fref, int Fout, struct pll_factors *pll)
139{
140 u64 Kpart;
141 unsigned int K, Ndiv, Nmod, target;
142
143 dev_dbg(dev, "Fref=%u Fout=%u\n", Fref, Fout);
144
145 /* The oscilator should run at should be 90-100MHz, and
146 * there's a divide by 4 plus an optional divide by 2 in the
147 * output path to generate the system clock. The clock table
148 * is sortd so we should always generate a suitable target. */
149 target = Fout * 4;
150 if (target < 90000000) {
151 pll->outdiv = 1;
152 target *= 2;
153 } else {
154 pll->outdiv = 0;
155 }
156
157 WARN_ON(target < 90000000 || target > 100000000);
158
159 dev_dbg(dev, "Fvco=%dHz\n", target);
160
161 /* Now, calculate N.K */
162 Ndiv = target / Fref;
163
164 pll->n = Ndiv;
165 Nmod = target % Fref;
166 dev_dbg(dev, "Nmod=%d\n", Nmod);
167
168 /* Calculate fractional part - scale up so we can round. */
169 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
170
171 do_div(Kpart, Fref);
172
173 K = Kpart & 0xFFFFFFFF;
174
175 if ((K % 10) >= 5)
176 K += 5;
177
178 /* Move down to proper range now rounding is done */
179 pll->k = K / 10;
180
181 dev_dbg(dev, "N=%x K=%x OUTDIV=%x\n", pll->n, pll->k, pll->outdiv);
182
183 return 0;
184}
185
186/* Lookup table specifiying SRATE (table 25 in datasheet); some of the
187 * output frequencies have been rounded to the standard frequencies
188 * they are intended to match where the error is slight. */
189static struct {
190 int mclk;
191 int fs;
192 int usb;
193 int sr;
194} clock_cfgs[] = {
195 { 18432000, 8000, 0, 3, },
196 { 18432000, 12000, 0, 9, },
197 { 18432000, 16000, 0, 11, },
198 { 18432000, 24000, 0, 29, },
199 { 18432000, 32000, 0, 13, },
200 { 18432000, 48000, 0, 1, },
201 { 18432000, 96000, 0, 15, },
202
203 { 16934400, 8018, 0, 19, },
204 { 16934400, 11025, 0, 25, },
205 { 16934400, 22050, 0, 27, },
206 { 16934400, 44100, 0, 17, },
207 { 16934400, 88200, 0, 31, },
208
209 { 12000000, 8000, 1, 2, },
210 { 12000000, 11025, 1, 25, },
211 { 12000000, 12000, 1, 8, },
212 { 12000000, 16000, 1, 10, },
213 { 12000000, 22050, 1, 27, },
214 { 12000000, 24000, 1, 28, },
215 { 12000000, 32000, 1, 12, },
216 { 12000000, 44100, 1, 17, },
217 { 12000000, 48000, 1, 0, },
218 { 12000000, 88200, 1, 31, },
219 { 12000000, 96000, 1, 14, },
220
221 { 12288000, 8000, 0, 2, },
222 { 12288000, 12000, 0, 8, },
223 { 12288000, 16000, 0, 10, },
224 { 12288000, 24000, 0, 28, },
225 { 12288000, 32000, 0, 12, },
226 { 12288000, 48000, 0, 0, },
227 { 12288000, 96000, 0, 14, },
228
229 { 12289600, 8018, 0, 18, },
230 { 12289600, 11025, 0, 24, },
231 { 12289600, 22050, 0, 26, },
232 { 11289600, 44100, 0, 16, },
233 { 11289600, 88200, 0, 31, },
234};
235
236static int wm8955_configure_clocking(struct snd_soc_codec *codec)
237{
238 struct wm8955_priv *wm8955 = codec->private_data;
239 int i, ret, val;
240 int clocking = 0;
241 int srate = 0;
242 int sr = -1;
243 struct pll_factors pll;
244
245 /* If we're not running a sample rate currently just pick one */
246 if (wm8955->fs == 0)
247 wm8955->fs = 8000;
248
249 /* Can we generate an exact output? */
250 for (i = 0; i < ARRAY_SIZE(clock_cfgs); i++) {
251 if (wm8955->fs != clock_cfgs[i].fs)
252 continue;
253 sr = i;
254
255 if (wm8955->mclk_rate == clock_cfgs[i].mclk)
256 break;
257 }
258
259 /* We should never get here with an unsupported sample rate */
260 if (sr == -1) {
261 dev_err(codec->dev, "Sample rate %dHz unsupported\n",
262 wm8955->fs);
263 WARN_ON(sr == -1);
264 return -EINVAL;
265 }
266
267 if (i == ARRAY_SIZE(clock_cfgs)) {
268 /* If we can't generate the right clock from MCLK then
269 * we should configure the PLL to supply us with an
270 * appropriate clock.
271 */
272 clocking |= WM8955_MCLKSEL;
273
274 /* Use the last divider configuration we saw for the
275 * sample rate. */
276 ret = wm8995_pll_factors(codec->dev, wm8955->mclk_rate,
277 clock_cfgs[sr].mclk, &pll);
278 if (ret != 0) {
279 dev_err(codec->dev,
280 "Unable to generate %dHz from %dHz MCLK\n",
281 wm8955->fs, wm8955->mclk_rate);
282 return -EINVAL;
283 }
284
285 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_1,
286 WM8955_N_MASK | WM8955_K_21_18_MASK,
287 (pll.n << WM8955_N_SHIFT) |
288 pll.k >> 18);
289 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
290 WM8955_K_17_9_MASK,
291 (pll.k >> 9) & WM8955_K_17_9_MASK);
292 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
293 WM8955_K_8_0_MASK,
294 pll.k & WM8955_K_8_0_MASK);
295 if (pll.k)
296 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
297 WM8955_KEN, WM8955_KEN);
298 else
299 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
300 WM8955_KEN, 0);
301
302 if (pll.outdiv)
303 val = WM8955_PLL_RB | WM8955_PLLOUTDIV2;
304 else
305 val = WM8955_PLL_RB;
306
307 /* Now start the PLL running */
308 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
309 WM8955_PLL_RB | WM8955_PLLOUTDIV2, val);
310 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
311 WM8955_PLLEN, WM8955_PLLEN);
312 }
313
314 srate = clock_cfgs[sr].usb | (clock_cfgs[sr].sr << WM8955_SR_SHIFT);
315
316 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
317 WM8955_USB | WM8955_SR_MASK, srate);
318 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
319 WM8955_MCLKSEL, clocking);
320
321 return 0;
322}
323
324static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
325 struct snd_kcontrol *kcontrol, int event)
326{
327 struct snd_soc_codec *codec = w->codec;
328 int ret = 0;
329
330 /* Always disable the clocks - if we're doing reconfiguration this
331 * avoids misclocking.
332 */
333 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
334 WM8955_DIGENB, 0);
335 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
336 WM8955_PLL_RB | WM8955_PLLEN, 0);
337
338 switch (event) {
339 case SND_SOC_DAPM_POST_PMD:
340 break;
341 case SND_SOC_DAPM_PRE_PMU:
342 ret = wm8955_configure_clocking(codec);
343 break;
344 default:
345 ret = -EINVAL;
346 break;
347 }
348
349 return ret;
350}
351
352static int deemph_settings[] = { 0, 32000, 44100, 48000 };
353
354static int wm8955_set_deemph(struct snd_soc_codec *codec)
355{
356 struct wm8955_priv *wm8955 = codec->private_data;
357 int val, i, best;
358
359 /* If we're using deemphasis select the nearest available sample
360 * rate.
361 */
362 if (wm8955->deemph) {
363 best = 1;
364 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
365 if (abs(deemph_settings[i] - wm8955->fs) <
366 abs(deemph_settings[best] - wm8955->fs))
367 best = i;
368 }
369
370 val = best << WM8955_DEEMPH_SHIFT;
371 } else {
372 val = 0;
373 }
374
375 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
376
377 return snd_soc_update_bits(codec, WM8955_DAC_CONTROL,
378 WM8955_DEEMPH_MASK, val);
379}
380
381static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol)
383{
384 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
385 struct wm8955_priv *wm8955 = codec->private_data;
386
387 return wm8955->deemph;
388}
389
390static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol)
392{
393 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
394 struct wm8955_priv *wm8955 = codec->private_data;
395 int deemph = ucontrol->value.enumerated.item[0];
396
397 if (deemph > 1)
398 return -EINVAL;
399
400 wm8955->deemph = deemph;
401
402 return wm8955_set_deemph(codec);
403}
404
405static const char *bass_mode_text[] = {
406 "Linear", "Adaptive",
407};
408
409static const struct soc_enum bass_mode =
410 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 7, 2, bass_mode_text);
411
412static const char *bass_cutoff_text[] = {
413 "Low", "High"
414};
415
416static const struct soc_enum bass_cutoff =
417 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 6, 2, bass_cutoff_text);
418
419static const char *treble_cutoff_text[] = {
420 "High", "Low"
421};
422
423static const struct soc_enum treble_cutoff =
424 SOC_ENUM_SINGLE(WM8955_TREBLE_CONTROL, 6, 2, treble_cutoff_text);
425
426static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
427static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0);
428static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
429static const DECLARE_TLV_DB_SCALE(mono_tlv, -2100, 300, 0);
430static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
431static const DECLARE_TLV_DB_SCALE(treble_tlv, -1200, 150, 1);
432
433static const struct snd_kcontrol_new wm8955_snd_controls[] = {
434SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8955_LEFT_DAC_VOLUME,
435 WM8955_RIGHT_DAC_VOLUME, 0, 255, 0, digital_tlv),
436SOC_SINGLE_TLV("Playback Attenuation Volume", WM8955_DAC_CONTROL, 7, 1, 1,
437 atten_tlv),
438SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
439 wm8955_get_deemph, wm8955_put_deemph),
440
441SOC_ENUM("Bass Mode", bass_mode),
442SOC_ENUM("Bass Cutoff", bass_cutoff),
443SOC_SINGLE("Bass Volume", WM8955_BASS_CONTROL, 0, 15, 1),
444
445SOC_ENUM("Treble Cutoff", treble_cutoff),
446SOC_SINGLE_TLV("Treble Volume", WM8955_TREBLE_CONTROL, 0, 14, 1, treble_tlv),
447
448SOC_SINGLE_TLV("Left Bypass Volume", WM8955_LEFT_OUT_MIX_1, 4, 7, 1,
449 bypass_tlv),
450SOC_SINGLE_TLV("Left Mono Volume", WM8955_LEFT_OUT_MIX_2, 4, 7, 1,
451 bypass_tlv),
452
453SOC_SINGLE_TLV("Right Mono Volume", WM8955_RIGHT_OUT_MIX_1, 4, 7, 1,
454 bypass_tlv),
455SOC_SINGLE_TLV("Right Bypass Volume", WM8955_RIGHT_OUT_MIX_2, 4, 7, 1,
456 bypass_tlv),
457
458/* Not a stereo pair so they line up with the DAPM switches */
459SOC_SINGLE_TLV("Mono Left Bypass Volume", WM8955_MONO_OUT_MIX_1, 4, 7, 1,
460 mono_tlv),
461SOC_SINGLE_TLV("Mono Right Bypass Volume", WM8955_MONO_OUT_MIX_2, 4, 7, 1,
462 mono_tlv),
463
464SOC_DOUBLE_R_TLV("Headphone Volume", WM8955_LOUT1_VOLUME,
465 WM8955_ROUT1_VOLUME, 0, 127, 0, out_tlv),
466SOC_DOUBLE_R("Headphone ZC Switch", WM8955_LOUT1_VOLUME,
467 WM8955_ROUT1_VOLUME, 7, 1, 0),
468
469SOC_DOUBLE_R_TLV("Speaker Volume", WM8955_LOUT2_VOLUME,
470 WM8955_ROUT2_VOLUME, 0, 127, 0, out_tlv),
471SOC_DOUBLE_R("Speaker ZC Switch", WM8955_LOUT2_VOLUME,
472 WM8955_ROUT2_VOLUME, 7, 1, 0),
473
474SOC_SINGLE_TLV("Mono Volume", WM8955_MONOOUT_VOLUME, 0, 127, 0, out_tlv),
475SOC_SINGLE("Mono ZC Switch", WM8955_MONOOUT_VOLUME, 7, 1, 0),
476};
477
478static const struct snd_kcontrol_new lmixer[] = {
479SOC_DAPM_SINGLE("Playback Switch", WM8955_LEFT_OUT_MIX_1, 8, 1, 0),
480SOC_DAPM_SINGLE("Bypass Switch", WM8955_LEFT_OUT_MIX_1, 7, 1, 0),
481SOC_DAPM_SINGLE("Right Playback Switch", WM8955_LEFT_OUT_MIX_2, 8, 1, 0),
482SOC_DAPM_SINGLE("Mono Switch", WM8955_LEFT_OUT_MIX_2, 7, 1, 0),
483};
484
485static const struct snd_kcontrol_new rmixer[] = {
486SOC_DAPM_SINGLE("Left Playback Switch", WM8955_RIGHT_OUT_MIX_1, 8, 1, 0),
487SOC_DAPM_SINGLE("Mono Switch", WM8955_RIGHT_OUT_MIX_1, 7, 1, 0),
488SOC_DAPM_SINGLE("Playback Switch", WM8955_RIGHT_OUT_MIX_2, 8, 1, 0),
489SOC_DAPM_SINGLE("Bypass Switch", WM8955_RIGHT_OUT_MIX_2, 7, 1, 0),
490};
491
492static const struct snd_kcontrol_new mmixer[] = {
493SOC_DAPM_SINGLE("Left Playback Switch", WM8955_MONO_OUT_MIX_1, 8, 1, 0),
494SOC_DAPM_SINGLE("Left Bypass Switch", WM8955_MONO_OUT_MIX_1, 7, 1, 0),
495SOC_DAPM_SINGLE("Right Playback Switch", WM8955_MONO_OUT_MIX_2, 8, 1, 0),
496SOC_DAPM_SINGLE("Right Bypass Switch", WM8955_MONO_OUT_MIX_2, 7, 1, 0),
497};
498
499static const struct snd_soc_dapm_widget wm8955_dapm_widgets[] = {
500SND_SOC_DAPM_INPUT("MONOIN-"),
501SND_SOC_DAPM_INPUT("MONOIN+"),
502SND_SOC_DAPM_INPUT("LINEINR"),
503SND_SOC_DAPM_INPUT("LINEINL"),
504
505SND_SOC_DAPM_PGA("Mono Input", SND_SOC_NOPM, 0, 0, NULL, 0),
506
507SND_SOC_DAPM_SUPPLY("SYSCLK", WM8955_POWER_MANAGEMENT_1, 0, 1, wm8955_sysclk,
508 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
509SND_SOC_DAPM_SUPPLY("TSDEN", WM8955_ADDITIONAL_CONTROL_1, 8, 0, NULL, 0),
510
511SND_SOC_DAPM_DAC("DACL", "Playback", WM8955_POWER_MANAGEMENT_2, 8, 0),
512SND_SOC_DAPM_DAC("DACR", "Playback", WM8955_POWER_MANAGEMENT_2, 7, 0),
513
514SND_SOC_DAPM_PGA("LOUT1 PGA", WM8955_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
515SND_SOC_DAPM_PGA("ROUT1 PGA", WM8955_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
516SND_SOC_DAPM_PGA("LOUT2 PGA", WM8955_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
517SND_SOC_DAPM_PGA("ROUT2 PGA", WM8955_POWER_MANAGEMENT_2, 3, 0, NULL, 0),
518SND_SOC_DAPM_PGA("MOUT PGA", WM8955_POWER_MANAGEMENT_2, 2, 0, NULL, 0),
519SND_SOC_DAPM_PGA("OUT3 PGA", WM8955_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
520
521/* The names are chosen to make the control names nice */
522SND_SOC_DAPM_MIXER("Left", SND_SOC_NOPM, 0, 0,
523 lmixer, ARRAY_SIZE(lmixer)),
524SND_SOC_DAPM_MIXER("Right", SND_SOC_NOPM, 0, 0,
525 rmixer, ARRAY_SIZE(rmixer)),
526SND_SOC_DAPM_MIXER("Mono", SND_SOC_NOPM, 0, 0,
527 mmixer, ARRAY_SIZE(mmixer)),
528
529SND_SOC_DAPM_OUTPUT("LOUT1"),
530SND_SOC_DAPM_OUTPUT("ROUT1"),
531SND_SOC_DAPM_OUTPUT("LOUT2"),
532SND_SOC_DAPM_OUTPUT("ROUT2"),
533SND_SOC_DAPM_OUTPUT("MONOOUT"),
534SND_SOC_DAPM_OUTPUT("OUT3"),
535};
536
537static const struct snd_soc_dapm_route wm8955_intercon[] = {
538 { "DACL", NULL, "SYSCLK" },
539 { "DACR", NULL, "SYSCLK" },
540
541 { "Mono Input", NULL, "MONOIN-" },
542 { "Mono Input", NULL, "MONOIN+" },
543
544 { "Left", "Playback Switch", "DACL" },
545 { "Left", "Right Playback Switch", "DACR" },
546 { "Left", "Bypass Switch", "LINEINL" },
547 { "Left", "Mono Switch", "Mono Input" },
548
549 { "Right", "Playback Switch", "DACR" },
550 { "Right", "Left Playback Switch", "DACL" },
551 { "Right", "Bypass Switch", "LINEINR" },
552 { "Right", "Mono Switch", "Mono Input" },
553
554 { "Mono", "Left Playback Switch", "DACL" },
555 { "Mono", "Right Playback Switch", "DACR" },
556 { "Mono", "Left Bypass Switch", "LINEINL" },
557 { "Mono", "Right Bypass Switch", "LINEINR" },
558
559 { "LOUT1 PGA", NULL, "Left" },
560 { "LOUT1", NULL, "TSDEN" },
561 { "LOUT1", NULL, "LOUT1 PGA" },
562
563 { "ROUT1 PGA", NULL, "Right" },
564 { "ROUT1", NULL, "TSDEN" },
565 { "ROUT1", NULL, "ROUT1 PGA" },
566
567 { "LOUT2 PGA", NULL, "Left" },
568 { "LOUT2", NULL, "TSDEN" },
569 { "LOUT2", NULL, "LOUT2 PGA" },
570
571 { "ROUT2 PGA", NULL, "Right" },
572 { "ROUT2", NULL, "TSDEN" },
573 { "ROUT2", NULL, "ROUT2 PGA" },
574
575 { "MOUT PGA", NULL, "Mono" },
576 { "MONOOUT", NULL, "MOUT PGA" },
577
578 /* OUT3 not currently implemented */
579 { "OUT3", NULL, "OUT3 PGA" },
580};
581
582static int wm8955_add_widgets(struct snd_soc_codec *codec)
583{
584 snd_soc_add_controls(codec, wm8955_snd_controls,
585 ARRAY_SIZE(wm8955_snd_controls));
586
587 snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets,
588 ARRAY_SIZE(wm8955_dapm_widgets));
589
590 snd_soc_dapm_add_routes(codec, wm8955_intercon,
591 ARRAY_SIZE(wm8955_intercon));
592
593 return 0;
594}
595
596static int wm8955_hw_params(struct snd_pcm_substream *substream,
597 struct snd_pcm_hw_params *params,
598 struct snd_soc_dai *dai)
599{
600 struct snd_soc_codec *codec = dai->codec;
601 struct wm8955_priv *wm8955 = codec->private_data;
602 int ret;
603 int wl;
604
605 switch (params_format(params)) {
606 case SNDRV_PCM_FORMAT_S16_LE:
607 wl = 0;
608 break;
609 case SNDRV_PCM_FORMAT_S20_3LE:
610 wl = 0x4;
611 break;
612 case SNDRV_PCM_FORMAT_S24_LE:
613 wl = 0x8;
614 break;
615 case SNDRV_PCM_FORMAT_S32_LE:
616 wl = 0xc;
617 break;
618 default:
619 return -EINVAL;
620 }
621 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
622 WM8955_WL_MASK, wl);
623
624 wm8955->fs = params_rate(params);
625 wm8955_set_deemph(codec);
626
627 /* If the chip is clocked then disable the clocks and force a
628 * reconfiguration, otherwise DAPM will power up the
629 * clocks for us later. */
630 ret = snd_soc_read(codec, WM8955_POWER_MANAGEMENT_1);
631 if (ret < 0)
632 return ret;
633 if (ret & WM8955_DIGENB) {
634 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
635 WM8955_DIGENB, 0);
636 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
637 WM8955_PLL_RB | WM8955_PLLEN, 0);
638
639 wm8955_configure_clocking(codec);
640 }
641
642 return 0;
643}
644
645
646static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
647 unsigned int freq, int dir)
648{
649 struct snd_soc_codec *codec = dai->codec;
650 struct wm8955_priv *priv = codec->private_data;
651 int div;
652
653 switch (clk_id) {
654 case WM8955_CLK_MCLK:
655 if (freq > 15000000) {
656 priv->mclk_rate = freq /= 2;
657 div = WM8955_MCLKDIV2;
658 } else {
659 priv->mclk_rate = freq;
660 div = 0;
661 }
662
663 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
664 WM8955_MCLKDIV2, div);
665 break;
666
667 default:
668 return -EINVAL;
669 }
670
671 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
672
673 return 0;
674}
675
676static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
677{
678 struct snd_soc_codec *codec = dai->codec;
679 u16 aif = 0;
680
681 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
682 case SND_SOC_DAIFMT_CBS_CFS:
683 break;
684 case SND_SOC_DAIFMT_CBM_CFM:
685 aif |= WM8955_MS;
686 break;
687 default:
688 return -EINVAL;
689 }
690
691 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
692 case SND_SOC_DAIFMT_DSP_B:
693 aif |= WM8955_LRP;
694 case SND_SOC_DAIFMT_DSP_A:
695 aif |= 0x3;
696 break;
697 case SND_SOC_DAIFMT_I2S:
698 aif |= 0x2;
699 break;
700 case SND_SOC_DAIFMT_RIGHT_J:
701 break;
702 case SND_SOC_DAIFMT_LEFT_J:
703 aif |= 0x1;
704 break;
705 default:
706 return -EINVAL;
707 }
708
709 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
710 case SND_SOC_DAIFMT_DSP_A:
711 case SND_SOC_DAIFMT_DSP_B:
712 /* frame inversion not valid for DSP modes */
713 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
714 case SND_SOC_DAIFMT_NB_NF:
715 break;
716 case SND_SOC_DAIFMT_IB_NF:
717 aif |= WM8955_BCLKINV;
718 break;
719 default:
720 return -EINVAL;
721 }
722 break;
723
724 case SND_SOC_DAIFMT_I2S:
725 case SND_SOC_DAIFMT_RIGHT_J:
726 case SND_SOC_DAIFMT_LEFT_J:
727 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
728 case SND_SOC_DAIFMT_NB_NF:
729 break;
730 case SND_SOC_DAIFMT_IB_IF:
731 aif |= WM8955_BCLKINV | WM8955_LRP;
732 break;
733 case SND_SOC_DAIFMT_IB_NF:
734 aif |= WM8955_BCLKINV;
735 break;
736 case SND_SOC_DAIFMT_NB_IF:
737 aif |= WM8955_LRP;
738 break;
739 default:
740 return -EINVAL;
741 }
742 break;
743 default:
744 return -EINVAL;
745 }
746
747 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
748 WM8955_MS | WM8955_FORMAT_MASK | WM8955_BCLKINV |
749 WM8955_LRP, aif);
750
751 return 0;
752}
753
754
755static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
756{
757 struct snd_soc_codec *codec = codec_dai->codec;
758 int val;
759
760 if (mute)
761 val = WM8955_DACMU;
762 else
763 val = 0;
764
765 snd_soc_update_bits(codec, WM8955_DAC_CONTROL, WM8955_DACMU, val);
766
767 return 0;
768}
769
770static int wm8955_set_bias_level(struct snd_soc_codec *codec,
771 enum snd_soc_bias_level level)
772{
773 struct wm8955_priv *wm8955 = codec->private_data;
774 int ret, i;
775
776 switch (level) {
777 case SND_SOC_BIAS_ON:
778 break;
779
780 case SND_SOC_BIAS_PREPARE:
781 /* VMID resistance 2*50k */
782 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
783 WM8955_VMIDSEL_MASK,
784 0x1 << WM8955_VMIDSEL_SHIFT);
785
786 /* Default bias current */
787 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
788 WM8955_VSEL_MASK,
789 0x2 << WM8955_VSEL_SHIFT);
790 break;
791
792 case SND_SOC_BIAS_STANDBY:
793 if (codec->bias_level == SND_SOC_BIAS_OFF) {
794 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
795 wm8955->supplies);
796 if (ret != 0) {
797 dev_err(codec->dev,
798 "Failed to enable supplies: %d\n",
799 ret);
800 return ret;
801 }
802
803 /* Sync back cached values if they're
804 * different from the hardware default.
805 */
806 for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
807 if (i == WM8955_RESET)
808 continue;
809
810 if (wm8955->reg_cache[i] == wm8955_reg[i])
811 continue;
812
813 snd_soc_write(codec, i, wm8955->reg_cache[i]);
814 }
815
816 /* Enable VREF and VMID */
817 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
818 WM8955_VREF |
819 WM8955_VMIDSEL_MASK,
820 WM8955_VREF |
821 0x3 << WM8955_VREF_SHIFT);
822
823 /* Let VMID ramp */
824 msleep(500);
825
826 /* High resistance VROI to maintain outputs */
827 snd_soc_update_bits(codec,
828 WM8955_ADDITIONAL_CONTROL_3,
829 WM8955_VROI, WM8955_VROI);
830 }
831
832 /* Maintain VMID with 2*250k */
833 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
834 WM8955_VMIDSEL_MASK,
835 0x2 << WM8955_VMIDSEL_SHIFT);
836
837 /* Minimum bias current */
838 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
839 WM8955_VSEL_MASK, 0);
840 break;
841
842 case SND_SOC_BIAS_OFF:
843 /* Low resistance VROI to help discharge */
844 snd_soc_update_bits(codec,
845 WM8955_ADDITIONAL_CONTROL_3,
846 WM8955_VROI, 0);
847
848 /* Turn off VMID and VREF */
849 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
850 WM8955_VREF |
851 WM8955_VMIDSEL_MASK, 0);
852
853 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies),
854 wm8955->supplies);
855 break;
856 }
857 codec->bias_level = level;
858 return 0;
859}
860
861#define WM8955_RATES SNDRV_PCM_RATE_8000_96000
862
863#define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
864 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
865
866static struct snd_soc_dai_ops wm8955_dai_ops = {
867 .set_sysclk = wm8955_set_sysclk,
868 .set_fmt = wm8955_set_fmt,
869 .hw_params = wm8955_hw_params,
870 .digital_mute = wm8955_digital_mute,
871};
872
873struct snd_soc_dai wm8955_dai = {
874 .name = "WM8955",
875 .playback = {
876 .stream_name = "Playback",
877 .channels_min = 2,
878 .channels_max = 2,
879 .rates = WM8955_RATES,
880 .formats = WM8955_FORMATS,
881 },
882 .ops = &wm8955_dai_ops,
883};
884EXPORT_SYMBOL_GPL(wm8955_dai);
885
886#ifdef CONFIG_PM
887static int wm8955_suspend(struct platform_device *pdev, pm_message_t state)
888{
889 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
890 struct snd_soc_codec *codec = socdev->card->codec;
891
892 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
893
894 return 0;
895}
896
897static int wm8955_resume(struct platform_device *pdev)
898{
899 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
900 struct snd_soc_codec *codec = socdev->card->codec;
901
902 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
903
904 return 0;
905}
906#else
907#define wm8955_suspend NULL
908#define wm8955_resume NULL
909#endif
910
911static int wm8955_probe(struct platform_device *pdev)
912{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec;
915 int ret = 0;
916
917 if (wm8955_codec == NULL) {
918 dev_err(&pdev->dev, "Codec device not registered\n");
919 return -ENODEV;
920 }
921
922 socdev->card->codec = wm8955_codec;
923 codec = wm8955_codec;
924
925 /* register pcms */
926 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
927 if (ret < 0) {
928 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
929 goto pcm_err;
930 }
931
932 wm8955_add_widgets(codec);
933
934 return ret;
935
936pcm_err:
937 return ret;
938}
939
940static int wm8955_remove(struct platform_device *pdev)
941{
942 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
943
944 snd_soc_free_pcms(socdev);
945 snd_soc_dapm_free(socdev);
946
947 return 0;
948}
949
950struct snd_soc_codec_device soc_codec_dev_wm8955 = {
951 .probe = wm8955_probe,
952 .remove = wm8955_remove,
953 .suspend = wm8955_suspend,
954 .resume = wm8955_resume,
955};
956EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955);
957
958static int wm8955_register(struct wm8955_priv *wm8955,
959 enum snd_soc_control_type control)
960{
961 int ret;
962 struct snd_soc_codec *codec = &wm8955->codec;
963 int i;
964
965 if (wm8955_codec) {
966 dev_err(codec->dev, "Another WM8955 is registered\n");
967 return -EINVAL;
968 }
969
970 mutex_init(&codec->mutex);
971 INIT_LIST_HEAD(&codec->dapm_widgets);
972 INIT_LIST_HEAD(&codec->dapm_paths);
973
974 codec->private_data = wm8955;
975 codec->name = "WM8955";
976 codec->owner = THIS_MODULE;
977 codec->bias_level = SND_SOC_BIAS_OFF;
978 codec->set_bias_level = wm8955_set_bias_level;
979 codec->dai = &wm8955_dai;
980 codec->num_dai = 1;
981 codec->reg_cache_size = WM8955_MAX_REGISTER;
982 codec->reg_cache = &wm8955->reg_cache;
983
984 memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg));
985
986 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
987 if (ret != 0) {
988 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
989 goto err;
990 }
991
992 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
993 wm8955->supplies[i].supply = wm8955_supply_names[i];
994
995 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies),
996 wm8955->supplies);
997 if (ret != 0) {
998 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
999 goto err;
1000 }
1001
1002 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
1003 wm8955->supplies);
1004 if (ret != 0) {
1005 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1006 goto err_get;
1007 }
1008
1009 ret = wm8955_reset(codec);
1010 if (ret < 0) {
1011 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1012 goto err_enable;
1013 }
1014
1015 wm8955_dai.dev = codec->dev;
1016
1017 /* Change some default settings - latch VU and enable ZC */
1018 wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
1019 wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
1020 wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
1021 wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
1022 wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
1023 wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
1024 wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
1025
1026 /* Also enable adaptive bass boost by default */
1027 wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
1028
1029 /* Set platform data values */
1030 if (wm8955->pdata) {
1031 if (wm8955->pdata->out2_speaker)
1032 wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
1033 |= WM8955_ROUT2INV;
1034
1035 if (wm8955->pdata->monoin_diff)
1036 wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
1037 |= WM8955_DMEN;
1038 }
1039
1040 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1041
1042 /* Bias level configuration will have done an extra enable */
1043 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1044
1045 wm8955_codec = codec;
1046
1047 ret = snd_soc_register_codec(codec);
1048 if (ret != 0) {
1049 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1050 return ret;
1051 }
1052
1053 ret = snd_soc_register_dai(&wm8955_dai);
1054 if (ret != 0) {
1055 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1056 snd_soc_unregister_codec(codec);
1057 return ret;
1058 }
1059
1060 return 0;
1061
1062err_enable:
1063 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1064err_get:
1065 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1066err:
1067 kfree(wm8955);
1068 return ret;
1069}
1070
1071static void wm8955_unregister(struct wm8955_priv *wm8955)
1072{
1073 wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF);
1074 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1075 snd_soc_unregister_dai(&wm8955_dai);
1076 snd_soc_unregister_codec(&wm8955->codec);
1077 kfree(wm8955);
1078 wm8955_codec = NULL;
1079}
1080
1081#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1082static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
1083 const struct i2c_device_id *id)
1084{
1085 struct wm8955_priv *wm8955;
1086 struct snd_soc_codec *codec;
1087
1088 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
1089 if (wm8955 == NULL)
1090 return -ENOMEM;
1091
1092 codec = &wm8955->codec;
1093 codec->hw_write = (hw_write_t)i2c_master_send;
1094
1095 i2c_set_clientdata(i2c, wm8955);
1096 codec->control_data = i2c;
1097 wm8955->pdata = i2c->dev.platform_data;
1098
1099 codec->dev = &i2c->dev;
1100
1101 return wm8955_register(wm8955, SND_SOC_I2C);
1102}
1103
1104static __devexit int wm8955_i2c_remove(struct i2c_client *client)
1105{
1106 struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
1107 wm8955_unregister(wm8955);
1108 return 0;
1109}
1110
1111static const struct i2c_device_id wm8955_i2c_id[] = {
1112 { "wm8955", 0 },
1113 { }
1114};
1115MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
1116
1117static struct i2c_driver wm8955_i2c_driver = {
1118 .driver = {
1119 .name = "wm8955",
1120 .owner = THIS_MODULE,
1121 },
1122 .probe = wm8955_i2c_probe,
1123 .remove = __devexit_p(wm8955_i2c_remove),
1124 .id_table = wm8955_i2c_id,
1125};
1126#endif
1127
1128static int __init wm8955_modinit(void)
1129{
1130 int ret;
1131#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1132 ret = i2c_add_driver(&wm8955_i2c_driver);
1133 if (ret != 0) {
1134 printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
1135 ret);
1136 }
1137#endif
1138 return 0;
1139}
1140module_init(wm8955_modinit);
1141
1142static void __exit wm8955_exit(void)
1143{
1144#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1145 i2c_del_driver(&wm8955_i2c_driver);
1146#endif
1147}
1148module_exit(wm8955_exit);
1149
1150MODULE_DESCRIPTION("ASoC WM8955 driver");
1151MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1152MODULE_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/wm8960.c b/sound/soc/codecs/wm8960.c
index f59703be61c8..f1e63e01b04d 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -15,6 +15,7 @@
15#include <linux/pm.h> 15#include <linux/pm.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/slab.h>
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
20#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
@@ -307,7 +308,6 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
307 308
308 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 309 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
309 310
310 snd_soc_dapm_new_widgets(codec);
311 return 0; 311 return 0;
312} 312}
313 313
@@ -540,8 +540,8 @@ static int pll_factors(unsigned int source, unsigned int target,
540 return 0; 540 return 0;
541} 541}
542 542
543static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, 543static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
544 int pll_id, unsigned int freq_in, unsigned int freq_out) 544 int source, unsigned int freq_in, unsigned int freq_out)
545{ 545{
546 struct snd_soc_codec *codec = codec_dai->codec; 546 struct snd_soc_codec *codec = codec_dai->codec;
547 u16 reg; 547 u16 reg;
@@ -713,17 +713,9 @@ static int wm8960_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, wm8960_snd_controls, 713 snd_soc_add_controls(codec, wm8960_snd_controls,
714 ARRAY_SIZE(wm8960_snd_controls)); 714 ARRAY_SIZE(wm8960_snd_controls));
715 wm8960_add_widgets(codec); 715 wm8960_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 716
722 return ret; 717 return ret;
723 718
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 719pcm_err:
728 return ret; 720 return ret;
729} 721}
@@ -883,21 +875,6 @@ static __devexit int wm8960_i2c_remove(struct i2c_client *client)
883 return 0; 875 return 0;
884} 876}
885 877
886#ifdef CONFIG_PM
887static int wm8960_i2c_suspend(struct i2c_client *client, pm_message_t msg)
888{
889 return snd_soc_suspend_device(&client->dev);
890}
891
892static int wm8960_i2c_resume(struct i2c_client *client)
893{
894 return snd_soc_resume_device(&client->dev);
895}
896#else
897#define wm8960_i2c_suspend NULL
898#define wm8960_i2c_resume NULL
899#endif
900
901static const struct i2c_device_id wm8960_i2c_id[] = { 878static const struct i2c_device_id wm8960_i2c_id[] = {
902 { "wm8960", 0 }, 879 { "wm8960", 0 },
903 { } 880 { }
@@ -911,8 +888,6 @@ static struct i2c_driver wm8960_i2c_driver = {
911 }, 888 },
912 .probe = wm8960_i2c_probe, 889 .probe = wm8960_i2c_probe,
913 .remove = __devexit_p(wm8960_i2c_remove), 890 .remove = __devexit_p(wm8960_i2c_remove),
914 .suspend = wm8960_i2c_suspend,
915 .resume = wm8960_i2c_resume,
916 .id_table = wm8960_i2c_id, 891 .id_table = wm8960_i2c_id,
917}; 892};
918 893
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 503032085899..50634ab76a5c 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -986,19 +987,9 @@ static int wm8961_probe(struct platform_device *pdev)
986 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets, 987 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
987 ARRAY_SIZE(wm8961_dapm_widgets)); 988 ARRAY_SIZE(wm8961_dapm_widgets));
988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 989 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
989 snd_soc_dapm_new_widgets(codec);
990
991 ret = snd_soc_init_card(socdev);
992 if (ret < 0) {
993 dev_err(codec->dev, "failed to register card: %d\n", ret);
994 goto card_err;
995 }
996 990
997 return ret; 991 return ret;
998 992
999card_err:
1000 snd_soc_free_pcms(socdev);
1001 snd_soc_dapm_free(socdev);
1002pcm_err: 993pcm_err:
1003 return ret; 994 return ret;
1004} 995}
@@ -1032,6 +1023,9 @@ static int wm8961_resume(struct platform_device *pdev)
1032 int i; 1023 int i;
1033 1024
1034 for (i = 0; i < codec->reg_cache_size; i++) { 1025 for (i = 0; i < codec->reg_cache_size; i++) {
1026 if (reg_cache[i] == wm8961_reg_defaults[i])
1027 continue;
1028
1035 if (i == WM8961_SOFTWARE_RESET) 1029 if (i == WM8961_SOFTWARE_RESET)
1036 continue; 1030 continue;
1037 1031
@@ -1206,21 +1200,6 @@ static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1206 return 0; 1200 return 0;
1207} 1201}
1208 1202
1209#ifdef CONFIG_PM
1210static int wm8961_i2c_suspend(struct i2c_client *client, pm_message_t state)
1211{
1212 return snd_soc_suspend_device(&client->dev);
1213}
1214
1215static int wm8961_i2c_resume(struct i2c_client *client)
1216{
1217 return snd_soc_resume_device(&client->dev);
1218}
1219#else
1220#define wm8961_i2c_suspend NULL
1221#define wm8961_i2c_resume NULL
1222#endif
1223
1224static const struct i2c_device_id wm8961_i2c_id[] = { 1203static const struct i2c_device_id wm8961_i2c_id[] = {
1225 { "wm8961", 0 }, 1204 { "wm8961", 0 },
1226 { } 1205 { }
@@ -1234,8 +1213,6 @@ static struct i2c_driver wm8961_i2c_driver = {
1234 }, 1213 },
1235 .probe = wm8961_i2c_probe, 1214 .probe = wm8961_i2c_probe,
1236 .remove = __devexit_p(wm8961_i2c_remove), 1215 .remove = __devexit_p(wm8961_i2c_remove),
1237 .suspend = wm8961_i2c_suspend,
1238 .resume = wm8961_i2c_resume,
1239 .id_table = wm8961_i2c_id, 1216 .id_table = wm8961_i2c_id,
1240}; 1217};
1241 1218
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index d66efb0546ea..a65b781af512 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -20,6 +20,7 @@
20#include <linux/pm.h> 20#include <linux/pm.h>
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
@@ -338,8 +339,6 @@ static int wm8971_add_widgets(struct snd_soc_codec *codec)
338 339
339 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 340 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
340 341
341 snd_soc_dapm_new_widgets(codec);
342
343 return 0; 342 return 0;
344} 343}
345 344
@@ -703,16 +702,9 @@ static int wm8971_init(struct snd_soc_device *socdev,
703 snd_soc_add_controls(codec, wm8971_snd_controls, 702 snd_soc_add_controls(codec, wm8971_snd_controls,
704 ARRAY_SIZE(wm8971_snd_controls)); 703 ARRAY_SIZE(wm8971_snd_controls));
705 wm8971_add_widgets(codec); 704 wm8971_add_widgets(codec);
706 ret = snd_soc_init_card(socdev); 705
707 if (ret < 0) {
708 printk(KERN_ERR "wm8971: failed to register card\n");
709 goto card_err;
710 }
711 return ret; 706 return ret;
712 707
713card_err:
714 snd_soc_free_pcms(socdev);
715 snd_soc_dapm_free(socdev);
716err: 708err:
717 kfree(codec->reg_cache); 709 kfree(codec->reg_cache);
718 return ret; 710 return ret;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 98d663afc97d..69708c4cc004 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -47,7 +48,7 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
47}; 48};
48 49
49#define WM8974_POWER1_BIASEN 0x08 50#define WM8974_POWER1_BIASEN 0x08
50#define WM8974_POWER1_BUFIOEN 0x10 51#define WM8974_POWER1_BUFIOEN 0x04
51 52
52struct wm8974_priv { 53struct wm8974_priv {
53 struct snd_soc_codec codec; 54 struct snd_soc_codec codec;
@@ -170,6 +171,10 @@ SOC_ENUM("Aux Mode", wm8974_auxmode),
170 171
171SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0), 172SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0),
172SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1), 173SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
174
175/* DAC / ADC oversampling */
176SOC_SINGLE("DAC 128x Oversampling Switch", WM8974_DAC, 8, 1, 0),
177SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 8, 1, 0),
173}; 178};
174 179
175/* Speaker Output Mixer */ 180/* Speaker Output Mixer */
@@ -276,41 +281,42 @@ static int wm8974_add_widgets(struct snd_soc_codec *codec)
276 281
277 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 282 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
278 283
279 snd_soc_dapm_new_widgets(codec);
280 return 0; 284 return 0;
281} 285}
282 286
283struct pll_ { 287struct pll_ {
284 unsigned int pre_div:4; /* prescale - 1 */ 288 unsigned int pre_div:1;
285 unsigned int n:4; 289 unsigned int n:4;
286 unsigned int k; 290 unsigned int k;
287}; 291};
288 292
289static struct pll_ pll_div;
290
291/* The size in bits of the pll divide multiplied by 10 293/* The size in bits of the pll divide multiplied by 10
292 * to allow rounding later */ 294 * to allow rounding later */
293#define FIXED_PLL_SIZE ((1 << 24) * 10) 295#define FIXED_PLL_SIZE ((1 << 24) * 10)
294 296
295static void pll_factors(unsigned int target, unsigned int source) 297static void pll_factors(struct pll_ *pll_div,
298 unsigned int target, unsigned int source)
296{ 299{
297 unsigned long long Kpart; 300 unsigned long long Kpart;
298 unsigned int K, Ndiv, Nmod; 301 unsigned int K, Ndiv, Nmod;
299 302
303 /* There is a fixed divide by 4 in the output path */
304 target *= 4;
305
300 Ndiv = target / source; 306 Ndiv = target / source;
301 if (Ndiv < 6) { 307 if (Ndiv < 6) {
302 source >>= 1; 308 source /= 2;
303 pll_div.pre_div = 1; 309 pll_div->pre_div = 1;
304 Ndiv = target / source; 310 Ndiv = target / source;
305 } else 311 } else
306 pll_div.pre_div = 0; 312 pll_div->pre_div = 0;
307 313
308 if ((Ndiv < 6) || (Ndiv > 12)) 314 if ((Ndiv < 6) || (Ndiv > 12))
309 printk(KERN_WARNING 315 printk(KERN_WARNING
310 "WM8974 N value %u outwith recommended range!\n", 316 "WM8974 N value %u outwith recommended range!\n",
311 Ndiv); 317 Ndiv);
312 318
313 pll_div.n = Ndiv; 319 pll_div->n = Ndiv;
314 Nmod = target % source; 320 Nmod = target % source;
315 Kpart = FIXED_PLL_SIZE * (long long)Nmod; 321 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
316 322
@@ -325,13 +331,14 @@ static void pll_factors(unsigned int target, unsigned int source)
325 /* Move down to proper range now rounding is done */ 331 /* Move down to proper range now rounding is done */
326 K /= 10; 332 K /= 10;
327 333
328 pll_div.k = K; 334 pll_div->k = K;
329} 335}
330 336
331static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, 337static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
332 int pll_id, unsigned int freq_in, unsigned int freq_out) 338 int source, unsigned int freq_in, unsigned int freq_out)
333{ 339{
334 struct snd_soc_codec *codec = codec_dai->codec; 340 struct snd_soc_codec *codec = codec_dai->codec;
341 struct pll_ pll_div;
335 u16 reg; 342 u16 reg;
336 343
337 if (freq_in == 0 || freq_out == 0) { 344 if (freq_in == 0 || freq_out == 0) {
@@ -345,7 +352,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
345 return 0; 352 return 0;
346 } 353 }
347 354
348 pll_factors(freq_out*4, freq_in); 355 pll_factors(&pll_div, freq_out, freq_in);
349 356
350 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); 357 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
351 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18); 358 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
@@ -379,14 +386,6 @@ static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
379 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f; 386 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
380 snd_soc_write(codec, WM8974_CLOCK, reg | div); 387 snd_soc_write(codec, WM8974_CLOCK, reg | div);
381 break; 388 break;
382 case WM8974_ADCCLK:
383 reg = snd_soc_read(codec, WM8974_ADC) & 0x1f7;
384 snd_soc_write(codec, WM8974_ADC, reg | div);
385 break;
386 case WM8974_DACCLK:
387 reg = snd_soc_read(codec, WM8974_DAC) & 0x1f7;
388 snd_soc_write(codec, WM8974_DAC, reg | div);
389 break;
390 case WM8974_BCLKDIV: 389 case WM8974_BCLKDIV:
391 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3; 390 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
392 snd_soc_write(codec, WM8974_CLOCK, reg | div); 391 snd_soc_write(codec, WM8974_CLOCK, reg | div);
@@ -480,23 +479,23 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
480 479
481 /* filter coefficient */ 480 /* filter coefficient */
482 switch (params_rate(params)) { 481 switch (params_rate(params)) {
483 case SNDRV_PCM_RATE_8000: 482 case 8000:
484 adn |= 0x5 << 1; 483 adn |= 0x5 << 1;
485 break; 484 break;
486 case SNDRV_PCM_RATE_11025: 485 case 11025:
487 adn |= 0x4 << 1; 486 adn |= 0x4 << 1;
488 break; 487 break;
489 case SNDRV_PCM_RATE_16000: 488 case 16000:
490 adn |= 0x3 << 1; 489 adn |= 0x3 << 1;
491 break; 490 break;
492 case SNDRV_PCM_RATE_22050: 491 case 22050:
493 adn |= 0x2 << 1; 492 adn |= 0x2 << 1;
494 break; 493 break;
495 case SNDRV_PCM_RATE_32000: 494 case 32000:
496 adn |= 0x1 << 1; 495 adn |= 0x1 << 1;
497 break; 496 break;
498 case SNDRV_PCM_RATE_44100: 497 case 44100:
499 case SNDRV_PCM_RATE_48000: 498 case 48000:
500 break; 499 break;
501 } 500 }
502 501
@@ -638,17 +637,9 @@ static int wm8974_probe(struct platform_device *pdev)
638 snd_soc_add_controls(codec, wm8974_snd_controls, 637 snd_soc_add_controls(codec, wm8974_snd_controls,
639 ARRAY_SIZE(wm8974_snd_controls)); 638 ARRAY_SIZE(wm8974_snd_controls));
640 wm8974_add_widgets(codec); 639 wm8974_add_widgets(codec);
641 ret = snd_soc_init_card(socdev);
642 if (ret < 0) {
643 dev_err(codec->dev, "failed to register card: %d\n", ret);
644 goto card_err;
645 }
646 640
647 return ret; 641 return ret;
648 642
649card_err:
650 snd_soc_free_pcms(socdev);
651 snd_soc_dapm_free(socdev);
652pcm_err: 643pcm_err:
653 return ret; 644 return ret;
654} 645}
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..526f56b09066
--- /dev/null
+++ b/sound/soc/codecs/wm8978.c
@@ -0,0 +1,1150 @@
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 <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <asm/div64.h>
31
32#include "wm8978.h"
33
34static struct snd_soc_codec *wm8978_codec;
35
36/* wm8978 register cache. Note that register 0 is not included in the cache. */
37static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
38 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
39 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */
40 0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */
41 0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */
42 0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */
43 0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */
44 0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */
45 0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */
46 0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */
47 0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */
48 0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */
49 0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */
50 0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */
51 0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */
52 0x0001, 0x0001, /* 0x38...0x3b */
53};
54
55/* codec private data */
56struct wm8978_priv {
57 struct snd_soc_codec codec;
58 unsigned int f_pllout;
59 unsigned int f_mclk;
60 unsigned int f_256fs;
61 unsigned int f_opclk;
62 int mclk_idx;
63 enum wm8978_sysclk_src sysclk;
64 u16 reg_cache[WM8978_CACHEREGNUM];
65};
66
67static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
68static const char *wm8978_eqmode[] = {"Capture", "Playback"};
69static const char *wm8978_bw[] = {"Narrow", "Wide"};
70static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"};
71static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"};
72static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"};
73static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"};
74static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
75static const char *wm8978_alc3[] = {"ALC", "Limiter"};
76static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"};
77
78static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1,
79 wm8978_companding);
80static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3,
81 wm8978_companding);
82static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode);
83static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1);
84static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw);
85static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2);
86static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw);
87static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3);
88static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw);
89static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4);
90static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5);
91static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3);
92static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1);
93
94static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
95static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
96static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
97static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
98static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
99
100static const struct snd_kcontrol_new wm8978_snd_controls[] = {
101
102 SOC_SINGLE("Digital Loopback Switch",
103 WM8978_COMPANDING_CONTROL, 0, 1, 0),
104
105 SOC_ENUM("ADC Companding", adc_compand),
106 SOC_ENUM("DAC Companding", dac_compand),
107
108 SOC_DOUBLE("DAC Inversion Switch", WM8978_DAC_CONTROL, 0, 1, 1, 0),
109
110 SOC_DOUBLE_R_TLV("PCM Volume",
111 WM8978_LEFT_DAC_DIGITAL_VOLUME, WM8978_RIGHT_DAC_DIGITAL_VOLUME,
112 0, 255, 0, digital_tlv),
113
114 SOC_SINGLE("High Pass Filter Switch", WM8978_ADC_CONTROL, 8, 1, 0),
115 SOC_SINGLE("High Pass Cut Off", WM8978_ADC_CONTROL, 4, 7, 0),
116 SOC_DOUBLE("ADC Inversion Switch", WM8978_ADC_CONTROL, 0, 1, 1, 0),
117
118 SOC_DOUBLE_R_TLV("ADC Volume",
119 WM8978_LEFT_ADC_DIGITAL_VOLUME, WM8978_RIGHT_ADC_DIGITAL_VOLUME,
120 0, 255, 0, digital_tlv),
121
122 SOC_ENUM("Equaliser Function", eqmode),
123 SOC_ENUM("EQ1 Cut Off", eq1),
124 SOC_SINGLE_TLV("EQ1 Volume", WM8978_EQ1, 0, 24, 1, eq_tlv),
125
126 SOC_ENUM("Equaliser EQ2 Bandwith", eq2bw),
127 SOC_ENUM("EQ2 Cut Off", eq2),
128 SOC_SINGLE_TLV("EQ2 Volume", WM8978_EQ2, 0, 24, 1, eq_tlv),
129
130 SOC_ENUM("Equaliser EQ3 Bandwith", eq3bw),
131 SOC_ENUM("EQ3 Cut Off", eq3),
132 SOC_SINGLE_TLV("EQ3 Volume", WM8978_EQ3, 0, 24, 1, eq_tlv),
133
134 SOC_ENUM("Equaliser EQ4 Bandwith", eq4bw),
135 SOC_ENUM("EQ4 Cut Off", eq4),
136 SOC_SINGLE_TLV("EQ4 Volume", WM8978_EQ4, 0, 24, 1, eq_tlv),
137
138 SOC_ENUM("EQ5 Cut Off", eq5),
139 SOC_SINGLE_TLV("EQ5 Volume", WM8978_EQ5, 0, 24, 1, eq_tlv),
140
141 SOC_SINGLE("DAC Playback Limiter Switch",
142 WM8978_DAC_LIMITER_1, 8, 1, 0),
143 SOC_SINGLE("DAC Playback Limiter Decay",
144 WM8978_DAC_LIMITER_1, 4, 15, 0),
145 SOC_SINGLE("DAC Playback Limiter Attack",
146 WM8978_DAC_LIMITER_1, 0, 15, 0),
147
148 SOC_SINGLE("DAC Playback Limiter Threshold",
149 WM8978_DAC_LIMITER_2, 4, 7, 0),
150 SOC_SINGLE("DAC Playback Limiter Boost",
151 WM8978_DAC_LIMITER_2, 0, 15, 0),
152
153 SOC_ENUM("ALC Enable Switch", alc1),
154 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
155 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0),
156
157 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 7, 0),
158 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0),
159
160 SOC_ENUM("ALC Capture Mode", alc3),
161 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 15, 0),
162 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 15, 0),
163
164 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0),
165 SOC_SINGLE("ALC Capture Noise Gate Threshold",
166 WM8978_NOISE_GATE, 0, 7, 0),
167
168 SOC_DOUBLE_R("Capture PGA ZC Switch",
169 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
170 7, 1, 0),
171
172 /* OUT1 - Headphones */
173 SOC_DOUBLE_R("Headphone Playback ZC Switch",
174 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 7, 1, 0),
175
176 SOC_DOUBLE_R_TLV("Headphone Playback Volume",
177 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL,
178 0, 63, 0, spk_tlv),
179
180 /* OUT2 - Speakers */
181 SOC_DOUBLE_R("Speaker Playback ZC Switch",
182 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 7, 1, 0),
183
184 SOC_DOUBLE_R_TLV("Speaker Playback Volume",
185 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL,
186 0, 63, 0, spk_tlv),
187
188 /* OUT3/4 - Line Output */
189 SOC_DOUBLE_R("Line Playback Switch",
190 WM8978_OUT3_MIXER_CONTROL, WM8978_OUT4_MIXER_CONTROL, 6, 1, 1),
191
192 /* Mixer #3: Boost (Input) mixer */
193 SOC_DOUBLE_R("PGA Boost (+20dB)",
194 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
195 8, 1, 0),
196 SOC_DOUBLE_R_TLV("L2/R2 Boost Volume",
197 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
198 4, 7, 0, boost_tlv),
199 SOC_DOUBLE_R_TLV("Aux Boost Volume",
200 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
201 0, 7, 0, boost_tlv),
202
203 /* Input PGA volume */
204 SOC_DOUBLE_R_TLV("Input PGA Volume",
205 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
206 0, 63, 0, inpga_tlv),
207
208 /* Headphone */
209 SOC_DOUBLE_R("Headphone Switch",
210 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 6, 1, 1),
211
212 /* Speaker */
213 SOC_DOUBLE_R("Speaker Switch",
214 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1),
215
216 /* DAC / ADC oversampling */
217 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, 8, 1, 0),
218 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, 8, 1, 0),
219};
220
221/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
222static const struct snd_kcontrol_new wm8978_left_out_mixer[] = {
223 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_LEFT_MIXER_CONTROL, 1, 1, 0),
224 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_LEFT_MIXER_CONTROL, 5, 1, 0),
225 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_LEFT_MIXER_CONTROL, 0, 1, 0),
226};
227
228static const struct snd_kcontrol_new wm8978_right_out_mixer[] = {
229 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_RIGHT_MIXER_CONTROL, 1, 1, 0),
230 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 5, 1, 0),
231 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 0, 1, 0),
232};
233
234/* OUT3/OUT4 Mixer not implemented */
235
236/* Mixer #2: Input PGA Mute */
237static const struct snd_kcontrol_new wm8978_left_input_mixer[] = {
238 SOC_DAPM_SINGLE("L2 Switch", WM8978_INPUT_CONTROL, 2, 1, 0),
239 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 1, 1, 0),
240 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 0, 1, 0),
241};
242static const struct snd_kcontrol_new wm8978_right_input_mixer[] = {
243 SOC_DAPM_SINGLE("R2 Switch", WM8978_INPUT_CONTROL, 6, 1, 0),
244 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 5, 1, 0),
245 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 4, 1, 0),
246};
247
248static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = {
249 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
250 WM8978_POWER_MANAGEMENT_3, 0, 0),
251 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
252 WM8978_POWER_MANAGEMENT_3, 1, 0),
253 SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
254 WM8978_POWER_MANAGEMENT_2, 0, 0),
255 SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
256 WM8978_POWER_MANAGEMENT_2, 1, 0),
257
258 /* Mixer #1: OUT1,2 */
259 SOC_MIXER_ARRAY("Left Output Mixer", WM8978_POWER_MANAGEMENT_3,
260 2, 0, wm8978_left_out_mixer),
261 SOC_MIXER_ARRAY("Right Output Mixer", WM8978_POWER_MANAGEMENT_3,
262 3, 0, wm8978_right_out_mixer),
263
264 SOC_MIXER_ARRAY("Left Input Mixer", WM8978_POWER_MANAGEMENT_2,
265 2, 0, wm8978_left_input_mixer),
266 SOC_MIXER_ARRAY("Right Input Mixer", WM8978_POWER_MANAGEMENT_2,
267 3, 0, wm8978_right_input_mixer),
268
269 SND_SOC_DAPM_PGA("Left Boost Mixer", WM8978_POWER_MANAGEMENT_2,
270 4, 0, NULL, 0),
271 SND_SOC_DAPM_PGA("Right Boost Mixer", WM8978_POWER_MANAGEMENT_2,
272 5, 0, NULL, 0),
273
274 SND_SOC_DAPM_PGA("Left Capture PGA", WM8978_LEFT_INP_PGA_CONTROL,
275 6, 1, NULL, 0),
276 SND_SOC_DAPM_PGA("Right Capture PGA", WM8978_RIGHT_INP_PGA_CONTROL,
277 6, 1, NULL, 0),
278
279 SND_SOC_DAPM_PGA("Left Headphone Out", WM8978_POWER_MANAGEMENT_2,
280 7, 0, NULL, 0),
281 SND_SOC_DAPM_PGA("Right Headphone Out", WM8978_POWER_MANAGEMENT_2,
282 8, 0, NULL, 0),
283
284 SND_SOC_DAPM_PGA("Left Speaker Out", WM8978_POWER_MANAGEMENT_3,
285 6, 0, NULL, 0),
286 SND_SOC_DAPM_PGA("Right Speaker Out", WM8978_POWER_MANAGEMENT_3,
287 5, 0, NULL, 0),
288
289 SND_SOC_DAPM_MIXER("OUT4 VMID", WM8978_POWER_MANAGEMENT_3,
290 8, 0, NULL, 0),
291
292 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8978_POWER_MANAGEMENT_1, 4, 0),
293
294 SND_SOC_DAPM_INPUT("LMICN"),
295 SND_SOC_DAPM_INPUT("LMICP"),
296 SND_SOC_DAPM_INPUT("RMICN"),
297 SND_SOC_DAPM_INPUT("RMICP"),
298 SND_SOC_DAPM_INPUT("LAUX"),
299 SND_SOC_DAPM_INPUT("RAUX"),
300 SND_SOC_DAPM_INPUT("L2"),
301 SND_SOC_DAPM_INPUT("R2"),
302 SND_SOC_DAPM_OUTPUT("LHP"),
303 SND_SOC_DAPM_OUTPUT("RHP"),
304 SND_SOC_DAPM_OUTPUT("LSPK"),
305 SND_SOC_DAPM_OUTPUT("RSPK"),
306};
307
308static const struct snd_soc_dapm_route audio_map[] = {
309 /* Output mixer */
310 {"Right Output Mixer", "PCM Playback Switch", "Right DAC"},
311 {"Right Output Mixer", "Aux Playback Switch", "RAUX"},
312 {"Right Output Mixer", "Line Bypass Switch", "Right Boost Mixer"},
313
314 {"Left Output Mixer", "PCM Playback Switch", "Left DAC"},
315 {"Left Output Mixer", "Aux Playback Switch", "LAUX"},
316 {"Left Output Mixer", "Line Bypass Switch", "Left Boost Mixer"},
317
318 /* Outputs */
319 {"Right Headphone Out", NULL, "Right Output Mixer"},
320 {"RHP", NULL, "Right Headphone Out"},
321
322 {"Left Headphone Out", NULL, "Left Output Mixer"},
323 {"LHP", NULL, "Left Headphone Out"},
324
325 {"Right Speaker Out", NULL, "Right Output Mixer"},
326 {"RSPK", NULL, "Right Speaker Out"},
327
328 {"Left Speaker Out", NULL, "Left Output Mixer"},
329 {"LSPK", NULL, "Left Speaker Out"},
330
331 /* Boost Mixer */
332 {"Right ADC", NULL, "Right Boost Mixer"},
333
334 {"Right Boost Mixer", NULL, "RAUX"},
335 {"Right Boost Mixer", NULL, "Right Capture PGA"},
336 {"Right Boost Mixer", NULL, "R2"},
337
338 {"Left ADC", NULL, "Left Boost Mixer"},
339
340 {"Left Boost Mixer", NULL, "LAUX"},
341 {"Left Boost Mixer", NULL, "Left Capture PGA"},
342 {"Left Boost Mixer", NULL, "L2"},
343
344 /* Input PGA */
345 {"Right Capture PGA", NULL, "Right Input Mixer"},
346 {"Left Capture PGA", NULL, "Left Input Mixer"},
347
348 {"Right Input Mixer", "R2 Switch", "R2"},
349 {"Right Input Mixer", "MicN Switch", "RMICN"},
350 {"Right Input Mixer", "MicP Switch", "RMICP"},
351
352 {"Left Input Mixer", "L2 Switch", "L2"},
353 {"Left Input Mixer", "MicN Switch", "LMICN"},
354 {"Left Input Mixer", "MicP Switch", "LMICP"},
355};
356
357static int wm8978_add_widgets(struct snd_soc_codec *codec)
358{
359 snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets,
360 ARRAY_SIZE(wm8978_dapm_widgets));
361
362 /* set up the WM8978 audio map */
363 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
364
365 return 0;
366}
367
368/* PLL divisors */
369struct wm8978_pll_div {
370 u32 k;
371 u8 n;
372 u8 div2;
373};
374
375#define FIXED_PLL_SIZE (1 << 24)
376
377static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
378 unsigned int source)
379{
380 u64 k_part;
381 unsigned int k, n_div, n_mod;
382
383 n_div = target / source;
384 if (n_div < 6) {
385 source >>= 1;
386 pll_div->div2 = 1;
387 n_div = target / source;
388 } else {
389 pll_div->div2 = 0;
390 }
391
392 if (n_div < 6 || n_div > 12)
393 dev_warn(wm8978_codec->dev,
394 "WM8978 N value exceeds recommended range! N = %u\n",
395 n_div);
396
397 pll_div->n = n_div;
398 n_mod = target - source * n_div;
399 k_part = FIXED_PLL_SIZE * (long long)n_mod + source / 2;
400
401 do_div(k_part, source);
402
403 k = k_part & 0xFFFFFFFF;
404
405 pll_div->k = k;
406}
407
408/* MCLK dividers */
409static const int mclk_numerator[] = {1, 3, 2, 3, 4, 6, 8, 12};
410static const int mclk_denominator[] = {1, 2, 1, 1, 1, 1, 1, 1};
411
412/*
413 * find index >= idx, such that, for a given f_out,
414 * 3 * f_mclk / 4 <= f_PLLOUT < 13 * f_mclk / 4
415 * f_out can be f_256fs or f_opclk, currently only used for f_256fs. Can be
416 * generalised for f_opclk with suitable coefficient arrays, but currently
417 * the OPCLK divisor is calculated directly, not iteratively.
418 */
419static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
420 unsigned int *f_pllout)
421{
422 int i;
423
424 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
425 unsigned int f_pllout_x4 = 4 * f_out * mclk_numerator[i] /
426 mclk_denominator[i];
427 if (3 * f_mclk <= f_pllout_x4 && f_pllout_x4 < 13 * f_mclk) {
428 *f_pllout = f_pllout_x4 / 4;
429 return i;
430 }
431 }
432
433 return -EINVAL;
434}
435
436/*
437 * Calculate internal frequencies and dividers, according to Figure 40
438 * "PLL and Clock Select Circuit" in WM8978 datasheet Rev. 2.6
439 */
440static int wm8978_configure_pll(struct snd_soc_codec *codec)
441{
442 struct wm8978_priv *wm8978 = codec->private_data;
443 struct wm8978_pll_div pll_div;
444 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
445 f_256fs = wm8978->f_256fs;
446 unsigned int f2;
447
448 if (!f_mclk)
449 return -EINVAL;
450
451 if (f_opclk) {
452 unsigned int opclk_div;
453 /* Cannot set up MCLK divider now, do later */
454 wm8978->mclk_idx = -1;
455
456 /*
457 * The user needs OPCLK. Choose OPCLKDIV to put
458 * 6 <= R = f2 / f1 < 13, 1 <= OPCLKDIV <= 4.
459 * f_opclk = f_mclk * prescale * R / 4 / OPCLKDIV, where
460 * prescale = 1, or prescale = 2. Prescale is calculated inside
461 * pll_factors(). We have to select f_PLLOUT, such that
462 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
463 * f_mclk * 3 / 16 <= f_opclk < f_mclk * 13 / 4.
464 */
465 if (16 * f_opclk < 3 * f_mclk || 4 * f_opclk >= 13 * f_mclk)
466 return -EINVAL;
467
468 if (4 * f_opclk < 3 * f_mclk)
469 /* Have to use OPCLKDIV */
470 opclk_div = (3 * f_mclk / 4 + f_opclk - 1) / f_opclk;
471 else
472 opclk_div = 1;
473
474 dev_dbg(codec->dev, "%s: OPCLKDIV=%d\n", __func__, opclk_div);
475
476 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 0x30,
477 (opclk_div - 1) << 4);
478
479 wm8978->f_pllout = f_opclk * opclk_div;
480 } else if (f_256fs) {
481 /*
482 * Not using OPCLK, but PLL is used for the codec, choose R:
483 * 6 <= R = f2 / f1 < 13, to put 1 <= MCLKDIV <= 12.
484 * f_256fs = f_mclk * prescale * R / 4 / MCLKDIV, where
485 * prescale = 1, or prescale = 2. Prescale is calculated inside
486 * pll_factors(). We have to select f_PLLOUT, such that
487 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
488 * f_mclk * 3 / 48 <= f_256fs < f_mclk * 13 / 4. This means MCLK
489 * must be 3.781MHz <= f_MCLK <= 32.768MHz
490 */
491 int idx = wm8978_enum_mclk(f_256fs, f_mclk, &wm8978->f_pllout);
492 if (idx < 0)
493 return idx;
494
495 wm8978->mclk_idx = idx;
496
497 /* GPIO1 into default mode as input - before configuring PLL */
498 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
499 } else {
500 return -EINVAL;
501 }
502
503 f2 = wm8978->f_pllout * 4;
504
505 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
506 wm8978->f_mclk, wm8978->f_pllout);
507
508 pll_factors(&pll_div, f2, wm8978->f_mclk);
509
510 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
511 __func__, pll_div.n, pll_div.k, pll_div.div2);
512
513 /* Turn PLL off for configuration... */
514 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
515
516 snd_soc_write(codec, WM8978_PLL_N, (pll_div.div2 << 4) | pll_div.n);
517 snd_soc_write(codec, WM8978_PLL_K1, pll_div.k >> 18);
518 snd_soc_write(codec, WM8978_PLL_K2, (pll_div.k >> 9) & 0x1ff);
519 snd_soc_write(codec, WM8978_PLL_K3, pll_div.k & 0x1ff);
520
521 /* ...and on again */
522 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
523
524 if (f_opclk)
525 /* Output PLL (OPCLK) to GPIO1 */
526 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 4);
527
528 return 0;
529}
530
531/*
532 * Configure WM8978 clock dividers.
533 */
534static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
535 int div_id, int div)
536{
537 struct snd_soc_codec *codec = codec_dai->codec;
538 struct wm8978_priv *wm8978 = codec->private_data;
539 int ret = 0;
540
541 switch (div_id) {
542 case WM8978_OPCLKRATE:
543 wm8978->f_opclk = div;
544
545 if (wm8978->f_mclk)
546 /*
547 * We know the MCLK frequency, the user has requested
548 * OPCLK, configure the PLL based on that and start it
549 * and OPCLK immediately. We will configure PLL to match
550 * user-requested OPCLK frquency as good as possible.
551 * In fact, it is likely, that matching the sampling
552 * rate, when it becomes known, is more important, and
553 * we will not be reconfiguring PLL then, because we
554 * must not interrupt OPCLK. But it should be fine,
555 * because typically the user will request OPCLK to run
556 * at 256fs or 512fs, and for these cases we will also
557 * find an exact MCLK divider configuration - it will
558 * be equal to or double the OPCLK divisor.
559 */
560 ret = wm8978_configure_pll(codec);
561 break;
562 case WM8978_BCLKDIV:
563 if (div & ~0x1c)
564 return -EINVAL;
565 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x1c, div);
566 break;
567 default:
568 return -EINVAL;
569 }
570
571 dev_dbg(codec->dev, "%s: ID %d, value %u\n", __func__, div_id, div);
572
573 return ret;
574}
575
576/*
577 * @freq: when .set_pll() us not used, freq is codec MCLK input frequency
578 */
579static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
580 unsigned int freq, int dir)
581{
582 struct snd_soc_codec *codec = codec_dai->codec;
583 struct wm8978_priv *wm8978 = codec->private_data;
584 int ret = 0;
585
586 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
587
588 if (freq) {
589 wm8978->f_mclk = freq;
590
591 /* Even if MCLK is used for system clock, might have to drive OPCLK */
592 if (wm8978->f_opclk)
593 ret = wm8978_configure_pll(codec);
594
595 /* Our sysclk is fixed to 256 * fs, will configure in .hw_params() */
596
597 if (!ret)
598 wm8978->sysclk = clk_id;
599 }
600
601 if (wm8978->sysclk == WM8978_PLL && (!freq || clk_id == WM8978_MCLK)) {
602 /* Clock CODEC directly from MCLK */
603 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
604
605 /* GPIO1 into default mode as input - before configuring PLL */
606 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
607
608 /* Turn off PLL */
609 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
610 wm8978->sysclk = WM8978_MCLK;
611 wm8978->f_pllout = 0;
612 wm8978->f_opclk = 0;
613 }
614
615 return ret;
616}
617
618/*
619 * Set ADC and Voice DAC format.
620 */
621static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
622{
623 struct snd_soc_codec *codec = codec_dai->codec;
624 /*
625 * BCLK polarity mask = 0x100, LRC clock polarity mask = 0x80,
626 * Data Format mask = 0x18: all will be calculated anew
627 */
628 u16 iface = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x198;
629 u16 clk = snd_soc_read(codec, WM8978_CLOCKING);
630
631 dev_dbg(codec->dev, "%s\n", __func__);
632
633 /* set master/slave audio interface */
634 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
635 case SND_SOC_DAIFMT_CBM_CFM:
636 clk |= 1;
637 break;
638 case SND_SOC_DAIFMT_CBS_CFS:
639 clk &= ~1;
640 break;
641 default:
642 return -EINVAL;
643 }
644
645 /* interface format */
646 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
647 case SND_SOC_DAIFMT_I2S:
648 iface |= 0x10;
649 break;
650 case SND_SOC_DAIFMT_RIGHT_J:
651 break;
652 case SND_SOC_DAIFMT_LEFT_J:
653 iface |= 0x8;
654 break;
655 case SND_SOC_DAIFMT_DSP_A:
656 iface |= 0x18;
657 break;
658 default:
659 return -EINVAL;
660 }
661
662 /* clock inversion */
663 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
664 case SND_SOC_DAIFMT_NB_NF:
665 break;
666 case SND_SOC_DAIFMT_IB_IF:
667 iface |= 0x180;
668 break;
669 case SND_SOC_DAIFMT_IB_NF:
670 iface |= 0x100;
671 break;
672 case SND_SOC_DAIFMT_NB_IF:
673 iface |= 0x80;
674 break;
675 default:
676 return -EINVAL;
677 }
678
679 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface);
680 snd_soc_write(codec, WM8978_CLOCKING, clk);
681
682 return 0;
683}
684
685/*
686 * Set PCM DAI bit size and sample rate.
687 */
688static int wm8978_hw_params(struct snd_pcm_substream *substream,
689 struct snd_pcm_hw_params *params,
690 struct snd_soc_dai *dai)
691{
692 struct snd_soc_pcm_runtime *rtd = substream->private_data;
693 struct snd_soc_device *socdev = rtd->socdev;
694 struct snd_soc_codec *codec = socdev->card->codec;
695 struct wm8978_priv *wm8978 = codec->private_data;
696 /* Word length mask = 0x60 */
697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
698 /* Sampling rate mask = 0xe (for filters) */
699 u16 add_ctl = snd_soc_read(codec, WM8978_ADDITIONAL_CONTROL) & ~0xe;
700 u16 clking = snd_soc_read(codec, WM8978_CLOCKING);
701 enum wm8978_sysclk_src current_clk_id = clking & 0x100 ?
702 WM8978_PLL : WM8978_MCLK;
703 unsigned int f_sel, diff, diff_best = INT_MAX;
704 int i, best = 0;
705
706 if (!wm8978->f_mclk)
707 return -EINVAL;
708
709 /* bit size */
710 switch (params_format(params)) {
711 case SNDRV_PCM_FORMAT_S16_LE:
712 break;
713 case SNDRV_PCM_FORMAT_S20_3LE:
714 iface_ctl |= 0x20;
715 break;
716 case SNDRV_PCM_FORMAT_S24_LE:
717 iface_ctl |= 0x40;
718 break;
719 case SNDRV_PCM_FORMAT_S32_LE:
720 iface_ctl |= 0x60;
721 break;
722 }
723
724 /* filter coefficient */
725 switch (params_rate(params)) {
726 case 8000:
727 add_ctl |= 0x5 << 1;
728 break;
729 case 11025:
730 add_ctl |= 0x4 << 1;
731 break;
732 case 16000:
733 add_ctl |= 0x3 << 1;
734 break;
735 case 22050:
736 add_ctl |= 0x2 << 1;
737 break;
738 case 32000:
739 add_ctl |= 0x1 << 1;
740 break;
741 case 44100:
742 case 48000:
743 break;
744 }
745
746 /* Sampling rate is known now, can configure the MCLK divider */
747 wm8978->f_256fs = params_rate(params) * 256;
748
749 if (wm8978->sysclk == WM8978_MCLK) {
750 wm8978->mclk_idx = -1;
751 f_sel = wm8978->f_mclk;
752 } else {
753 if (!wm8978->f_pllout) {
754 /* We only enter here, if OPCLK is not used */
755 int ret = wm8978_configure_pll(codec);
756 if (ret < 0)
757 return ret;
758 }
759 f_sel = wm8978->f_pllout;
760 }
761
762 if (wm8978->mclk_idx < 0) {
763 /* Either MCLK is used directly, or OPCLK is used */
764 if (f_sel < wm8978->f_256fs || f_sel > 12 * wm8978->f_256fs)
765 return -EINVAL;
766
767 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
768 diff = abs(wm8978->f_256fs * 3 -
769 f_sel * 3 * mclk_denominator[i] / mclk_numerator[i]);
770
771 if (diff < diff_best) {
772 diff_best = diff;
773 best = i;
774 }
775
776 if (!diff)
777 break;
778 }
779 } else {
780 /* OPCLK not used, codec driven by PLL */
781 best = wm8978->mclk_idx;
782 diff = 0;
783 }
784
785 if (diff)
786 dev_warn(codec->dev, "Imprecise sampling rate: %uHz%s\n",
787 f_sel * mclk_denominator[best] / mclk_numerator[best] / 256,
788 wm8978->sysclk == WM8978_MCLK ?
789 ", consider using PLL" : "");
790
791 dev_dbg(codec->dev, "%s: fmt %d, rate %u, MCLK divisor #%d\n", __func__,
792 params_format(params), params_rate(params), best);
793
794 /* MCLK divisor mask = 0xe0 */
795 snd_soc_update_bits(codec, WM8978_CLOCKING, 0xe0, best << 5);
796
797 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface_ctl);
798 snd_soc_write(codec, WM8978_ADDITIONAL_CONTROL, add_ctl);
799
800 if (wm8978->sysclk != current_clk_id) {
801 if (wm8978->sysclk == WM8978_PLL)
802 /* Run CODEC from PLL instead of MCLK */
803 snd_soc_update_bits(codec, WM8978_CLOCKING,
804 0x100, 0x100);
805 else
806 /* Clock CODEC directly from MCLK */
807 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
808 }
809
810 return 0;
811}
812
813static int wm8978_mute(struct snd_soc_dai *dai, int mute)
814{
815 struct snd_soc_codec *codec = dai->codec;
816
817 dev_dbg(codec->dev, "%s: %d\n", __func__, mute);
818
819 if (mute)
820 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0x40);
821 else
822 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0);
823
824 return 0;
825}
826
827static int wm8978_set_bias_level(struct snd_soc_codec *codec,
828 enum snd_soc_bias_level level)
829{
830 u16 power1 = snd_soc_read(codec, WM8978_POWER_MANAGEMENT_1) & ~3;
831
832 switch (level) {
833 case SND_SOC_BIAS_ON:
834 case SND_SOC_BIAS_PREPARE:
835 power1 |= 1; /* VMID 75k */
836 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
837 break;
838 case SND_SOC_BIAS_STANDBY:
839 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
840 power1 |= 0xc;
841
842 if (codec->bias_level == SND_SOC_BIAS_OFF) {
843 /* Initial cap charge at VMID 5k */
844 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
845 power1 | 0x3);
846 mdelay(100);
847 }
848
849 power1 |= 0x2; /* VMID 500k */
850 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
851 break;
852 case SND_SOC_BIAS_OFF:
853 /* Preserve PLL - OPCLK may be used by someone */
854 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
855 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0);
856 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0);
857 break;
858 }
859
860 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
861
862 codec->bias_level = level;
863 return 0;
864}
865
866#define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
867 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
868
869static struct snd_soc_dai_ops wm8978_dai_ops = {
870 .hw_params = wm8978_hw_params,
871 .digital_mute = wm8978_mute,
872 .set_fmt = wm8978_set_dai_fmt,
873 .set_clkdiv = wm8978_set_dai_clkdiv,
874 .set_sysclk = wm8978_set_dai_sysclk,
875};
876
877/* Also supports 12kHz */
878struct snd_soc_dai wm8978_dai = {
879 .name = "WM8978 HiFi",
880 .id = 1,
881 .playback = {
882 .stream_name = "Playback",
883 .channels_min = 1,
884 .channels_max = 2,
885 .rates = SNDRV_PCM_RATE_8000_48000,
886 .formats = WM8978_FORMATS,
887 },
888 .capture = {
889 .stream_name = "Capture",
890 .channels_min = 1,
891 .channels_max = 2,
892 .rates = SNDRV_PCM_RATE_8000_48000,
893 .formats = WM8978_FORMATS,
894 },
895 .ops = &wm8978_dai_ops,
896};
897EXPORT_SYMBOL_GPL(wm8978_dai);
898
899static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
900{
901 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
902 struct snd_soc_codec *codec = socdev->card->codec;
903
904 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
905 /* Also switch PLL off */
906 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
907
908 return 0;
909}
910
911static int wm8978_resume(struct platform_device *pdev)
912{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec = socdev->card->codec;
915 struct wm8978_priv *wm8978 = codec->private_data;
916 int i;
917 u16 *cache = codec->reg_cache;
918
919 /* Sync reg_cache with the hardware */
920 for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) {
921 if (i == WM8978_RESET)
922 continue;
923 if (cache[i] != wm8978_reg[i])
924 snd_soc_write(codec, i, cache[i]);
925 }
926
927 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
928
929 if (wm8978->f_pllout)
930 /* Switch PLL on */
931 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
932
933 return 0;
934}
935
936static int wm8978_probe(struct platform_device *pdev)
937{
938 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
939 struct snd_soc_codec *codec;
940 int ret = 0;
941
942 if (wm8978_codec == NULL) {
943 dev_err(&pdev->dev, "Codec device not registered\n");
944 return -ENODEV;
945 }
946
947 socdev->card->codec = wm8978_codec;
948 codec = wm8978_codec;
949
950 /* register pcms */
951 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
952 if (ret < 0) {
953 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
954 goto pcm_err;
955 }
956
957 snd_soc_add_controls(codec, wm8978_snd_controls,
958 ARRAY_SIZE(wm8978_snd_controls));
959 wm8978_add_widgets(codec);
960
961pcm_err:
962 return ret;
963}
964
965/* power down chip */
966static int wm8978_remove(struct platform_device *pdev)
967{
968 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
969
970 snd_soc_free_pcms(socdev);
971 snd_soc_dapm_free(socdev);
972
973 return 0;
974}
975
976struct snd_soc_codec_device soc_codec_dev_wm8978 = {
977 .probe = wm8978_probe,
978 .remove = wm8978_remove,
979 .suspend = wm8978_suspend,
980 .resume = wm8978_resume,
981};
982EXPORT_SYMBOL_GPL(soc_codec_dev_wm8978);
983
984/*
985 * These registers contain an "update" bit - bit 8. This means, for example,
986 * that one can write new DAC digital volume for both channels, but only when
987 * the update bit is set, will also the volume be updated - simultaneously for
988 * both channels.
989 */
990static const int update_reg[] = {
991 WM8978_LEFT_DAC_DIGITAL_VOLUME,
992 WM8978_RIGHT_DAC_DIGITAL_VOLUME,
993 WM8978_LEFT_ADC_DIGITAL_VOLUME,
994 WM8978_RIGHT_ADC_DIGITAL_VOLUME,
995 WM8978_LEFT_INP_PGA_CONTROL,
996 WM8978_RIGHT_INP_PGA_CONTROL,
997 WM8978_LOUT1_HP_CONTROL,
998 WM8978_ROUT1_HP_CONTROL,
999 WM8978_LOUT2_SPK_CONTROL,
1000 WM8978_ROUT2_SPK_CONTROL,
1001};
1002
1003static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1004{
1005 int ret, i;
1006 struct snd_soc_codec *codec = &wm8978->codec;
1007
1008 if (wm8978_codec) {
1009 dev_err(codec->dev, "Another WM8978 is registered\n");
1010 return -EINVAL;
1011 }
1012
1013 /*
1014 * Set default system clock to PLL, it is more precise, this is also the
1015 * default hardware setting
1016 */
1017 wm8978->sysclk = WM8978_PLL;
1018
1019 mutex_init(&codec->mutex);
1020 INIT_LIST_HEAD(&codec->dapm_widgets);
1021 INIT_LIST_HEAD(&codec->dapm_paths);
1022
1023 codec->private_data = wm8978;
1024 codec->name = "WM8978";
1025 codec->owner = THIS_MODULE;
1026 codec->bias_level = SND_SOC_BIAS_OFF;
1027 codec->set_bias_level = wm8978_set_bias_level;
1028 codec->dai = &wm8978_dai;
1029 codec->num_dai = 1;
1030 codec->reg_cache_size = WM8978_CACHEREGNUM;
1031 codec->reg_cache = &wm8978->reg_cache;
1032
1033 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
1034 if (ret < 0) {
1035 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1036 goto err;
1037 }
1038
1039 memcpy(codec->reg_cache, wm8978_reg, sizeof(wm8978_reg));
1040
1041 /*
1042 * Set the update bit in all registers, that have one. This way all
1043 * writes to those registers will also cause the update bit to be
1044 * written.
1045 */
1046 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
1047 ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100;
1048
1049 /* Reset the codec */
1050 ret = snd_soc_write(codec, WM8978_RESET, 0);
1051 if (ret < 0) {
1052 dev_err(codec->dev, "Failed to issue reset\n");
1053 goto err;
1054 }
1055
1056 wm8978_dai.dev = codec->dev;
1057
1058 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1059
1060 wm8978_codec = codec;
1061
1062 ret = snd_soc_register_codec(codec);
1063 if (ret != 0) {
1064 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1065 goto err;
1066 }
1067
1068 ret = snd_soc_register_dai(&wm8978_dai);
1069 if (ret != 0) {
1070 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1071 goto err_codec;
1072 }
1073
1074 return 0;
1075
1076err_codec:
1077 snd_soc_unregister_codec(codec);
1078err:
1079 kfree(wm8978);
1080 return ret;
1081}
1082
1083static __devexit void wm8978_unregister(struct wm8978_priv *wm8978)
1084{
1085 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF);
1086 snd_soc_unregister_dai(&wm8978_dai);
1087 snd_soc_unregister_codec(&wm8978->codec);
1088 kfree(wm8978);
1089 wm8978_codec = NULL;
1090}
1091
1092static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1093 const struct i2c_device_id *id)
1094{
1095 struct wm8978_priv *wm8978;
1096 struct snd_soc_codec *codec;
1097
1098 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
1099 if (wm8978 == NULL)
1100 return -ENOMEM;
1101
1102 codec = &wm8978->codec;
1103 codec->hw_write = (hw_write_t)i2c_master_send;
1104
1105 i2c_set_clientdata(i2c, wm8978);
1106 codec->control_data = i2c;
1107
1108 codec->dev = &i2c->dev;
1109
1110 return wm8978_register(wm8978);
1111}
1112
1113static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1114{
1115 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1116 wm8978_unregister(wm8978);
1117 return 0;
1118}
1119
1120static const struct i2c_device_id wm8978_i2c_id[] = {
1121 { "wm8978", 0 },
1122 { }
1123};
1124MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1125
1126static struct i2c_driver wm8978_i2c_driver = {
1127 .driver = {
1128 .name = "WM8978",
1129 .owner = THIS_MODULE,
1130 },
1131 .probe = wm8978_i2c_probe,
1132 .remove = __devexit_p(wm8978_i2c_remove),
1133 .id_table = wm8978_i2c_id,
1134};
1135
1136static int __init wm8978_modinit(void)
1137{
1138 return i2c_add_driver(&wm8978_i2c_driver);
1139}
1140module_init(wm8978_modinit);
1141
1142static void __exit wm8978_exit(void)
1143{
1144 i2c_del_driver(&wm8978_i2c_driver);
1145}
1146module_exit(wm8978_exit);
1147
1148MODULE_DESCRIPTION("ASoC WM8978 codec driver");
1149MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1150MODULE_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/wm8988.c b/sound/soc/codecs/wm8988.c
index 3f530f8a972a..bb18c3ecfeb9 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -19,6 +19,7 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -790,19 +791,9 @@ static int wm8988_probe(struct platform_device *pdev)
790 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, 791 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
791 ARRAY_SIZE(wm8988_dapm_widgets)); 792 ARRAY_SIZE(wm8988_dapm_widgets));
792 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 793 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
793 snd_soc_dapm_new_widgets(codec);
794
795 ret = snd_soc_init_card(socdev);
796 if (ret < 0) {
797 dev_err(codec->dev, "failed to register card: %d\n", ret);
798 goto card_err;
799 }
800 794
801 return ret; 795 return ret;
802 796
803card_err:
804 snd_soc_free_pcms(socdev);
805 snd_soc_dapm_free(socdev);
806pcm_err: 797pcm_err:
807 return ret; 798 return ret;
808} 799}
@@ -944,21 +935,6 @@ static int wm8988_i2c_remove(struct i2c_client *client)
944 return 0; 935 return 0;
945} 936}
946 937
947#ifdef CONFIG_PM
948static int wm8988_i2c_suspend(struct i2c_client *client, pm_message_t msg)
949{
950 return snd_soc_suspend_device(&client->dev);
951}
952
953static int wm8988_i2c_resume(struct i2c_client *client)
954{
955 return snd_soc_resume_device(&client->dev);
956}
957#else
958#define wm8988_i2c_suspend NULL
959#define wm8988_i2c_resume NULL
960#endif
961
962static const struct i2c_device_id wm8988_i2c_id[] = { 938static const struct i2c_device_id wm8988_i2c_id[] = {
963 { "wm8988", 0 }, 939 { "wm8988", 0 },
964 { } 940 { }
@@ -972,8 +948,6 @@ static struct i2c_driver wm8988_i2c_driver = {
972 }, 948 },
973 .probe = wm8988_i2c_probe, 949 .probe = wm8988_i2c_probe,
974 .remove = wm8988_i2c_remove, 950 .remove = wm8988_i2c_remove,
975 .suspend = wm8988_i2c_suspend,
976 .resume = wm8988_i2c_resume,
977 .id_table = wm8988_i2c_id, 951 .id_table = wm8988_i2c_id,
978}; 952};
979#endif 953#endif
@@ -1006,21 +980,6 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi)
1006 return 0; 980 return 0;
1007} 981}
1008 982
1009#ifdef CONFIG_PM
1010static int wm8988_spi_suspend(struct spi_device *spi, pm_message_t msg)
1011{
1012 return snd_soc_suspend_device(&spi->dev);
1013}
1014
1015static int wm8988_spi_resume(struct spi_device *spi)
1016{
1017 return snd_soc_resume_device(&spi->dev);
1018}
1019#else
1020#define wm8988_spi_suspend NULL
1021#define wm8988_spi_resume NULL
1022#endif
1023
1024static struct spi_driver wm8988_spi_driver = { 983static struct spi_driver wm8988_spi_driver = {
1025 .driver = { 984 .driver = {
1026 .name = "wm8988", 985 .name = "wm8988",
@@ -1029,8 +988,6 @@ static struct spi_driver wm8988_spi_driver = {
1029 }, 988 },
1030 .probe = wm8988_spi_probe, 989 .probe = wm8988_spi_probe,
1031 .remove = __devexit_p(wm8988_spi_remove), 990 .remove = __devexit_p(wm8988_spi_remove),
1032 .suspend = wm8988_spi_suspend,
1033 .resume = wm8988_spi_resume,
1034}; 991};
1035#endif 992#endif
1036 993
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 2d702db4131d..831f4730bfd5 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -920,7 +921,6 @@ static int wm8990_add_widgets(struct snd_soc_codec *codec)
920 /* set up the WM8990 audio map */ 921 /* set up the WM8990 audio map */
921 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 922 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
922 923
923 snd_soc_dapm_new_widgets(codec);
924 return 0; 924 return 0;
925} 925}
926 926
@@ -972,8 +972,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
972 pll_div->k = K; 972 pll_div->k = K;
973} 973}
974 974
975static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, 975static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
976 int pll_id, unsigned int freq_in, unsigned int freq_out) 976 int source, unsigned int freq_in, unsigned int freq_out)
977{ 977{
978 u16 reg; 978 u16 reg;
979 struct snd_soc_codec *codec = codec_dai->codec; 979 struct snd_soc_codec *codec = codec_dai->codec;
@@ -991,7 +991,7 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai,
991 reg = snd_soc_read(codec, WM8990_CLOCKING_2); 991 reg = snd_soc_read(codec, WM8990_CLOCKING_2);
992 snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); 992 snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC);
993 993
994 /* set up N , fractional mode and pre-divisor if neccessary */ 994 /* set up N , fractional mode and pre-divisor if necessary */
995 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | 995 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
996 (pll_div.div2?WM8990_PRESCALE:0)); 996 (pll_div.div2?WM8990_PRESCALE:0));
997 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); 997 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
@@ -1320,10 +1320,6 @@ static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
1320 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1320 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1321 struct snd_soc_codec *codec = socdev->card->codec; 1321 struct snd_soc_codec *codec = socdev->card->codec;
1322 1322
1323 /* we only need to suspend if we are a valid card */
1324 if (!codec->card)
1325 return 0;
1326
1327 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); 1323 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1328 return 0; 1324 return 0;
1329} 1325}
@@ -1336,10 +1332,6 @@ static int wm8990_resume(struct platform_device *pdev)
1336 u8 data[2]; 1332 u8 data[2];
1337 u16 *cache = codec->reg_cache; 1333 u16 *cache = codec->reg_cache;
1338 1334
1339 /* we only need to resume if we are a valid card */
1340 if (!codec->card)
1341 return 0;
1342
1343 /* Sync reg_cache with the hardware */ 1335 /* Sync reg_cache with the hardware */
1344 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) { 1336 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) {
1345 if (i + 1 == WM8990_RESET) 1337 if (i + 1 == WM8990_RESET)
@@ -1409,16 +1401,9 @@ static int wm8990_init(struct snd_soc_device *socdev)
1409 snd_soc_add_controls(codec, wm8990_snd_controls, 1401 snd_soc_add_controls(codec, wm8990_snd_controls,
1410 ARRAY_SIZE(wm8990_snd_controls)); 1402 ARRAY_SIZE(wm8990_snd_controls));
1411 wm8990_add_widgets(codec); 1403 wm8990_add_widgets(codec);
1412 ret = snd_soc_init_card(socdev); 1404
1413 if (ret < 0) {
1414 printk(KERN_ERR "wm8990: failed to register card\n");
1415 goto card_err;
1416 }
1417 return ret; 1405 return ret;
1418 1406
1419card_err:
1420 snd_soc_free_pcms(socdev);
1421 snd_soc_dapm_free(socdev);
1422pcm_err: 1407pcm_err:
1423 kfree(codec->reg_cache); 1408 kfree(codec->reg_cache);
1424 return ret; 1409 return ret;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d9987999e92c..03e8b1a6a56c 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,7 +16,9 @@
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>
21#include <linux/slab.h>
20#include <sound/core.h> 22#include <sound/core.h>
21#include <sound/pcm.h> 23#include <sound/pcm.h>
22#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -29,6 +31,16 @@
29#include "wm8993.h" 31#include "wm8993.h"
30#include "wm_hubs.h" 32#include "wm_hubs.h"
31 33
34#define WM8993_NUM_SUPPLIES 6
35static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
36 "DCVDD",
37 "DBVDD",
38 "AVDD1",
39 "AVDD2",
40 "CPVDD",
41 "SPKVDD",
42};
43
32static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { 44static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = {
33 0x8993, /* R0 - Software Reset */ 45 0x8993, /* R0 - Software Reset */
34 0x0000, /* R1 - Power Management (1) */ 46 0x0000, /* R1 - Power Management (1) */
@@ -213,7 +225,9 @@ static struct {
213}; 225};
214 226
215struct wm8993_priv { 227struct wm8993_priv {
228 struct wm_hubs_data hubs_data;
216 u16 reg_cache[WM8993_REGISTER_COUNT]; 229 u16 reg_cache[WM8993_REGISTER_COUNT];
230 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
217 struct wm8993_platform_data pdata; 231 struct wm8993_platform_data pdata;
218 struct snd_soc_codec codec; 232 struct snd_soc_codec codec;
219 int master; 233 int master;
@@ -227,36 +241,9 @@ struct wm8993_priv {
227 int class_w_users; 241 int class_w_users;
228 unsigned int fll_fref; 242 unsigned int fll_fref;
229 unsigned int fll_fout; 243 unsigned int fll_fout;
244 int fll_src;
230}; 245};
231 246
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) 247static int wm8993_volatile(unsigned int reg)
261{ 248{
262 switch (reg) { 249 switch (reg) {
@@ -271,48 +258,6 @@ static int wm8993_volatile(unsigned int reg)
271 } 258 }
272} 259}
273 260
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 { 261struct _fll_div {
317 u16 fll_fratio; 262 u16 fll_fratio;
318 u16 fll_outdiv; 263 u16 fll_outdiv;
@@ -422,7 +367,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
422 return 0; 367 return 0;
423} 368}
424 369
425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, 370static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
426 unsigned int Fref, unsigned int Fout) 371 unsigned int Fref, unsigned int Fout)
427{ 372{
428 struct snd_soc_codec *codec = dai->codec; 373 struct snd_soc_codec *codec = dai->codec;
@@ -441,9 +386,9 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id,
441 wm8993->fll_fref = 0; 386 wm8993->fll_fref = 0;
442 wm8993->fll_fout = 0; 387 wm8993->fll_fout = 0;
443 388
444 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 389 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
445 reg1 &= ~WM8993_FLL_ENA; 390 reg1 &= ~WM8993_FLL_ENA;
446 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 391 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
447 392
448 return 0; 393 return 0;
449 } 394 }
@@ -452,7 +397,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id,
452 if (ret != 0) 397 if (ret != 0)
453 return ret; 398 return ret;
454 399
455 reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5); 400 reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5);
456 reg5 &= ~WM8993_FLL_CLK_SRC_MASK; 401 reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
457 402
458 switch (fll_id) { 403 switch (fll_id) {
@@ -474,38 +419,39 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id,
474 419
475 /* Any FLL configuration change requires that the FLL be 420 /* Any FLL configuration change requires that the FLL be
476 * disabled first. */ 421 * disabled first. */
477 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 422 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
478 reg1 &= ~WM8993_FLL_ENA; 423 reg1 &= ~WM8993_FLL_ENA;
479 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 424 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
480 425
481 /* Apply the configuration */ 426 /* Apply the configuration */
482 if (fll_div.k) 427 if (fll_div.k)
483 reg1 |= WM8993_FLL_FRAC_MASK; 428 reg1 |= WM8993_FLL_FRAC_MASK;
484 else 429 else
485 reg1 &= ~WM8993_FLL_FRAC_MASK; 430 reg1 &= ~WM8993_FLL_FRAC_MASK;
486 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 431 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
487 432
488 wm8993_write(codec, WM8993_FLL_CONTROL_2, 433 snd_soc_write(codec, WM8993_FLL_CONTROL_2,
489 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) | 434 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
490 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT)); 435 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
491 wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k); 436 snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
492 437
493 reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4); 438 reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4);
494 reg4 &= ~WM8993_FLL_N_MASK; 439 reg4 &= ~WM8993_FLL_N_MASK;
495 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT; 440 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
496 wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4); 441 snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4);
497 442
498 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK; 443 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
499 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; 444 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
500 wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5); 445 snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
501 446
502 /* Enable the FLL */ 447 /* Enable the FLL */
503 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); 448 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
504 449
505 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 450 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
506 451
507 wm8993->fll_fref = Fref; 452 wm8993->fll_fref = Fref;
508 wm8993->fll_fout = Fout; 453 wm8993->fll_fout = Fout;
454 wm8993->fll_src = source;
509 455
510 return 0; 456 return 0;
511} 457}
@@ -520,7 +466,7 @@ static int configure_clock(struct snd_soc_codec *codec)
520 case WM8993_SYSCLK_MCLK: 466 case WM8993_SYSCLK_MCLK:
521 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); 467 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
522 468
523 reg = wm8993_read(codec, WM8993_CLOCKING_2); 469 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
524 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC); 470 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
525 if (wm8993->mclk_rate > 13500000) { 471 if (wm8993->mclk_rate > 13500000) {
526 reg |= WM8993_MCLK_DIV; 472 reg |= WM8993_MCLK_DIV;
@@ -529,14 +475,14 @@ static int configure_clock(struct snd_soc_codec *codec)
529 reg &= ~WM8993_MCLK_DIV; 475 reg &= ~WM8993_MCLK_DIV;
530 wm8993->sysclk_rate = wm8993->mclk_rate; 476 wm8993->sysclk_rate = wm8993->mclk_rate;
531 } 477 }
532 wm8993_write(codec, WM8993_CLOCKING_2, reg); 478 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
533 break; 479 break;
534 480
535 case WM8993_SYSCLK_FLL: 481 case WM8993_SYSCLK_FLL:
536 dev_dbg(codec->dev, "Using %dHz FLL clock\n", 482 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
537 wm8993->fll_fout); 483 wm8993->fll_fout);
538 484
539 reg = wm8993_read(codec, WM8993_CLOCKING_2); 485 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
540 reg |= WM8993_SYSCLK_SRC; 486 reg |= WM8993_SYSCLK_SRC;
541 if (wm8993->fll_fout > 13500000) { 487 if (wm8993->fll_fout > 13500000) {
542 reg |= WM8993_MCLK_DIV; 488 reg |= WM8993_MCLK_DIV;
@@ -545,7 +491,7 @@ static int configure_clock(struct snd_soc_codec *codec)
545 reg &= ~WM8993_MCLK_DIV; 491 reg &= ~WM8993_MCLK_DIV;
546 wm8993->sysclk_rate = wm8993->fll_fout; 492 wm8993->sysclk_rate = wm8993->fll_fout;
547 } 493 }
548 wm8993_write(codec, WM8993_CLOCKING_2, reg); 494 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
549 break; 495 break;
550 496
551 default: 497 default:
@@ -689,7 +635,7 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE,
689 635
690SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0), 636SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0),
691SOC_ENUM("DRC Path", drc_path), 637SOC_ENUM("DRC Path", drc_path),
692SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8993_DRC_CONTROL_2, 638SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8993_DRC_CONTROL_2,
693 2, 60, 1, drc_comp_threash), 639 2, 60, 1, drc_comp_threash),
694SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3, 640SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3,
695 11, 30, 1, drc_comp_amp), 641 11, 30, 1, drc_comp_amp),
@@ -709,7 +655,7 @@ SOC_SINGLE_TLV("DRC Quick Release Volume", WM8993_DRC_CONTROL_3, 2, 3, 0,
709SOC_ENUM("DRC Quick Release Rate", drc_qr_rate), 655SOC_ENUM("DRC Quick Release Rate", drc_qr_rate),
710SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0), 656SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0),
711SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0), 657SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0),
712SOC_ENUM("DRC Smoothing Hysteresis Threashold", drc_smooth), 658SOC_ENUM("DRC Smoothing Hysteresis Threshold", drc_smooth),
713SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0, 659SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0,
714 drc_startup_tlv), 660 drc_startup_tlv),
715 661
@@ -978,10 +924,33 @@ static const struct snd_soc_dapm_route routes[] = {
978 { "Right Headphone Mux", "DAC", "DACR" }, 924 { "Right Headphone Mux", "DAC", "DACR" },
979}; 925};
980 926
927static void wm8993_cache_restore(struct snd_soc_codec *codec)
928{
929 u16 *cache = codec->reg_cache;
930 int i;
931
932 if (!codec->cache_sync)
933 return;
934
935 /* Reenable hardware writes */
936 codec->cache_only = 0;
937
938 /* Restore the register settings */
939 for (i = 1; i < WM8993_MAX_REGISTER; i++) {
940 if (cache[i] == wm8993_reg_defaults[i])
941 continue;
942 snd_soc_write(codec, i, cache[i]);
943 }
944
945 /* We're in sync again */
946 codec->cache_sync = 0;
947}
948
981static int wm8993_set_bias_level(struct snd_soc_codec *codec, 949static int wm8993_set_bias_level(struct snd_soc_codec *codec,
982 enum snd_soc_bias_level level) 950 enum snd_soc_bias_level level)
983{ 951{
984 struct wm8993_priv *wm8993 = codec->private_data; 952 struct wm8993_priv *wm8993 = codec->private_data;
953 int ret;
985 954
986 switch (level) { 955 switch (level) {
987 case SND_SOC_BIAS_ON: 956 case SND_SOC_BIAS_ON:
@@ -995,6 +964,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
995 964
996 case SND_SOC_BIAS_STANDBY: 965 case SND_SOC_BIAS_STANDBY:
997 if (codec->bias_level == SND_SOC_BIAS_OFF) { 966 if (codec->bias_level == SND_SOC_BIAS_OFF) {
967 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
968 wm8993->supplies);
969 if (ret != 0)
970 return ret;
971
972 wm8993_cache_restore(codec);
973
974 /* Tune DC servo configuration */
975 snd_soc_write(codec, 0x44, 3);
976 snd_soc_write(codec, 0x56, 3);
977 snd_soc_write(codec, 0x44, 0);
978
998 /* Bring up VMID with fast soft start */ 979 /* Bring up VMID with fast soft start */
999 snd_soc_update_bits(codec, WM8993_ANTIPOP2, 980 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1000 WM8993_STARTUP_BIAS_ENA | 981 WM8993_STARTUP_BIAS_ENA |
@@ -1042,6 +1023,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1042 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 1023 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1043 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 1024 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1044 0); 1025 0);
1026
1027#ifdef CONFIG_REGULATOR
1028 /* Post 2.6.34 we will be able to get a callback when
1029 * the regulators are disabled which we can use but
1030 * for now just assume that the power will be cut if
1031 * the regulator API is in use.
1032 */
1033 codec->cache_sync = 1;
1034#endif
1035
1036 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
1037 wm8993->supplies);
1045 break; 1038 break;
1046 } 1039 }
1047 1040
@@ -1075,8 +1068,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1075{ 1068{
1076 struct snd_soc_codec *codec = dai->codec; 1069 struct snd_soc_codec *codec = dai->codec;
1077 struct wm8993_priv *wm8993 = codec->private_data; 1070 struct wm8993_priv *wm8993 = codec->private_data;
1078 unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1071 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1079 unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1072 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1080 1073
1081 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | 1074 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1082 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); 1075 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
@@ -1159,8 +1152,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1159 return -EINVAL; 1152 return -EINVAL;
1160 } 1153 }
1161 1154
1162 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1155 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1163 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1156 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1164 1157
1165 return 0; 1158 return 0;
1166} 1159}
@@ -1174,16 +1167,16 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1174 int ret, i, best, best_val, cur_val; 1167 int ret, i, best, best_val, cur_val;
1175 unsigned int clocking1, clocking3, aif1, aif4; 1168 unsigned int clocking1, clocking3, aif1, aif4;
1176 1169
1177 clocking1 = wm8993_read(codec, WM8993_CLOCKING_1); 1170 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
1178 clocking1 &= ~WM8993_BCLK_DIV_MASK; 1171 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1179 1172
1180 clocking3 = wm8993_read(codec, WM8993_CLOCKING_3); 1173 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
1181 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); 1174 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
1182 1175
1183 aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1176 aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1184 aif1 &= ~WM8993_AIF_WL_MASK; 1177 aif1 &= ~WM8993_AIF_WL_MASK;
1185 1178
1186 aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1179 aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1187 aif4 &= ~WM8993_LRCLK_RATE_MASK; 1180 aif4 &= ~WM8993_LRCLK_RATE_MASK;
1188 1181
1189 /* What BCLK do we need? */ 1182 /* What BCLK do we need? */
@@ -1276,14 +1269,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); 1269 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
1277 aif4 |= wm8993->bclk / wm8993->fs; 1270 aif4 |= wm8993->bclk / wm8993->fs;
1278 1271
1279 wm8993_write(codec, WM8993_CLOCKING_1, clocking1); 1272 snd_soc_write(codec, WM8993_CLOCKING_1, clocking1);
1280 wm8993_write(codec, WM8993_CLOCKING_3, clocking3); 1273 snd_soc_write(codec, WM8993_CLOCKING_3, clocking3);
1281 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1274 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1282 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1275 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1283 1276
1284 /* ReTune Mobile? */ 1277 /* ReTune Mobile? */
1285 if (wm8993->pdata.num_retune_configs) { 1278 if (wm8993->pdata.num_retune_configs) {
1286 u16 eq1 = wm8993_read(codec, WM8993_EQ1); 1279 u16 eq1 = snd_soc_read(codec, WM8993_EQ1);
1287 struct wm8993_retune_mobile_setting *s; 1280 struct wm8993_retune_mobile_setting *s;
1288 1281
1289 best = 0; 1282 best = 0;
@@ -1306,7 +1299,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1306 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0); 1299 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
1307 1300
1308 for (i = 1; i < ARRAY_SIZE(s->config); i++) 1301 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1309 wm8993_write(codec, WM8993_EQ1 + i, s->config[i]); 1302 snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]);
1310 1303
1311 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1); 1304 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
1312 } 1305 }
@@ -1319,14 +1312,14 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1319 struct snd_soc_codec *codec = codec_dai->codec; 1312 struct snd_soc_codec *codec = codec_dai->codec;
1320 unsigned int reg; 1313 unsigned int reg;
1321 1314
1322 reg = wm8993_read(codec, WM8993_DAC_CTRL); 1315 reg = snd_soc_read(codec, WM8993_DAC_CTRL);
1323 1316
1324 if (mute) 1317 if (mute)
1325 reg |= WM8993_DAC_MUTE; 1318 reg |= WM8993_DAC_MUTE;
1326 else 1319 else
1327 reg &= ~WM8993_DAC_MUTE; 1320 reg &= ~WM8993_DAC_MUTE;
1328 1321
1329 wm8993_write(codec, WM8993_DAC_CTRL, reg); 1322 snd_soc_write(codec, WM8993_DAC_CTRL, reg);
1330 1323
1331 return 0; 1324 return 0;
1332} 1325}
@@ -1464,19 +1457,8 @@ static int wm8993_probe(struct platform_device *pdev)
1464 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1457 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1465 wm8993->pdata.lineout2_diff); 1458 wm8993->pdata.lineout2_diff);
1466 1459
1467 snd_soc_dapm_new_widgets(codec);
1468
1469 ret = snd_soc_init_card(socdev);
1470 if (ret < 0) {
1471 dev_err(codec->dev, "failed to register card\n");
1472 goto card_err;
1473 }
1474
1475 return ret; 1460 return ret;
1476 1461
1477card_err:
1478 snd_soc_free_pcms(socdev);
1479 snd_soc_dapm_free(socdev);
1480err: 1462err:
1481 return ret; 1463 return ret;
1482} 1464}
@@ -1491,9 +1473,66 @@ static int wm8993_remove(struct platform_device *pdev)
1491 return 0; 1473 return 0;
1492} 1474}
1493 1475
1476#ifdef CONFIG_PM
1477static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1478{
1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1480 struct snd_soc_codec *codec = socdev->card->codec;
1481 struct wm8993_priv *wm8993 = codec->private_data;
1482 int fll_fout = wm8993->fll_fout;
1483 int fll_fref = wm8993->fll_fref;
1484 int ret;
1485
1486 /* Stop the FLL in an orderly fashion */
1487 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
1488 if (ret != 0) {
1489 dev_err(&pdev->dev, "Failed to stop FLL\n");
1490 return ret;
1491 }
1492
1493 wm8993->fll_fout = fll_fout;
1494 wm8993->fll_fref = fll_fref;
1495
1496 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1497
1498 return 0;
1499}
1500
1501static int wm8993_resume(struct platform_device *pdev)
1502{
1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1504 struct snd_soc_codec *codec = socdev->card->codec;
1505 struct wm8993_priv *wm8993 = codec->private_data;
1506 int ret;
1507
1508 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1509
1510 /* Restart the FLL? */
1511 if (wm8993->fll_fout) {
1512 int fll_fout = wm8993->fll_fout;
1513 int fll_fref = wm8993->fll_fref;
1514
1515 wm8993->fll_fref = 0;
1516 wm8993->fll_fout = 0;
1517
1518 ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src,
1519 fll_fref, fll_fout);
1520 if (ret != 0)
1521 dev_err(codec->dev, "Failed to restart FLL\n");
1522 }
1523
1524 return 0;
1525}
1526#else
1527#define wm8993_suspend NULL
1528#define wm8993_resume NULL
1529#endif
1530
1494struct snd_soc_codec_device soc_codec_dev_wm8993 = { 1531struct snd_soc_codec_device soc_codec_dev_wm8993 = {
1495 .probe = wm8993_probe, 1532 .probe = wm8993_probe,
1496 .remove = wm8993_remove, 1533 .remove = wm8993_remove,
1534 .suspend = wm8993_suspend,
1535 .resume = wm8993_resume,
1497}; 1536};
1498EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993); 1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1499 1538
@@ -1504,6 +1543,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1504 struct snd_soc_codec *codec; 1543 struct snd_soc_codec *codec;
1505 unsigned int val; 1544 unsigned int val;
1506 int ret; 1545 int ret;
1546 int i;
1507 1547
1508 if (wm8993_codec) { 1548 if (wm8993_codec) {
1509 dev_err(&i2c->dev, "A WM8993 is already registered\n"); 1549 dev_err(&i2c->dev, "A WM8993 is already registered\n");
@@ -1524,9 +1564,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1524 INIT_LIST_HEAD(&codec->dapm_paths); 1564 INIT_LIST_HEAD(&codec->dapm_paths);
1525 1565
1526 codec->name = "WM8993"; 1566 codec->name = "WM8993";
1527 codec->read = wm8993_read; 1567 codec->volatile_register = wm8993_volatile;
1528 codec->write = wm8993_write;
1529 codec->hw_write = (hw_write_t)i2c_master_send;
1530 codec->reg_cache = wm8993->reg_cache; 1568 codec->reg_cache = wm8993->reg_cache;
1531 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); 1569 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1532 codec->bias_level = SND_SOC_BIAS_OFF; 1570 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -1535,25 +1573,53 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1535 codec->num_dai = 1; 1573 codec->num_dai = 1;
1536 codec->private_data = wm8993; 1574 codec->private_data = wm8993;
1537 1575
1576 wm8993->hubs_data.hp_startup_mode = 1;
1577 wm8993->hubs_data.dcs_codes = -2;
1578
1538 memcpy(wm8993->reg_cache, wm8993_reg_defaults, 1579 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1539 sizeof(wm8993->reg_cache)); 1580 sizeof(wm8993->reg_cache));
1540 1581
1582 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1583 if (ret != 0) {
1584 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1585 goto err;
1586 }
1587
1541 i2c_set_clientdata(i2c, wm8993); 1588 i2c_set_clientdata(i2c, wm8993);
1542 codec->control_data = i2c; 1589 codec->control_data = i2c;
1543 wm8993_codec = codec; 1590 wm8993_codec = codec;
1544 1591
1545 codec->dev = &i2c->dev; 1592 codec->dev = &i2c->dev;
1546 1593
1547 val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET); 1594 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1595 wm8993->supplies[i].supply = wm8993_supply_names[i];
1596
1597 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1598 wm8993->supplies);
1599 if (ret != 0) {
1600 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1601 goto err;
1602 }
1603
1604 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1605 wm8993->supplies);
1606 if (ret != 0) {
1607 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1608 goto err_get;
1609 }
1610
1611 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1548 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { 1612 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1549 dev_err(codec->dev, "Invalid ID register value %x\n", val); 1613 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1550 ret = -EINVAL; 1614 ret = -EINVAL;
1551 goto err; 1615 goto err_enable;
1552 } 1616 }
1553 1617
1554 ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff); 1618 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1555 if (ret != 0) 1619 if (ret != 0)
1556 goto err; 1620 goto err_enable;
1621
1622 codec->cache_only = 1;
1557 1623
1558 /* By default we're using the output mixers */ 1624 /* By default we're using the output mixers */
1559 wm8993->class_w_users = 2; 1625 wm8993->class_w_users = 2;
@@ -1572,36 +1638,18 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1572 /* Use automatic clock configuration */ 1638 /* Use automatic clock configuration */
1573 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0); 1639 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1574 1640
1575 if (!wm8993->pdata.lineout1_diff) 1641 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1576 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 1642 wm8993->pdata.lineout2_diff,
1577 WM8993_LINEOUT1_MODE, 1643 wm8993->pdata.lineout1fb,
1578 WM8993_LINEOUT1_MODE); 1644 wm8993->pdata.lineout2fb,
1579 if (!wm8993->pdata.lineout2_diff) 1645 wm8993->pdata.jd_scthr,
1580 snd_soc_update_bits(codec, WM8993_LINE_MIXER2, 1646 wm8993->pdata.jd_thr,
1581 WM8993_LINEOUT2_MODE, 1647 wm8993->pdata.micbias1_lvl,
1582 WM8993_LINEOUT2_MODE); 1648 wm8993->pdata.micbias2_lvl);
1583 1649
1584 if (wm8993->pdata.lineout1fb)
1585 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1586 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
1587
1588 if (wm8993->pdata.lineout2fb)
1589 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1590 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
1591
1592 /* Apply the microphone bias/detection configuration - the
1593 * platform data is directly applicable to the register. */
1594 snd_soc_update_bits(codec, WM8993_MICBIAS,
1595 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
1596 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
1597 wm8993->pdata.jd_scthr << WM8993_JD_SCTHR_SHIFT |
1598 wm8993->pdata.jd_thr << WM8993_JD_THR_SHIFT |
1599 wm8993->pdata.micbias1_lvl |
1600 wm8993->pdata.micbias1_lvl << 1);
1601
1602 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1650 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1603 if (ret != 0) 1651 if (ret != 0)
1604 goto err; 1652 goto err_enable;
1605 1653
1606 wm8993_dai.dev = codec->dev; 1654 wm8993_dai.dev = codec->dev;
1607 1655
@@ -1615,6 +1663,10 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1615 1663
1616err_bias: 1664err_bias:
1617 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); 1665 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1666err_enable:
1667 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1668err_get:
1669 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1618err: 1670err:
1619 wm8993_codec = NULL; 1671 wm8993_codec = NULL;
1620 kfree(wm8993); 1672 kfree(wm8993);
@@ -1629,6 +1681,7 @@ static int wm8993_i2c_remove(struct i2c_client *client)
1629 snd_soc_unregister_dai(&wm8993_dai); 1681 snd_soc_unregister_dai(&wm8993_dai);
1630 1682
1631 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); 1683 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1684 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1632 kfree(wm8993); 1685 kfree(wm8993);
1633 1686
1634 return 0; 1687 return 0;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
new file mode 100644
index 000000000000..9da0724cd47a
--- /dev/null
+++ b/sound/soc/codecs/wm8994.c
@@ -0,0 +1,3874 @@
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 <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include <linux/mfd/wm8994/core.h>
32#include <linux/mfd/wm8994/registers.h>
33#include <linux/mfd/wm8994/pdata.h>
34#include <linux/mfd/wm8994/gpio.h>
35
36#include "wm8994.h"
37#include "wm_hubs.h"
38
39static struct snd_soc_codec *wm8994_codec;
40struct snd_soc_codec_device soc_codec_dev_wm8994;
41
42struct fll_config {
43 int src;
44 int in;
45 int out;
46};
47
48#define WM8994_NUM_DRC 3
49#define WM8994_NUM_EQ 3
50
51static int wm8994_drc_base[] = {
52 WM8994_AIF1_DRC1_1,
53 WM8994_AIF1_DRC2_1,
54 WM8994_AIF2_DRC_1,
55};
56
57static int wm8994_retune_mobile_base[] = {
58 WM8994_AIF1_DAC1_EQ_GAINS_1,
59 WM8994_AIF1_DAC2_EQ_GAINS_1,
60 WM8994_AIF2_EQ_GAINS_1,
61};
62
63#define WM8994_REG_CACHE_SIZE 0x621
64
65/* codec private data */
66struct wm8994_priv {
67 struct wm_hubs_data hubs;
68 struct snd_soc_codec codec;
69 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
70 int sysclk[2];
71 int sysclk_rate[2];
72 int mclk[2];
73 int aifclk[2];
74 struct fll_config fll[2], fll_suspend[2];
75
76 int dac_rates[2];
77 int lrclk_shared[2];
78
79 /* Platform dependant DRC configuration */
80 const char **drc_texts;
81 int drc_cfg[WM8994_NUM_DRC];
82 struct soc_enum drc_enum;
83
84 /* Platform dependant ReTune mobile configuration */
85 int num_retune_mobile_texts;
86 const char **retune_mobile_texts;
87 int retune_mobile_cfg[WM8994_NUM_EQ];
88 struct soc_enum retune_mobile_enum;
89
90 struct wm8994_pdata *pdata;
91};
92
93static struct {
94 unsigned short readable; /* Mask of readable bits */
95 unsigned short writable; /* Mask of writable bits */
96 unsigned short vol; /* Mask of volatile bits */
97} access_masks[] = {
98 { 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Software Reset */
99 { 0x3B37, 0x3B37, 0x0000 }, /* R1 - Power Management (1) */
100 { 0x6BF0, 0x6BF0, 0x0000 }, /* R2 - Power Management (2) */
101 { 0x3FF0, 0x3FF0, 0x0000 }, /* R3 - Power Management (3) */
102 { 0x3F3F, 0x3F3F, 0x0000 }, /* R4 - Power Management (4) */
103 { 0x3F0F, 0x3F0F, 0x0000 }, /* R5 - Power Management (5) */
104 { 0x003F, 0x003F, 0x0000 }, /* R6 - Power Management (6) */
105 { 0x0000, 0x0000, 0x0000 }, /* R7 */
106 { 0x0000, 0x0000, 0x0000 }, /* R8 */
107 { 0x0000, 0x0000, 0x0000 }, /* R9 */
108 { 0x0000, 0x0000, 0x0000 }, /* R10 */
109 { 0x0000, 0x0000, 0x0000 }, /* R11 */
110 { 0x0000, 0x0000, 0x0000 }, /* R12 */
111 { 0x0000, 0x0000, 0x0000 }, /* R13 */
112 { 0x0000, 0x0000, 0x0000 }, /* R14 */
113 { 0x0000, 0x0000, 0x0000 }, /* R15 */
114 { 0x0000, 0x0000, 0x0000 }, /* R16 */
115 { 0x0000, 0x0000, 0x0000 }, /* R17 */
116 { 0x0000, 0x0000, 0x0000 }, /* R18 */
117 { 0x0000, 0x0000, 0x0000 }, /* R19 */
118 { 0x0000, 0x0000, 0x0000 }, /* R20 */
119 { 0x01C0, 0x01C0, 0x0000 }, /* R21 - Input Mixer (1) */
120 { 0x0000, 0x0000, 0x0000 }, /* R22 */
121 { 0x0000, 0x0000, 0x0000 }, /* R23 */
122 { 0x00DF, 0x01DF, 0x0000 }, /* R24 - Left Line Input 1&2 Volume */
123 { 0x00DF, 0x01DF, 0x0000 }, /* R25 - Left Line Input 3&4 Volume */
124 { 0x00DF, 0x01DF, 0x0000 }, /* R26 - Right Line Input 1&2 Volume */
125 { 0x00DF, 0x01DF, 0x0000 }, /* R27 - Right Line Input 3&4 Volume */
126 { 0x00FF, 0x01FF, 0x0000 }, /* R28 - Left Output Volume */
127 { 0x00FF, 0x01FF, 0x0000 }, /* R29 - Right Output Volume */
128 { 0x0077, 0x0077, 0x0000 }, /* R30 - Line Outputs Volume */
129 { 0x0030, 0x0030, 0x0000 }, /* R31 - HPOUT2 Volume */
130 { 0x00FF, 0x01FF, 0x0000 }, /* R32 - Left OPGA Volume */
131 { 0x00FF, 0x01FF, 0x0000 }, /* R33 - Right OPGA Volume */
132 { 0x007F, 0x007F, 0x0000 }, /* R34 - SPKMIXL Attenuation */
133 { 0x017F, 0x017F, 0x0000 }, /* R35 - SPKMIXR Attenuation */
134 { 0x003F, 0x003F, 0x0000 }, /* R36 - SPKOUT Mixers */
135 { 0x003F, 0x003F, 0x0000 }, /* R37 - ClassD */
136 { 0x00FF, 0x01FF, 0x0000 }, /* R38 - Speaker Volume Left */
137 { 0x00FF, 0x01FF, 0x0000 }, /* R39 - Speaker Volume Right */
138 { 0x00FF, 0x00FF, 0x0000 }, /* R40 - Input Mixer (2) */
139 { 0x01B7, 0x01B7, 0x0000 }, /* R41 - Input Mixer (3) */
140 { 0x01B7, 0x01B7, 0x0000 }, /* R42 - Input Mixer (4) */
141 { 0x01C7, 0x01C7, 0x0000 }, /* R43 - Input Mixer (5) */
142 { 0x01C7, 0x01C7, 0x0000 }, /* R44 - Input Mixer (6) */
143 { 0x01FF, 0x01FF, 0x0000 }, /* R45 - Output Mixer (1) */
144 { 0x01FF, 0x01FF, 0x0000 }, /* R46 - Output Mixer (2) */
145 { 0x0FFF, 0x0FFF, 0x0000 }, /* R47 - Output Mixer (3) */
146 { 0x0FFF, 0x0FFF, 0x0000 }, /* R48 - Output Mixer (4) */
147 { 0x0FFF, 0x0FFF, 0x0000 }, /* R49 - Output Mixer (5) */
148 { 0x0FFF, 0x0FFF, 0x0000 }, /* R50 - Output Mixer (6) */
149 { 0x0038, 0x0038, 0x0000 }, /* R51 - HPOUT2 Mixer */
150 { 0x0077, 0x0077, 0x0000 }, /* R52 - Line Mixer (1) */
151 { 0x0077, 0x0077, 0x0000 }, /* R53 - Line Mixer (2) */
152 { 0x03FF, 0x03FF, 0x0000 }, /* R54 - Speaker Mixer */
153 { 0x00C1, 0x00C1, 0x0000 }, /* R55 - Additional Control */
154 { 0x00F0, 0x00F0, 0x0000 }, /* R56 - AntiPOP (1) */
155 { 0x01EF, 0x01EF, 0x0000 }, /* R57 - AntiPOP (2) */
156 { 0x00FF, 0x00FF, 0x0000 }, /* R58 - MICBIAS */
157 { 0x000F, 0x000F, 0x0000 }, /* R59 - LDO 1 */
158 { 0x0007, 0x0007, 0x0000 }, /* R60 - LDO 2 */
159 { 0x0000, 0x0000, 0x0000 }, /* R61 */
160 { 0x0000, 0x0000, 0x0000 }, /* R62 */
161 { 0x0000, 0x0000, 0x0000 }, /* R63 */
162 { 0x0000, 0x0000, 0x0000 }, /* R64 */
163 { 0x0000, 0x0000, 0x0000 }, /* R65 */
164 { 0x0000, 0x0000, 0x0000 }, /* R66 */
165 { 0x0000, 0x0000, 0x0000 }, /* R67 */
166 { 0x0000, 0x0000, 0x0000 }, /* R68 */
167 { 0x0000, 0x0000, 0x0000 }, /* R69 */
168 { 0x0000, 0x0000, 0x0000 }, /* R70 */
169 { 0x0000, 0x0000, 0x0000 }, /* R71 */
170 { 0x0000, 0x0000, 0x0000 }, /* R72 */
171 { 0x0000, 0x0000, 0x0000 }, /* R73 */
172 { 0x0000, 0x0000, 0x0000 }, /* R74 */
173 { 0x0000, 0x0000, 0x0000 }, /* R75 */
174 { 0x8000, 0x8000, 0x0000 }, /* R76 - Charge Pump (1) */
175 { 0x0000, 0x0000, 0x0000 }, /* R77 */
176 { 0x0000, 0x0000, 0x0000 }, /* R78 */
177 { 0x0000, 0x0000, 0x0000 }, /* R79 */
178 { 0x0000, 0x0000, 0x0000 }, /* R80 */
179 { 0x0301, 0x0301, 0x0000 }, /* R81 - Class W (1) */
180 { 0x0000, 0x0000, 0x0000 }, /* R82 */
181 { 0x0000, 0x0000, 0x0000 }, /* R83 */
182 { 0x333F, 0x333F, 0x0000 }, /* R84 - DC Servo (1) */
183 { 0x0FEF, 0x0FEF, 0x0000 }, /* R85 - DC Servo (2) */
184 { 0x0000, 0x0000, 0x0000 }, /* R86 */
185 { 0xFFFF, 0xFFFF, 0x0000 }, /* R87 - DC Servo (4) */
186 { 0x0333, 0x0000, 0x0000 }, /* R88 - DC Servo Readback */
187 { 0x0000, 0x0000, 0x0000 }, /* R89 */
188 { 0x0000, 0x0000, 0x0000 }, /* R90 */
189 { 0x0000, 0x0000, 0x0000 }, /* R91 */
190 { 0x0000, 0x0000, 0x0000 }, /* R92 */
191 { 0x0000, 0x0000, 0x0000 }, /* R93 */
192 { 0x0000, 0x0000, 0x0000 }, /* R94 */
193 { 0x0000, 0x0000, 0x0000 }, /* R95 */
194 { 0x00EE, 0x00EE, 0x0000 }, /* R96 - Analogue HP (1) */
195 { 0x0000, 0x0000, 0x0000 }, /* R97 */
196 { 0x0000, 0x0000, 0x0000 }, /* R98 */
197 { 0x0000, 0x0000, 0x0000 }, /* R99 */
198 { 0x0000, 0x0000, 0x0000 }, /* R100 */
199 { 0x0000, 0x0000, 0x0000 }, /* R101 */
200 { 0x0000, 0x0000, 0x0000 }, /* R102 */
201 { 0x0000, 0x0000, 0x0000 }, /* R103 */
202 { 0x0000, 0x0000, 0x0000 }, /* R104 */
203 { 0x0000, 0x0000, 0x0000 }, /* R105 */
204 { 0x0000, 0x0000, 0x0000 }, /* R106 */
205 { 0x0000, 0x0000, 0x0000 }, /* R107 */
206 { 0x0000, 0x0000, 0x0000 }, /* R108 */
207 { 0x0000, 0x0000, 0x0000 }, /* R109 */
208 { 0x0000, 0x0000, 0x0000 }, /* R110 */
209 { 0x0000, 0x0000, 0x0000 }, /* R111 */
210 { 0x0000, 0x0000, 0x0000 }, /* R112 */
211 { 0x0000, 0x0000, 0x0000 }, /* R113 */
212 { 0x0000, 0x0000, 0x0000 }, /* R114 */
213 { 0x0000, 0x0000, 0x0000 }, /* R115 */
214 { 0x0000, 0x0000, 0x0000 }, /* R116 */
215 { 0x0000, 0x0000, 0x0000 }, /* R117 */
216 { 0x0000, 0x0000, 0x0000 }, /* R118 */
217 { 0x0000, 0x0000, 0x0000 }, /* R119 */
218 { 0x0000, 0x0000, 0x0000 }, /* R120 */
219 { 0x0000, 0x0000, 0x0000 }, /* R121 */
220 { 0x0000, 0x0000, 0x0000 }, /* R122 */
221 { 0x0000, 0x0000, 0x0000 }, /* R123 */
222 { 0x0000, 0x0000, 0x0000 }, /* R124 */
223 { 0x0000, 0x0000, 0x0000 }, /* R125 */
224 { 0x0000, 0x0000, 0x0000 }, /* R126 */
225 { 0x0000, 0x0000, 0x0000 }, /* R127 */
226 { 0x0000, 0x0000, 0x0000 }, /* R128 */
227 { 0x0000, 0x0000, 0x0000 }, /* R129 */
228 { 0x0000, 0x0000, 0x0000 }, /* R130 */
229 { 0x0000, 0x0000, 0x0000 }, /* R131 */
230 { 0x0000, 0x0000, 0x0000 }, /* R132 */
231 { 0x0000, 0x0000, 0x0000 }, /* R133 */
232 { 0x0000, 0x0000, 0x0000 }, /* R134 */
233 { 0x0000, 0x0000, 0x0000 }, /* R135 */
234 { 0x0000, 0x0000, 0x0000 }, /* R136 */
235 { 0x0000, 0x0000, 0x0000 }, /* R137 */
236 { 0x0000, 0x0000, 0x0000 }, /* R138 */
237 { 0x0000, 0x0000, 0x0000 }, /* R139 */
238 { 0x0000, 0x0000, 0x0000 }, /* R140 */
239 { 0x0000, 0x0000, 0x0000 }, /* R141 */
240 { 0x0000, 0x0000, 0x0000 }, /* R142 */
241 { 0x0000, 0x0000, 0x0000 }, /* R143 */
242 { 0x0000, 0x0000, 0x0000 }, /* R144 */
243 { 0x0000, 0x0000, 0x0000 }, /* R145 */
244 { 0x0000, 0x0000, 0x0000 }, /* R146 */
245 { 0x0000, 0x0000, 0x0000 }, /* R147 */
246 { 0x0000, 0x0000, 0x0000 }, /* R148 */
247 { 0x0000, 0x0000, 0x0000 }, /* R149 */
248 { 0x0000, 0x0000, 0x0000 }, /* R150 */
249 { 0x0000, 0x0000, 0x0000 }, /* R151 */
250 { 0x0000, 0x0000, 0x0000 }, /* R152 */
251 { 0x0000, 0x0000, 0x0000 }, /* R153 */
252 { 0x0000, 0x0000, 0x0000 }, /* R154 */
253 { 0x0000, 0x0000, 0x0000 }, /* R155 */
254 { 0x0000, 0x0000, 0x0000 }, /* R156 */
255 { 0x0000, 0x0000, 0x0000 }, /* R157 */
256 { 0x0000, 0x0000, 0x0000 }, /* R158 */
257 { 0x0000, 0x0000, 0x0000 }, /* R159 */
258 { 0x0000, 0x0000, 0x0000 }, /* R160 */
259 { 0x0000, 0x0000, 0x0000 }, /* R161 */
260 { 0x0000, 0x0000, 0x0000 }, /* R162 */
261 { 0x0000, 0x0000, 0x0000 }, /* R163 */
262 { 0x0000, 0x0000, 0x0000 }, /* R164 */
263 { 0x0000, 0x0000, 0x0000 }, /* R165 */
264 { 0x0000, 0x0000, 0x0000 }, /* R166 */
265 { 0x0000, 0x0000, 0x0000 }, /* R167 */
266 { 0x0000, 0x0000, 0x0000 }, /* R168 */
267 { 0x0000, 0x0000, 0x0000 }, /* R169 */
268 { 0x0000, 0x0000, 0x0000 }, /* R170 */
269 { 0x0000, 0x0000, 0x0000 }, /* R171 */
270 { 0x0000, 0x0000, 0x0000 }, /* R172 */
271 { 0x0000, 0x0000, 0x0000 }, /* R173 */
272 { 0x0000, 0x0000, 0x0000 }, /* R174 */
273 { 0x0000, 0x0000, 0x0000 }, /* R175 */
274 { 0x0000, 0x0000, 0x0000 }, /* R176 */
275 { 0x0000, 0x0000, 0x0000 }, /* R177 */
276 { 0x0000, 0x0000, 0x0000 }, /* R178 */
277 { 0x0000, 0x0000, 0x0000 }, /* R179 */
278 { 0x0000, 0x0000, 0x0000 }, /* R180 */
279 { 0x0000, 0x0000, 0x0000 }, /* R181 */
280 { 0x0000, 0x0000, 0x0000 }, /* R182 */
281 { 0x0000, 0x0000, 0x0000 }, /* R183 */
282 { 0x0000, 0x0000, 0x0000 }, /* R184 */
283 { 0x0000, 0x0000, 0x0000 }, /* R185 */
284 { 0x0000, 0x0000, 0x0000 }, /* R186 */
285 { 0x0000, 0x0000, 0x0000 }, /* R187 */
286 { 0x0000, 0x0000, 0x0000 }, /* R188 */
287 { 0x0000, 0x0000, 0x0000 }, /* R189 */
288 { 0x0000, 0x0000, 0x0000 }, /* R190 */
289 { 0x0000, 0x0000, 0x0000 }, /* R191 */
290 { 0x0000, 0x0000, 0x0000 }, /* R192 */
291 { 0x0000, 0x0000, 0x0000 }, /* R193 */
292 { 0x0000, 0x0000, 0x0000 }, /* R194 */
293 { 0x0000, 0x0000, 0x0000 }, /* R195 */
294 { 0x0000, 0x0000, 0x0000 }, /* R196 */
295 { 0x0000, 0x0000, 0x0000 }, /* R197 */
296 { 0x0000, 0x0000, 0x0000 }, /* R198 */
297 { 0x0000, 0x0000, 0x0000 }, /* R199 */
298 { 0x0000, 0x0000, 0x0000 }, /* R200 */
299 { 0x0000, 0x0000, 0x0000 }, /* R201 */
300 { 0x0000, 0x0000, 0x0000 }, /* R202 */
301 { 0x0000, 0x0000, 0x0000 }, /* R203 */
302 { 0x0000, 0x0000, 0x0000 }, /* R204 */
303 { 0x0000, 0x0000, 0x0000 }, /* R205 */
304 { 0x0000, 0x0000, 0x0000 }, /* R206 */
305 { 0x0000, 0x0000, 0x0000 }, /* R207 */
306 { 0x0000, 0x0000, 0x0000 }, /* R208 */
307 { 0x0000, 0x0000, 0x0000 }, /* R209 */
308 { 0x0000, 0x0000, 0x0000 }, /* R210 */
309 { 0x0000, 0x0000, 0x0000 }, /* R211 */
310 { 0x0000, 0x0000, 0x0000 }, /* R212 */
311 { 0x0000, 0x0000, 0x0000 }, /* R213 */
312 { 0x0000, 0x0000, 0x0000 }, /* R214 */
313 { 0x0000, 0x0000, 0x0000 }, /* R215 */
314 { 0x0000, 0x0000, 0x0000 }, /* R216 */
315 { 0x0000, 0x0000, 0x0000 }, /* R217 */
316 { 0x0000, 0x0000, 0x0000 }, /* R218 */
317 { 0x0000, 0x0000, 0x0000 }, /* R219 */
318 { 0x0000, 0x0000, 0x0000 }, /* R220 */
319 { 0x0000, 0x0000, 0x0000 }, /* R221 */
320 { 0x0000, 0x0000, 0x0000 }, /* R222 */
321 { 0x0000, 0x0000, 0x0000 }, /* R223 */
322 { 0x0000, 0x0000, 0x0000 }, /* R224 */
323 { 0x0000, 0x0000, 0x0000 }, /* R225 */
324 { 0x0000, 0x0000, 0x0000 }, /* R226 */
325 { 0x0000, 0x0000, 0x0000 }, /* R227 */
326 { 0x0000, 0x0000, 0x0000 }, /* R228 */
327 { 0x0000, 0x0000, 0x0000 }, /* R229 */
328 { 0x0000, 0x0000, 0x0000 }, /* R230 */
329 { 0x0000, 0x0000, 0x0000 }, /* R231 */
330 { 0x0000, 0x0000, 0x0000 }, /* R232 */
331 { 0x0000, 0x0000, 0x0000 }, /* R233 */
332 { 0x0000, 0x0000, 0x0000 }, /* R234 */
333 { 0x0000, 0x0000, 0x0000 }, /* R235 */
334 { 0x0000, 0x0000, 0x0000 }, /* R236 */
335 { 0x0000, 0x0000, 0x0000 }, /* R237 */
336 { 0x0000, 0x0000, 0x0000 }, /* R238 */
337 { 0x0000, 0x0000, 0x0000 }, /* R239 */
338 { 0x0000, 0x0000, 0x0000 }, /* R240 */
339 { 0x0000, 0x0000, 0x0000 }, /* R241 */
340 { 0x0000, 0x0000, 0x0000 }, /* R242 */
341 { 0x0000, 0x0000, 0x0000 }, /* R243 */
342 { 0x0000, 0x0000, 0x0000 }, /* R244 */
343 { 0x0000, 0x0000, 0x0000 }, /* R245 */
344 { 0x0000, 0x0000, 0x0000 }, /* R246 */
345 { 0x0000, 0x0000, 0x0000 }, /* R247 */
346 { 0x0000, 0x0000, 0x0000 }, /* R248 */
347 { 0x0000, 0x0000, 0x0000 }, /* R249 */
348 { 0x0000, 0x0000, 0x0000 }, /* R250 */
349 { 0x0000, 0x0000, 0x0000 }, /* R251 */
350 { 0x0000, 0x0000, 0x0000 }, /* R252 */
351 { 0x0000, 0x0000, 0x0000 }, /* R253 */
352 { 0x0000, 0x0000, 0x0000 }, /* R254 */
353 { 0x0000, 0x0000, 0x0000 }, /* R255 */
354 { 0x000F, 0x0000, 0x0000 }, /* R256 - Chip Revision */
355 { 0x0074, 0x0074, 0x0000 }, /* R257 - Control Interface */
356 { 0x0000, 0x0000, 0x0000 }, /* R258 */
357 { 0x0000, 0x0000, 0x0000 }, /* R259 */
358 { 0x0000, 0x0000, 0x0000 }, /* R260 */
359 { 0x0000, 0x0000, 0x0000 }, /* R261 */
360 { 0x0000, 0x0000, 0x0000 }, /* R262 */
361 { 0x0000, 0x0000, 0x0000 }, /* R263 */
362 { 0x0000, 0x0000, 0x0000 }, /* R264 */
363 { 0x0000, 0x0000, 0x0000 }, /* R265 */
364 { 0x0000, 0x0000, 0x0000 }, /* R266 */
365 { 0x0000, 0x0000, 0x0000 }, /* R267 */
366 { 0x0000, 0x0000, 0x0000 }, /* R268 */
367 { 0x0000, 0x0000, 0x0000 }, /* R269 */
368 { 0x0000, 0x0000, 0x0000 }, /* R270 */
369 { 0x0000, 0x0000, 0x0000 }, /* R271 */
370 { 0x807F, 0x837F, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
371 { 0x017F, 0x0000, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
372 { 0x0000, 0x0000, 0x0000 }, /* R274 */
373 { 0x0000, 0x0000, 0x0000 }, /* R275 */
374 { 0x0000, 0x0000, 0x0000 }, /* R276 */
375 { 0x0000, 0x0000, 0x0000 }, /* R277 */
376 { 0x0000, 0x0000, 0x0000 }, /* R278 */
377 { 0x0000, 0x0000, 0x0000 }, /* R279 */
378 { 0x0000, 0x0000, 0x0000 }, /* R280 */
379 { 0x0000, 0x0000, 0x0000 }, /* R281 */
380 { 0x0000, 0x0000, 0x0000 }, /* R282 */
381 { 0x0000, 0x0000, 0x0000 }, /* R283 */
382 { 0x0000, 0x0000, 0x0000 }, /* R284 */
383 { 0x0000, 0x0000, 0x0000 }, /* R285 */
384 { 0x0000, 0x0000, 0x0000 }, /* R286 */
385 { 0x0000, 0x0000, 0x0000 }, /* R287 */
386 { 0x0000, 0x0000, 0x0000 }, /* R288 */
387 { 0x0000, 0x0000, 0x0000 }, /* R289 */
388 { 0x0000, 0x0000, 0x0000 }, /* R290 */
389 { 0x0000, 0x0000, 0x0000 }, /* R291 */
390 { 0x0000, 0x0000, 0x0000 }, /* R292 */
391 { 0x0000, 0x0000, 0x0000 }, /* R293 */
392 { 0x0000, 0x0000, 0x0000 }, /* R294 */
393 { 0x0000, 0x0000, 0x0000 }, /* R295 */
394 { 0x0000, 0x0000, 0x0000 }, /* R296 */
395 { 0x0000, 0x0000, 0x0000 }, /* R297 */
396 { 0x0000, 0x0000, 0x0000 }, /* R298 */
397 { 0x0000, 0x0000, 0x0000 }, /* R299 */
398 { 0x0000, 0x0000, 0x0000 }, /* R300 */
399 { 0x0000, 0x0000, 0x0000 }, /* R301 */
400 { 0x0000, 0x0000, 0x0000 }, /* R302 */
401 { 0x0000, 0x0000, 0x0000 }, /* R303 */
402 { 0x0000, 0x0000, 0x0000 }, /* R304 */
403 { 0x0000, 0x0000, 0x0000 }, /* R305 */
404 { 0x0000, 0x0000, 0x0000 }, /* R306 */
405 { 0x0000, 0x0000, 0x0000 }, /* R307 */
406 { 0x0000, 0x0000, 0x0000 }, /* R308 */
407 { 0x0000, 0x0000, 0x0000 }, /* R309 */
408 { 0x0000, 0x0000, 0x0000 }, /* R310 */
409 { 0x0000, 0x0000, 0x0000 }, /* R311 */
410 { 0x0000, 0x0000, 0x0000 }, /* R312 */
411 { 0x0000, 0x0000, 0x0000 }, /* R313 */
412 { 0x0000, 0x0000, 0x0000 }, /* R314 */
413 { 0x0000, 0x0000, 0x0000 }, /* R315 */
414 { 0x0000, 0x0000, 0x0000 }, /* R316 */
415 { 0x0000, 0x0000, 0x0000 }, /* R317 */
416 { 0x0000, 0x0000, 0x0000 }, /* R318 */
417 { 0x0000, 0x0000, 0x0000 }, /* R319 */
418 { 0x0000, 0x0000, 0x0000 }, /* R320 */
419 { 0x0000, 0x0000, 0x0000 }, /* R321 */
420 { 0x0000, 0x0000, 0x0000 }, /* R322 */
421 { 0x0000, 0x0000, 0x0000 }, /* R323 */
422 { 0x0000, 0x0000, 0x0000 }, /* R324 */
423 { 0x0000, 0x0000, 0x0000 }, /* R325 */
424 { 0x0000, 0x0000, 0x0000 }, /* R326 */
425 { 0x0000, 0x0000, 0x0000 }, /* R327 */
426 { 0x0000, 0x0000, 0x0000 }, /* R328 */
427 { 0x0000, 0x0000, 0x0000 }, /* R329 */
428 { 0x0000, 0x0000, 0x0000 }, /* R330 */
429 { 0x0000, 0x0000, 0x0000 }, /* R331 */
430 { 0x0000, 0x0000, 0x0000 }, /* R332 */
431 { 0x0000, 0x0000, 0x0000 }, /* R333 */
432 { 0x0000, 0x0000, 0x0000 }, /* R334 */
433 { 0x0000, 0x0000, 0x0000 }, /* R335 */
434 { 0x0000, 0x0000, 0x0000 }, /* R336 */
435 { 0x0000, 0x0000, 0x0000 }, /* R337 */
436 { 0x0000, 0x0000, 0x0000 }, /* R338 */
437 { 0x0000, 0x0000, 0x0000 }, /* R339 */
438 { 0x0000, 0x0000, 0x0000 }, /* R340 */
439 { 0x0000, 0x0000, 0x0000 }, /* R341 */
440 { 0x0000, 0x0000, 0x0000 }, /* R342 */
441 { 0x0000, 0x0000, 0x0000 }, /* R343 */
442 { 0x0000, 0x0000, 0x0000 }, /* R344 */
443 { 0x0000, 0x0000, 0x0000 }, /* R345 */
444 { 0x0000, 0x0000, 0x0000 }, /* R346 */
445 { 0x0000, 0x0000, 0x0000 }, /* R347 */
446 { 0x0000, 0x0000, 0x0000 }, /* R348 */
447 { 0x0000, 0x0000, 0x0000 }, /* R349 */
448 { 0x0000, 0x0000, 0x0000 }, /* R350 */
449 { 0x0000, 0x0000, 0x0000 }, /* R351 */
450 { 0x0000, 0x0000, 0x0000 }, /* R352 */
451 { 0x0000, 0x0000, 0x0000 }, /* R353 */
452 { 0x0000, 0x0000, 0x0000 }, /* R354 */
453 { 0x0000, 0x0000, 0x0000 }, /* R355 */
454 { 0x0000, 0x0000, 0x0000 }, /* R356 */
455 { 0x0000, 0x0000, 0x0000 }, /* R357 */
456 { 0x0000, 0x0000, 0x0000 }, /* R358 */
457 { 0x0000, 0x0000, 0x0000 }, /* R359 */
458 { 0x0000, 0x0000, 0x0000 }, /* R360 */
459 { 0x0000, 0x0000, 0x0000 }, /* R361 */
460 { 0x0000, 0x0000, 0x0000 }, /* R362 */
461 { 0x0000, 0x0000, 0x0000 }, /* R363 */
462 { 0x0000, 0x0000, 0x0000 }, /* R364 */
463 { 0x0000, 0x0000, 0x0000 }, /* R365 */
464 { 0x0000, 0x0000, 0x0000 }, /* R366 */
465 { 0x0000, 0x0000, 0x0000 }, /* R367 */
466 { 0x0000, 0x0000, 0x0000 }, /* R368 */
467 { 0x0000, 0x0000, 0x0000 }, /* R369 */
468 { 0x0000, 0x0000, 0x0000 }, /* R370 */
469 { 0x0000, 0x0000, 0x0000 }, /* R371 */
470 { 0x0000, 0x0000, 0x0000 }, /* R372 */
471 { 0x0000, 0x0000, 0x0000 }, /* R373 */
472 { 0x0000, 0x0000, 0x0000 }, /* R374 */
473 { 0x0000, 0x0000, 0x0000 }, /* R375 */
474 { 0x0000, 0x0000, 0x0000 }, /* R376 */
475 { 0x0000, 0x0000, 0x0000 }, /* R377 */
476 { 0x0000, 0x0000, 0x0000 }, /* R378 */
477 { 0x0000, 0x0000, 0x0000 }, /* R379 */
478 { 0x0000, 0x0000, 0x0000 }, /* R380 */
479 { 0x0000, 0x0000, 0x0000 }, /* R381 */
480 { 0x0000, 0x0000, 0x0000 }, /* R382 */
481 { 0x0000, 0x0000, 0x0000 }, /* R383 */
482 { 0x0000, 0x0000, 0x0000 }, /* R384 */
483 { 0x0000, 0x0000, 0x0000 }, /* R385 */
484 { 0x0000, 0x0000, 0x0000 }, /* R386 */
485 { 0x0000, 0x0000, 0x0000 }, /* R387 */
486 { 0x0000, 0x0000, 0x0000 }, /* R388 */
487 { 0x0000, 0x0000, 0x0000 }, /* R389 */
488 { 0x0000, 0x0000, 0x0000 }, /* R390 */
489 { 0x0000, 0x0000, 0x0000 }, /* R391 */
490 { 0x0000, 0x0000, 0x0000 }, /* R392 */
491 { 0x0000, 0x0000, 0x0000 }, /* R393 */
492 { 0x0000, 0x0000, 0x0000 }, /* R394 */
493 { 0x0000, 0x0000, 0x0000 }, /* R395 */
494 { 0x0000, 0x0000, 0x0000 }, /* R396 */
495 { 0x0000, 0x0000, 0x0000 }, /* R397 */
496 { 0x0000, 0x0000, 0x0000 }, /* R398 */
497 { 0x0000, 0x0000, 0x0000 }, /* R399 */
498 { 0x0000, 0x0000, 0x0000 }, /* R400 */
499 { 0x0000, 0x0000, 0x0000 }, /* R401 */
500 { 0x0000, 0x0000, 0x0000 }, /* R402 */
501 { 0x0000, 0x0000, 0x0000 }, /* R403 */
502 { 0x0000, 0x0000, 0x0000 }, /* R404 */
503 { 0x0000, 0x0000, 0x0000 }, /* R405 */
504 { 0x0000, 0x0000, 0x0000 }, /* R406 */
505 { 0x0000, 0x0000, 0x0000 }, /* R407 */
506 { 0x0000, 0x0000, 0x0000 }, /* R408 */
507 { 0x0000, 0x0000, 0x0000 }, /* R409 */
508 { 0x0000, 0x0000, 0x0000 }, /* R410 */
509 { 0x0000, 0x0000, 0x0000 }, /* R411 */
510 { 0x0000, 0x0000, 0x0000 }, /* R412 */
511 { 0x0000, 0x0000, 0x0000 }, /* R413 */
512 { 0x0000, 0x0000, 0x0000 }, /* R414 */
513 { 0x0000, 0x0000, 0x0000 }, /* R415 */
514 { 0x0000, 0x0000, 0x0000 }, /* R416 */
515 { 0x0000, 0x0000, 0x0000 }, /* R417 */
516 { 0x0000, 0x0000, 0x0000 }, /* R418 */
517 { 0x0000, 0x0000, 0x0000 }, /* R419 */
518 { 0x0000, 0x0000, 0x0000 }, /* R420 */
519 { 0x0000, 0x0000, 0x0000 }, /* R421 */
520 { 0x0000, 0x0000, 0x0000 }, /* R422 */
521 { 0x0000, 0x0000, 0x0000 }, /* R423 */
522 { 0x0000, 0x0000, 0x0000 }, /* R424 */
523 { 0x0000, 0x0000, 0x0000 }, /* R425 */
524 { 0x0000, 0x0000, 0x0000 }, /* R426 */
525 { 0x0000, 0x0000, 0x0000 }, /* R427 */
526 { 0x0000, 0x0000, 0x0000 }, /* R428 */
527 { 0x0000, 0x0000, 0x0000 }, /* R429 */
528 { 0x0000, 0x0000, 0x0000 }, /* R430 */
529 { 0x0000, 0x0000, 0x0000 }, /* R431 */
530 { 0x0000, 0x0000, 0x0000 }, /* R432 */
531 { 0x0000, 0x0000, 0x0000 }, /* R433 */
532 { 0x0000, 0x0000, 0x0000 }, /* R434 */
533 { 0x0000, 0x0000, 0x0000 }, /* R435 */
534 { 0x0000, 0x0000, 0x0000 }, /* R436 */
535 { 0x0000, 0x0000, 0x0000 }, /* R437 */
536 { 0x0000, 0x0000, 0x0000 }, /* R438 */
537 { 0x0000, 0x0000, 0x0000 }, /* R439 */
538 { 0x0000, 0x0000, 0x0000 }, /* R440 */
539 { 0x0000, 0x0000, 0x0000 }, /* R441 */
540 { 0x0000, 0x0000, 0x0000 }, /* R442 */
541 { 0x0000, 0x0000, 0x0000 }, /* R443 */
542 { 0x0000, 0x0000, 0x0000 }, /* R444 */
543 { 0x0000, 0x0000, 0x0000 }, /* R445 */
544 { 0x0000, 0x0000, 0x0000 }, /* R446 */
545 { 0x0000, 0x0000, 0x0000 }, /* R447 */
546 { 0x0000, 0x0000, 0x0000 }, /* R448 */
547 { 0x0000, 0x0000, 0x0000 }, /* R449 */
548 { 0x0000, 0x0000, 0x0000 }, /* R450 */
549 { 0x0000, 0x0000, 0x0000 }, /* R451 */
550 { 0x0000, 0x0000, 0x0000 }, /* R452 */
551 { 0x0000, 0x0000, 0x0000 }, /* R453 */
552 { 0x0000, 0x0000, 0x0000 }, /* R454 */
553 { 0x0000, 0x0000, 0x0000 }, /* R455 */
554 { 0x0000, 0x0000, 0x0000 }, /* R456 */
555 { 0x0000, 0x0000, 0x0000 }, /* R457 */
556 { 0x0000, 0x0000, 0x0000 }, /* R458 */
557 { 0x0000, 0x0000, 0x0000 }, /* R459 */
558 { 0x0000, 0x0000, 0x0000 }, /* R460 */
559 { 0x0000, 0x0000, 0x0000 }, /* R461 */
560 { 0x0000, 0x0000, 0x0000 }, /* R462 */
561 { 0x0000, 0x0000, 0x0000 }, /* R463 */
562 { 0x0000, 0x0000, 0x0000 }, /* R464 */
563 { 0x0000, 0x0000, 0x0000 }, /* R465 */
564 { 0x0000, 0x0000, 0x0000 }, /* R466 */
565 { 0x0000, 0x0000, 0x0000 }, /* R467 */
566 { 0x0000, 0x0000, 0x0000 }, /* R468 */
567 { 0x0000, 0x0000, 0x0000 }, /* R469 */
568 { 0x0000, 0x0000, 0x0000 }, /* R470 */
569 { 0x0000, 0x0000, 0x0000 }, /* R471 */
570 { 0x0000, 0x0000, 0x0000 }, /* R472 */
571 { 0x0000, 0x0000, 0x0000 }, /* R473 */
572 { 0x0000, 0x0000, 0x0000 }, /* R474 */
573 { 0x0000, 0x0000, 0x0000 }, /* R475 */
574 { 0x0000, 0x0000, 0x0000 }, /* R476 */
575 { 0x0000, 0x0000, 0x0000 }, /* R477 */
576 { 0x0000, 0x0000, 0x0000 }, /* R478 */
577 { 0x0000, 0x0000, 0x0000 }, /* R479 */
578 { 0x0000, 0x0000, 0x0000 }, /* R480 */
579 { 0x0000, 0x0000, 0x0000 }, /* R481 */
580 { 0x0000, 0x0000, 0x0000 }, /* R482 */
581 { 0x0000, 0x0000, 0x0000 }, /* R483 */
582 { 0x0000, 0x0000, 0x0000 }, /* R484 */
583 { 0x0000, 0x0000, 0x0000 }, /* R485 */
584 { 0x0000, 0x0000, 0x0000 }, /* R486 */
585 { 0x0000, 0x0000, 0x0000 }, /* R487 */
586 { 0x0000, 0x0000, 0x0000 }, /* R488 */
587 { 0x0000, 0x0000, 0x0000 }, /* R489 */
588 { 0x0000, 0x0000, 0x0000 }, /* R490 */
589 { 0x0000, 0x0000, 0x0000 }, /* R491 */
590 { 0x0000, 0x0000, 0x0000 }, /* R492 */
591 { 0x0000, 0x0000, 0x0000 }, /* R493 */
592 { 0x0000, 0x0000, 0x0000 }, /* R494 */
593 { 0x0000, 0x0000, 0x0000 }, /* R495 */
594 { 0x0000, 0x0000, 0x0000 }, /* R496 */
595 { 0x0000, 0x0000, 0x0000 }, /* R497 */
596 { 0x0000, 0x0000, 0x0000 }, /* R498 */
597 { 0x0000, 0x0000, 0x0000 }, /* R499 */
598 { 0x0000, 0x0000, 0x0000 }, /* R500 */
599 { 0x0000, 0x0000, 0x0000 }, /* R501 */
600 { 0x0000, 0x0000, 0x0000 }, /* R502 */
601 { 0x0000, 0x0000, 0x0000 }, /* R503 */
602 { 0x0000, 0x0000, 0x0000 }, /* R504 */
603 { 0x0000, 0x0000, 0x0000 }, /* R505 */
604 { 0x0000, 0x0000, 0x0000 }, /* R506 */
605 { 0x0000, 0x0000, 0x0000 }, /* R507 */
606 { 0x0000, 0x0000, 0x0000 }, /* R508 */
607 { 0x0000, 0x0000, 0x0000 }, /* R509 */
608 { 0x0000, 0x0000, 0x0000 }, /* R510 */
609 { 0x0000, 0x0000, 0x0000 }, /* R511 */
610 { 0x001F, 0x001F, 0x0000 }, /* R512 - AIF1 Clocking (1) */
611 { 0x003F, 0x003F, 0x0000 }, /* R513 - AIF1 Clocking (2) */
612 { 0x0000, 0x0000, 0x0000 }, /* R514 */
613 { 0x0000, 0x0000, 0x0000 }, /* R515 */
614 { 0x001F, 0x001F, 0x0000 }, /* R516 - AIF2 Clocking (1) */
615 { 0x003F, 0x003F, 0x0000 }, /* R517 - AIF2 Clocking (2) */
616 { 0x0000, 0x0000, 0x0000 }, /* R518 */
617 { 0x0000, 0x0000, 0x0000 }, /* R519 */
618 { 0x001F, 0x001F, 0x0000 }, /* R520 - Clocking (1) */
619 { 0x0777, 0x0777, 0x0000 }, /* R521 - Clocking (2) */
620 { 0x0000, 0x0000, 0x0000 }, /* R522 */
621 { 0x0000, 0x0000, 0x0000 }, /* R523 */
622 { 0x0000, 0x0000, 0x0000 }, /* R524 */
623 { 0x0000, 0x0000, 0x0000 }, /* R525 */
624 { 0x0000, 0x0000, 0x0000 }, /* R526 */
625 { 0x0000, 0x0000, 0x0000 }, /* R527 */
626 { 0x00FF, 0x00FF, 0x0000 }, /* R528 - AIF1 Rate */
627 { 0x00FF, 0x00FF, 0x0000 }, /* R529 - AIF2 Rate */
628 { 0x000F, 0x0000, 0x0000 }, /* R530 - Rate Status */
629 { 0x0000, 0x0000, 0x0000 }, /* R531 */
630 { 0x0000, 0x0000, 0x0000 }, /* R532 */
631 { 0x0000, 0x0000, 0x0000 }, /* R533 */
632 { 0x0000, 0x0000, 0x0000 }, /* R534 */
633 { 0x0000, 0x0000, 0x0000 }, /* R535 */
634 { 0x0000, 0x0000, 0x0000 }, /* R536 */
635 { 0x0000, 0x0000, 0x0000 }, /* R537 */
636 { 0x0000, 0x0000, 0x0000 }, /* R538 */
637 { 0x0000, 0x0000, 0x0000 }, /* R539 */
638 { 0x0000, 0x0000, 0x0000 }, /* R540 */
639 { 0x0000, 0x0000, 0x0000 }, /* R541 */
640 { 0x0000, 0x0000, 0x0000 }, /* R542 */
641 { 0x0000, 0x0000, 0x0000 }, /* R543 */
642 { 0x0007, 0x0007, 0x0000 }, /* R544 - FLL1 Control (1) */
643 { 0x3F77, 0x3F77, 0x0000 }, /* R545 - FLL1 Control (2) */
644 { 0xFFFF, 0xFFFF, 0x0000 }, /* R546 - FLL1 Control (3) */
645 { 0x7FEF, 0x7FEF, 0x0000 }, /* R547 - FLL1 Control (4) */
646 { 0x1FDB, 0x1FDB, 0x0000 }, /* R548 - FLL1 Control (5) */
647 { 0x0000, 0x0000, 0x0000 }, /* R549 */
648 { 0x0000, 0x0000, 0x0000 }, /* R550 */
649 { 0x0000, 0x0000, 0x0000 }, /* R551 */
650 { 0x0000, 0x0000, 0x0000 }, /* R552 */
651 { 0x0000, 0x0000, 0x0000 }, /* R553 */
652 { 0x0000, 0x0000, 0x0000 }, /* R554 */
653 { 0x0000, 0x0000, 0x0000 }, /* R555 */
654 { 0x0000, 0x0000, 0x0000 }, /* R556 */
655 { 0x0000, 0x0000, 0x0000 }, /* R557 */
656 { 0x0000, 0x0000, 0x0000 }, /* R558 */
657 { 0x0000, 0x0000, 0x0000 }, /* R559 */
658 { 0x0000, 0x0000, 0x0000 }, /* R560 */
659 { 0x0000, 0x0000, 0x0000 }, /* R561 */
660 { 0x0000, 0x0000, 0x0000 }, /* R562 */
661 { 0x0000, 0x0000, 0x0000 }, /* R563 */
662 { 0x0000, 0x0000, 0x0000 }, /* R564 */
663 { 0x0000, 0x0000, 0x0000 }, /* R565 */
664 { 0x0000, 0x0000, 0x0000 }, /* R566 */
665 { 0x0000, 0x0000, 0x0000 }, /* R567 */
666 { 0x0000, 0x0000, 0x0000 }, /* R568 */
667 { 0x0000, 0x0000, 0x0000 }, /* R569 */
668 { 0x0000, 0x0000, 0x0000 }, /* R570 */
669 { 0x0000, 0x0000, 0x0000 }, /* R571 */
670 { 0x0000, 0x0000, 0x0000 }, /* R572 */
671 { 0x0000, 0x0000, 0x0000 }, /* R573 */
672 { 0x0000, 0x0000, 0x0000 }, /* R574 */
673 { 0x0000, 0x0000, 0x0000 }, /* R575 */
674 { 0x0007, 0x0007, 0x0000 }, /* R576 - FLL2 Control (1) */
675 { 0x3F77, 0x3F77, 0x0000 }, /* R577 - FLL2 Control (2) */
676 { 0xFFFF, 0xFFFF, 0x0000 }, /* R578 - FLL2 Control (3) */
677 { 0x7FEF, 0x7FEF, 0x0000 }, /* R579 - FLL2 Control (4) */
678 { 0x1FDB, 0x1FDB, 0x0000 }, /* R580 - FLL2 Control (5) */
679 { 0x0000, 0x0000, 0x0000 }, /* R581 */
680 { 0x0000, 0x0000, 0x0000 }, /* R582 */
681 { 0x0000, 0x0000, 0x0000 }, /* R583 */
682 { 0x0000, 0x0000, 0x0000 }, /* R584 */
683 { 0x0000, 0x0000, 0x0000 }, /* R585 */
684 { 0x0000, 0x0000, 0x0000 }, /* R586 */
685 { 0x0000, 0x0000, 0x0000 }, /* R587 */
686 { 0x0000, 0x0000, 0x0000 }, /* R588 */
687 { 0x0000, 0x0000, 0x0000 }, /* R589 */
688 { 0x0000, 0x0000, 0x0000 }, /* R590 */
689 { 0x0000, 0x0000, 0x0000 }, /* R591 */
690 { 0x0000, 0x0000, 0x0000 }, /* R592 */
691 { 0x0000, 0x0000, 0x0000 }, /* R593 */
692 { 0x0000, 0x0000, 0x0000 }, /* R594 */
693 { 0x0000, 0x0000, 0x0000 }, /* R595 */
694 { 0x0000, 0x0000, 0x0000 }, /* R596 */
695 { 0x0000, 0x0000, 0x0000 }, /* R597 */
696 { 0x0000, 0x0000, 0x0000 }, /* R598 */
697 { 0x0000, 0x0000, 0x0000 }, /* R599 */
698 { 0x0000, 0x0000, 0x0000 }, /* R600 */
699 { 0x0000, 0x0000, 0x0000 }, /* R601 */
700 { 0x0000, 0x0000, 0x0000 }, /* R602 */
701 { 0x0000, 0x0000, 0x0000 }, /* R603 */
702 { 0x0000, 0x0000, 0x0000 }, /* R604 */
703 { 0x0000, 0x0000, 0x0000 }, /* R605 */
704 { 0x0000, 0x0000, 0x0000 }, /* R606 */
705 { 0x0000, 0x0000, 0x0000 }, /* R607 */
706 { 0x0000, 0x0000, 0x0000 }, /* R608 */
707 { 0x0000, 0x0000, 0x0000 }, /* R609 */
708 { 0x0000, 0x0000, 0x0000 }, /* R610 */
709 { 0x0000, 0x0000, 0x0000 }, /* R611 */
710 { 0x0000, 0x0000, 0x0000 }, /* R612 */
711 { 0x0000, 0x0000, 0x0000 }, /* R613 */
712 { 0x0000, 0x0000, 0x0000 }, /* R614 */
713 { 0x0000, 0x0000, 0x0000 }, /* R615 */
714 { 0x0000, 0x0000, 0x0000 }, /* R616 */
715 { 0x0000, 0x0000, 0x0000 }, /* R617 */
716 { 0x0000, 0x0000, 0x0000 }, /* R618 */
717 { 0x0000, 0x0000, 0x0000 }, /* R619 */
718 { 0x0000, 0x0000, 0x0000 }, /* R620 */
719 { 0x0000, 0x0000, 0x0000 }, /* R621 */
720 { 0x0000, 0x0000, 0x0000 }, /* R622 */
721 { 0x0000, 0x0000, 0x0000 }, /* R623 */
722 { 0x0000, 0x0000, 0x0000 }, /* R624 */
723 { 0x0000, 0x0000, 0x0000 }, /* R625 */
724 { 0x0000, 0x0000, 0x0000 }, /* R626 */
725 { 0x0000, 0x0000, 0x0000 }, /* R627 */
726 { 0x0000, 0x0000, 0x0000 }, /* R628 */
727 { 0x0000, 0x0000, 0x0000 }, /* R629 */
728 { 0x0000, 0x0000, 0x0000 }, /* R630 */
729 { 0x0000, 0x0000, 0x0000 }, /* R631 */
730 { 0x0000, 0x0000, 0x0000 }, /* R632 */
731 { 0x0000, 0x0000, 0x0000 }, /* R633 */
732 { 0x0000, 0x0000, 0x0000 }, /* R634 */
733 { 0x0000, 0x0000, 0x0000 }, /* R635 */
734 { 0x0000, 0x0000, 0x0000 }, /* R636 */
735 { 0x0000, 0x0000, 0x0000 }, /* R637 */
736 { 0x0000, 0x0000, 0x0000 }, /* R638 */
737 { 0x0000, 0x0000, 0x0000 }, /* R639 */
738 { 0x0000, 0x0000, 0x0000 }, /* R640 */
739 { 0x0000, 0x0000, 0x0000 }, /* R641 */
740 { 0x0000, 0x0000, 0x0000 }, /* R642 */
741 { 0x0000, 0x0000, 0x0000 }, /* R643 */
742 { 0x0000, 0x0000, 0x0000 }, /* R644 */
743 { 0x0000, 0x0000, 0x0000 }, /* R645 */
744 { 0x0000, 0x0000, 0x0000 }, /* R646 */
745 { 0x0000, 0x0000, 0x0000 }, /* R647 */
746 { 0x0000, 0x0000, 0x0000 }, /* R648 */
747 { 0x0000, 0x0000, 0x0000 }, /* R649 */
748 { 0x0000, 0x0000, 0x0000 }, /* R650 */
749 { 0x0000, 0x0000, 0x0000 }, /* R651 */
750 { 0x0000, 0x0000, 0x0000 }, /* R652 */
751 { 0x0000, 0x0000, 0x0000 }, /* R653 */
752 { 0x0000, 0x0000, 0x0000 }, /* R654 */
753 { 0x0000, 0x0000, 0x0000 }, /* R655 */
754 { 0x0000, 0x0000, 0x0000 }, /* R656 */
755 { 0x0000, 0x0000, 0x0000 }, /* R657 */
756 { 0x0000, 0x0000, 0x0000 }, /* R658 */
757 { 0x0000, 0x0000, 0x0000 }, /* R659 */
758 { 0x0000, 0x0000, 0x0000 }, /* R660 */
759 { 0x0000, 0x0000, 0x0000 }, /* R661 */
760 { 0x0000, 0x0000, 0x0000 }, /* R662 */
761 { 0x0000, 0x0000, 0x0000 }, /* R663 */
762 { 0x0000, 0x0000, 0x0000 }, /* R664 */
763 { 0x0000, 0x0000, 0x0000 }, /* R665 */
764 { 0x0000, 0x0000, 0x0000 }, /* R666 */
765 { 0x0000, 0x0000, 0x0000 }, /* R667 */
766 { 0x0000, 0x0000, 0x0000 }, /* R668 */
767 { 0x0000, 0x0000, 0x0000 }, /* R669 */
768 { 0x0000, 0x0000, 0x0000 }, /* R670 */
769 { 0x0000, 0x0000, 0x0000 }, /* R671 */
770 { 0x0000, 0x0000, 0x0000 }, /* R672 */
771 { 0x0000, 0x0000, 0x0000 }, /* R673 */
772 { 0x0000, 0x0000, 0x0000 }, /* R674 */
773 { 0x0000, 0x0000, 0x0000 }, /* R675 */
774 { 0x0000, 0x0000, 0x0000 }, /* R676 */
775 { 0x0000, 0x0000, 0x0000 }, /* R677 */
776 { 0x0000, 0x0000, 0x0000 }, /* R678 */
777 { 0x0000, 0x0000, 0x0000 }, /* R679 */
778 { 0x0000, 0x0000, 0x0000 }, /* R680 */
779 { 0x0000, 0x0000, 0x0000 }, /* R681 */
780 { 0x0000, 0x0000, 0x0000 }, /* R682 */
781 { 0x0000, 0x0000, 0x0000 }, /* R683 */
782 { 0x0000, 0x0000, 0x0000 }, /* R684 */
783 { 0x0000, 0x0000, 0x0000 }, /* R685 */
784 { 0x0000, 0x0000, 0x0000 }, /* R686 */
785 { 0x0000, 0x0000, 0x0000 }, /* R687 */
786 { 0x0000, 0x0000, 0x0000 }, /* R688 */
787 { 0x0000, 0x0000, 0x0000 }, /* R689 */
788 { 0x0000, 0x0000, 0x0000 }, /* R690 */
789 { 0x0000, 0x0000, 0x0000 }, /* R691 */
790 { 0x0000, 0x0000, 0x0000 }, /* R692 */
791 { 0x0000, 0x0000, 0x0000 }, /* R693 */
792 { 0x0000, 0x0000, 0x0000 }, /* R694 */
793 { 0x0000, 0x0000, 0x0000 }, /* R695 */
794 { 0x0000, 0x0000, 0x0000 }, /* R696 */
795 { 0x0000, 0x0000, 0x0000 }, /* R697 */
796 { 0x0000, 0x0000, 0x0000 }, /* R698 */
797 { 0x0000, 0x0000, 0x0000 }, /* R699 */
798 { 0x0000, 0x0000, 0x0000 }, /* R700 */
799 { 0x0000, 0x0000, 0x0000 }, /* R701 */
800 { 0x0000, 0x0000, 0x0000 }, /* R702 */
801 { 0x0000, 0x0000, 0x0000 }, /* R703 */
802 { 0x0000, 0x0000, 0x0000 }, /* R704 */
803 { 0x0000, 0x0000, 0x0000 }, /* R705 */
804 { 0x0000, 0x0000, 0x0000 }, /* R706 */
805 { 0x0000, 0x0000, 0x0000 }, /* R707 */
806 { 0x0000, 0x0000, 0x0000 }, /* R708 */
807 { 0x0000, 0x0000, 0x0000 }, /* R709 */
808 { 0x0000, 0x0000, 0x0000 }, /* R710 */
809 { 0x0000, 0x0000, 0x0000 }, /* R711 */
810 { 0x0000, 0x0000, 0x0000 }, /* R712 */
811 { 0x0000, 0x0000, 0x0000 }, /* R713 */
812 { 0x0000, 0x0000, 0x0000 }, /* R714 */
813 { 0x0000, 0x0000, 0x0000 }, /* R715 */
814 { 0x0000, 0x0000, 0x0000 }, /* R716 */
815 { 0x0000, 0x0000, 0x0000 }, /* R717 */
816 { 0x0000, 0x0000, 0x0000 }, /* R718 */
817 { 0x0000, 0x0000, 0x0000 }, /* R719 */
818 { 0x0000, 0x0000, 0x0000 }, /* R720 */
819 { 0x0000, 0x0000, 0x0000 }, /* R721 */
820 { 0x0000, 0x0000, 0x0000 }, /* R722 */
821 { 0x0000, 0x0000, 0x0000 }, /* R723 */
822 { 0x0000, 0x0000, 0x0000 }, /* R724 */
823 { 0x0000, 0x0000, 0x0000 }, /* R725 */
824 { 0x0000, 0x0000, 0x0000 }, /* R726 */
825 { 0x0000, 0x0000, 0x0000 }, /* R727 */
826 { 0x0000, 0x0000, 0x0000 }, /* R728 */
827 { 0x0000, 0x0000, 0x0000 }, /* R729 */
828 { 0x0000, 0x0000, 0x0000 }, /* R730 */
829 { 0x0000, 0x0000, 0x0000 }, /* R731 */
830 { 0x0000, 0x0000, 0x0000 }, /* R732 */
831 { 0x0000, 0x0000, 0x0000 }, /* R733 */
832 { 0x0000, 0x0000, 0x0000 }, /* R734 */
833 { 0x0000, 0x0000, 0x0000 }, /* R735 */
834 { 0x0000, 0x0000, 0x0000 }, /* R736 */
835 { 0x0000, 0x0000, 0x0000 }, /* R737 */
836 { 0x0000, 0x0000, 0x0000 }, /* R738 */
837 { 0x0000, 0x0000, 0x0000 }, /* R739 */
838 { 0x0000, 0x0000, 0x0000 }, /* R740 */
839 { 0x0000, 0x0000, 0x0000 }, /* R741 */
840 { 0x0000, 0x0000, 0x0000 }, /* R742 */
841 { 0x0000, 0x0000, 0x0000 }, /* R743 */
842 { 0x0000, 0x0000, 0x0000 }, /* R744 */
843 { 0x0000, 0x0000, 0x0000 }, /* R745 */
844 { 0x0000, 0x0000, 0x0000 }, /* R746 */
845 { 0x0000, 0x0000, 0x0000 }, /* R747 */
846 { 0x0000, 0x0000, 0x0000 }, /* R748 */
847 { 0x0000, 0x0000, 0x0000 }, /* R749 */
848 { 0x0000, 0x0000, 0x0000 }, /* R750 */
849 { 0x0000, 0x0000, 0x0000 }, /* R751 */
850 { 0x0000, 0x0000, 0x0000 }, /* R752 */
851 { 0x0000, 0x0000, 0x0000 }, /* R753 */
852 { 0x0000, 0x0000, 0x0000 }, /* R754 */
853 { 0x0000, 0x0000, 0x0000 }, /* R755 */
854 { 0x0000, 0x0000, 0x0000 }, /* R756 */
855 { 0x0000, 0x0000, 0x0000 }, /* R757 */
856 { 0x0000, 0x0000, 0x0000 }, /* R758 */
857 { 0x0000, 0x0000, 0x0000 }, /* R759 */
858 { 0x0000, 0x0000, 0x0000 }, /* R760 */
859 { 0x0000, 0x0000, 0x0000 }, /* R761 */
860 { 0x0000, 0x0000, 0x0000 }, /* R762 */
861 { 0x0000, 0x0000, 0x0000 }, /* R763 */
862 { 0x0000, 0x0000, 0x0000 }, /* R764 */
863 { 0x0000, 0x0000, 0x0000 }, /* R765 */
864 { 0x0000, 0x0000, 0x0000 }, /* R766 */
865 { 0x0000, 0x0000, 0x0000 }, /* R767 */
866 { 0xE1F8, 0xE1F8, 0x0000 }, /* R768 - AIF1 Control (1) */
867 { 0xCD1F, 0xCD1F, 0x0000 }, /* R769 - AIF1 Control (2) */
868 { 0xF000, 0xF000, 0x0000 }, /* R770 - AIF1 Master/Slave */
869 { 0x01F0, 0x01F0, 0x0000 }, /* R771 - AIF1 BCLK */
870 { 0x0FFF, 0x0FFF, 0x0000 }, /* R772 - AIF1ADC LRCLK */
871 { 0x0FFF, 0x0FFF, 0x0000 }, /* R773 - AIF1DAC LRCLK */
872 { 0x0003, 0x0003, 0x0000 }, /* R774 - AIF1DAC Data */
873 { 0x0003, 0x0003, 0x0000 }, /* R775 - AIF1ADC Data */
874 { 0x0000, 0x0000, 0x0000 }, /* R776 */
875 { 0x0000, 0x0000, 0x0000 }, /* R777 */
876 { 0x0000, 0x0000, 0x0000 }, /* R778 */
877 { 0x0000, 0x0000, 0x0000 }, /* R779 */
878 { 0x0000, 0x0000, 0x0000 }, /* R780 */
879 { 0x0000, 0x0000, 0x0000 }, /* R781 */
880 { 0x0000, 0x0000, 0x0000 }, /* R782 */
881 { 0x0000, 0x0000, 0x0000 }, /* R783 */
882 { 0xF1F8, 0xF1F8, 0x0000 }, /* R784 - AIF2 Control (1) */
883 { 0xFD1F, 0xFD1F, 0x0000 }, /* R785 - AIF2 Control (2) */
884 { 0xF000, 0xF000, 0x0000 }, /* R786 - AIF2 Master/Slave */
885 { 0x01F0, 0x01F0, 0x0000 }, /* R787 - AIF2 BCLK */
886 { 0x0FFF, 0x0FFF, 0x0000 }, /* R788 - AIF2ADC LRCLK */
887 { 0x0FFF, 0x0FFF, 0x0000 }, /* R789 - AIF2DAC LRCLK */
888 { 0x0003, 0x0003, 0x0000 }, /* R790 - AIF2DAC Data */
889 { 0x0003, 0x0003, 0x0000 }, /* R791 - AIF2ADC Data */
890 { 0x0000, 0x0000, 0x0000 }, /* R792 */
891 { 0x0000, 0x0000, 0x0000 }, /* R793 */
892 { 0x0000, 0x0000, 0x0000 }, /* R794 */
893 { 0x0000, 0x0000, 0x0000 }, /* R795 */
894 { 0x0000, 0x0000, 0x0000 }, /* R796 */
895 { 0x0000, 0x0000, 0x0000 }, /* R797 */
896 { 0x0000, 0x0000, 0x0000 }, /* R798 */
897 { 0x0000, 0x0000, 0x0000 }, /* R799 */
898 { 0x0000, 0x0000, 0x0000 }, /* R800 */
899 { 0x0000, 0x0000, 0x0000 }, /* R801 */
900 { 0x0000, 0x0000, 0x0000 }, /* R802 */
901 { 0x0000, 0x0000, 0x0000 }, /* R803 */
902 { 0x0000, 0x0000, 0x0000 }, /* R804 */
903 { 0x0000, 0x0000, 0x0000 }, /* R805 */
904 { 0x0000, 0x0000, 0x0000 }, /* R806 */
905 { 0x0000, 0x0000, 0x0000 }, /* R807 */
906 { 0x0000, 0x0000, 0x0000 }, /* R808 */
907 { 0x0000, 0x0000, 0x0000 }, /* R809 */
908 { 0x0000, 0x0000, 0x0000 }, /* R810 */
909 { 0x0000, 0x0000, 0x0000 }, /* R811 */
910 { 0x0000, 0x0000, 0x0000 }, /* R812 */
911 { 0x0000, 0x0000, 0x0000 }, /* R813 */
912 { 0x0000, 0x0000, 0x0000 }, /* R814 */
913 { 0x0000, 0x0000, 0x0000 }, /* R815 */
914 { 0x0000, 0x0000, 0x0000 }, /* R816 */
915 { 0x0000, 0x0000, 0x0000 }, /* R817 */
916 { 0x0000, 0x0000, 0x0000 }, /* R818 */
917 { 0x0000, 0x0000, 0x0000 }, /* R819 */
918 { 0x0000, 0x0000, 0x0000 }, /* R820 */
919 { 0x0000, 0x0000, 0x0000 }, /* R821 */
920 { 0x0000, 0x0000, 0x0000 }, /* R822 */
921 { 0x0000, 0x0000, 0x0000 }, /* R823 */
922 { 0x0000, 0x0000, 0x0000 }, /* R824 */
923 { 0x0000, 0x0000, 0x0000 }, /* R825 */
924 { 0x0000, 0x0000, 0x0000 }, /* R826 */
925 { 0x0000, 0x0000, 0x0000 }, /* R827 */
926 { 0x0000, 0x0000, 0x0000 }, /* R828 */
927 { 0x0000, 0x0000, 0x0000 }, /* R829 */
928 { 0x0000, 0x0000, 0x0000 }, /* R830 */
929 { 0x0000, 0x0000, 0x0000 }, /* R831 */
930 { 0x0000, 0x0000, 0x0000 }, /* R832 */
931 { 0x0000, 0x0000, 0x0000 }, /* R833 */
932 { 0x0000, 0x0000, 0x0000 }, /* R834 */
933 { 0x0000, 0x0000, 0x0000 }, /* R835 */
934 { 0x0000, 0x0000, 0x0000 }, /* R836 */
935 { 0x0000, 0x0000, 0x0000 }, /* R837 */
936 { 0x0000, 0x0000, 0x0000 }, /* R838 */
937 { 0x0000, 0x0000, 0x0000 }, /* R839 */
938 { 0x0000, 0x0000, 0x0000 }, /* R840 */
939 { 0x0000, 0x0000, 0x0000 }, /* R841 */
940 { 0x0000, 0x0000, 0x0000 }, /* R842 */
941 { 0x0000, 0x0000, 0x0000 }, /* R843 */
942 { 0x0000, 0x0000, 0x0000 }, /* R844 */
943 { 0x0000, 0x0000, 0x0000 }, /* R845 */
944 { 0x0000, 0x0000, 0x0000 }, /* R846 */
945 { 0x0000, 0x0000, 0x0000 }, /* R847 */
946 { 0x0000, 0x0000, 0x0000 }, /* R848 */
947 { 0x0000, 0x0000, 0x0000 }, /* R849 */
948 { 0x0000, 0x0000, 0x0000 }, /* R850 */
949 { 0x0000, 0x0000, 0x0000 }, /* R851 */
950 { 0x0000, 0x0000, 0x0000 }, /* R852 */
951 { 0x0000, 0x0000, 0x0000 }, /* R853 */
952 { 0x0000, 0x0000, 0x0000 }, /* R854 */
953 { 0x0000, 0x0000, 0x0000 }, /* R855 */
954 { 0x0000, 0x0000, 0x0000 }, /* R856 */
955 { 0x0000, 0x0000, 0x0000 }, /* R857 */
956 { 0x0000, 0x0000, 0x0000 }, /* R858 */
957 { 0x0000, 0x0000, 0x0000 }, /* R859 */
958 { 0x0000, 0x0000, 0x0000 }, /* R860 */
959 { 0x0000, 0x0000, 0x0000 }, /* R861 */
960 { 0x0000, 0x0000, 0x0000 }, /* R862 */
961 { 0x0000, 0x0000, 0x0000 }, /* R863 */
962 { 0x0000, 0x0000, 0x0000 }, /* R864 */
963 { 0x0000, 0x0000, 0x0000 }, /* R865 */
964 { 0x0000, 0x0000, 0x0000 }, /* R866 */
965 { 0x0000, 0x0000, 0x0000 }, /* R867 */
966 { 0x0000, 0x0000, 0x0000 }, /* R868 */
967 { 0x0000, 0x0000, 0x0000 }, /* R869 */
968 { 0x0000, 0x0000, 0x0000 }, /* R870 */
969 { 0x0000, 0x0000, 0x0000 }, /* R871 */
970 { 0x0000, 0x0000, 0x0000 }, /* R872 */
971 { 0x0000, 0x0000, 0x0000 }, /* R873 */
972 { 0x0000, 0x0000, 0x0000 }, /* R874 */
973 { 0x0000, 0x0000, 0x0000 }, /* R875 */
974 { 0x0000, 0x0000, 0x0000 }, /* R876 */
975 { 0x0000, 0x0000, 0x0000 }, /* R877 */
976 { 0x0000, 0x0000, 0x0000 }, /* R878 */
977 { 0x0000, 0x0000, 0x0000 }, /* R879 */
978 { 0x0000, 0x0000, 0x0000 }, /* R880 */
979 { 0x0000, 0x0000, 0x0000 }, /* R881 */
980 { 0x0000, 0x0000, 0x0000 }, /* R882 */
981 { 0x0000, 0x0000, 0x0000 }, /* R883 */
982 { 0x0000, 0x0000, 0x0000 }, /* R884 */
983 { 0x0000, 0x0000, 0x0000 }, /* R885 */
984 { 0x0000, 0x0000, 0x0000 }, /* R886 */
985 { 0x0000, 0x0000, 0x0000 }, /* R887 */
986 { 0x0000, 0x0000, 0x0000 }, /* R888 */
987 { 0x0000, 0x0000, 0x0000 }, /* R889 */
988 { 0x0000, 0x0000, 0x0000 }, /* R890 */
989 { 0x0000, 0x0000, 0x0000 }, /* R891 */
990 { 0x0000, 0x0000, 0x0000 }, /* R892 */
991 { 0x0000, 0x0000, 0x0000 }, /* R893 */
992 { 0x0000, 0x0000, 0x0000 }, /* R894 */
993 { 0x0000, 0x0000, 0x0000 }, /* R895 */
994 { 0x0000, 0x0000, 0x0000 }, /* R896 */
995 { 0x0000, 0x0000, 0x0000 }, /* R897 */
996 { 0x0000, 0x0000, 0x0000 }, /* R898 */
997 { 0x0000, 0x0000, 0x0000 }, /* R899 */
998 { 0x0000, 0x0000, 0x0000 }, /* R900 */
999 { 0x0000, 0x0000, 0x0000 }, /* R901 */
1000 { 0x0000, 0x0000, 0x0000 }, /* R902 */
1001 { 0x0000, 0x0000, 0x0000 }, /* R903 */
1002 { 0x0000, 0x0000, 0x0000 }, /* R904 */
1003 { 0x0000, 0x0000, 0x0000 }, /* R905 */
1004 { 0x0000, 0x0000, 0x0000 }, /* R906 */
1005 { 0x0000, 0x0000, 0x0000 }, /* R907 */
1006 { 0x0000, 0x0000, 0x0000 }, /* R908 */
1007 { 0x0000, 0x0000, 0x0000 }, /* R909 */
1008 { 0x0000, 0x0000, 0x0000 }, /* R910 */
1009 { 0x0000, 0x0000, 0x0000 }, /* R911 */
1010 { 0x0000, 0x0000, 0x0000 }, /* R912 */
1011 { 0x0000, 0x0000, 0x0000 }, /* R913 */
1012 { 0x0000, 0x0000, 0x0000 }, /* R914 */
1013 { 0x0000, 0x0000, 0x0000 }, /* R915 */
1014 { 0x0000, 0x0000, 0x0000 }, /* R916 */
1015 { 0x0000, 0x0000, 0x0000 }, /* R917 */
1016 { 0x0000, 0x0000, 0x0000 }, /* R918 */
1017 { 0x0000, 0x0000, 0x0000 }, /* R919 */
1018 { 0x0000, 0x0000, 0x0000 }, /* R920 */
1019 { 0x0000, 0x0000, 0x0000 }, /* R921 */
1020 { 0x0000, 0x0000, 0x0000 }, /* R922 */
1021 { 0x0000, 0x0000, 0x0000 }, /* R923 */
1022 { 0x0000, 0x0000, 0x0000 }, /* R924 */
1023 { 0x0000, 0x0000, 0x0000 }, /* R925 */
1024 { 0x0000, 0x0000, 0x0000 }, /* R926 */
1025 { 0x0000, 0x0000, 0x0000 }, /* R927 */
1026 { 0x0000, 0x0000, 0x0000 }, /* R928 */
1027 { 0x0000, 0x0000, 0x0000 }, /* R929 */
1028 { 0x0000, 0x0000, 0x0000 }, /* R930 */
1029 { 0x0000, 0x0000, 0x0000 }, /* R931 */
1030 { 0x0000, 0x0000, 0x0000 }, /* R932 */
1031 { 0x0000, 0x0000, 0x0000 }, /* R933 */
1032 { 0x0000, 0x0000, 0x0000 }, /* R934 */
1033 { 0x0000, 0x0000, 0x0000 }, /* R935 */
1034 { 0x0000, 0x0000, 0x0000 }, /* R936 */
1035 { 0x0000, 0x0000, 0x0000 }, /* R937 */
1036 { 0x0000, 0x0000, 0x0000 }, /* R938 */
1037 { 0x0000, 0x0000, 0x0000 }, /* R939 */
1038 { 0x0000, 0x0000, 0x0000 }, /* R940 */
1039 { 0x0000, 0x0000, 0x0000 }, /* R941 */
1040 { 0x0000, 0x0000, 0x0000 }, /* R942 */
1041 { 0x0000, 0x0000, 0x0000 }, /* R943 */
1042 { 0x0000, 0x0000, 0x0000 }, /* R944 */
1043 { 0x0000, 0x0000, 0x0000 }, /* R945 */
1044 { 0x0000, 0x0000, 0x0000 }, /* R946 */
1045 { 0x0000, 0x0000, 0x0000 }, /* R947 */
1046 { 0x0000, 0x0000, 0x0000 }, /* R948 */
1047 { 0x0000, 0x0000, 0x0000 }, /* R949 */
1048 { 0x0000, 0x0000, 0x0000 }, /* R950 */
1049 { 0x0000, 0x0000, 0x0000 }, /* R951 */
1050 { 0x0000, 0x0000, 0x0000 }, /* R952 */
1051 { 0x0000, 0x0000, 0x0000 }, /* R953 */
1052 { 0x0000, 0x0000, 0x0000 }, /* R954 */
1053 { 0x0000, 0x0000, 0x0000 }, /* R955 */
1054 { 0x0000, 0x0000, 0x0000 }, /* R956 */
1055 { 0x0000, 0x0000, 0x0000 }, /* R957 */
1056 { 0x0000, 0x0000, 0x0000 }, /* R958 */
1057 { 0x0000, 0x0000, 0x0000 }, /* R959 */
1058 { 0x0000, 0x0000, 0x0000 }, /* R960 */
1059 { 0x0000, 0x0000, 0x0000 }, /* R961 */
1060 { 0x0000, 0x0000, 0x0000 }, /* R962 */
1061 { 0x0000, 0x0000, 0x0000 }, /* R963 */
1062 { 0x0000, 0x0000, 0x0000 }, /* R964 */
1063 { 0x0000, 0x0000, 0x0000 }, /* R965 */
1064 { 0x0000, 0x0000, 0x0000 }, /* R966 */
1065 { 0x0000, 0x0000, 0x0000 }, /* R967 */
1066 { 0x0000, 0x0000, 0x0000 }, /* R968 */
1067 { 0x0000, 0x0000, 0x0000 }, /* R969 */
1068 { 0x0000, 0x0000, 0x0000 }, /* R970 */
1069 { 0x0000, 0x0000, 0x0000 }, /* R971 */
1070 { 0x0000, 0x0000, 0x0000 }, /* R972 */
1071 { 0x0000, 0x0000, 0x0000 }, /* R973 */
1072 { 0x0000, 0x0000, 0x0000 }, /* R974 */
1073 { 0x0000, 0x0000, 0x0000 }, /* R975 */
1074 { 0x0000, 0x0000, 0x0000 }, /* R976 */
1075 { 0x0000, 0x0000, 0x0000 }, /* R977 */
1076 { 0x0000, 0x0000, 0x0000 }, /* R978 */
1077 { 0x0000, 0x0000, 0x0000 }, /* R979 */
1078 { 0x0000, 0x0000, 0x0000 }, /* R980 */
1079 { 0x0000, 0x0000, 0x0000 }, /* R981 */
1080 { 0x0000, 0x0000, 0x0000 }, /* R982 */
1081 { 0x0000, 0x0000, 0x0000 }, /* R983 */
1082 { 0x0000, 0x0000, 0x0000 }, /* R984 */
1083 { 0x0000, 0x0000, 0x0000 }, /* R985 */
1084 { 0x0000, 0x0000, 0x0000 }, /* R986 */
1085 { 0x0000, 0x0000, 0x0000 }, /* R987 */
1086 { 0x0000, 0x0000, 0x0000 }, /* R988 */
1087 { 0x0000, 0x0000, 0x0000 }, /* R989 */
1088 { 0x0000, 0x0000, 0x0000 }, /* R990 */
1089 { 0x0000, 0x0000, 0x0000 }, /* R991 */
1090 { 0x0000, 0x0000, 0x0000 }, /* R992 */
1091 { 0x0000, 0x0000, 0x0000 }, /* R993 */
1092 { 0x0000, 0x0000, 0x0000 }, /* R994 */
1093 { 0x0000, 0x0000, 0x0000 }, /* R995 */
1094 { 0x0000, 0x0000, 0x0000 }, /* R996 */
1095 { 0x0000, 0x0000, 0x0000 }, /* R997 */
1096 { 0x0000, 0x0000, 0x0000 }, /* R998 */
1097 { 0x0000, 0x0000, 0x0000 }, /* R999 */
1098 { 0x0000, 0x0000, 0x0000 }, /* R1000 */
1099 { 0x0000, 0x0000, 0x0000 }, /* R1001 */
1100 { 0x0000, 0x0000, 0x0000 }, /* R1002 */
1101 { 0x0000, 0x0000, 0x0000 }, /* R1003 */
1102 { 0x0000, 0x0000, 0x0000 }, /* R1004 */
1103 { 0x0000, 0x0000, 0x0000 }, /* R1005 */
1104 { 0x0000, 0x0000, 0x0000 }, /* R1006 */
1105 { 0x0000, 0x0000, 0x0000 }, /* R1007 */
1106 { 0x0000, 0x0000, 0x0000 }, /* R1008 */
1107 { 0x0000, 0x0000, 0x0000 }, /* R1009 */
1108 { 0x0000, 0x0000, 0x0000 }, /* R1010 */
1109 { 0x0000, 0x0000, 0x0000 }, /* R1011 */
1110 { 0x0000, 0x0000, 0x0000 }, /* R1012 */
1111 { 0x0000, 0x0000, 0x0000 }, /* R1013 */
1112 { 0x0000, 0x0000, 0x0000 }, /* R1014 */
1113 { 0x0000, 0x0000, 0x0000 }, /* R1015 */
1114 { 0x0000, 0x0000, 0x0000 }, /* R1016 */
1115 { 0x0000, 0x0000, 0x0000 }, /* R1017 */
1116 { 0x0000, 0x0000, 0x0000 }, /* R1018 */
1117 { 0x0000, 0x0000, 0x0000 }, /* R1019 */
1118 { 0x0000, 0x0000, 0x0000 }, /* R1020 */
1119 { 0x0000, 0x0000, 0x0000 }, /* R1021 */
1120 { 0x0000, 0x0000, 0x0000 }, /* R1022 */
1121 { 0x0000, 0x0000, 0x0000 }, /* R1023 */
1122 { 0x00FF, 0x01FF, 0x0000 }, /* R1024 - AIF1 ADC1 Left Volume */
1123 { 0x00FF, 0x01FF, 0x0000 }, /* R1025 - AIF1 ADC1 Right Volume */
1124 { 0x00FF, 0x01FF, 0x0000 }, /* R1026 - AIF1 DAC1 Left Volume */
1125 { 0x00FF, 0x01FF, 0x0000 }, /* R1027 - AIF1 DAC1 Right Volume */
1126 { 0x00FF, 0x01FF, 0x0000 }, /* R1028 - AIF1 ADC2 Left Volume */
1127 { 0x00FF, 0x01FF, 0x0000 }, /* R1029 - AIF1 ADC2 Right Volume */
1128 { 0x00FF, 0x01FF, 0x0000 }, /* R1030 - AIF1 DAC2 Left Volume */
1129 { 0x00FF, 0x01FF, 0x0000 }, /* R1031 - AIF1 DAC2 Right Volume */
1130 { 0x0000, 0x0000, 0x0000 }, /* R1032 */
1131 { 0x0000, 0x0000, 0x0000 }, /* R1033 */
1132 { 0x0000, 0x0000, 0x0000 }, /* R1034 */
1133 { 0x0000, 0x0000, 0x0000 }, /* R1035 */
1134 { 0x0000, 0x0000, 0x0000 }, /* R1036 */
1135 { 0x0000, 0x0000, 0x0000 }, /* R1037 */
1136 { 0x0000, 0x0000, 0x0000 }, /* R1038 */
1137 { 0x0000, 0x0000, 0x0000 }, /* R1039 */
1138 { 0xF800, 0xF800, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
1139 { 0x7800, 0x7800, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
1140 { 0x0000, 0x0000, 0x0000 }, /* R1042 */
1141 { 0x0000, 0x0000, 0x0000 }, /* R1043 */
1142 { 0x0000, 0x0000, 0x0000 }, /* R1044 */
1143 { 0x0000, 0x0000, 0x0000 }, /* R1045 */
1144 { 0x0000, 0x0000, 0x0000 }, /* R1046 */
1145 { 0x0000, 0x0000, 0x0000 }, /* R1047 */
1146 { 0x0000, 0x0000, 0x0000 }, /* R1048 */
1147 { 0x0000, 0x0000, 0x0000 }, /* R1049 */
1148 { 0x0000, 0x0000, 0x0000 }, /* R1050 */
1149 { 0x0000, 0x0000, 0x0000 }, /* R1051 */
1150 { 0x0000, 0x0000, 0x0000 }, /* R1052 */
1151 { 0x0000, 0x0000, 0x0000 }, /* R1053 */
1152 { 0x0000, 0x0000, 0x0000 }, /* R1054 */
1153 { 0x0000, 0x0000, 0x0000 }, /* R1055 */
1154 { 0x02B6, 0x02B6, 0x0000 }, /* R1056 - AIF1 DAC1 Filters (1) */
1155 { 0x3F00, 0x3F00, 0x0000 }, /* R1057 - AIF1 DAC1 Filters (2) */
1156 { 0x02B6, 0x02B6, 0x0000 }, /* R1058 - AIF1 DAC2 Filters (1) */
1157 { 0x3F00, 0x3F00, 0x0000 }, /* R1059 - AIF1 DAC2 Filters (2) */
1158 { 0x0000, 0x0000, 0x0000 }, /* R1060 */
1159 { 0x0000, 0x0000, 0x0000 }, /* R1061 */
1160 { 0x0000, 0x0000, 0x0000 }, /* R1062 */
1161 { 0x0000, 0x0000, 0x0000 }, /* R1063 */
1162 { 0x0000, 0x0000, 0x0000 }, /* R1064 */
1163 { 0x0000, 0x0000, 0x0000 }, /* R1065 */
1164 { 0x0000, 0x0000, 0x0000 }, /* R1066 */
1165 { 0x0000, 0x0000, 0x0000 }, /* R1067 */
1166 { 0x0000, 0x0000, 0x0000 }, /* R1068 */
1167 { 0x0000, 0x0000, 0x0000 }, /* R1069 */
1168 { 0x0000, 0x0000, 0x0000 }, /* R1070 */
1169 { 0x0000, 0x0000, 0x0000 }, /* R1071 */
1170 { 0x0000, 0x0000, 0x0000 }, /* R1072 */
1171 { 0x0000, 0x0000, 0x0000 }, /* R1073 */
1172 { 0x0000, 0x0000, 0x0000 }, /* R1074 */
1173 { 0x0000, 0x0000, 0x0000 }, /* R1075 */
1174 { 0x0000, 0x0000, 0x0000 }, /* R1076 */
1175 { 0x0000, 0x0000, 0x0000 }, /* R1077 */
1176 { 0x0000, 0x0000, 0x0000 }, /* R1078 */
1177 { 0x0000, 0x0000, 0x0000 }, /* R1079 */
1178 { 0x0000, 0x0000, 0x0000 }, /* R1080 */
1179 { 0x0000, 0x0000, 0x0000 }, /* R1081 */
1180 { 0x0000, 0x0000, 0x0000 }, /* R1082 */
1181 { 0x0000, 0x0000, 0x0000 }, /* R1083 */
1182 { 0x0000, 0x0000, 0x0000 }, /* R1084 */
1183 { 0x0000, 0x0000, 0x0000 }, /* R1085 */
1184 { 0x0000, 0x0000, 0x0000 }, /* R1086 */
1185 { 0x0000, 0x0000, 0x0000 }, /* R1087 */
1186 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1088 - AIF1 DRC1 (1) */
1187 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1089 - AIF1 DRC1 (2) */
1188 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
1189 { 0x07FF, 0x07FF, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
1190 { 0x03FF, 0x03FF, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
1191 { 0x0000, 0x0000, 0x0000 }, /* R1093 */
1192 { 0x0000, 0x0000, 0x0000 }, /* R1094 */
1193 { 0x0000, 0x0000, 0x0000 }, /* R1095 */
1194 { 0x0000, 0x0000, 0x0000 }, /* R1096 */
1195 { 0x0000, 0x0000, 0x0000 }, /* R1097 */
1196 { 0x0000, 0x0000, 0x0000 }, /* R1098 */
1197 { 0x0000, 0x0000, 0x0000 }, /* R1099 */
1198 { 0x0000, 0x0000, 0x0000 }, /* R1100 */
1199 { 0x0000, 0x0000, 0x0000 }, /* R1101 */
1200 { 0x0000, 0x0000, 0x0000 }, /* R1102 */
1201 { 0x0000, 0x0000, 0x0000 }, /* R1103 */
1202 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1104 - AIF1 DRC2 (1) */
1203 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1105 - AIF1 DRC2 (2) */
1204 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
1205 { 0x07FF, 0x07FF, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
1206 { 0x03FF, 0x03FF, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
1207 { 0x0000, 0x0000, 0x0000 }, /* R1109 */
1208 { 0x0000, 0x0000, 0x0000 }, /* R1110 */
1209 { 0x0000, 0x0000, 0x0000 }, /* R1111 */
1210 { 0x0000, 0x0000, 0x0000 }, /* R1112 */
1211 { 0x0000, 0x0000, 0x0000 }, /* R1113 */
1212 { 0x0000, 0x0000, 0x0000 }, /* R1114 */
1213 { 0x0000, 0x0000, 0x0000 }, /* R1115 */
1214 { 0x0000, 0x0000, 0x0000 }, /* R1116 */
1215 { 0x0000, 0x0000, 0x0000 }, /* R1117 */
1216 { 0x0000, 0x0000, 0x0000 }, /* R1118 */
1217 { 0x0000, 0x0000, 0x0000 }, /* R1119 */
1218 { 0x0000, 0x0000, 0x0000 }, /* R1120 */
1219 { 0x0000, 0x0000, 0x0000 }, /* R1121 */
1220 { 0x0000, 0x0000, 0x0000 }, /* R1122 */
1221 { 0x0000, 0x0000, 0x0000 }, /* R1123 */
1222 { 0x0000, 0x0000, 0x0000 }, /* R1124 */
1223 { 0x0000, 0x0000, 0x0000 }, /* R1125 */
1224 { 0x0000, 0x0000, 0x0000 }, /* R1126 */
1225 { 0x0000, 0x0000, 0x0000 }, /* R1127 */
1226 { 0x0000, 0x0000, 0x0000 }, /* R1128 */
1227 { 0x0000, 0x0000, 0x0000 }, /* R1129 */
1228 { 0x0000, 0x0000, 0x0000 }, /* R1130 */
1229 { 0x0000, 0x0000, 0x0000 }, /* R1131 */
1230 { 0x0000, 0x0000, 0x0000 }, /* R1132 */
1231 { 0x0000, 0x0000, 0x0000 }, /* R1133 */
1232 { 0x0000, 0x0000, 0x0000 }, /* R1134 */
1233 { 0x0000, 0x0000, 0x0000 }, /* R1135 */
1234 { 0x0000, 0x0000, 0x0000 }, /* R1136 */
1235 { 0x0000, 0x0000, 0x0000 }, /* R1137 */
1236 { 0x0000, 0x0000, 0x0000 }, /* R1138 */
1237 { 0x0000, 0x0000, 0x0000 }, /* R1139 */
1238 { 0x0000, 0x0000, 0x0000 }, /* R1140 */
1239 { 0x0000, 0x0000, 0x0000 }, /* R1141 */
1240 { 0x0000, 0x0000, 0x0000 }, /* R1142 */
1241 { 0x0000, 0x0000, 0x0000 }, /* R1143 */
1242 { 0x0000, 0x0000, 0x0000 }, /* R1144 */
1243 { 0x0000, 0x0000, 0x0000 }, /* R1145 */
1244 { 0x0000, 0x0000, 0x0000 }, /* R1146 */
1245 { 0x0000, 0x0000, 0x0000 }, /* R1147 */
1246 { 0x0000, 0x0000, 0x0000 }, /* R1148 */
1247 { 0x0000, 0x0000, 0x0000 }, /* R1149 */
1248 { 0x0000, 0x0000, 0x0000 }, /* R1150 */
1249 { 0x0000, 0x0000, 0x0000 }, /* R1151 */
1250 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1251 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1252 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1253 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1254 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1255 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1256 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1257 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1258 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1259 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1260 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1261 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1262 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1263 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1264 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1265 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1266 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1267 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1268 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1269 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1270 { 0x0000, 0x0000, 0x0000 }, /* R1172 */
1271 { 0x0000, 0x0000, 0x0000 }, /* R1173 */
1272 { 0x0000, 0x0000, 0x0000 }, /* R1174 */
1273 { 0x0000, 0x0000, 0x0000 }, /* R1175 */
1274 { 0x0000, 0x0000, 0x0000 }, /* R1176 */
1275 { 0x0000, 0x0000, 0x0000 }, /* R1177 */
1276 { 0x0000, 0x0000, 0x0000 }, /* R1178 */
1277 { 0x0000, 0x0000, 0x0000 }, /* R1179 */
1278 { 0x0000, 0x0000, 0x0000 }, /* R1180 */
1279 { 0x0000, 0x0000, 0x0000 }, /* R1181 */
1280 { 0x0000, 0x0000, 0x0000 }, /* R1182 */
1281 { 0x0000, 0x0000, 0x0000 }, /* R1183 */
1282 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1283 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1284 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1285 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1286 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1287 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1288 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1289 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1290 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1291 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1292 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1293 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1294 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1295 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1296 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1297 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1298 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1299 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1300 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1301 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1302 { 0x0000, 0x0000, 0x0000 }, /* R1204 */
1303 { 0x0000, 0x0000, 0x0000 }, /* R1205 */
1304 { 0x0000, 0x0000, 0x0000 }, /* R1206 */
1305 { 0x0000, 0x0000, 0x0000 }, /* R1207 */
1306 { 0x0000, 0x0000, 0x0000 }, /* R1208 */
1307 { 0x0000, 0x0000, 0x0000 }, /* R1209 */
1308 { 0x0000, 0x0000, 0x0000 }, /* R1210 */
1309 { 0x0000, 0x0000, 0x0000 }, /* R1211 */
1310 { 0x0000, 0x0000, 0x0000 }, /* R1212 */
1311 { 0x0000, 0x0000, 0x0000 }, /* R1213 */
1312 { 0x0000, 0x0000, 0x0000 }, /* R1214 */
1313 { 0x0000, 0x0000, 0x0000 }, /* R1215 */
1314 { 0x0000, 0x0000, 0x0000 }, /* R1216 */
1315 { 0x0000, 0x0000, 0x0000 }, /* R1217 */
1316 { 0x0000, 0x0000, 0x0000 }, /* R1218 */
1317 { 0x0000, 0x0000, 0x0000 }, /* R1219 */
1318 { 0x0000, 0x0000, 0x0000 }, /* R1220 */
1319 { 0x0000, 0x0000, 0x0000 }, /* R1221 */
1320 { 0x0000, 0x0000, 0x0000 }, /* R1222 */
1321 { 0x0000, 0x0000, 0x0000 }, /* R1223 */
1322 { 0x0000, 0x0000, 0x0000 }, /* R1224 */
1323 { 0x0000, 0x0000, 0x0000 }, /* R1225 */
1324 { 0x0000, 0x0000, 0x0000 }, /* R1226 */
1325 { 0x0000, 0x0000, 0x0000 }, /* R1227 */
1326 { 0x0000, 0x0000, 0x0000 }, /* R1228 */
1327 { 0x0000, 0x0000, 0x0000 }, /* R1229 */
1328 { 0x0000, 0x0000, 0x0000 }, /* R1230 */
1329 { 0x0000, 0x0000, 0x0000 }, /* R1231 */
1330 { 0x0000, 0x0000, 0x0000 }, /* R1232 */
1331 { 0x0000, 0x0000, 0x0000 }, /* R1233 */
1332 { 0x0000, 0x0000, 0x0000 }, /* R1234 */
1333 { 0x0000, 0x0000, 0x0000 }, /* R1235 */
1334 { 0x0000, 0x0000, 0x0000 }, /* R1236 */
1335 { 0x0000, 0x0000, 0x0000 }, /* R1237 */
1336 { 0x0000, 0x0000, 0x0000 }, /* R1238 */
1337 { 0x0000, 0x0000, 0x0000 }, /* R1239 */
1338 { 0x0000, 0x0000, 0x0000 }, /* R1240 */
1339 { 0x0000, 0x0000, 0x0000 }, /* R1241 */
1340 { 0x0000, 0x0000, 0x0000 }, /* R1242 */
1341 { 0x0000, 0x0000, 0x0000 }, /* R1243 */
1342 { 0x0000, 0x0000, 0x0000 }, /* R1244 */
1343 { 0x0000, 0x0000, 0x0000 }, /* R1245 */
1344 { 0x0000, 0x0000, 0x0000 }, /* R1246 */
1345 { 0x0000, 0x0000, 0x0000 }, /* R1247 */
1346 { 0x0000, 0x0000, 0x0000 }, /* R1248 */
1347 { 0x0000, 0x0000, 0x0000 }, /* R1249 */
1348 { 0x0000, 0x0000, 0x0000 }, /* R1250 */
1349 { 0x0000, 0x0000, 0x0000 }, /* R1251 */
1350 { 0x0000, 0x0000, 0x0000 }, /* R1252 */
1351 { 0x0000, 0x0000, 0x0000 }, /* R1253 */
1352 { 0x0000, 0x0000, 0x0000 }, /* R1254 */
1353 { 0x0000, 0x0000, 0x0000 }, /* R1255 */
1354 { 0x0000, 0x0000, 0x0000 }, /* R1256 */
1355 { 0x0000, 0x0000, 0x0000 }, /* R1257 */
1356 { 0x0000, 0x0000, 0x0000 }, /* R1258 */
1357 { 0x0000, 0x0000, 0x0000 }, /* R1259 */
1358 { 0x0000, 0x0000, 0x0000 }, /* R1260 */
1359 { 0x0000, 0x0000, 0x0000 }, /* R1261 */
1360 { 0x0000, 0x0000, 0x0000 }, /* R1262 */
1361 { 0x0000, 0x0000, 0x0000 }, /* R1263 */
1362 { 0x0000, 0x0000, 0x0000 }, /* R1264 */
1363 { 0x0000, 0x0000, 0x0000 }, /* R1265 */
1364 { 0x0000, 0x0000, 0x0000 }, /* R1266 */
1365 { 0x0000, 0x0000, 0x0000 }, /* R1267 */
1366 { 0x0000, 0x0000, 0x0000 }, /* R1268 */
1367 { 0x0000, 0x0000, 0x0000 }, /* R1269 */
1368 { 0x0000, 0x0000, 0x0000 }, /* R1270 */
1369 { 0x0000, 0x0000, 0x0000 }, /* R1271 */
1370 { 0x0000, 0x0000, 0x0000 }, /* R1272 */
1371 { 0x0000, 0x0000, 0x0000 }, /* R1273 */
1372 { 0x0000, 0x0000, 0x0000 }, /* R1274 */
1373 { 0x0000, 0x0000, 0x0000 }, /* R1275 */
1374 { 0x0000, 0x0000, 0x0000 }, /* R1276 */
1375 { 0x0000, 0x0000, 0x0000 }, /* R1277 */
1376 { 0x0000, 0x0000, 0x0000 }, /* R1278 */
1377 { 0x0000, 0x0000, 0x0000 }, /* R1279 */
1378 { 0x00FF, 0x01FF, 0x0000 }, /* R1280 - AIF2 ADC Left Volume */
1379 { 0x00FF, 0x01FF, 0x0000 }, /* R1281 - AIF2 ADC Right Volume */
1380 { 0x00FF, 0x01FF, 0x0000 }, /* R1282 - AIF2 DAC Left Volume */
1381 { 0x00FF, 0x01FF, 0x0000 }, /* R1283 - AIF2 DAC Right Volume */
1382 { 0x0000, 0x0000, 0x0000 }, /* R1284 */
1383 { 0x0000, 0x0000, 0x0000 }, /* R1285 */
1384 { 0x0000, 0x0000, 0x0000 }, /* R1286 */
1385 { 0x0000, 0x0000, 0x0000 }, /* R1287 */
1386 { 0x0000, 0x0000, 0x0000 }, /* R1288 */
1387 { 0x0000, 0x0000, 0x0000 }, /* R1289 */
1388 { 0x0000, 0x0000, 0x0000 }, /* R1290 */
1389 { 0x0000, 0x0000, 0x0000 }, /* R1291 */
1390 { 0x0000, 0x0000, 0x0000 }, /* R1292 */
1391 { 0x0000, 0x0000, 0x0000 }, /* R1293 */
1392 { 0x0000, 0x0000, 0x0000 }, /* R1294 */
1393 { 0x0000, 0x0000, 0x0000 }, /* R1295 */
1394 { 0xF800, 0xF800, 0x0000 }, /* R1296 - AIF2 ADC Filters */
1395 { 0x0000, 0x0000, 0x0000 }, /* R1297 */
1396 { 0x0000, 0x0000, 0x0000 }, /* R1298 */
1397 { 0x0000, 0x0000, 0x0000 }, /* R1299 */
1398 { 0x0000, 0x0000, 0x0000 }, /* R1300 */
1399 { 0x0000, 0x0000, 0x0000 }, /* R1301 */
1400 { 0x0000, 0x0000, 0x0000 }, /* R1302 */
1401 { 0x0000, 0x0000, 0x0000 }, /* R1303 */
1402 { 0x0000, 0x0000, 0x0000 }, /* R1304 */
1403 { 0x0000, 0x0000, 0x0000 }, /* R1305 */
1404 { 0x0000, 0x0000, 0x0000 }, /* R1306 */
1405 { 0x0000, 0x0000, 0x0000 }, /* R1307 */
1406 { 0x0000, 0x0000, 0x0000 }, /* R1308 */
1407 { 0x0000, 0x0000, 0x0000 }, /* R1309 */
1408 { 0x0000, 0x0000, 0x0000 }, /* R1310 */
1409 { 0x0000, 0x0000, 0x0000 }, /* R1311 */
1410 { 0x02B6, 0x02B6, 0x0000 }, /* R1312 - AIF2 DAC Filters (1) */
1411 { 0x3F00, 0x3F00, 0x0000 }, /* R1313 - AIF2 DAC Filters (2) */
1412 { 0x0000, 0x0000, 0x0000 }, /* R1314 */
1413 { 0x0000, 0x0000, 0x0000 }, /* R1315 */
1414 { 0x0000, 0x0000, 0x0000 }, /* R1316 */
1415 { 0x0000, 0x0000, 0x0000 }, /* R1317 */
1416 { 0x0000, 0x0000, 0x0000 }, /* R1318 */
1417 { 0x0000, 0x0000, 0x0000 }, /* R1319 */
1418 { 0x0000, 0x0000, 0x0000 }, /* R1320 */
1419 { 0x0000, 0x0000, 0x0000 }, /* R1321 */
1420 { 0x0000, 0x0000, 0x0000 }, /* R1322 */
1421 { 0x0000, 0x0000, 0x0000 }, /* R1323 */
1422 { 0x0000, 0x0000, 0x0000 }, /* R1324 */
1423 { 0x0000, 0x0000, 0x0000 }, /* R1325 */
1424 { 0x0000, 0x0000, 0x0000 }, /* R1326 */
1425 { 0x0000, 0x0000, 0x0000 }, /* R1327 */
1426 { 0x0000, 0x0000, 0x0000 }, /* R1328 */
1427 { 0x0000, 0x0000, 0x0000 }, /* R1329 */
1428 { 0x0000, 0x0000, 0x0000 }, /* R1330 */
1429 { 0x0000, 0x0000, 0x0000 }, /* R1331 */
1430 { 0x0000, 0x0000, 0x0000 }, /* R1332 */
1431 { 0x0000, 0x0000, 0x0000 }, /* R1333 */
1432 { 0x0000, 0x0000, 0x0000 }, /* R1334 */
1433 { 0x0000, 0x0000, 0x0000 }, /* R1335 */
1434 { 0x0000, 0x0000, 0x0000 }, /* R1336 */
1435 { 0x0000, 0x0000, 0x0000 }, /* R1337 */
1436 { 0x0000, 0x0000, 0x0000 }, /* R1338 */
1437 { 0x0000, 0x0000, 0x0000 }, /* R1339 */
1438 { 0x0000, 0x0000, 0x0000 }, /* R1340 */
1439 { 0x0000, 0x0000, 0x0000 }, /* R1341 */
1440 { 0x0000, 0x0000, 0x0000 }, /* R1342 */
1441 { 0x0000, 0x0000, 0x0000 }, /* R1343 */
1442 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1344 - AIF2 DRC (1) */
1443 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1345 - AIF2 DRC (2) */
1444 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1346 - AIF2 DRC (3) */
1445 { 0x07FF, 0x07FF, 0x0000 }, /* R1347 - AIF2 DRC (4) */
1446 { 0x03FF, 0x03FF, 0x0000 }, /* R1348 - AIF2 DRC (5) */
1447 { 0x0000, 0x0000, 0x0000 }, /* R1349 */
1448 { 0x0000, 0x0000, 0x0000 }, /* R1350 */
1449 { 0x0000, 0x0000, 0x0000 }, /* R1351 */
1450 { 0x0000, 0x0000, 0x0000 }, /* R1352 */
1451 { 0x0000, 0x0000, 0x0000 }, /* R1353 */
1452 { 0x0000, 0x0000, 0x0000 }, /* R1354 */
1453 { 0x0000, 0x0000, 0x0000 }, /* R1355 */
1454 { 0x0000, 0x0000, 0x0000 }, /* R1356 */
1455 { 0x0000, 0x0000, 0x0000 }, /* R1357 */
1456 { 0x0000, 0x0000, 0x0000 }, /* R1358 */
1457 { 0x0000, 0x0000, 0x0000 }, /* R1359 */
1458 { 0x0000, 0x0000, 0x0000 }, /* R1360 */
1459 { 0x0000, 0x0000, 0x0000 }, /* R1361 */
1460 { 0x0000, 0x0000, 0x0000 }, /* R1362 */
1461 { 0x0000, 0x0000, 0x0000 }, /* R1363 */
1462 { 0x0000, 0x0000, 0x0000 }, /* R1364 */
1463 { 0x0000, 0x0000, 0x0000 }, /* R1365 */
1464 { 0x0000, 0x0000, 0x0000 }, /* R1366 */
1465 { 0x0000, 0x0000, 0x0000 }, /* R1367 */
1466 { 0x0000, 0x0000, 0x0000 }, /* R1368 */
1467 { 0x0000, 0x0000, 0x0000 }, /* R1369 */
1468 { 0x0000, 0x0000, 0x0000 }, /* R1370 */
1469 { 0x0000, 0x0000, 0x0000 }, /* R1371 */
1470 { 0x0000, 0x0000, 0x0000 }, /* R1372 */
1471 { 0x0000, 0x0000, 0x0000 }, /* R1373 */
1472 { 0x0000, 0x0000, 0x0000 }, /* R1374 */
1473 { 0x0000, 0x0000, 0x0000 }, /* R1375 */
1474 { 0x0000, 0x0000, 0x0000 }, /* R1376 */
1475 { 0x0000, 0x0000, 0x0000 }, /* R1377 */
1476 { 0x0000, 0x0000, 0x0000 }, /* R1378 */
1477 { 0x0000, 0x0000, 0x0000 }, /* R1379 */
1478 { 0x0000, 0x0000, 0x0000 }, /* R1380 */
1479 { 0x0000, 0x0000, 0x0000 }, /* R1381 */
1480 { 0x0000, 0x0000, 0x0000 }, /* R1382 */
1481 { 0x0000, 0x0000, 0x0000 }, /* R1383 */
1482 { 0x0000, 0x0000, 0x0000 }, /* R1384 */
1483 { 0x0000, 0x0000, 0x0000 }, /* R1385 */
1484 { 0x0000, 0x0000, 0x0000 }, /* R1386 */
1485 { 0x0000, 0x0000, 0x0000 }, /* R1387 */
1486 { 0x0000, 0x0000, 0x0000 }, /* R1388 */
1487 { 0x0000, 0x0000, 0x0000 }, /* R1389 */
1488 { 0x0000, 0x0000, 0x0000 }, /* R1390 */
1489 { 0x0000, 0x0000, 0x0000 }, /* R1391 */
1490 { 0x0000, 0x0000, 0x0000 }, /* R1392 */
1491 { 0x0000, 0x0000, 0x0000 }, /* R1393 */
1492 { 0x0000, 0x0000, 0x0000 }, /* R1394 */
1493 { 0x0000, 0x0000, 0x0000 }, /* R1395 */
1494 { 0x0000, 0x0000, 0x0000 }, /* R1396 */
1495 { 0x0000, 0x0000, 0x0000 }, /* R1397 */
1496 { 0x0000, 0x0000, 0x0000 }, /* R1398 */
1497 { 0x0000, 0x0000, 0x0000 }, /* R1399 */
1498 { 0x0000, 0x0000, 0x0000 }, /* R1400 */
1499 { 0x0000, 0x0000, 0x0000 }, /* R1401 */
1500 { 0x0000, 0x0000, 0x0000 }, /* R1402 */
1501 { 0x0000, 0x0000, 0x0000 }, /* R1403 */
1502 { 0x0000, 0x0000, 0x0000 }, /* R1404 */
1503 { 0x0000, 0x0000, 0x0000 }, /* R1405 */
1504 { 0x0000, 0x0000, 0x0000 }, /* R1406 */
1505 { 0x0000, 0x0000, 0x0000 }, /* R1407 */
1506 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1408 - AIF2 EQ Gains (1) */
1507 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1409 - AIF2 EQ Gains (2) */
1508 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1410 - AIF2 EQ Band 1 A */
1509 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1411 - AIF2 EQ Band 1 B */
1510 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1412 - AIF2 EQ Band 1 PG */
1511 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1413 - AIF2 EQ Band 2 A */
1512 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1414 - AIF2 EQ Band 2 B */
1513 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1415 - AIF2 EQ Band 2 C */
1514 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1416 - AIF2 EQ Band 2 PG */
1515 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1417 - AIF2 EQ Band 3 A */
1516 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1418 - AIF2 EQ Band 3 B */
1517 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1419 - AIF2 EQ Band 3 C */
1518 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1420 - AIF2 EQ Band 3 PG */
1519 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1421 - AIF2 EQ Band 4 A */
1520 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1422 - AIF2 EQ Band 4 B */
1521 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1423 - AIF2 EQ Band 4 C */
1522 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1424 - AIF2 EQ Band 4 PG */
1523 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1425 - AIF2 EQ Band 5 A */
1524 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1426 - AIF2 EQ Band 5 B */
1525 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1427 - AIF2 EQ Band 5 PG */
1526 { 0x0000, 0x0000, 0x0000 }, /* R1428 */
1527 { 0x0000, 0x0000, 0x0000 }, /* R1429 */
1528 { 0x0000, 0x0000, 0x0000 }, /* R1430 */
1529 { 0x0000, 0x0000, 0x0000 }, /* R1431 */
1530 { 0x0000, 0x0000, 0x0000 }, /* R1432 */
1531 { 0x0000, 0x0000, 0x0000 }, /* R1433 */
1532 { 0x0000, 0x0000, 0x0000 }, /* R1434 */
1533 { 0x0000, 0x0000, 0x0000 }, /* R1435 */
1534 { 0x0000, 0x0000, 0x0000 }, /* R1436 */
1535 { 0x0000, 0x0000, 0x0000 }, /* R1437 */
1536 { 0x0000, 0x0000, 0x0000 }, /* R1438 */
1537 { 0x0000, 0x0000, 0x0000 }, /* R1439 */
1538 { 0x0000, 0x0000, 0x0000 }, /* R1440 */
1539 { 0x0000, 0x0000, 0x0000 }, /* R1441 */
1540 { 0x0000, 0x0000, 0x0000 }, /* R1442 */
1541 { 0x0000, 0x0000, 0x0000 }, /* R1443 */
1542 { 0x0000, 0x0000, 0x0000 }, /* R1444 */
1543 { 0x0000, 0x0000, 0x0000 }, /* R1445 */
1544 { 0x0000, 0x0000, 0x0000 }, /* R1446 */
1545 { 0x0000, 0x0000, 0x0000 }, /* R1447 */
1546 { 0x0000, 0x0000, 0x0000 }, /* R1448 */
1547 { 0x0000, 0x0000, 0x0000 }, /* R1449 */
1548 { 0x0000, 0x0000, 0x0000 }, /* R1450 */
1549 { 0x0000, 0x0000, 0x0000 }, /* R1451 */
1550 { 0x0000, 0x0000, 0x0000 }, /* R1452 */
1551 { 0x0000, 0x0000, 0x0000 }, /* R1453 */
1552 { 0x0000, 0x0000, 0x0000 }, /* R1454 */
1553 { 0x0000, 0x0000, 0x0000 }, /* R1455 */
1554 { 0x0000, 0x0000, 0x0000 }, /* R1456 */
1555 { 0x0000, 0x0000, 0x0000 }, /* R1457 */
1556 { 0x0000, 0x0000, 0x0000 }, /* R1458 */
1557 { 0x0000, 0x0000, 0x0000 }, /* R1459 */
1558 { 0x0000, 0x0000, 0x0000 }, /* R1460 */
1559 { 0x0000, 0x0000, 0x0000 }, /* R1461 */
1560 { 0x0000, 0x0000, 0x0000 }, /* R1462 */
1561 { 0x0000, 0x0000, 0x0000 }, /* R1463 */
1562 { 0x0000, 0x0000, 0x0000 }, /* R1464 */
1563 { 0x0000, 0x0000, 0x0000 }, /* R1465 */
1564 { 0x0000, 0x0000, 0x0000 }, /* R1466 */
1565 { 0x0000, 0x0000, 0x0000 }, /* R1467 */
1566 { 0x0000, 0x0000, 0x0000 }, /* R1468 */
1567 { 0x0000, 0x0000, 0x0000 }, /* R1469 */
1568 { 0x0000, 0x0000, 0x0000 }, /* R1470 */
1569 { 0x0000, 0x0000, 0x0000 }, /* R1471 */
1570 { 0x0000, 0x0000, 0x0000 }, /* R1472 */
1571 { 0x0000, 0x0000, 0x0000 }, /* R1473 */
1572 { 0x0000, 0x0000, 0x0000 }, /* R1474 */
1573 { 0x0000, 0x0000, 0x0000 }, /* R1475 */
1574 { 0x0000, 0x0000, 0x0000 }, /* R1476 */
1575 { 0x0000, 0x0000, 0x0000 }, /* R1477 */
1576 { 0x0000, 0x0000, 0x0000 }, /* R1478 */
1577 { 0x0000, 0x0000, 0x0000 }, /* R1479 */
1578 { 0x0000, 0x0000, 0x0000 }, /* R1480 */
1579 { 0x0000, 0x0000, 0x0000 }, /* R1481 */
1580 { 0x0000, 0x0000, 0x0000 }, /* R1482 */
1581 { 0x0000, 0x0000, 0x0000 }, /* R1483 */
1582 { 0x0000, 0x0000, 0x0000 }, /* R1484 */
1583 { 0x0000, 0x0000, 0x0000 }, /* R1485 */
1584 { 0x0000, 0x0000, 0x0000 }, /* R1486 */
1585 { 0x0000, 0x0000, 0x0000 }, /* R1487 */
1586 { 0x0000, 0x0000, 0x0000 }, /* R1488 */
1587 { 0x0000, 0x0000, 0x0000 }, /* R1489 */
1588 { 0x0000, 0x0000, 0x0000 }, /* R1490 */
1589 { 0x0000, 0x0000, 0x0000 }, /* R1491 */
1590 { 0x0000, 0x0000, 0x0000 }, /* R1492 */
1591 { 0x0000, 0x0000, 0x0000 }, /* R1493 */
1592 { 0x0000, 0x0000, 0x0000 }, /* R1494 */
1593 { 0x0000, 0x0000, 0x0000 }, /* R1495 */
1594 { 0x0000, 0x0000, 0x0000 }, /* R1496 */
1595 { 0x0000, 0x0000, 0x0000 }, /* R1497 */
1596 { 0x0000, 0x0000, 0x0000 }, /* R1498 */
1597 { 0x0000, 0x0000, 0x0000 }, /* R1499 */
1598 { 0x0000, 0x0000, 0x0000 }, /* R1500 */
1599 { 0x0000, 0x0000, 0x0000 }, /* R1501 */
1600 { 0x0000, 0x0000, 0x0000 }, /* R1502 */
1601 { 0x0000, 0x0000, 0x0000 }, /* R1503 */
1602 { 0x0000, 0x0000, 0x0000 }, /* R1504 */
1603 { 0x0000, 0x0000, 0x0000 }, /* R1505 */
1604 { 0x0000, 0x0000, 0x0000 }, /* R1506 */
1605 { 0x0000, 0x0000, 0x0000 }, /* R1507 */
1606 { 0x0000, 0x0000, 0x0000 }, /* R1508 */
1607 { 0x0000, 0x0000, 0x0000 }, /* R1509 */
1608 { 0x0000, 0x0000, 0x0000 }, /* R1510 */
1609 { 0x0000, 0x0000, 0x0000 }, /* R1511 */
1610 { 0x0000, 0x0000, 0x0000 }, /* R1512 */
1611 { 0x0000, 0x0000, 0x0000 }, /* R1513 */
1612 { 0x0000, 0x0000, 0x0000 }, /* R1514 */
1613 { 0x0000, 0x0000, 0x0000 }, /* R1515 */
1614 { 0x0000, 0x0000, 0x0000 }, /* R1516 */
1615 { 0x0000, 0x0000, 0x0000 }, /* R1517 */
1616 { 0x0000, 0x0000, 0x0000 }, /* R1518 */
1617 { 0x0000, 0x0000, 0x0000 }, /* R1519 */
1618 { 0x0000, 0x0000, 0x0000 }, /* R1520 */
1619 { 0x0000, 0x0000, 0x0000 }, /* R1521 */
1620 { 0x0000, 0x0000, 0x0000 }, /* R1522 */
1621 { 0x0000, 0x0000, 0x0000 }, /* R1523 */
1622 { 0x0000, 0x0000, 0x0000 }, /* R1524 */
1623 { 0x0000, 0x0000, 0x0000 }, /* R1525 */
1624 { 0x0000, 0x0000, 0x0000 }, /* R1526 */
1625 { 0x0000, 0x0000, 0x0000 }, /* R1527 */
1626 { 0x0000, 0x0000, 0x0000 }, /* R1528 */
1627 { 0x0000, 0x0000, 0x0000 }, /* R1529 */
1628 { 0x0000, 0x0000, 0x0000 }, /* R1530 */
1629 { 0x0000, 0x0000, 0x0000 }, /* R1531 */
1630 { 0x0000, 0x0000, 0x0000 }, /* R1532 */
1631 { 0x0000, 0x0000, 0x0000 }, /* R1533 */
1632 { 0x0000, 0x0000, 0x0000 }, /* R1534 */
1633 { 0x0000, 0x0000, 0x0000 }, /* R1535 */
1634 { 0x01EF, 0x01EF, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
1635 { 0x0037, 0x0037, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
1636 { 0x0037, 0x0037, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
1637 { 0x01EF, 0x01EF, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
1638 { 0x0037, 0x0037, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
1639 { 0x0037, 0x0037, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
1640 { 0x0003, 0x0003, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1641 { 0x0003, 0x0003, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1642 { 0x0003, 0x0003, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1643 { 0x0003, 0x0003, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1644 { 0x0000, 0x0000, 0x0000 }, /* R1546 */
1645 { 0x0000, 0x0000, 0x0000 }, /* R1547 */
1646 { 0x0000, 0x0000, 0x0000 }, /* R1548 */
1647 { 0x0000, 0x0000, 0x0000 }, /* R1549 */
1648 { 0x0000, 0x0000, 0x0000 }, /* R1550 */
1649 { 0x0000, 0x0000, 0x0000 }, /* R1551 */
1650 { 0x02FF, 0x03FF, 0x0000 }, /* R1552 - DAC1 Left Volume */
1651 { 0x02FF, 0x03FF, 0x0000 }, /* R1553 - DAC1 Right Volume */
1652 { 0x02FF, 0x03FF, 0x0000 }, /* R1554 - DAC2 Left Volume */
1653 { 0x02FF, 0x03FF, 0x0000 }, /* R1555 - DAC2 Right Volume */
1654 { 0x0003, 0x0003, 0x0000 }, /* R1556 - DAC Softmute */
1655 { 0x0000, 0x0000, 0x0000 }, /* R1557 */
1656 { 0x0000, 0x0000, 0x0000 }, /* R1558 */
1657 { 0x0000, 0x0000, 0x0000 }, /* R1559 */
1658 { 0x0000, 0x0000, 0x0000 }, /* R1560 */
1659 { 0x0000, 0x0000, 0x0000 }, /* R1561 */
1660 { 0x0000, 0x0000, 0x0000 }, /* R1562 */
1661 { 0x0000, 0x0000, 0x0000 }, /* R1563 */
1662 { 0x0000, 0x0000, 0x0000 }, /* R1564 */
1663 { 0x0000, 0x0000, 0x0000 }, /* R1565 */
1664 { 0x0000, 0x0000, 0x0000 }, /* R1566 */
1665 { 0x0000, 0x0000, 0x0000 }, /* R1567 */
1666 { 0x0003, 0x0003, 0x0000 }, /* R1568 - Oversampling */
1667 { 0x03C3, 0x03C3, 0x0000 }, /* R1569 - Sidetone */
1668};
1669
1670static int wm8994_readable(unsigned int reg)
1671{
1672 if (reg >= ARRAY_SIZE(access_masks))
1673 return 0;
1674 return access_masks[reg].readable != 0;
1675}
1676
1677static int wm8994_volatile(unsigned int reg)
1678{
1679 if (reg >= WM8994_REG_CACHE_SIZE)
1680 return 1;
1681
1682 switch (reg) {
1683 case WM8994_SOFTWARE_RESET:
1684 case WM8994_CHIP_REVISION:
1685 case WM8994_DC_SERVO_1:
1686 case WM8994_DC_SERVO_READBACK:
1687 case WM8994_RATE_STATUS:
1688 case WM8994_LDO_1:
1689 case WM8994_LDO_2:
1690 return 1;
1691 default:
1692 return 0;
1693 }
1694}
1695
1696static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1697 unsigned int value)
1698{
1699 struct wm8994_priv *wm8994 = codec->private_data;
1700
1701 BUG_ON(reg > WM8994_MAX_REGISTER);
1702
1703 if (!wm8994_volatile(reg))
1704 wm8994->reg_cache[reg] = value;
1705
1706 return wm8994_reg_write(codec->control_data, reg, value);
1707}
1708
1709static unsigned int wm8994_read(struct snd_soc_codec *codec,
1710 unsigned int reg)
1711{
1712 u16 *reg_cache = codec->reg_cache;
1713
1714 BUG_ON(reg > WM8994_MAX_REGISTER);
1715
1716 if (wm8994_volatile(reg))
1717 return wm8994_reg_read(codec->control_data, reg);
1718 else
1719 return reg_cache[reg];
1720}
1721
1722static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1723{
1724 struct wm8994_priv *wm8994 = codec->private_data;
1725 int rate;
1726 int reg1 = 0;
1727 int offset;
1728
1729 if (aif)
1730 offset = 4;
1731 else
1732 offset = 0;
1733
1734 switch (wm8994->sysclk[aif]) {
1735 case WM8994_SYSCLK_MCLK1:
1736 rate = wm8994->mclk[0];
1737 break;
1738
1739 case WM8994_SYSCLK_MCLK2:
1740 reg1 |= 0x8;
1741 rate = wm8994->mclk[1];
1742 break;
1743
1744 case WM8994_SYSCLK_FLL1:
1745 reg1 |= 0x10;
1746 rate = wm8994->fll[0].out;
1747 break;
1748
1749 case WM8994_SYSCLK_FLL2:
1750 reg1 |= 0x18;
1751 rate = wm8994->fll[1].out;
1752 break;
1753
1754 default:
1755 return -EINVAL;
1756 }
1757
1758 if (rate >= 13500000) {
1759 rate /= 2;
1760 reg1 |= WM8994_AIF1CLK_DIV;
1761
1762 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
1763 aif + 1, rate);
1764 }
1765 wm8994->aifclk[aif] = rate;
1766
1767 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
1768 WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
1769 reg1);
1770
1771 return 0;
1772}
1773
1774static int configure_clock(struct snd_soc_codec *codec)
1775{
1776 struct wm8994_priv *wm8994 = codec->private_data;
1777 int old, new;
1778
1779 /* Bring up the AIF clocks first */
1780 configure_aif_clock(codec, 0);
1781 configure_aif_clock(codec, 1);
1782
1783 /* Then switch CLK_SYS over to the higher of them; a change
1784 * can only happen as a result of a clocking change which can
1785 * only be made outside of DAPM so we can safely redo the
1786 * clocking.
1787 */
1788
1789 /* If they're equal it doesn't matter which is used */
1790 if (wm8994->aifclk[0] == wm8994->aifclk[1])
1791 return 0;
1792
1793 if (wm8994->aifclk[0] < wm8994->aifclk[1])
1794 new = WM8994_SYSCLK_SRC;
1795 else
1796 new = 0;
1797
1798 old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC;
1799
1800 /* If there's no change then we're done. */
1801 if (old == new)
1802 return 0;
1803
1804 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
1805
1806 snd_soc_dapm_sync(codec);
1807
1808 return 0;
1809}
1810
1811static int check_clk_sys(struct snd_soc_dapm_widget *source,
1812 struct snd_soc_dapm_widget *sink)
1813{
1814 int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1);
1815 const char *clk;
1816
1817 /* Check what we're currently using for CLK_SYS */
1818 if (reg & WM8994_SYSCLK_SRC)
1819 clk = "AIF2CLK";
1820 else
1821 clk = "AIF1CLK";
1822
1823 return strcmp(source->name, clk) == 0;
1824}
1825
1826static const char *sidetone_hpf_text[] = {
1827 "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
1828};
1829
1830static const struct soc_enum sidetone_hpf =
1831 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
1832
1833static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
1834static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
1835static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
1836static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
1837static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1838
1839#define WM8994_DRC_SWITCH(xname, reg, shift) \
1840{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1841 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
1842 .put = wm8994_put_drc_sw, \
1843 .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
1844
1845static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1846 struct snd_ctl_elem_value *ucontrol)
1847{
1848 struct soc_mixer_control *mc =
1849 (struct soc_mixer_control *)kcontrol->private_value;
1850 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1851 int mask, ret;
1852
1853 /* Can't enable both ADC and DAC paths simultaneously */
1854 if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT)
1855 mask = WM8994_AIF1ADC1L_DRC_ENA_MASK |
1856 WM8994_AIF1ADC1R_DRC_ENA_MASK;
1857 else
1858 mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
1859
1860 ret = snd_soc_read(codec, mc->reg);
1861 if (ret < 0)
1862 return ret;
1863 if (ret & mask)
1864 return -EINVAL;
1865
1866 return snd_soc_put_volsw(kcontrol, ucontrol);
1867}
1868
1869
1870
1871static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1872{
1873 struct wm8994_priv *wm8994 = codec->private_data;
1874 struct wm8994_pdata *pdata = wm8994->pdata;
1875 int base = wm8994_drc_base[drc];
1876 int cfg = wm8994->drc_cfg[drc];
1877 int save, i;
1878
1879 /* Save any enables; the configuration should clear them. */
1880 save = snd_soc_read(codec, base);
1881 save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
1882 WM8994_AIF1ADC1R_DRC_ENA;
1883
1884 for (i = 0; i < WM8994_DRC_REGS; i++)
1885 snd_soc_update_bits(codec, base + i, 0xffff,
1886 pdata->drc_cfgs[cfg].regs[i]);
1887
1888 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA |
1889 WM8994_AIF1ADC1L_DRC_ENA |
1890 WM8994_AIF1ADC1R_DRC_ENA, save);
1891}
1892
1893/* Icky as hell but saves code duplication */
1894static int wm8994_get_drc(const char *name)
1895{
1896 if (strcmp(name, "AIF1DRC1 Mode") == 0)
1897 return 0;
1898 if (strcmp(name, "AIF1DRC2 Mode") == 0)
1899 return 1;
1900 if (strcmp(name, "AIF2DRC Mode") == 0)
1901 return 2;
1902 return -EINVAL;
1903}
1904
1905static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1906 struct snd_ctl_elem_value *ucontrol)
1907{
1908 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1909 struct wm8994_priv *wm8994 = codec->private_data;
1910 struct wm8994_pdata *pdata = wm8994->pdata;
1911 int drc = wm8994_get_drc(kcontrol->id.name);
1912 int value = ucontrol->value.integer.value[0];
1913
1914 if (drc < 0)
1915 return drc;
1916
1917 if (value >= pdata->num_drc_cfgs)
1918 return -EINVAL;
1919
1920 wm8994->drc_cfg[drc] = value;
1921
1922 wm8994_set_drc(codec, drc);
1923
1924 return 0;
1925}
1926
1927static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1928 struct snd_ctl_elem_value *ucontrol)
1929{
1930 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1931 struct wm8994_priv *wm8994 = codec->private_data;
1932 int drc = wm8994_get_drc(kcontrol->id.name);
1933
1934 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
1935
1936 return 0;
1937}
1938
1939static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
1940{
1941 struct wm8994_priv *wm8994 = codec->private_data;
1942 struct wm8994_pdata *pdata = wm8994->pdata;
1943 int base = wm8994_retune_mobile_base[block];
1944 int iface, best, best_val, save, i, cfg;
1945
1946 if (!pdata || !wm8994->num_retune_mobile_texts)
1947 return;
1948
1949 switch (block) {
1950 case 0:
1951 case 1:
1952 iface = 0;
1953 break;
1954 case 2:
1955 iface = 1;
1956 break;
1957 default:
1958 return;
1959 }
1960
1961 /* Find the version of the currently selected configuration
1962 * with the nearest sample rate. */
1963 cfg = wm8994->retune_mobile_cfg[block];
1964 best = 0;
1965 best_val = INT_MAX;
1966 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
1967 if (strcmp(pdata->retune_mobile_cfgs[i].name,
1968 wm8994->retune_mobile_texts[cfg]) == 0 &&
1969 abs(pdata->retune_mobile_cfgs[i].rate
1970 - wm8994->dac_rates[iface]) < best_val) {
1971 best = i;
1972 best_val = abs(pdata->retune_mobile_cfgs[i].rate
1973 - wm8994->dac_rates[iface]);
1974 }
1975 }
1976
1977 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
1978 block,
1979 pdata->retune_mobile_cfgs[best].name,
1980 pdata->retune_mobile_cfgs[best].rate,
1981 wm8994->dac_rates[iface]);
1982
1983 /* The EQ will be disabled while reconfiguring it, remember the
1984 * current configuration.
1985 */
1986 save = snd_soc_read(codec, base);
1987 save &= WM8994_AIF1DAC1_EQ_ENA;
1988
1989 for (i = 0; i < WM8994_EQ_REGS; i++)
1990 snd_soc_update_bits(codec, base + i, 0xffff,
1991 pdata->retune_mobile_cfgs[best].regs[i]);
1992
1993 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save);
1994}
1995
1996/* Icky as hell but saves code duplication */
1997static int wm8994_get_retune_mobile_block(const char *name)
1998{
1999 if (strcmp(name, "AIF1.1 EQ Mode") == 0)
2000 return 0;
2001 if (strcmp(name, "AIF1.2 EQ Mode") == 0)
2002 return 1;
2003 if (strcmp(name, "AIF2 EQ Mode") == 0)
2004 return 2;
2005 return -EINVAL;
2006}
2007
2008static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2009 struct snd_ctl_elem_value *ucontrol)
2010{
2011 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2012 struct wm8994_priv *wm8994 = codec->private_data;
2013 struct wm8994_pdata *pdata = wm8994->pdata;
2014 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2015 int value = ucontrol->value.integer.value[0];
2016
2017 if (block < 0)
2018 return block;
2019
2020 if (value >= pdata->num_retune_mobile_cfgs)
2021 return -EINVAL;
2022
2023 wm8994->retune_mobile_cfg[block] = value;
2024
2025 wm8994_set_retune_mobile(codec, block);
2026
2027 return 0;
2028}
2029
2030static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_value *ucontrol)
2032{
2033 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2034 struct wm8994_priv *wm8994 = codec->private_data;
2035 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2036
2037 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
2038
2039 return 0;
2040}
2041
2042static const struct snd_kcontrol_new wm8994_snd_controls[] = {
2043SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
2044 WM8994_AIF1_ADC1_RIGHT_VOLUME,
2045 1, 119, 0, digital_tlv),
2046SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
2047 WM8994_AIF1_ADC2_RIGHT_VOLUME,
2048 1, 119, 0, digital_tlv),
2049SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
2050 WM8994_AIF2_ADC_RIGHT_VOLUME,
2051 1, 119, 0, digital_tlv),
2052
2053SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
2054 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2055SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
2056 WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2057SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
2058 WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2059
2060SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
2061SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
2062
2063SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
2064SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
2065SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
2066
2067WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
2068WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
2069WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
2070
2071WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
2072WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
2073WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
2074
2075WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
2076WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
2077WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
2078
2079SOC_SINGLE_TLV("DAC1 Right Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2080 5, 12, 0, st_tlv),
2081SOC_SINGLE_TLV("DAC1 Left Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2082 0, 12, 0, st_tlv),
2083SOC_SINGLE_TLV("DAC2 Right Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2084 5, 12, 0, st_tlv),
2085SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2086 0, 12, 0, st_tlv),
2087SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
2088SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
2089
2090SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
2091 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2092SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
2093 WM8994_DAC1_RIGHT_VOLUME, 9, 1, 1),
2094
2095SOC_DOUBLE_R_TLV("DAC2 Volume", WM8994_DAC2_LEFT_VOLUME,
2096 WM8994_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2097SOC_DOUBLE_R("DAC2 Switch", WM8994_DAC2_LEFT_VOLUME,
2098 WM8994_DAC2_RIGHT_VOLUME, 9, 1, 1),
2099
2100SOC_SINGLE_TLV("SPKL DAC2 Volume", WM8994_SPKMIXL_ATTENUATION,
2101 6, 1, 1, wm_hubs_spkmix_tlv),
2102SOC_SINGLE_TLV("SPKL DAC1 Volume", WM8994_SPKMIXL_ATTENUATION,
2103 2, 1, 1, wm_hubs_spkmix_tlv),
2104
2105SOC_SINGLE_TLV("SPKR DAC2 Volume", WM8994_SPKMIXR_ATTENUATION,
2106 6, 1, 1, wm_hubs_spkmix_tlv),
2107SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
2108 2, 1, 1, wm_hubs_spkmix_tlv),
2109
2110SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2111 10, 15, 0, wm8994_3d_tlv),
2112SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2113 8, 1, 0),
2114SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
2115 10, 15, 0, wm8994_3d_tlv),
2116SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2117 8, 1, 0),
2118SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2119 10, 15, 0, wm8994_3d_tlv),
2120SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2121 8, 1, 0),
2122};
2123
2124static const struct snd_kcontrol_new wm8994_eq_controls[] = {
2125SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
2126 eq_tlv),
2127SOC_SINGLE_TLV("AIF1DAC1 EQ2 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 6, 31, 0,
2128 eq_tlv),
2129SOC_SINGLE_TLV("AIF1DAC1 EQ3 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 1, 31, 0,
2130 eq_tlv),
2131SOC_SINGLE_TLV("AIF1DAC1 EQ4 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 11, 31, 0,
2132 eq_tlv),
2133SOC_SINGLE_TLV("AIF1DAC1 EQ5 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 6, 31, 0,
2134 eq_tlv),
2135
2136SOC_SINGLE_TLV("AIF1DAC2 EQ1 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 11, 31, 0,
2137 eq_tlv),
2138SOC_SINGLE_TLV("AIF1DAC2 EQ2 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 6, 31, 0,
2139 eq_tlv),
2140SOC_SINGLE_TLV("AIF1DAC2 EQ3 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 1, 31, 0,
2141 eq_tlv),
2142SOC_SINGLE_TLV("AIF1DAC2 EQ4 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 11, 31, 0,
2143 eq_tlv),
2144SOC_SINGLE_TLV("AIF1DAC2 EQ5 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 6, 31, 0,
2145 eq_tlv),
2146
2147SOC_SINGLE_TLV("AIF2 EQ1 Volume", WM8994_AIF2_EQ_GAINS_1, 11, 31, 0,
2148 eq_tlv),
2149SOC_SINGLE_TLV("AIF2 EQ2 Volume", WM8994_AIF2_EQ_GAINS_1, 6, 31, 0,
2150 eq_tlv),
2151SOC_SINGLE_TLV("AIF2 EQ3 Volume", WM8994_AIF2_EQ_GAINS_1, 1, 31, 0,
2152 eq_tlv),
2153SOC_SINGLE_TLV("AIF2 EQ4 Volume", WM8994_AIF2_EQ_GAINS_2, 11, 31, 0,
2154 eq_tlv),
2155SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
2156 eq_tlv),
2157};
2158
2159static int clk_sys_event(struct snd_soc_dapm_widget *w,
2160 struct snd_kcontrol *kcontrol, int event)
2161{
2162 struct snd_soc_codec *codec = w->codec;
2163
2164 switch (event) {
2165 case SND_SOC_DAPM_PRE_PMU:
2166 return configure_clock(codec);
2167
2168 case SND_SOC_DAPM_POST_PMD:
2169 configure_clock(codec);
2170 break;
2171 }
2172
2173 return 0;
2174}
2175
2176static void wm8994_update_class_w(struct snd_soc_codec *codec)
2177{
2178 int enable = 1;
2179 int source = 0; /* GCC flow analysis can't track enable */
2180 int reg, reg_r;
2181
2182 /* Only support direct DAC->headphone paths */
2183 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
2184 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
2185 dev_dbg(codec->dev, "HPL connected to output mixer\n");
2186 enable = 0;
2187 }
2188
2189 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
2190 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
2191 dev_dbg(codec->dev, "HPR connected to output mixer\n");
2192 enable = 0;
2193 }
2194
2195 /* We also need the same setting for L/R and only one path */
2196 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
2197 switch (reg) {
2198 case WM8994_AIF2DACL_TO_DAC1L:
2199 dev_dbg(codec->dev, "Class W source AIF2DAC\n");
2200 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2201 break;
2202 case WM8994_AIF1DAC2L_TO_DAC1L:
2203 dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
2204 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2205 break;
2206 case WM8994_AIF1DAC1L_TO_DAC1L:
2207 dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
2208 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2209 break;
2210 default:
2211 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
2212 enable = 0;
2213 break;
2214 }
2215
2216 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
2217 if (reg_r != reg) {
2218 dev_dbg(codec->dev, "Left and right DAC mixers different\n");
2219 enable = 0;
2220 }
2221
2222 if (enable) {
2223 dev_dbg(codec->dev, "Class W enabled\n");
2224 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2225 WM8994_CP_DYN_PWR |
2226 WM8994_CP_DYN_SRC_SEL_MASK,
2227 source | WM8994_CP_DYN_PWR);
2228
2229 } else {
2230 dev_dbg(codec->dev, "Class W disabled\n");
2231 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2232 WM8994_CP_DYN_PWR, 0);
2233 }
2234}
2235
2236static const char *hp_mux_text[] = {
2237 "Mixer",
2238 "DAC",
2239};
2240
2241#define WM8994_HP_ENUM(xname, xenum) \
2242{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2243 .info = snd_soc_info_enum_double, \
2244 .get = snd_soc_dapm_get_enum_double, \
2245 .put = wm8994_put_hp_enum, \
2246 .private_value = (unsigned long)&xenum }
2247
2248static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
2249 struct snd_ctl_elem_value *ucontrol)
2250{
2251 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2252 struct snd_soc_codec *codec = w->codec;
2253 int ret;
2254
2255 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
2256
2257 wm8994_update_class_w(codec);
2258
2259 return ret;
2260}
2261
2262static const struct soc_enum hpl_enum =
2263 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text);
2264
2265static const struct snd_kcontrol_new hpl_mux =
2266 WM8994_HP_ENUM("Left Headphone Mux", hpl_enum);
2267
2268static const struct soc_enum hpr_enum =
2269 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text);
2270
2271static const struct snd_kcontrol_new hpr_mux =
2272 WM8994_HP_ENUM("Right Headphone Mux", hpr_enum);
2273
2274static const char *adc_mux_text[] = {
2275 "ADC",
2276 "DMIC",
2277};
2278
2279static const struct soc_enum adc_enum =
2280 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
2281
2282static const struct snd_kcontrol_new adcl_mux =
2283 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
2284
2285static const struct snd_kcontrol_new adcr_mux =
2286 SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
2287
2288static const struct snd_kcontrol_new left_speaker_mixer[] = {
2289SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0),
2290SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 7, 1, 0),
2291SOC_DAPM_SINGLE("IN1LP Switch", WM8994_SPEAKER_MIXER, 5, 1, 0),
2292SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 3, 1, 0),
2293SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 1, 1, 0),
2294};
2295
2296static const struct snd_kcontrol_new right_speaker_mixer[] = {
2297SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 8, 1, 0),
2298SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 6, 1, 0),
2299SOC_DAPM_SINGLE("IN1RP Switch", WM8994_SPEAKER_MIXER, 4, 1, 0),
2300SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 2, 1, 0),
2301SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
2302};
2303
2304/* Debugging; dump chip status after DAPM transitions */
2305static int post_ev(struct snd_soc_dapm_widget *w,
2306 struct snd_kcontrol *kcontrol, int event)
2307{
2308 struct snd_soc_codec *codec = w->codec;
2309 dev_dbg(codec->dev, "SRC status: %x\n",
2310 snd_soc_read(codec,
2311 WM8994_RATE_STATUS));
2312 return 0;
2313}
2314
2315static const struct snd_kcontrol_new aif1adc1l_mix[] = {
2316SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2317 1, 1, 0),
2318SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2319 0, 1, 0),
2320};
2321
2322static const struct snd_kcontrol_new aif1adc1r_mix[] = {
2323SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2324 1, 1, 0),
2325SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2326 0, 1, 0),
2327};
2328
2329static const struct snd_kcontrol_new aif2dac2l_mix[] = {
2330SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2331 5, 1, 0),
2332SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2333 4, 1, 0),
2334SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2335 2, 1, 0),
2336SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2337 1, 1, 0),
2338SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2339 0, 1, 0),
2340};
2341
2342static const struct snd_kcontrol_new aif2dac2r_mix[] = {
2343SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2344 5, 1, 0),
2345SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2346 4, 1, 0),
2347SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2348 2, 1, 0),
2349SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2350 1, 1, 0),
2351SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2352 0, 1, 0),
2353};
2354
2355#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
2356{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2357 .info = snd_soc_info_volsw, \
2358 .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
2359 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
2360
2361static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
2362 struct snd_ctl_elem_value *ucontrol)
2363{
2364 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2365 struct snd_soc_codec *codec = w->codec;
2366 int ret;
2367
2368 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
2369
2370 wm8994_update_class_w(codec);
2371
2372 return ret;
2373}
2374
2375static const struct snd_kcontrol_new dac1l_mix[] = {
2376WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2377 5, 1, 0),
2378WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2379 4, 1, 0),
2380WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2381 2, 1, 0),
2382WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2383 1, 1, 0),
2384WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2385 0, 1, 0),
2386};
2387
2388static const struct snd_kcontrol_new dac1r_mix[] = {
2389WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2390 5, 1, 0),
2391WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2392 4, 1, 0),
2393WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2394 2, 1, 0),
2395WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2396 1, 1, 0),
2397WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2398 0, 1, 0),
2399};
2400
2401static const char *sidetone_text[] = {
2402 "ADC/DMIC1", "DMIC2",
2403};
2404
2405static const struct soc_enum sidetone1_enum =
2406 SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text);
2407
2408static const struct snd_kcontrol_new sidetone1_mux =
2409 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
2410
2411static const struct soc_enum sidetone2_enum =
2412 SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text);
2413
2414static const struct snd_kcontrol_new sidetone2_mux =
2415 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
2416
2417static const char *aif1dac_text[] = {
2418 "AIF1DACDAT", "AIF3DACDAT",
2419};
2420
2421static const struct soc_enum aif1dac_enum =
2422 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
2423
2424static const struct snd_kcontrol_new aif1dac_mux =
2425 SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
2426
2427static const char *aif2dac_text[] = {
2428 "AIF2DACDAT", "AIF3DACDAT",
2429};
2430
2431static const struct soc_enum aif2dac_enum =
2432 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text);
2433
2434static const struct snd_kcontrol_new aif2dac_mux =
2435 SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
2436
2437static const char *aif2adc_text[] = {
2438 "AIF2ADCDAT", "AIF3DACDAT",
2439};
2440
2441static const struct soc_enum aif2adc_enum =
2442 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text);
2443
2444static const struct snd_kcontrol_new aif2adc_mux =
2445 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
2446
2447static const char *aif3adc_text[] = {
2448 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT",
2449};
2450
2451static const struct soc_enum aif3adc_enum =
2452 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
2453
2454static const struct snd_kcontrol_new aif3adc_mux =
2455 SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum);
2456
2457static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2458SND_SOC_DAPM_INPUT("DMIC1DAT"),
2459SND_SOC_DAPM_INPUT("DMIC2DAT"),
2460
2461SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
2462 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2463
2464SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
2465SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
2466SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
2467
2468SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
2469SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
2470
2471SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
2472 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
2473SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
2474 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
2475SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0,
2476 WM8994_POWER_MANAGEMENT_5, 9, 0),
2477SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0,
2478 WM8994_POWER_MANAGEMENT_5, 8, 0),
2479
2480SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
2481 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
2482SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
2483 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
2484SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0,
2485 WM8994_POWER_MANAGEMENT_5, 11, 0),
2486SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0,
2487 WM8994_POWER_MANAGEMENT_5, 10, 0),
2488
2489SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2490 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
2491SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
2492 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
2493
2494SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
2495 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
2496SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
2497 aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
2498
2499SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
2500SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
2501
2502SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
2503 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
2504SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
2505 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
2506
2507SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
2508 WM8994_POWER_MANAGEMENT_4, 13, 0),
2509SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
2510 WM8994_POWER_MANAGEMENT_4, 12, 0),
2511SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0,
2512 WM8994_POWER_MANAGEMENT_5, 13, 0),
2513SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0,
2514 WM8994_POWER_MANAGEMENT_5, 12, 0),
2515
2516SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2517SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
2518SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2519
2520SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
2521SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
2522SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
2523SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
2524
2525SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2526SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
2527
2528SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
2529
2530SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8994_POWER_MANAGEMENT_4, 5, 0),
2531SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8994_POWER_MANAGEMENT_4, 4, 0),
2532SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8994_POWER_MANAGEMENT_4, 3, 0),
2533SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
2534
2535/* Power is done with the muxes since the ADC power also controls the
2536 * downsampling chain, the chip will automatically manage the analogue
2537 * specific portions.
2538 */
2539SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
2540SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
2541
2542SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
2543SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
2544
2545SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
2546SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
2547SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
2548SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
2549
2550SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
2551SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
2552
2553SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
2554 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
2555SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
2556 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
2557
2558SND_SOC_DAPM_POST("Debug log", post_ev),
2559};
2560
2561static const struct snd_soc_dapm_route intercon[] = {
2562
2563 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
2564 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
2565
2566 { "DSP1CLK", NULL, "CLK_SYS" },
2567 { "DSP2CLK", NULL, "CLK_SYS" },
2568 { "DSPINTCLK", NULL, "CLK_SYS" },
2569
2570 { "AIF1ADC1L", NULL, "AIF1CLK" },
2571 { "AIF1ADC1L", NULL, "DSP1CLK" },
2572 { "AIF1ADC1R", NULL, "AIF1CLK" },
2573 { "AIF1ADC1R", NULL, "DSP1CLK" },
2574 { "AIF1ADC1R", NULL, "DSPINTCLK" },
2575
2576 { "AIF1DAC1L", NULL, "AIF1CLK" },
2577 { "AIF1DAC1L", NULL, "DSP1CLK" },
2578 { "AIF1DAC1R", NULL, "AIF1CLK" },
2579 { "AIF1DAC1R", NULL, "DSP1CLK" },
2580 { "AIF1DAC1R", NULL, "DSPINTCLK" },
2581
2582 { "AIF1ADC2L", NULL, "AIF1CLK" },
2583 { "AIF1ADC2L", NULL, "DSP1CLK" },
2584 { "AIF1ADC2R", NULL, "AIF1CLK" },
2585 { "AIF1ADC2R", NULL, "DSP1CLK" },
2586 { "AIF1ADC2R", NULL, "DSPINTCLK" },
2587
2588 { "AIF1DAC2L", NULL, "AIF1CLK" },
2589 { "AIF1DAC2L", NULL, "DSP1CLK" },
2590 { "AIF1DAC2R", NULL, "AIF1CLK" },
2591 { "AIF1DAC2R", NULL, "DSP1CLK" },
2592 { "AIF1DAC2R", NULL, "DSPINTCLK" },
2593
2594 { "AIF2ADCL", NULL, "AIF2CLK" },
2595 { "AIF2ADCL", NULL, "DSP2CLK" },
2596 { "AIF2ADCR", NULL, "AIF2CLK" },
2597 { "AIF2ADCR", NULL, "DSP2CLK" },
2598 { "AIF2ADCR", NULL, "DSPINTCLK" },
2599
2600 { "AIF2DACL", NULL, "AIF2CLK" },
2601 { "AIF2DACL", NULL, "DSP2CLK" },
2602 { "AIF2DACR", NULL, "AIF2CLK" },
2603 { "AIF2DACR", NULL, "DSP2CLK" },
2604 { "AIF2DACR", NULL, "DSPINTCLK" },
2605
2606 { "DMIC1L", NULL, "DMIC1DAT" },
2607 { "DMIC1L", NULL, "CLK_SYS" },
2608 { "DMIC1R", NULL, "DMIC1DAT" },
2609 { "DMIC1R", NULL, "CLK_SYS" },
2610 { "DMIC2L", NULL, "DMIC2DAT" },
2611 { "DMIC2L", NULL, "CLK_SYS" },
2612 { "DMIC2R", NULL, "DMIC2DAT" },
2613 { "DMIC2R", NULL, "CLK_SYS" },
2614
2615 { "ADCL", NULL, "AIF1CLK" },
2616 { "ADCL", NULL, "DSP1CLK" },
2617 { "ADCL", NULL, "DSPINTCLK" },
2618
2619 { "ADCR", NULL, "AIF1CLK" },
2620 { "ADCR", NULL, "DSP1CLK" },
2621 { "ADCR", NULL, "DSPINTCLK" },
2622
2623 { "ADCL Mux", "ADC", "ADCL" },
2624 { "ADCL Mux", "DMIC", "DMIC1L" },
2625 { "ADCR Mux", "ADC", "ADCR" },
2626 { "ADCR Mux", "DMIC", "DMIC1R" },
2627
2628 { "DAC1L", NULL, "AIF1CLK" },
2629 { "DAC1L", NULL, "DSP1CLK" },
2630 { "DAC1L", NULL, "DSPINTCLK" },
2631
2632 { "DAC1R", NULL, "AIF1CLK" },
2633 { "DAC1R", NULL, "DSP1CLK" },
2634 { "DAC1R", NULL, "DSPINTCLK" },
2635
2636 { "DAC2L", NULL, "AIF2CLK" },
2637 { "DAC2L", NULL, "DSP2CLK" },
2638 { "DAC2L", NULL, "DSPINTCLK" },
2639
2640 { "DAC2R", NULL, "AIF2DACR" },
2641 { "DAC2R", NULL, "AIF2CLK" },
2642 { "DAC2R", NULL, "DSP2CLK" },
2643 { "DAC2R", NULL, "DSPINTCLK" },
2644
2645 { "TOCLK", NULL, "CLK_SYS" },
2646
2647 /* AIF1 outputs */
2648 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
2649 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
2650 { "AIF1ADC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2651
2652 { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
2653 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
2654 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2655
2656 /* Pin level routing for AIF3 */
2657 { "AIF1DAC1L", NULL, "AIF1DAC Mux" },
2658 { "AIF1DAC1R", NULL, "AIF1DAC Mux" },
2659 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
2660 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
2661
2662 { "AIF2DACL", NULL, "AIF2DAC Mux" },
2663 { "AIF2DACR", NULL, "AIF2DAC Mux" },
2664
2665 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
2666 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2667 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
2668 { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2669 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
2670 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
2671 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
2672
2673 /* DAC1 inputs */
2674 { "DAC1L", NULL, "DAC1L Mixer" },
2675 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2676 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2677 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2678 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2679 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2680
2681 { "DAC1R", NULL, "DAC1R Mixer" },
2682 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2683 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2684 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2685 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2686 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2687
2688 /* DAC2/AIF2 outputs */
2689 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
2690 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
2691 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
2692 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2693 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2694 { "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2695 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2696
2697 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
2698 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
2699 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
2700 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2701 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2702 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2703 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2704
2705 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
2706
2707 /* AIF3 output */
2708 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" },
2709 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" },
2710 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" },
2711 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" },
2712 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" },
2713 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" },
2714 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
2715 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
2716
2717 /* Sidetone */
2718 { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
2719 { "Left Sidetone", "DMIC2", "DMIC2L" },
2720 { "Right Sidetone", "ADC/DMIC1", "ADCR Mux" },
2721 { "Right Sidetone", "DMIC2", "DMIC2R" },
2722
2723 /* Output stages */
2724 { "Left Output Mixer", "DAC Switch", "DAC1L" },
2725 { "Right Output Mixer", "DAC Switch", "DAC1R" },
2726
2727 { "SPKL", "DAC1 Switch", "DAC1L" },
2728 { "SPKL", "DAC2 Switch", "DAC2L" },
2729
2730 { "SPKR", "DAC1 Switch", "DAC1R" },
2731 { "SPKR", "DAC2 Switch", "DAC2R" },
2732
2733 { "Left Headphone Mux", "DAC", "DAC1L" },
2734 { "Right Headphone Mux", "DAC", "DAC1R" },
2735};
2736
2737/* The size in bits of the FLL divide multiplied by 10
2738 * to allow rounding later */
2739#define FIXED_FLL_SIZE ((1 << 16) * 10)
2740
2741struct fll_div {
2742 u16 outdiv;
2743 u16 n;
2744 u16 k;
2745 u16 clk_ref_div;
2746 u16 fll_fratio;
2747};
2748
2749static int wm8994_get_fll_config(struct fll_div *fll,
2750 int freq_in, int freq_out)
2751{
2752 u64 Kpart;
2753 unsigned int K, Ndiv, Nmod;
2754
2755 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
2756
2757 /* Scale the input frequency down to <= 13.5MHz */
2758 fll->clk_ref_div = 0;
2759 while (freq_in > 13500000) {
2760 fll->clk_ref_div++;
2761 freq_in /= 2;
2762
2763 if (fll->clk_ref_div > 3)
2764 return -EINVAL;
2765 }
2766 pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
2767
2768 /* Scale the output to give 90MHz<=Fvco<=100MHz */
2769 fll->outdiv = 3;
2770 while (freq_out * (fll->outdiv + 1) < 90000000) {
2771 fll->outdiv++;
2772 if (fll->outdiv > 63)
2773 return -EINVAL;
2774 }
2775 freq_out *= fll->outdiv + 1;
2776 pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
2777
2778 if (freq_in > 1000000) {
2779 fll->fll_fratio = 0;
2780 } else {
2781 fll->fll_fratio = 3;
2782 freq_in *= 8;
2783 }
2784 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
2785
2786 /* Now, calculate N.K */
2787 Ndiv = freq_out / freq_in;
2788
2789 fll->n = Ndiv;
2790 Nmod = freq_out % freq_in;
2791 pr_debug("Nmod=%d\n", Nmod);
2792
2793 /* Calculate fractional part - scale up so we can round. */
2794 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
2795
2796 do_div(Kpart, freq_in);
2797
2798 K = Kpart & 0xFFFFFFFF;
2799
2800 if ((K % 10) >= 5)
2801 K += 5;
2802
2803 /* Move down to proper range now rounding is done */
2804 fll->k = K / 10;
2805
2806 pr_debug("N=%x K=%x\n", fll->n, fll->k);
2807
2808 return 0;
2809}
2810
2811static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2812 unsigned int freq_in, unsigned int freq_out)
2813{
2814 struct snd_soc_codec *codec = dai->codec;
2815 struct wm8994_priv *wm8994 = codec->private_data;
2816 int reg_offset, ret;
2817 struct fll_div fll;
2818 u16 reg, aif1, aif2;
2819
2820 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
2821 & WM8994_AIF1CLK_ENA;
2822
2823 aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
2824 & WM8994_AIF2CLK_ENA;
2825
2826 switch (id) {
2827 case WM8994_FLL1:
2828 reg_offset = 0;
2829 id = 0;
2830 break;
2831 case WM8994_FLL2:
2832 reg_offset = 0x20;
2833 id = 1;
2834 break;
2835 default:
2836 return -EINVAL;
2837 }
2838
2839 /* Are we changing anything? */
2840 if (wm8994->fll[id].src == src &&
2841 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
2842 return 0;
2843
2844 /* If we're stopping the FLL redo the old config - no
2845 * registers will actually be written but we avoid GCC flow
2846 * analysis bugs spewing warnings.
2847 */
2848 if (freq_out)
2849 ret = wm8994_get_fll_config(&fll, freq_in, freq_out);
2850 else
2851 ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in,
2852 wm8994->fll[id].out);
2853 if (ret < 0)
2854 return ret;
2855
2856 /* Gate the AIF clocks while we reclock */
2857 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2858 WM8994_AIF1CLK_ENA, 0);
2859 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2860 WM8994_AIF2CLK_ENA, 0);
2861
2862 /* We always need to disable the FLL while reconfiguring */
2863 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2864 WM8994_FLL1_ENA, 0);
2865
2866 reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
2867 (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
2868 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
2869 WM8994_FLL1_OUTDIV_MASK |
2870 WM8994_FLL1_FRATIO_MASK, reg);
2871
2872 snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k);
2873
2874 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
2875 WM8994_FLL1_N_MASK,
2876 fll.n << WM8994_FLL1_N_SHIFT);
2877
2878 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2879 WM8994_FLL1_REFCLK_DIV_MASK,
2880 fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT);
2881
2882 /* Enable (with fractional mode if required) */
2883 if (freq_out) {
2884 if (fll.k)
2885 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
2886 else
2887 reg = WM8994_FLL1_ENA;
2888 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2889 WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
2890 reg);
2891 }
2892
2893 wm8994->fll[id].in = freq_in;
2894 wm8994->fll[id].out = freq_out;
2895
2896 /* Enable any gated AIF clocks */
2897 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2898 WM8994_AIF1CLK_ENA, aif1);
2899 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2900 WM8994_AIF2CLK_ENA, aif2);
2901
2902 configure_clock(codec);
2903
2904 return 0;
2905}
2906
2907static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2908 int clk_id, unsigned int freq, int dir)
2909{
2910 struct snd_soc_codec *codec = dai->codec;
2911 struct wm8994_priv *wm8994 = codec->private_data;
2912
2913 switch (dai->id) {
2914 case 1:
2915 case 2:
2916 break;
2917
2918 default:
2919 /* AIF3 shares clocking with AIF1/2 */
2920 return -EINVAL;
2921 }
2922
2923 switch (clk_id) {
2924 case WM8994_SYSCLK_MCLK1:
2925 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
2926 wm8994->mclk[0] = freq;
2927 dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
2928 dai->id, freq);
2929 break;
2930
2931 case WM8994_SYSCLK_MCLK2:
2932 /* TODO: Set GPIO AF */
2933 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
2934 wm8994->mclk[1] = freq;
2935 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
2936 dai->id, freq);
2937 break;
2938
2939 case WM8994_SYSCLK_FLL1:
2940 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
2941 dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id);
2942 break;
2943
2944 case WM8994_SYSCLK_FLL2:
2945 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
2946 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
2947 break;
2948
2949 default:
2950 return -EINVAL;
2951 }
2952
2953 configure_clock(codec);
2954
2955 return 0;
2956}
2957
2958static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2959 enum snd_soc_bias_level level)
2960{
2961 switch (level) {
2962 case SND_SOC_BIAS_ON:
2963 break;
2964
2965 case SND_SOC_BIAS_PREPARE:
2966 /* VMID=2x40k */
2967 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2968 WM8994_VMID_SEL_MASK, 0x2);
2969 break;
2970
2971 case SND_SOC_BIAS_STANDBY:
2972 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2973 /* Tweak DC servo configuration for improved
2974 * performance. */
2975 snd_soc_write(codec, 0x102, 0x3);
2976 snd_soc_write(codec, 0x56, 0x3);
2977 snd_soc_write(codec, 0x102, 0);
2978
2979 /* Discharge LINEOUT1 & 2 */
2980 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
2981 WM8994_LINEOUT1_DISCH |
2982 WM8994_LINEOUT2_DISCH,
2983 WM8994_LINEOUT1_DISCH |
2984 WM8994_LINEOUT2_DISCH);
2985
2986 /* Startup bias, VMID ramp & buffer */
2987 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
2988 WM8994_STARTUP_BIAS_ENA |
2989 WM8994_VMID_BUF_ENA |
2990 WM8994_VMID_RAMP_MASK,
2991 WM8994_STARTUP_BIAS_ENA |
2992 WM8994_VMID_BUF_ENA |
2993 (0x11 << WM8994_VMID_RAMP_SHIFT));
2994
2995 /* Main bias enable, VMID=2x40k */
2996 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2997 WM8994_BIAS_ENA |
2998 WM8994_VMID_SEL_MASK,
2999 WM8994_BIAS_ENA | 0x2);
3000
3001 msleep(20);
3002 }
3003
3004 /* VMID=2x500k */
3005 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3006 WM8994_VMID_SEL_MASK, 0x4);
3007
3008 break;
3009
3010 case SND_SOC_BIAS_OFF:
3011 if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
3012 /* Switch over to startup biases */
3013 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3014 WM8994_BIAS_SRC |
3015 WM8994_STARTUP_BIAS_ENA |
3016 WM8994_VMID_BUF_ENA |
3017 WM8994_VMID_RAMP_MASK,
3018 WM8994_BIAS_SRC |
3019 WM8994_STARTUP_BIAS_ENA |
3020 WM8994_VMID_BUF_ENA |
3021 (1 << WM8994_VMID_RAMP_SHIFT));
3022
3023 /* Disable main biases */
3024 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3025 WM8994_BIAS_ENA |
3026 WM8994_VMID_SEL_MASK, 0);
3027
3028 /* Discharge line */
3029 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
3030 WM8994_LINEOUT1_DISCH |
3031 WM8994_LINEOUT2_DISCH,
3032 WM8994_LINEOUT1_DISCH |
3033 WM8994_LINEOUT2_DISCH);
3034
3035 msleep(5);
3036
3037 /* Switch off startup biases */
3038 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3039 WM8994_BIAS_SRC |
3040 WM8994_STARTUP_BIAS_ENA |
3041 WM8994_VMID_BUF_ENA |
3042 WM8994_VMID_RAMP_MASK, 0);
3043 }
3044 break;
3045 }
3046 codec->bias_level = level;
3047 return 0;
3048}
3049
3050static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3051{
3052 struct snd_soc_codec *codec = dai->codec;
3053 int ms_reg;
3054 int aif1_reg;
3055 int ms = 0;
3056 int aif1 = 0;
3057
3058 switch (dai->id) {
3059 case 1:
3060 ms_reg = WM8994_AIF1_MASTER_SLAVE;
3061 aif1_reg = WM8994_AIF1_CONTROL_1;
3062 break;
3063 case 2:
3064 ms_reg = WM8994_AIF2_MASTER_SLAVE;
3065 aif1_reg = WM8994_AIF2_CONTROL_1;
3066 break;
3067 default:
3068 return -EINVAL;
3069 }
3070
3071 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3072 case SND_SOC_DAIFMT_CBS_CFS:
3073 break;
3074 case SND_SOC_DAIFMT_CBM_CFM:
3075 ms = WM8994_AIF1_MSTR;
3076 break;
3077 default:
3078 return -EINVAL;
3079 }
3080
3081 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3082 case SND_SOC_DAIFMT_DSP_B:
3083 aif1 |= WM8994_AIF1_LRCLK_INV;
3084 case SND_SOC_DAIFMT_DSP_A:
3085 aif1 |= 0x18;
3086 break;
3087 case SND_SOC_DAIFMT_I2S:
3088 aif1 |= 0x10;
3089 break;
3090 case SND_SOC_DAIFMT_RIGHT_J:
3091 break;
3092 case SND_SOC_DAIFMT_LEFT_J:
3093 aif1 |= 0x8;
3094 break;
3095 default:
3096 return -EINVAL;
3097 }
3098
3099 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3100 case SND_SOC_DAIFMT_DSP_A:
3101 case SND_SOC_DAIFMT_DSP_B:
3102 /* frame inversion not valid for DSP modes */
3103 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3104 case SND_SOC_DAIFMT_NB_NF:
3105 break;
3106 case SND_SOC_DAIFMT_IB_NF:
3107 aif1 |= WM8994_AIF1_BCLK_INV;
3108 break;
3109 default:
3110 return -EINVAL;
3111 }
3112 break;
3113
3114 case SND_SOC_DAIFMT_I2S:
3115 case SND_SOC_DAIFMT_RIGHT_J:
3116 case SND_SOC_DAIFMT_LEFT_J:
3117 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3118 case SND_SOC_DAIFMT_NB_NF:
3119 break;
3120 case SND_SOC_DAIFMT_IB_IF:
3121 aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
3122 break;
3123 case SND_SOC_DAIFMT_IB_NF:
3124 aif1 |= WM8994_AIF1_BCLK_INV;
3125 break;
3126 case SND_SOC_DAIFMT_NB_IF:
3127 aif1 |= WM8994_AIF1_LRCLK_INV;
3128 break;
3129 default:
3130 return -EINVAL;
3131 }
3132 break;
3133 default:
3134 return -EINVAL;
3135 }
3136
3137 snd_soc_update_bits(codec, aif1_reg,
3138 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
3139 WM8994_AIF1_FMT_MASK,
3140 aif1);
3141 snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
3142 ms);
3143
3144 return 0;
3145}
3146
3147static struct {
3148 int val, rate;
3149} srs[] = {
3150 { 0, 8000 },
3151 { 1, 11025 },
3152 { 2, 12000 },
3153 { 3, 16000 },
3154 { 4, 22050 },
3155 { 5, 24000 },
3156 { 6, 32000 },
3157 { 7, 44100 },
3158 { 8, 48000 },
3159 { 9, 88200 },
3160 { 10, 96000 },
3161};
3162
3163static int fs_ratios[] = {
3164 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
3165};
3166
3167static int bclk_divs[] = {
3168 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
3169 640, 880, 960, 1280, 1760, 1920
3170};
3171
3172static int wm8994_hw_params(struct snd_pcm_substream *substream,
3173 struct snd_pcm_hw_params *params,
3174 struct snd_soc_dai *dai)
3175{
3176 struct snd_soc_codec *codec = dai->codec;
3177 struct wm8994_priv *wm8994 = codec->private_data;
3178 int aif1_reg;
3179 int bclk_reg;
3180 int lrclk_reg;
3181 int rate_reg;
3182 int aif1 = 0;
3183 int bclk = 0;
3184 int lrclk = 0;
3185 int rate_val = 0;
3186 int id = dai->id - 1;
3187
3188 int i, cur_val, best_val, bclk_rate, best;
3189
3190 switch (dai->id) {
3191 case 1:
3192 aif1_reg = WM8994_AIF1_CONTROL_1;
3193 bclk_reg = WM8994_AIF1_BCLK;
3194 rate_reg = WM8994_AIF1_RATE;
3195 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3196 wm8994->lrclk_shared[0])
3197 lrclk_reg = WM8994_AIF1DAC_LRCLK;
3198 else
3199 lrclk_reg = WM8994_AIF1ADC_LRCLK;
3200 break;
3201 case 2:
3202 aif1_reg = WM8994_AIF2_CONTROL_1;
3203 bclk_reg = WM8994_AIF2_BCLK;
3204 rate_reg = WM8994_AIF2_RATE;
3205 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3206 wm8994->lrclk_shared[1])
3207 lrclk_reg = WM8994_AIF2DAC_LRCLK;
3208 else
3209 lrclk_reg = WM8994_AIF2ADC_LRCLK;
3210 break;
3211 default:
3212 return -EINVAL;
3213 }
3214
3215 bclk_rate = params_rate(params) * 2;
3216 switch (params_format(params)) {
3217 case SNDRV_PCM_FORMAT_S16_LE:
3218 bclk_rate *= 16;
3219 break;
3220 case SNDRV_PCM_FORMAT_S20_3LE:
3221 bclk_rate *= 20;
3222 aif1 |= 0x20;
3223 break;
3224 case SNDRV_PCM_FORMAT_S24_LE:
3225 bclk_rate *= 24;
3226 aif1 |= 0x40;
3227 break;
3228 case SNDRV_PCM_FORMAT_S32_LE:
3229 bclk_rate *= 32;
3230 aif1 |= 0x60;
3231 break;
3232 default:
3233 return -EINVAL;
3234 }
3235
3236 /* Try to find an appropriate sample rate; look for an exact match. */
3237 for (i = 0; i < ARRAY_SIZE(srs); i++)
3238 if (srs[i].rate == params_rate(params))
3239 break;
3240 if (i == ARRAY_SIZE(srs))
3241 return -EINVAL;
3242 rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
3243
3244 dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
3245 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
3246 dai->id, wm8994->aifclk[id], bclk_rate);
3247
3248 if (wm8994->aifclk[id] == 0) {
3249 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
3250 return -EINVAL;
3251 }
3252
3253 /* AIFCLK/fs ratio; look for a close match in either direction */
3254 best = 0;
3255 best_val = abs((fs_ratios[0] * params_rate(params))
3256 - wm8994->aifclk[id]);
3257 for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
3258 cur_val = abs((fs_ratios[i] * params_rate(params))
3259 - wm8994->aifclk[id]);
3260 if (cur_val >= best_val)
3261 continue;
3262 best = i;
3263 best_val = cur_val;
3264 }
3265 dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
3266 dai->id, fs_ratios[best]);
3267 rate_val |= best;
3268
3269 /* We may not get quite the right frequency if using
3270 * approximate clocks so look for the closest match that is
3271 * higher than the target (we need to ensure that there enough
3272 * BCLKs to clock out the samples).
3273 */
3274 best = 0;
3275 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
3276 cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate;
3277 if (cur_val < 0) /* BCLK table is sorted */
3278 break;
3279 best = i;
3280 }
3281 bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
3282 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
3283 bclk_divs[best], bclk_rate);
3284 bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
3285
3286 lrclk = bclk_rate / params_rate(params);
3287 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
3288 lrclk, bclk_rate / lrclk);
3289
3290 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
3291 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
3292 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
3293 lrclk);
3294 snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK |
3295 WM8994_AIF1CLK_RATE_MASK, rate_val);
3296
3297 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3298 switch (dai->id) {
3299 case 1:
3300 wm8994->dac_rates[0] = params_rate(params);
3301 wm8994_set_retune_mobile(codec, 0);
3302 wm8994_set_retune_mobile(codec, 1);
3303 break;
3304 case 2:
3305 wm8994->dac_rates[1] = params_rate(params);
3306 wm8994_set_retune_mobile(codec, 2);
3307 break;
3308 }
3309 }
3310
3311 return 0;
3312}
3313
3314static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3315{
3316 struct snd_soc_codec *codec = codec_dai->codec;
3317 int mute_reg;
3318 int reg;
3319
3320 switch (codec_dai->id) {
3321 case 1:
3322 mute_reg = WM8994_AIF1_DAC1_FILTERS_1;
3323 break;
3324 case 2:
3325 mute_reg = WM8994_AIF2_DAC_FILTERS_1;
3326 break;
3327 default:
3328 return -EINVAL;
3329 }
3330
3331 if (mute)
3332 reg = WM8994_AIF1DAC1_MUTE;
3333 else
3334 reg = 0;
3335
3336 snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
3337
3338 return 0;
3339}
3340
3341#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
3342
3343#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
3344 SNDRV_PCM_FMTBIT_S24_LE)
3345
3346static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
3347 .set_sysclk = wm8994_set_dai_sysclk,
3348 .set_fmt = wm8994_set_dai_fmt,
3349 .hw_params = wm8994_hw_params,
3350 .digital_mute = wm8994_aif_mute,
3351 .set_pll = wm8994_set_fll,
3352};
3353
3354static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3355 .set_sysclk = wm8994_set_dai_sysclk,
3356 .set_fmt = wm8994_set_dai_fmt,
3357 .hw_params = wm8994_hw_params,
3358 .digital_mute = wm8994_aif_mute,
3359 .set_pll = wm8994_set_fll,
3360};
3361
3362struct snd_soc_dai wm8994_dai[] = {
3363 {
3364 .name = "WM8994 AIF1",
3365 .id = 1,
3366 .playback = {
3367 .stream_name = "AIF1 Playback",
3368 .channels_min = 2,
3369 .channels_max = 2,
3370 .rates = WM8994_RATES,
3371 .formats = WM8994_FORMATS,
3372 },
3373 .capture = {
3374 .stream_name = "AIF1 Capture",
3375 .channels_min = 2,
3376 .channels_max = 2,
3377 .rates = WM8994_RATES,
3378 .formats = WM8994_FORMATS,
3379 },
3380 .ops = &wm8994_aif1_dai_ops,
3381 },
3382 {
3383 .name = "WM8994 AIF2",
3384 .id = 2,
3385 .playback = {
3386 .stream_name = "AIF2 Playback",
3387 .channels_min = 2,
3388 .channels_max = 2,
3389 .rates = WM8994_RATES,
3390 .formats = WM8994_FORMATS,
3391 },
3392 .capture = {
3393 .stream_name = "AIF2 Capture",
3394 .channels_min = 2,
3395 .channels_max = 2,
3396 .rates = WM8994_RATES,
3397 .formats = WM8994_FORMATS,
3398 },
3399 .ops = &wm8994_aif2_dai_ops,
3400 },
3401 {
3402 .name = "WM8994 AIF3",
3403 .playback = {
3404 .stream_name = "AIF3 Playback",
3405 .channels_min = 2,
3406 .channels_max = 2,
3407 .rates = WM8994_RATES,
3408 .formats = WM8994_FORMATS,
3409 },
3410 .capture = {
3411 .stream_name = "AIF3 Capture",
3412 .channels_min = 2,
3413 .channels_max = 2,
3414 .rates = WM8994_RATES,
3415 .formats = WM8994_FORMATS,
3416 },
3417 }
3418};
3419EXPORT_SYMBOL_GPL(wm8994_dai);
3420
3421#ifdef CONFIG_PM
3422static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3423{
3424 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3425 struct snd_soc_codec *codec = socdev->card->codec;
3426 struct wm8994_priv *wm8994 = codec->private_data;
3427 int i, ret;
3428
3429 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3430 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
3431 sizeof(struct fll_config));
3432 ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0);
3433 if (ret < 0)
3434 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
3435 i + 1, ret);
3436 }
3437
3438 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3439
3440 return 0;
3441}
3442
3443static int wm8994_resume(struct platform_device *pdev)
3444{
3445 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3446 struct snd_soc_codec *codec = socdev->card->codec;
3447 struct wm8994_priv *wm8994 = codec->private_data;
3448 u16 *reg_cache = codec->reg_cache;
3449 int i, ret;
3450
3451 /* Restore the registers */
3452 for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) {
3453 switch (i) {
3454 case WM8994_LDO_1:
3455 case WM8994_LDO_2:
3456 case WM8994_SOFTWARE_RESET:
3457 /* Handled by other MFD drivers */
3458 continue;
3459 default:
3460 break;
3461 }
3462
3463 if (!access_masks[i].writable)
3464 continue;
3465
3466 wm8994_reg_write(codec->control_data, i, reg_cache[i]);
3467 }
3468
3469 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3470
3471 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3472 ret = wm8994_set_fll(&codec->dai[0], i + 1,
3473 wm8994->fll_suspend[i].src,
3474 wm8994->fll_suspend[i].in,
3475 wm8994->fll_suspend[i].out);
3476 if (ret < 0)
3477 dev_warn(codec->dev, "Failed to restore FLL%d: %d\n",
3478 i + 1, ret);
3479 }
3480
3481 return 0;
3482}
3483#else
3484#define wm8994_suspend NULL
3485#define wm8994_resume NULL
3486#endif
3487
3488static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3489{
3490 struct snd_soc_codec *codec = &wm8994->codec;
3491 struct wm8994_pdata *pdata = wm8994->pdata;
3492 struct snd_kcontrol_new controls[] = {
3493 SOC_ENUM_EXT("AIF1.1 EQ Mode",
3494 wm8994->retune_mobile_enum,
3495 wm8994_get_retune_mobile_enum,
3496 wm8994_put_retune_mobile_enum),
3497 SOC_ENUM_EXT("AIF1.2 EQ Mode",
3498 wm8994->retune_mobile_enum,
3499 wm8994_get_retune_mobile_enum,
3500 wm8994_put_retune_mobile_enum),
3501 SOC_ENUM_EXT("AIF2 EQ Mode",
3502 wm8994->retune_mobile_enum,
3503 wm8994_get_retune_mobile_enum,
3504 wm8994_put_retune_mobile_enum),
3505 };
3506 int ret, i, j;
3507 const char **t;
3508
3509 /* We need an array of texts for the enum API but the number
3510 * of texts is likely to be less than the number of
3511 * configurations due to the sample rate dependency of the
3512 * configurations. */
3513 wm8994->num_retune_mobile_texts = 0;
3514 wm8994->retune_mobile_texts = NULL;
3515 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
3516 for (j = 0; j < wm8994->num_retune_mobile_texts; j++) {
3517 if (strcmp(pdata->retune_mobile_cfgs[i].name,
3518 wm8994->retune_mobile_texts[j]) == 0)
3519 break;
3520 }
3521
3522 if (j != wm8994->num_retune_mobile_texts)
3523 continue;
3524
3525 /* Expand the array... */
3526 t = krealloc(wm8994->retune_mobile_texts,
3527 sizeof(char *) *
3528 (wm8994->num_retune_mobile_texts + 1),
3529 GFP_KERNEL);
3530 if (t == NULL)
3531 continue;
3532
3533 /* ...store the new entry... */
3534 t[wm8994->num_retune_mobile_texts] =
3535 pdata->retune_mobile_cfgs[i].name;
3536
3537 /* ...and remember the new version. */
3538 wm8994->num_retune_mobile_texts++;
3539 wm8994->retune_mobile_texts = t;
3540 }
3541
3542 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
3543 wm8994->num_retune_mobile_texts);
3544
3545 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
3546 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3547
3548 ret = snd_soc_add_controls(&wm8994->codec, controls,
3549 ARRAY_SIZE(controls));
3550 if (ret != 0)
3551 dev_err(wm8994->codec.dev,
3552 "Failed to add ReTune Mobile controls: %d\n", ret);
3553}
3554
3555static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3556{
3557 struct snd_soc_codec *codec = &wm8994->codec;
3558 struct wm8994_pdata *pdata = wm8994->pdata;
3559 int ret, i;
3560
3561 if (!pdata)
3562 return;
3563
3564 wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff,
3565 pdata->lineout2_diff,
3566 pdata->lineout1fb,
3567 pdata->lineout2fb,
3568 pdata->jd_scthr,
3569 pdata->jd_thr,
3570 pdata->micbias1_lvl,
3571 pdata->micbias2_lvl);
3572
3573 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
3574
3575 if (pdata->num_drc_cfgs) {
3576 struct snd_kcontrol_new controls[] = {
3577 SOC_ENUM_EXT("AIF1DRC1 Mode", wm8994->drc_enum,
3578 wm8994_get_drc_enum, wm8994_put_drc_enum),
3579 SOC_ENUM_EXT("AIF1DRC2 Mode", wm8994->drc_enum,
3580 wm8994_get_drc_enum, wm8994_put_drc_enum),
3581 SOC_ENUM_EXT("AIF2DRC Mode", wm8994->drc_enum,
3582 wm8994_get_drc_enum, wm8994_put_drc_enum),
3583 };
3584
3585 /* We need an array of texts for the enum API */
3586 wm8994->drc_texts = kmalloc(sizeof(char *)
3587 * pdata->num_drc_cfgs, GFP_KERNEL);
3588 if (!wm8994->drc_texts) {
3589 dev_err(wm8994->codec.dev,
3590 "Failed to allocate %d DRC config texts\n",
3591 pdata->num_drc_cfgs);
3592 return;
3593 }
3594
3595 for (i = 0; i < pdata->num_drc_cfgs; i++)
3596 wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
3597
3598 wm8994->drc_enum.max = pdata->num_drc_cfgs;
3599 wm8994->drc_enum.texts = wm8994->drc_texts;
3600
3601 ret = snd_soc_add_controls(&wm8994->codec, controls,
3602 ARRAY_SIZE(controls));
3603 if (ret != 0)
3604 dev_err(wm8994->codec.dev,
3605 "Failed to add DRC mode controls: %d\n", ret);
3606
3607 for (i = 0; i < WM8994_NUM_DRC; i++)
3608 wm8994_set_drc(codec, i);
3609 }
3610
3611 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
3612 pdata->num_retune_mobile_cfgs);
3613
3614 if (pdata->num_retune_mobile_cfgs)
3615 wm8994_handle_retune_mobile_pdata(wm8994);
3616 else
3617 snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls,
3618 ARRAY_SIZE(wm8994_eq_controls));
3619}
3620
3621static int wm8994_probe(struct platform_device *pdev)
3622{
3623 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3624 struct snd_soc_codec *codec;
3625 int ret = 0;
3626
3627 if (wm8994_codec == NULL) {
3628 dev_err(&pdev->dev, "Codec device not registered\n");
3629 return -ENODEV;
3630 }
3631
3632 socdev->card->codec = wm8994_codec;
3633 codec = wm8994_codec;
3634
3635 /* register pcms */
3636 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
3637 if (ret < 0) {
3638 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
3639 return ret;
3640 }
3641
3642 wm8994_handle_pdata(codec->private_data);
3643
3644 wm_hubs_add_analogue_controls(codec);
3645 snd_soc_add_controls(codec, wm8994_snd_controls,
3646 ARRAY_SIZE(wm8994_snd_controls));
3647 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
3648 ARRAY_SIZE(wm8994_dapm_widgets));
3649 wm_hubs_add_analogue_routes(codec, 0, 0);
3650 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
3651
3652 return 0;
3653}
3654
3655static int wm8994_remove(struct platform_device *pdev)
3656{
3657 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3658
3659 snd_soc_free_pcms(socdev);
3660 snd_soc_dapm_free(socdev);
3661
3662 return 0;
3663}
3664
3665struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3666 .probe = wm8994_probe,
3667 .remove = wm8994_remove,
3668 .suspend = wm8994_suspend,
3669 .resume = wm8994_resume,
3670};
3671EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3672
3673static int wm8994_codec_probe(struct platform_device *pdev)
3674{
3675 int ret;
3676 struct wm8994_priv *wm8994;
3677 struct snd_soc_codec *codec;
3678 int i;
3679 u16 rev;
3680
3681 if (wm8994_codec) {
3682 dev_err(&pdev->dev, "Another WM8994 is registered\n");
3683 return -EINVAL;
3684 }
3685
3686 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
3687 if (!wm8994) {
3688 dev_err(&pdev->dev, "Failed to allocate private data\n");
3689 return -ENOMEM;
3690 }
3691
3692 codec = &wm8994->codec;
3693
3694 mutex_init(&codec->mutex);
3695 INIT_LIST_HEAD(&codec->dapm_widgets);
3696 INIT_LIST_HEAD(&codec->dapm_paths);
3697
3698 codec->private_data = wm8994;
3699 codec->control_data = dev_get_drvdata(pdev->dev.parent);
3700 codec->name = "WM8994";
3701 codec->owner = THIS_MODULE;
3702 codec->read = wm8994_read;
3703 codec->write = wm8994_write;
3704 codec->readable_register = wm8994_readable;
3705 codec->bias_level = SND_SOC_BIAS_OFF;
3706 codec->set_bias_level = wm8994_set_bias_level;
3707 codec->dai = &wm8994_dai[0];
3708 codec->num_dai = 3;
3709 codec->reg_cache_size = WM8994_MAX_REGISTER;
3710 codec->reg_cache = &wm8994->reg_cache;
3711 codec->dev = &pdev->dev;
3712
3713 wm8994->pdata = pdev->dev.parent->platform_data;
3714
3715 /* Fill the cache with physical values we inherited; don't reset */
3716 ret = wm8994_bulk_read(codec->control_data, 0,
3717 ARRAY_SIZE(wm8994->reg_cache) - 1,
3718 codec->reg_cache);
3719 if (ret < 0) {
3720 dev_err(codec->dev, "Failed to fill register cache: %d\n",
3721 ret);
3722 goto err;
3723 }
3724
3725 /* Clear the cached values for unreadable/volatile registers to
3726 * avoid potential confusion.
3727 */
3728 for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++)
3729 if (wm8994_volatile(i) || !wm8994_readable(i))
3730 wm8994->reg_cache[i] = 0;
3731
3732 /* Set revision-specific configuration */
3733 rev = snd_soc_read(codec, WM8994_CHIP_REVISION);
3734 switch (rev) {
3735 case 2:
3736 case 3:
3737 wm8994->hubs.dcs_codes = -5;
3738 wm8994->hubs.hp_startup_mode = 1;
3739 wm8994->hubs.dcs_readback_mode = 1;
3740 break;
3741 default:
3742 wm8994->hubs.dcs_readback_mode = 1;
3743 break;
3744 }
3745
3746 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3747 * configured on init - if a system wants to do this dynamically
3748 * at runtime we can deal with that then.
3749 */
3750 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
3751 if (ret < 0) {
3752 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
3753 goto err;
3754 }
3755 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3756 wm8994->lrclk_shared[0] = 1;
3757 wm8994_dai[0].symmetric_rates = 1;
3758 } else {
3759 wm8994->lrclk_shared[0] = 0;
3760 }
3761
3762 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
3763 if (ret < 0) {
3764 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
3765 goto err;
3766 }
3767 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3768 wm8994->lrclk_shared[1] = 1;
3769 wm8994_dai[1].symmetric_rates = 1;
3770 } else {
3771 wm8994->lrclk_shared[1] = 0;
3772 }
3773
3774 for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
3775 wm8994_dai[i].dev = codec->dev;
3776
3777 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3778
3779 wm8994_codec = codec;
3780
3781 /* Latch volume updates (right only; we always do left then right). */
3782 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
3783 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
3784 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME,
3785 WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
3786 snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME,
3787 WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
3788 snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME,
3789 WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
3790 snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME,
3791 WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
3792 snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME,
3793 WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
3794 snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME,
3795 WM8994_DAC1_VU, WM8994_DAC1_VU);
3796 snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME,
3797 WM8994_DAC2_VU, WM8994_DAC2_VU);
3798
3799 /* Set the low bit of the 3D stereo depth so TLV matches */
3800 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
3801 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
3802 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
3803 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2,
3804 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
3805 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
3806 snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2,
3807 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
3808 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
3809
3810 wm8994_update_class_w(codec);
3811
3812 ret = snd_soc_register_codec(codec);
3813 if (ret != 0) {
3814 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
3815 goto err;
3816 }
3817
3818 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3819 if (ret != 0) {
3820 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
3821 goto err_codec;
3822 }
3823
3824 platform_set_drvdata(pdev, wm8994);
3825
3826 return 0;
3827
3828err_codec:
3829 snd_soc_unregister_codec(codec);
3830err:
3831 kfree(wm8994);
3832 return ret;
3833}
3834
3835static int __devexit wm8994_codec_remove(struct platform_device *pdev)
3836{
3837 struct wm8994_priv *wm8994 = platform_get_drvdata(pdev);
3838 struct snd_soc_codec *codec = &wm8994->codec;
3839
3840 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3841 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3842 snd_soc_unregister_codec(&wm8994->codec);
3843 kfree(wm8994);
3844 wm8994_codec = NULL;
3845
3846 return 0;
3847}
3848
3849static struct platform_driver wm8994_codec_driver = {
3850 .driver = {
3851 .name = "wm8994-codec",
3852 .owner = THIS_MODULE,
3853 },
3854 .probe = wm8994_codec_probe,
3855 .remove = __devexit_p(wm8994_codec_remove),
3856};
3857
3858static __init int wm8994_init(void)
3859{
3860 return platform_driver_register(&wm8994_codec_driver);
3861}
3862module_init(wm8994_init);
3863
3864static __exit void wm8994_exit(void)
3865{
3866 platform_driver_unregister(&wm8994_codec_driver);
3867}
3868module_exit(wm8994_exit);
3869
3870
3871MODULE_DESCRIPTION("ASoC WM8994 driver");
3872MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
3873MODULE_LICENSE("GPL");
3874MODULE_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/wm9081.c b/sound/soc/codecs/wm9081.c
index 686e5aa97206..3a184fcb702b 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -1262,19 +1263,9 @@ static int wm9081_probe(struct platform_device *pdev)
1262 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets, 1263 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets,
1263 ARRAY_SIZE(wm9081_dapm_widgets)); 1264 ARRAY_SIZE(wm9081_dapm_widgets));
1264 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1265 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1265 snd_soc_dapm_new_widgets(codec);
1266
1267 ret = snd_soc_init_card(socdev);
1268 if (ret < 0) {
1269 dev_err(codec->dev, "failed to register card: %d\n", ret);
1270 goto card_err;
1271 }
1272 1266
1273 return ret; 1267 return ret;
1274 1268
1275card_err:
1276 snd_soc_free_pcms(socdev);
1277 snd_soc_dapm_free(socdev);
1278pcm_err: 1269pcm_err:
1279 return ret; 1270 return ret;
1280} 1271}
@@ -1452,21 +1443,6 @@ static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1452 return 0; 1443 return 0;
1453} 1444}
1454 1445
1455#ifdef CONFIG_PM
1456static int wm9081_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1457{
1458 return snd_soc_suspend_device(&client->dev);
1459}
1460
1461static int wm9081_i2c_resume(struct i2c_client *client)
1462{
1463 return snd_soc_resume_device(&client->dev);
1464}
1465#else
1466#define wm9081_i2c_suspend NULL
1467#define wm9081_i2c_resume NULL
1468#endif
1469
1470static const struct i2c_device_id wm9081_i2c_id[] = { 1446static const struct i2c_device_id wm9081_i2c_id[] = {
1471 { "wm9081", 0 }, 1447 { "wm9081", 0 },
1472 { } 1448 { }
@@ -1480,8 +1456,6 @@ static struct i2c_driver wm9081_i2c_driver = {
1480 }, 1456 },
1481 .probe = wm9081_i2c_probe, 1457 .probe = wm9081_i2c_probe,
1482 .remove = __devexit_p(wm9081_i2c_remove), 1458 .remove = __devexit_p(wm9081_i2c_remove),
1483 .suspend = wm9081_i2c_suspend,
1484 .resume = wm9081_i2c_resume,
1485 .id_table = wm9081_i2c_id, 1459 .id_table = wm9081_i2c_id,
1486}; 1460};
1487 1461
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index e7d2840d9e59..8793341849d1 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/slab.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/device.h> 16#include <linux/device.h>
@@ -205,7 +206,6 @@ static int wm9705_add_widgets(struct snd_soc_codec *codec)
205 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, 206 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets,
206 ARRAY_SIZE(wm9705_dapm_widgets)); 207 ARRAY_SIZE(wm9705_dapm_widgets));
207 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 208 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
208 snd_soc_dapm_new_widgets(codec);
209 209
210 return 0; 210 return 0;
211} 211}
@@ -403,12 +403,6 @@ static int wm9705_soc_probe(struct platform_device *pdev)
403 ARRAY_SIZE(wm9705_snd_ac97_controls)); 403 ARRAY_SIZE(wm9705_snd_ac97_controls));
404 wm9705_add_widgets(codec); 404 wm9705_add_widgets(codec);
405 405
406 ret = snd_soc_init_card(socdev);
407 if (ret < 0) {
408 printk(KERN_ERR "wm9705: failed to register card\n");
409 goto reset_err;
410 }
411
412 return 0; 406 return 0;
413 407
414reset_err: 408reset_err:
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 1fd4e88f50cf..2f48a8aae22c 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/slab.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/device.h> 17#include <linux/device.h>
@@ -436,7 +437,6 @@ static int wm9712_add_widgets(struct snd_soc_codec *codec)
436 437
437 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 438 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
438 439
439 snd_soc_dapm_new_widgets(codec);
440 return 0; 440 return 0;
441} 441}
442 442
@@ -464,7 +464,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
464{ 464{
465 u16 *cache = codec->reg_cache; 465 u16 *cache = codec->reg_cache;
466 466
467 soc_ac97_ops.write(codec->ac97, reg, val); 467 if (reg < 0x7c)
468 soc_ac97_ops.write(codec->ac97, reg, val);
468 reg = reg >> 1; 469 reg = reg >> 1;
469 if (reg < (ARRAY_SIZE(wm9712_reg))) 470 if (reg < (ARRAY_SIZE(wm9712_reg)))
470 cache[reg] = val; 471 cache[reg] = val;
@@ -695,17 +696,11 @@ static int wm9712_soc_probe(struct platform_device *pdev)
695 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 696 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
696 ARRAY_SIZE(wm9712_snd_ac97_controls)); 697 ARRAY_SIZE(wm9712_snd_ac97_controls));
697 wm9712_add_widgets(codec); 698 wm9712_add_widgets(codec);
698 ret = snd_soc_init_card(socdev);
699 if (ret < 0) {
700 printk(KERN_ERR "wm9712: failed to register card\n");
701 goto reset_err;
702 }
703 699
704 return 0; 700 return 0;
705 701
706reset_err: 702reset_err:
707 snd_soc_free_pcms(socdev); 703 snd_soc_free_pcms(socdev);
708
709pcm_err: 704pcm_err:
710 snd_soc_free_ac97_codec(codec); 705 snd_soc_free_ac97_codec(codec);
711 706
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index abed37acf787..2fca514fde58 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/slab.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/device.h> 21#include <linux/device.h>
21#include <sound/core.h> 22#include <sound/core.h>
@@ -23,13 +24,12 @@
23#include <sound/ac97_codec.h> 24#include <sound/ac97_codec.h>
24#include <sound/initval.h> 25#include <sound/initval.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/tlv.h>
26#include <sound/soc.h> 28#include <sound/soc.h>
27#include <sound/soc-dapm.h> 29#include <sound/soc-dapm.h>
28 30
29#include "wm9713.h" 31#include "wm9713.h"
30 32
31#define WM9713_VERSION "0.15"
32
33struct wm9713_priv { 33struct wm9713_priv {
34 u32 pll_in; /* PLL input frequency */ 34 u32 pll_in; /* PLL input frequency */
35}; 35};
@@ -115,15 +115,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 */ 115SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */
116}; 116};
117 117
118static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
119static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
120static const DECLARE_TLV_DB_SCALE(misc_tlv, -1500, 300, 0);
121static unsigned int mic_tlv[] = {
122 TLV_DB_RANGE_HEAD(2),
123 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
124 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
125};
126
118static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = { 127static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = {
119SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1), 128SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, out_tlv),
120SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1), 129SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1),
121SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), 130SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1,
131 out_tlv),
122SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1), 132SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1),
123SOC_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), 133SOC_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), 134SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1, main_tlv),
125SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 135SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
126SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 136SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
137SOC_SINGLE_TLV("Mic 1 Preamp Volume", AC97_3D_CONTROL, 10, 3, 0, mic_tlv),
138SOC_SINGLE_TLV("Mic 2 Preamp Volume", AC97_3D_CONTROL, 12, 3, 0, mic_tlv),
127 139
128SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), 140SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
129SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), 141SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
@@ -133,7 +145,7 @@ SOC_ENUM("Capture Volume Steps", wm9713_enum[5]),
133SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0), 145SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0),
134SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), 146SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
135 147
136SOC_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), 148SOC_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), 149SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
138SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), 150SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
139 151
@@ -154,28 +166,43 @@ SOC_DOUBLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
154 166
155SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1), 167SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
156SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0), 168SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0),
157SOC_SINGLE("Out4 Playback Volume", AC97_MASTER_MONO, 8, 63, 1), 169SOC_SINGLE_TLV("Out4 Playback Volume", AC97_MASTER_MONO, 8, 31, 1, out_tlv),
158 170
159SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1), 171SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1),
160SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0), 172SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0),
161SOC_SINGLE("Out3 Playback Volume", AC97_MASTER_MONO, 0, 63, 1), 173SOC_SINGLE_TLV("Out3 Playback Volume", AC97_MASTER_MONO, 0, 31, 1, out_tlv),
162 174
163SOC_SINGLE("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1), 175SOC_SINGLE_TLV("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1, main_tlv),
164SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1), 176SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
165SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0), 177SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
166SOC_SINGLE("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1), 178SOC_SINGLE_TLV("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1, out_tlv),
167 179
168SOC_SINGLE("PC Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1), 180SOC_SINGLE_TLV("Headphone Mixer Beep Playback Volume", AC97_AUX, 12, 7, 1,
169SOC_SINGLE("PC Beep Playback Speaker Volume", AC97_AUX, 8, 7, 1), 181 misc_tlv),
170SOC_SINGLE("PC Beep Playback Mono Volume", AC97_AUX, 4, 7, 1), 182SOC_SINGLE_TLV("Speaker Mixer Beep Playback Volume", AC97_AUX, 8, 7, 1,
183 misc_tlv),
184SOC_SINGLE_TLV("Mono Mixer Beep Playback Volume", AC97_AUX, 4, 7, 1, misc_tlv),
171 185
172SOC_SINGLE("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1), 186SOC_SINGLE_TLV("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1,
187 misc_tlv),
173SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1), 188SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
174SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1), 189SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1),
175 190
191SOC_SINGLE_TLV("Headphone Mixer Aux Playback Volume", AC97_REC_SEL, 12, 7, 1,
192 misc_tlv),
193
194SOC_SINGLE_TLV("Speaker Mixer Voice Playback Volume", AC97_PCM, 8, 7, 1,
195 misc_tlv),
196SOC_SINGLE_TLV("Speaker Mixer Aux Playback Volume", AC97_REC_SEL, 8, 7, 1,
197 misc_tlv),
198
199SOC_SINGLE_TLV("Mono Mixer Voice Playback Volume", AC97_PCM, 4, 7, 1,
200 misc_tlv),
201SOC_SINGLE_TLV("Mono Mixer Aux Playback Volume", AC97_REC_SEL, 4, 7, 1,
202 misc_tlv),
203
176SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1), 204SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1),
177SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1), 205SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1),
178SOC_SINGLE("Aux Playback Mono Volume", AC97_REC_SEL, 4, 7, 1),
179 206
180SOC_ENUM("Bass Control", wm9713_enum[16]), 207SOC_ENUM("Bass Control", wm9713_enum[16]),
181SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), 208SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
@@ -266,7 +293,7 @@ static int mixer_event(struct snd_soc_dapm_widget *w,
266 293
267/* Left Headphone Mixers */ 294/* Left Headphone Mixers */
268static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = { 295static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = {
269SOC_DAPM_SINGLE("PC Beep Playback Switch", HPL_MIXER, 5, 1, 0), 296SOC_DAPM_SINGLE("Beep Playback Switch", HPL_MIXER, 5, 1, 0),
270SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0), 297SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0),
271SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0), 298SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0),
272SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0), 299SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0),
@@ -276,7 +303,7 @@ SOC_DAPM_SINGLE("Bypass Playback Switch", HPL_MIXER, 0, 1, 0),
276 303
277/* Right Headphone Mixers */ 304/* Right Headphone Mixers */
278static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = { 305static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = {
279SOC_DAPM_SINGLE("PC Beep Playback Switch", HPR_MIXER, 5, 1, 0), 306SOC_DAPM_SINGLE("Beep Playback Switch", HPR_MIXER, 5, 1, 0),
280SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0), 307SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0),
281SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0), 308SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0),
282SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0), 309SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0),
@@ -294,7 +321,7 @@ SOC_DAPM_ENUM("Route", wm9713_enum[0]);
294 321
295/* Speaker Mixer */ 322/* Speaker Mixer */
296static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = { 323static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = {
297SOC_DAPM_SINGLE("PC Beep Playback Switch", AC97_AUX, 11, 1, 1), 324SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 11, 1, 1),
298SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1), 325SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1),
299SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1), 326SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1),
300SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1), 327SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1),
@@ -304,7 +331,7 @@ SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 14, 1, 1),
304 331
305/* Mono Mixer */ 332/* Mono Mixer */
306static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = { 333static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = {
307SOC_DAPM_SINGLE("PC Beep Playback Switch", AC97_AUX, 7, 1, 1), 334SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 7, 1, 1),
308SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1), 335SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1),
309SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1), 336SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1),
310SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1), 337SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1),
@@ -463,7 +490,7 @@ SND_SOC_DAPM_VMID("VMID"),
463 490
464static const struct snd_soc_dapm_route audio_map[] = { 491static const struct snd_soc_dapm_route audio_map[] = {
465 /* left HP mixer */ 492 /* left HP mixer */
466 {"Left HP Mixer", "PC Beep Playback Switch", "PCBEEP"}, 493 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
467 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, 494 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
468 {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"}, 495 {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"},
469 {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"}, 496 {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"},
@@ -472,7 +499,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
472 {"Left HP Mixer", NULL, "Capture Headphone Mux"}, 499 {"Left HP Mixer", NULL, "Capture Headphone Mux"},
473 500
474 /* right HP mixer */ 501 /* right HP mixer */
475 {"Right HP Mixer", "PC Beep Playback Switch", "PCBEEP"}, 502 {"Right HP Mixer", "Beep Playback Switch", "PCBEEP"},
476 {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"}, 503 {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"},
477 {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"}, 504 {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"},
478 {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"}, 505 {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"},
@@ -491,7 +518,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
491 {"Capture Mixer", NULL, "Right Capture Source"}, 518 {"Capture Mixer", NULL, "Right Capture Source"},
492 519
493 /* speaker mixer */ 520 /* speaker mixer */
494 {"Speaker Mixer", "PC Beep Playback Switch", "PCBEEP"}, 521 {"Speaker Mixer", "Beep Playback Switch", "PCBEEP"},
495 {"Speaker Mixer", "Voice Playback Switch", "Voice DAC"}, 522 {"Speaker Mixer", "Voice Playback Switch", "Voice DAC"},
496 {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"}, 523 {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"},
497 {"Speaker Mixer", "Bypass Playback Switch", "Line Mixer"}, 524 {"Speaker Mixer", "Bypass Playback Switch", "Line Mixer"},
@@ -499,7 +526,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
499 {"Speaker Mixer", "MonoIn Playback Switch", "Mono In"}, 526 {"Speaker Mixer", "MonoIn Playback Switch", "Mono In"},
500 527
501 /* mono mixer */ 528 /* mono mixer */
502 {"Mono Mixer", "PC Beep Playback Switch", "PCBEEP"}, 529 {"Mono Mixer", "Beep Playback Switch", "PCBEEP"},
503 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"}, 530 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
504 {"Mono Mixer", "Aux Playback Switch", "Aux DAC"}, 531 {"Mono Mixer", "Aux Playback Switch", "Aux DAC"},
505 {"Mono Mixer", "Bypass Playback Switch", "Line Mixer"}, 532 {"Mono Mixer", "Bypass Playback Switch", "Line Mixer"},
@@ -625,7 +652,6 @@ static int wm9713_add_widgets(struct snd_soc_codec *codec)
625 652
626 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 653 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
627 654
628 snd_soc_dapm_new_widgets(codec);
629 return 0; 655 return 0;
630} 656}
631 657
@@ -800,8 +826,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
800 return 0; 826 return 0;
801} 827}
802 828
803static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, 829static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
804 int pll_id, unsigned int freq_in, unsigned int freq_out) 830 int source, unsigned int freq_in, unsigned int freq_out)
805{ 831{
806 struct snd_soc_codec *codec = codec_dai->codec; 832 struct snd_soc_codec *codec = codec_dai->codec;
807 return wm9713_set_pll(codec, pll_id, freq_in, freq_out); 833 return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
@@ -1187,8 +1213,6 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1187 struct snd_soc_codec *codec; 1213 struct snd_soc_codec *codec;
1188 int ret = 0, reg; 1214 int ret = 0, reg;
1189 1215
1190 printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION);
1191
1192 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), 1216 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
1193 GFP_KERNEL); 1217 GFP_KERNEL);
1194 if (socdev->card->codec == NULL) 1218 if (socdev->card->codec == NULL)
@@ -1247,14 +1271,11 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1247 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1271 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1248 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1272 ARRAY_SIZE(wm9713_snd_ac97_controls));
1249 wm9713_add_widgets(codec); 1273 wm9713_add_widgets(codec);
1250 ret = snd_soc_init_card(socdev); 1274
1251 if (ret < 0)
1252 goto reset_err;
1253 return 0; 1275 return 0;
1254 1276
1255reset_err: 1277reset_err:
1256 snd_soc_free_pcms(socdev); 1278 snd_soc_free_pcms(socdev);
1257
1258pcm_err: 1279pcm_err:
1259 snd_soc_free_ac97_codec(codec); 1280 snd_soc_free_ac97_codec(codec);
1260 1281
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e542027eea89..e1f225a3ac46 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -62,36 +62,108 @@ static const char *speaker_mode_text[] = {
62static const struct soc_enum speaker_mode = 62static const struct soc_enum speaker_mode =
63 SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text); 63 SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
64 64
65static void wait_for_dc_servo(struct snd_soc_codec *codec) 65static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
66{ 66{
67 unsigned int reg; 67 unsigned int reg;
68 int count = 0; 68 int count = 0;
69 unsigned int val;
70
71 val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
72
73 /* Trigger the command */
74 snd_soc_write(codec, WM8993_DC_SERVO_0, val);
69 75
70 dev_dbg(codec->dev, "Waiting for DC servo...\n"); 76 dev_dbg(codec->dev, "Waiting for DC servo...\n");
77
71 do { 78 do {
72 count++; 79 count++;
73 msleep(1); 80 msleep(1);
74 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); 81 reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
75 dev_dbg(codec->dev, "DC servo status: %x\n", reg); 82 dev_dbg(codec->dev, "DC servo: %x\n", reg);
76 } while ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 83 } while (reg & op && count < 400);
77 != WM8993_DCS_CAL_COMPLETE_MASK && count < 1000);
78 84
79 if ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 85 if (reg & op)
80 != WM8993_DCS_CAL_COMPLETE_MASK)
81 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 86 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
82} 87}
83 88
84/* 89/*
90 * Startup calibration of the DC servo
91 */
92static void calibrate_dc_servo(struct snd_soc_codec *codec)
93{
94 struct wm_hubs_data *hubs = codec->private_data;
95 u16 reg, reg_l, reg_r, dcs_cfg;
96
97 /* Set for 32 series updates */
98 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
99 WM8993_DCS_SERIES_NO_01_MASK,
100 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
101 wait_for_dc_servo(codec,
102 WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
103
104 /* Apply correction to DC servo result */
105 if (hubs->dcs_codes) {
106 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
107 hubs->dcs_codes);
108
109 /* Different chips in the family support different
110 * readback methods.
111 */
112 switch (hubs->dcs_readback_mode) {
113 case 0:
114 reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
115 & WM8993_DCS_INTEG_CHAN_0_MASK;;
116 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
117 & WM8993_DCS_INTEG_CHAN_1_MASK;
118 break;
119 case 1:
120 reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
121 reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
122 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
123 reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
124 break;
125 default:
126 WARN(1, "Unknown DCS readback method");
127 break;
128 }
129
130 /* HPOUT1L */
131 if (reg_l + hubs->dcs_codes > 0 &&
132 reg_l + hubs->dcs_codes < 0xff)
133 reg_l += hubs->dcs_codes;
134 dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
135
136 /* HPOUT1R */
137 if (reg_r + hubs->dcs_codes > 0 &&
138 reg_r + hubs->dcs_codes < 0xff)
139 reg_r += hubs->dcs_codes;
140 dcs_cfg |= reg_r;
141
142 /* Do it */
143 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
144 wait_for_dc_servo(codec,
145 WM8993_DCS_TRIG_DAC_WR_0 |
146 WM8993_DCS_TRIG_DAC_WR_1);
147 }
148}
149
150/*
85 * Update the DC servo calibration on gain changes 151 * Update the DC servo calibration on gain changes
86 */ 152 */
87static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, 153static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
88 struct snd_ctl_elem_value *ucontrol) 154 struct snd_ctl_elem_value *ucontrol)
89{ 155{
90 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 156 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
157 struct wm_hubs_data *hubs = codec->private_data;
91 int ret; 158 int ret;
92 159
93 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 160 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
94 161
162 /* If we're applying an offset correction then updating the
163 * callibration would be likely to introduce further offsets. */
164 if (hubs->dcs_codes)
165 return ret;
166
95 /* Only need to do this if the outputs are active */ 167 /* Only need to do this if the outputs are active */
96 if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1) 168 if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
97 & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA)) 169 & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
@@ -251,6 +323,47 @@ SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
251 line_tlv), 323 line_tlv),
252}; 324};
253 325
326static int hp_supply_event(struct snd_soc_dapm_widget *w,
327 struct snd_kcontrol *kcontrol, int event)
328{
329 struct snd_soc_codec *codec = w->codec;
330 struct wm_hubs_data *hubs = codec->private_data;
331
332 switch (event) {
333 case SND_SOC_DAPM_PRE_PMU:
334 switch (hubs->hp_startup_mode) {
335 case 0:
336 break;
337 case 1:
338 /* Enable the headphone amp */
339 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
340 WM8993_HPOUT1L_ENA |
341 WM8993_HPOUT1R_ENA,
342 WM8993_HPOUT1L_ENA |
343 WM8993_HPOUT1R_ENA);
344
345 /* Enable the second stage */
346 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
347 WM8993_HPOUT1L_DLY |
348 WM8993_HPOUT1R_DLY,
349 WM8993_HPOUT1L_DLY |
350 WM8993_HPOUT1R_DLY);
351 break;
352 default:
353 dev_err(codec->dev, "Unknown HP startup mode %d\n",
354 hubs->hp_startup_mode);
355 break;
356 }
357
358 case SND_SOC_DAPM_PRE_PMD:
359 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
360 WM8993_CP_ENA, 0);
361 break;
362 }
363
364 return 0;
365}
366
254static int hp_event(struct snd_soc_dapm_widget *w, 367static int hp_event(struct snd_soc_dapm_widget *w,
255 struct snd_kcontrol *kcontrol, int event) 368 struct snd_kcontrol *kcontrol, int event)
256{ 369{
@@ -271,14 +384,11 @@ static int hp_event(struct snd_soc_dapm_widget *w,
271 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY; 384 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
272 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg); 385 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
273 386
274 /* Start the DC servo */ 387 /* Smallest supported update interval */
275 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 388 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
276 0xFFFF, 389 WM8993_DCS_TIMER_PERIOD_01_MASK, 1);
277 WM8993_DCS_ENA_CHAN_0 | 390
278 WM8993_DCS_ENA_CHAN_1 | 391 calibrate_dc_servo(codec);
279 WM8993_DCS_TRIG_STARTUP_1 |
280 WM8993_DCS_TRIG_STARTUP_0);
281 wait_for_dc_servo(codec);
282 392
283 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | 393 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
284 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; 394 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
@@ -286,23 +396,19 @@ static int hp_event(struct snd_soc_dapm_widget *w,
286 break; 396 break;
287 397
288 case SND_SOC_DAPM_PRE_PMD: 398 case SND_SOC_DAPM_PRE_PMD:
289 reg &= ~(WM8993_HPOUT1L_RMV_SHORT | 399 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
290 WM8993_HPOUT1L_DLY | 400 WM8993_HPOUT1L_DLY |
291 WM8993_HPOUT1L_OUTP | 401 WM8993_HPOUT1R_DLY |
292 WM8993_HPOUT1R_RMV_SHORT | 402 WM8993_HPOUT1L_RMV_SHORT |
293 WM8993_HPOUT1R_DLY | 403 WM8993_HPOUT1R_RMV_SHORT, 0);
294 WM8993_HPOUT1R_OUTP);
295 404
296 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 405 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
297 0xffff, 0); 406 WM8993_HPOUT1L_OUTP |
407 WM8993_HPOUT1R_OUTP, 0);
298 408
299 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
300 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 409 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
301 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 410 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
302 0); 411 0);
303
304 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
305 WM8993_CP_ENA, 0);
306 break; 412 break;
307 } 413 }
308 414
@@ -438,11 +544,11 @@ static const struct snd_soc_dapm_widget analogue_dapm_widgets[] = {
438SND_SOC_DAPM_INPUT("IN1LN"), 544SND_SOC_DAPM_INPUT("IN1LN"),
439SND_SOC_DAPM_INPUT("IN1LP"), 545SND_SOC_DAPM_INPUT("IN1LP"),
440SND_SOC_DAPM_INPUT("IN2LN"), 546SND_SOC_DAPM_INPUT("IN2LN"),
441SND_SOC_DAPM_INPUT("IN2LP/VXRN"), 547SND_SOC_DAPM_INPUT("IN2LP:VXRN"),
442SND_SOC_DAPM_INPUT("IN1RN"), 548SND_SOC_DAPM_INPUT("IN1RN"),
443SND_SOC_DAPM_INPUT("IN1RP"), 549SND_SOC_DAPM_INPUT("IN1RP"),
444SND_SOC_DAPM_INPUT("IN2RN"), 550SND_SOC_DAPM_INPUT("IN2RN"),
445SND_SOC_DAPM_INPUT("IN2RP/VXRP"), 551SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
446 552
447SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0), 553SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0),
448SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0), 554SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0),
@@ -473,6 +579,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), 579SND_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), 580SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
475 581
582SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
583 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
476SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, 584SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0,
477 NULL, 0, 585 NULL, 0,
478 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 586 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -537,14 +645,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
537 { "IN1R PGA", "IN1RP Switch", "IN1RP" }, 645 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
538 { "IN1R PGA", "IN1RN Switch", "IN1RN" }, 646 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
539 647
540 { "IN2L PGA", "IN2LP Switch", "IN2LP/VXRN" }, 648 { "IN2L PGA", "IN2LP Switch", "IN2LP:VXRN" },
541 { "IN2L PGA", "IN2LN Switch", "IN2LN" }, 649 { "IN2L PGA", "IN2LN Switch", "IN2LN" },
542 650
543 { "IN2R PGA", "IN2RP Switch", "IN2RP/VXRP" }, 651 { "IN2R PGA", "IN2RP Switch", "IN2RP:VXRP" },
544 { "IN2R PGA", "IN2RN Switch", "IN2RN" }, 652 { "IN2R PGA", "IN2RN Switch", "IN2RN" },
545 653
546 { "Direct Voice", NULL, "IN2LP/VXRN" }, 654 { "Direct Voice", NULL, "IN2LP:VXRN" },
547 { "Direct Voice", NULL, "IN2RP/VXRP" }, 655 { "Direct Voice", NULL, "IN2RP:VXRP" },
548 656
549 { "MIXINL", "IN1L Switch", "IN1L PGA" }, 657 { "MIXINL", "IN1L Switch", "IN1L PGA" },
550 { "MIXINL", "IN2L Switch", "IN2L PGA" }, 658 { "MIXINL", "IN2L Switch", "IN2L PGA" },
@@ -565,7 +673,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
565 { "Left Output Mixer", "Right Input Switch", "MIXINR" }, 673 { "Left Output Mixer", "Right Input Switch", "MIXINR" },
566 { "Left Output Mixer", "IN2RN Switch", "IN2RN" }, 674 { "Left Output Mixer", "IN2RN Switch", "IN2RN" },
567 { "Left Output Mixer", "IN2LN Switch", "IN2LN" }, 675 { "Left Output Mixer", "IN2LN Switch", "IN2LN" },
568 { "Left Output Mixer", "IN2LP Switch", "IN2LP/VXRN" }, 676 { "Left Output Mixer", "IN2LP Switch", "IN2LP:VXRN" },
569 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" }, 677 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" },
570 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" }, 678 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" },
571 679
@@ -573,7 +681,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
573 { "Right Output Mixer", "Right Input Switch", "MIXINR" }, 681 { "Right Output Mixer", "Right Input Switch", "MIXINR" },
574 { "Right Output Mixer", "IN2LN Switch", "IN2LN" }, 682 { "Right Output Mixer", "IN2LN Switch", "IN2LN" },
575 { "Right Output Mixer", "IN2RN Switch", "IN2RN" }, 683 { "Right Output Mixer", "IN2RN Switch", "IN2RN" },
576 { "Right Output Mixer", "IN2RP Switch", "IN2RP/VXRP" }, 684 { "Right Output Mixer", "IN2RP Switch", "IN2RP:VXRP" },
577 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" }, 685 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" },
578 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" }, 686 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" },
579 687
@@ -626,6 +734,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
626 { "Headphone PGA", NULL, "Left Headphone Mux" }, 734 { "Headphone PGA", NULL, "Left Headphone Mux" },
627 { "Headphone PGA", NULL, "Right Headphone Mux" }, 735 { "Headphone PGA", NULL, "Right Headphone Mux" },
628 { "Headphone PGA", NULL, "CLK_SYS" }, 736 { "Headphone PGA", NULL, "CLK_SYS" },
737 { "Headphone PGA", NULL, "Headphone Supply" },
629 738
630 { "HPOUT1L", NULL, "Headphone PGA" }, 739 { "HPOUT1L", NULL, "Headphone PGA" },
631 { "HPOUT1R", NULL, "Headphone PGA" }, 740 { "HPOUT1R", NULL, "Headphone PGA" },
@@ -738,6 +847,47 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
738} 847}
739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes); 848EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
740 849
850int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
851 int lineout1_diff, int lineout2_diff,
852 int lineout1fb, int lineout2fb,
853 int jd_scthr, int jd_thr, int micbias1_lvl,
854 int micbias2_lvl)
855{
856 if (!lineout1_diff)
857 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
858 WM8993_LINEOUT1_MODE,
859 WM8993_LINEOUT1_MODE);
860 if (!lineout2_diff)
861 snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
862 WM8993_LINEOUT2_MODE,
863 WM8993_LINEOUT2_MODE);
864
865 /* If the line outputs are differential then we aren't presenting
866 * VMID as an output and can disable it.
867 */
868 if (lineout1_diff && lineout2_diff)
869 codec->idle_bias_off = 1;
870
871 if (lineout1fb)
872 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
873 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
874
875 if (lineout2fb)
876 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
877 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
878
879 snd_soc_update_bits(codec, WM8993_MICBIAS,
880 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
881 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
882 jd_scthr << WM8993_JD_SCTHR_SHIFT |
883 jd_thr << WM8993_JD_THR_SHIFT |
884 micbias1_lvl |
885 micbias2_lvl << WM8993_MICB2_LVL_SHIFT);
886
887 return 0;
888}
889EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
890
741MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 891MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
742MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 892MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
743MODULE_LICENSE("GPL"); 893MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index ec09cb6a2939..e51c16683589 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -18,7 +18,19 @@ 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 dcs_readback_mode;
25 int hp_startup_mode;
26};
27
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 28extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int); 29extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
30extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
31 int lineout1_diff, int lineout2_diff,
32 int lineout1fb, int lineout2fb,
33 int jd_scthr, int jd_thr,
34 int micbias1_lvl, int micbias2_lvl);
23 35
24#endif 36#endif