aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig44
-rw-r--r--sound/soc/codecs/Makefile26
-rw-r--r--sound/soc/codecs/ad1836.c446
-rw-r--r--sound/soc/codecs/ad1836.h64
-rw-r--r--sound/soc/codecs/ad1938.c682
-rw-r--r--sound/soc/codecs/ad1938.h100
-rw-r--r--sound/soc/codecs/ak4535.c16
-rw-r--r--sound/soc/codecs/cs4270.c27
-rw-r--r--sound/soc/codecs/cx20442.c501
-rw-r--r--sound/soc/codecs/cx20442.h20
-rw-r--r--sound/soc/codecs/max9877.c308
-rw-r--r--sound/soc/codecs/max9877.h37
-rw-r--r--sound/soc/codecs/spdif_transciever.c74
-rw-r--r--sound/soc/codecs/spdif_transciever.h17
-rw-r--r--sound/soc/codecs/ssm2602.c29
-rw-r--r--sound/soc/codecs/stac9766.c463
-rw-r--r--sound/soc/codecs/stac9766.h21
-rw-r--r--sound/soc/codecs/tlv320aic23.c14
-rw-r--r--sound/soc/codecs/tlv320aic3x.c22
-rw-r--r--sound/soc/codecs/twl4030.c358
-rw-r--r--sound/soc/codecs/twl4030.h9
-rw-r--r--sound/soc/codecs/uda134x.c4
-rw-r--r--sound/soc/codecs/uda1380.c313
-rw-r--r--sound/soc/codecs/uda1380.h8
-rw-r--r--sound/soc/codecs/wm8350.c42
-rw-r--r--sound/soc/codecs/wm8400.c30
-rw-r--r--sound/soc/codecs/wm8510.c177
-rw-r--r--sound/soc/codecs/wm8523.c699
-rw-r--r--sound/soc/codecs/wm8523.h160
-rw-r--r--sound/soc/codecs/wm8580.c213
-rw-r--r--sound/soc/codecs/wm8728.c111
-rw-r--r--sound/soc/codecs/wm8731.c218
-rw-r--r--sound/soc/codecs/wm8750.c154
-rw-r--r--sound/soc/codecs/wm8753.c43
-rw-r--r--sound/soc/codecs/wm8776.c744
-rw-r--r--sound/soc/codecs/wm8776.h51
-rw-r--r--sound/soc/codecs/wm8900.c351
-rw-r--r--sound/soc/codecs/wm8903.c271
-rw-r--r--sound/soc/codecs/wm8940.c160
-rw-r--r--sound/soc/codecs/wm8960.c233
-rw-r--r--sound/soc/codecs/wm8961.c1265
-rw-r--r--sound/soc/codecs/wm8961.h866
-rw-r--r--sound/soc/codecs/wm8971.c127
-rw-r--r--sound/soc/codecs/wm8988.c180
-rw-r--r--sound/soc/codecs/wm8990.c196
-rw-r--r--sound/soc/codecs/wm8993.c1534
-rw-r--r--sound/soc/codecs/wm8993.h2132
-rw-r--r--sound/soc/codecs/wm9081.c317
-rw-r--r--sound/soc/codecs/wm9713.c2
-rw-r--r--sound/soc/codecs/wm_hubs.c758
-rw-r--r--sound/soc/codecs/wm_hubs.h24
51 files changed, 12727 insertions, 1934 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 91daffd30e8b..167a5ce06cdf 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -12,13 +12,18 @@ config SND_SOC_ALL_CODECS
12 tristate "Build all ASoC CODEC drivers" 12 tristate "Build all ASoC CODEC drivers"
13 select SND_SOC_L3 13 select SND_SOC_L3
14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
15 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD1938 if SPI_MASTER
15 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
16 select SND_SOC_AD73311 if I2C 18 select SND_SOC_AD73311 if I2C
17 select SND_SOC_AK4104 if SPI_MASTER 19 select SND_SOC_AK4104 if SPI_MASTER
18 select SND_SOC_AK4535 if I2C 20 select SND_SOC_AK4535 if I2C
19 select SND_SOC_CS4270 if I2C 21 select SND_SOC_CS4270 if I2C
22 select SND_SOC_MAX9877 if I2C
20 select SND_SOC_PCM3008 23 select SND_SOC_PCM3008
24 select SND_SOC_SPDIF
21 select SND_SOC_SSM2602 if I2C 25 select SND_SOC_SSM2602 if I2C
26 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
22 select SND_SOC_TLV320AIC23 if I2C 27 select SND_SOC_TLV320AIC23 if I2C
23 select SND_SOC_TLV320AIC26 if SPI_MASTER 28 select SND_SOC_TLV320AIC26 if SPI_MASTER
24 select SND_SOC_TLV320AIC3X if I2C 29 select SND_SOC_TLV320AIC3X if I2C
@@ -28,19 +33,23 @@ config SND_SOC_ALL_CODECS
28 select SND_SOC_WM8350 if MFD_WM8350 33 select SND_SOC_WM8350 if MFD_WM8350
29 select SND_SOC_WM8400 if MFD_WM8400 34 select SND_SOC_WM8400 if MFD_WM8400
30 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 35 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
36 select SND_SOC_WM8523 if I2C
31 select SND_SOC_WM8580 if I2C 37 select SND_SOC_WM8580 if I2C
32 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 38 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
33 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 39 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
34 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 40 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
35 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI 41 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
42 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
36 select SND_SOC_WM8900 if I2C 43 select SND_SOC_WM8900 if I2C
37 select SND_SOC_WM8903 if I2C 44 select SND_SOC_WM8903 if I2C
38 select SND_SOC_WM8940 if I2C 45 select SND_SOC_WM8940 if I2C
39 select SND_SOC_WM8960 if I2C 46 select SND_SOC_WM8960 if I2C
47 select SND_SOC_WM8961 if I2C
40 select SND_SOC_WM8971 if I2C 48 select SND_SOC_WM8971 if I2C
41 select SND_SOC_WM8974 if I2C 49 select SND_SOC_WM8974 if I2C
42 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 50 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
43 select SND_SOC_WM8990 if I2C 51 select SND_SOC_WM8990 if I2C
52 select SND_SOC_WM8993 if I2C
44 select SND_SOC_WM9081 if I2C 53 select SND_SOC_WM9081 if I2C
45 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 54 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
46 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 55 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -56,11 +65,21 @@ config SND_SOC_ALL_CODECS
56 65
57 If unsure select "N". 66 If unsure select "N".
58 67
68config SND_SOC_WM_HUBS
69 tristate
70 default y if SND_SOC_WM8993=y
71 default m if SND_SOC_WM8993=m
59 72
60config SND_SOC_AC97_CODEC 73config SND_SOC_AC97_CODEC
61 tristate 74 tristate
62 select SND_AC97_CODEC 75 select SND_AC97_CODEC
63 76
77config SND_SOC_AD1836
78 tristate
79
80config SND_SOC_AD1938
81 tristate
82
64config SND_SOC_AD1980 83config SND_SOC_AD1980
65 tristate 84 tristate
66 85
@@ -85,15 +104,24 @@ config SND_SOC_CS4270_VD33_ERRATA
85 bool 104 bool
86 depends on SND_SOC_CS4270 105 depends on SND_SOC_CS4270
87 106
107config SND_SOC_CX20442
108 tristate
109
88config SND_SOC_L3 110config SND_SOC_L3
89 tristate 111 tristate
90 112
91config SND_SOC_PCM3008 113config SND_SOC_PCM3008
92 tristate 114 tristate
93 115
116config SND_SOC_SPDIF
117 tristate
118
94config SND_SOC_SSM2602 119config SND_SOC_SSM2602
95 tristate 120 tristate
96 121
122config SND_SOC_STAC9766
123 tristate
124
97config SND_SOC_TLV320AIC23 125config SND_SOC_TLV320AIC23
98 tristate 126 tristate
99 127
@@ -122,6 +150,9 @@ config SND_SOC_WM8400
122config SND_SOC_WM8510 150config SND_SOC_WM8510
123 tristate 151 tristate
124 152
153config SND_SOC_WM8523
154 tristate
155
125config SND_SOC_WM8580 156config SND_SOC_WM8580
126 tristate 157 tristate
127 158
@@ -137,6 +168,9 @@ config SND_SOC_WM8750
137config SND_SOC_WM8753 168config SND_SOC_WM8753
138 tristate 169 tristate
139 170
171config SND_SOC_WM8776
172 tristate
173
140config SND_SOC_WM8900 174config SND_SOC_WM8900
141 tristate 175 tristate
142 176
@@ -149,6 +183,9 @@ config SND_SOC_WM8940
149config SND_SOC_WM8960 183config SND_SOC_WM8960
150 tristate 184 tristate
151 185
186config SND_SOC_WM8961
187 tristate
188
152config SND_SOC_WM8971 189config SND_SOC_WM8971
153 tristate 190 tristate
154 191
@@ -161,6 +198,9 @@ config SND_SOC_WM8988
161config SND_SOC_WM8990 198config SND_SOC_WM8990
162 tristate 199 tristate
163 200
201config SND_SOC_WM8993
202 tristate
203
164config SND_SOC_WM9081 204config SND_SOC_WM9081
165 tristate 205 tristate
166 206
@@ -172,3 +212,7 @@ config SND_SOC_WM9712
172 212
173config SND_SOC_WM9713 213config SND_SOC_WM9713
174 tristate 214 tristate
215
216# Amp
217config SND_SOC_MAX9877
218 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 9c67d66cdb71..fbab43bbe3a7 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,12 +1,17 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad1938-objs := ad1938.o
2snd-soc-ad1980-objs := ad1980.o 4snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o 5snd-soc-ad73311-objs := ad73311.o
4snd-soc-ak4104-objs := ak4104.o 6snd-soc-ak4104-objs := ak4104.o
5snd-soc-ak4535-objs := ak4535.o 7snd-soc-ak4535-objs := ak4535.o
6snd-soc-cs4270-objs := cs4270.o 8snd-soc-cs4270-objs := cs4270.o
9snd-soc-cx20442-objs := cx20442.o
7snd-soc-l3-objs := l3.o 10snd-soc-l3-objs := l3.o
8snd-soc-pcm3008-objs := pcm3008.o 11snd-soc-pcm3008-objs := pcm3008.o
12snd-soc-spdif-objs := spdif_transciever.o
9snd-soc-ssm2602-objs := ssm2602.o 13snd-soc-ssm2602-objs := ssm2602.o
14snd-soc-stac9766-objs := stac9766.o
10snd-soc-tlv320aic23-objs := tlv320aic23.o 15snd-soc-tlv320aic23-objs := tlv320aic23.o
11snd-soc-tlv320aic26-objs := tlv320aic26.o 16snd-soc-tlv320aic26-objs := tlv320aic26.o
12snd-soc-tlv320aic3x-objs := tlv320aic3x.o 17snd-soc-tlv320aic3x-objs := tlv320aic3x.o
@@ -16,33 +21,46 @@ snd-soc-uda1380-objs := uda1380.o
16snd-soc-wm8350-objs := wm8350.o 21snd-soc-wm8350-objs := wm8350.o
17snd-soc-wm8400-objs := wm8400.o 22snd-soc-wm8400-objs := wm8400.o
18snd-soc-wm8510-objs := wm8510.o 23snd-soc-wm8510-objs := wm8510.o
24snd-soc-wm8523-objs := wm8523.o
19snd-soc-wm8580-objs := wm8580.o 25snd-soc-wm8580-objs := wm8580.o
20snd-soc-wm8728-objs := wm8728.o 26snd-soc-wm8728-objs := wm8728.o
21snd-soc-wm8731-objs := wm8731.o 27snd-soc-wm8731-objs := wm8731.o
22snd-soc-wm8750-objs := wm8750.o 28snd-soc-wm8750-objs := wm8750.o
23snd-soc-wm8753-objs := wm8753.o 29snd-soc-wm8753-objs := wm8753.o
30snd-soc-wm8776-objs := wm8776.o
24snd-soc-wm8900-objs := wm8900.o 31snd-soc-wm8900-objs := wm8900.o
25snd-soc-wm8903-objs := wm8903.o 32snd-soc-wm8903-objs := wm8903.o
26snd-soc-wm8940-objs := wm8940.o 33snd-soc-wm8940-objs := wm8940.o
27snd-soc-wm8960-objs := wm8960.o 34snd-soc-wm8960-objs := wm8960.o
35snd-soc-wm8961-objs := wm8961.o
28snd-soc-wm8971-objs := wm8971.o 36snd-soc-wm8971-objs := wm8971.o
29snd-soc-wm8974-objs := wm8974.o 37snd-soc-wm8974-objs := wm8974.o
30snd-soc-wm8988-objs := wm8988.o 38snd-soc-wm8988-objs := wm8988.o
31snd-soc-wm8990-objs := wm8990.o 39snd-soc-wm8990-objs := wm8990.o
40snd-soc-wm8993-objs := wm8993.o
32snd-soc-wm9081-objs := wm9081.o 41snd-soc-wm9081-objs := wm9081.o
33snd-soc-wm9705-objs := wm9705.o 42snd-soc-wm9705-objs := wm9705.o
34snd-soc-wm9712-objs := wm9712.o 43snd-soc-wm9712-objs := wm9712.o
35snd-soc-wm9713-objs := wm9713.o 44snd-soc-wm9713-objs := wm9713.o
45snd-soc-wm-hubs-objs := wm_hubs.o
46
47# Amp
48snd-soc-max9877-objs := max9877.o
36 49
37obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 50obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
51obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
52obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o
38obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 53obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
39obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 54obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
40obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 55obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
41obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 56obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
42obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 57obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
58obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
43obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 59obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
44obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 60obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
61obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
45obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 62obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
63obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
46obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 64obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
47obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 65obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
48obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 66obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
@@ -52,20 +70,28 @@ obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
52obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 70obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
53obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 71obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
54obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 72obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
73obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
55obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 74obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
56obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 75obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
57obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 76obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
58obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 77obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
59obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 78obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
79obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
60obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 80obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
61obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 81obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
62obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 82obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
63obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o 83obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
64obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 84obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
65obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 85obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
86obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
66obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 87obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
67obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 88obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
89obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
68obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 90obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
69obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 91obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
70obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 92obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
71obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o 93obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
94obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
95
96# Amp
97obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
new file mode 100644
index 000000000000..3612bb92df90
--- /dev/null
+++ b/sound/soc/codecs/ad1836.c
@@ -0,0 +1,446 @@
1/*
2 * File: sound/soc/codecs/ad1836.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: Aug 04 2009
6 * Description: Driver for AD1836 sound chip
7 *
8 * Modified:
9 * Copyright 2009 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 */
18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/version.h>
22#include <linux/kernel.h>
23#include <linux/device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/initval.h>
28#include <sound/soc.h>
29#include <sound/tlv.h>
30#include <sound/soc-dapm.h>
31#include <linux/spi/spi.h>
32#include "ad1836.h"
33
34/* codec private data */
35struct ad1836_priv {
36 struct snd_soc_codec codec;
37 u16 reg_cache[AD1836_NUM_REGS];
38};
39
40static struct snd_soc_codec *ad1836_codec;
41struct snd_soc_codec_device soc_codec_dev_ad1836;
42static int ad1836_register(struct ad1836_priv *ad1836);
43static void ad1836_unregister(struct ad1836_priv *ad1836);
44
45/*
46 * AD1836 volume/mute/de-emphasis etc. controls
47 */
48static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"};
49
50static const struct soc_enum ad1836_deemp_enum =
51 SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp);
52
53static const struct snd_kcontrol_new ad1836_snd_controls[] = {
54 /* DAC volume control */
55 SOC_DOUBLE_R("DAC1 Volume", AD1836_DAC_L1_VOL,
56 AD1836_DAC_R1_VOL, 0, 0x3FF, 0),
57 SOC_DOUBLE_R("DAC2 Volume", AD1836_DAC_L2_VOL,
58 AD1836_DAC_R2_VOL, 0, 0x3FF, 0),
59 SOC_DOUBLE_R("DAC3 Volume", AD1836_DAC_L3_VOL,
60 AD1836_DAC_R3_VOL, 0, 0x3FF, 0),
61
62 /* ADC switch control */
63 SOC_DOUBLE("ADC1 Switch", AD1836_ADC_CTRL2, AD1836_ADCL1_MUTE,
64 AD1836_ADCR1_MUTE, 1, 1),
65 SOC_DOUBLE("ADC2 Switch", AD1836_ADC_CTRL2, AD1836_ADCL2_MUTE,
66 AD1836_ADCR2_MUTE, 1, 1),
67
68 /* DAC switch control */
69 SOC_DOUBLE("DAC1 Switch", AD1836_DAC_CTRL2, AD1836_DACL1_MUTE,
70 AD1836_DACR1_MUTE, 1, 1),
71 SOC_DOUBLE("DAC2 Switch", AD1836_DAC_CTRL2, AD1836_DACL2_MUTE,
72 AD1836_DACR2_MUTE, 1, 1),
73 SOC_DOUBLE("DAC3 Switch", AD1836_DAC_CTRL2, AD1836_DACL3_MUTE,
74 AD1836_DACR3_MUTE, 1, 1),
75
76 /* ADC high-pass filter */
77 SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1,
78 AD1836_ADC_HIGHPASS_FILTER, 1, 0),
79
80 /* DAC de-emphasis */
81 SOC_ENUM("Playback Deemphasis", ad1836_deemp_enum),
82};
83
84static const struct snd_soc_dapm_widget ad1836_dapm_widgets[] = {
85 SND_SOC_DAPM_DAC("DAC", "Playback", AD1836_DAC_CTRL1,
86 AD1836_DAC_POWERDOWN, 1),
87 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
88 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1836_ADC_CTRL1,
89 AD1836_ADC_POWERDOWN, 1, NULL, 0),
90 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
91 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
92 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
93 SND_SOC_DAPM_INPUT("ADC1IN"),
94 SND_SOC_DAPM_INPUT("ADC2IN"),
95};
96
97static const struct snd_soc_dapm_route audio_paths[] = {
98 { "DAC", NULL, "ADC_PWR" },
99 { "ADC", NULL, "ADC_PWR" },
100 { "DAC1OUT", "DAC1 Switch", "DAC" },
101 { "DAC2OUT", "DAC2 Switch", "DAC" },
102 { "DAC3OUT", "DAC3 Switch", "DAC" },
103 { "ADC", "ADC1 Switch", "ADC1IN" },
104 { "ADC", "ADC2 Switch", "ADC2IN" },
105};
106
107/*
108 * DAI ops entries
109 */
110
111static int ad1836_set_dai_fmt(struct snd_soc_dai *codec_dai,
112 unsigned int fmt)
113{
114 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
115 /* at present, we support adc aux mode to interface with
116 * blackfin sport tdm mode
117 */
118 case SND_SOC_DAIFMT_DSP_A:
119 break;
120 default:
121 return -EINVAL;
122 }
123
124 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
125 case SND_SOC_DAIFMT_IB_IF:
126 break;
127 default:
128 return -EINVAL;
129 }
130
131 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
132 /* ALCLK,ABCLK are both output, AD1836 can only be master */
133 case SND_SOC_DAIFMT_CBM_CFM:
134 break;
135 default:
136 return -EINVAL;
137 }
138
139 return 0;
140}
141
142static int ad1836_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params,
144 struct snd_soc_dai *dai)
145{
146 int word_len = 0;
147
148 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct snd_soc_device *socdev = rtd->socdev;
150 struct snd_soc_codec *codec = socdev->card->codec;
151
152 /* bit size */
153 switch (params_format(params)) {
154 case SNDRV_PCM_FORMAT_S16_LE:
155 word_len = 3;
156 break;
157 case SNDRV_PCM_FORMAT_S20_3LE:
158 word_len = 1;
159 break;
160 case SNDRV_PCM_FORMAT_S24_LE:
161 case SNDRV_PCM_FORMAT_S32_LE:
162 word_len = 0;
163 break;
164 }
165
166 snd_soc_update_bits(codec, AD1836_DAC_CTRL1,
167 AD1836_DAC_WORD_LEN_MASK, word_len);
168
169 snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
170 AD1836_ADC_WORD_LEN_MASK, word_len);
171
172 return 0;
173}
174
175
176/*
177 * interface to read/write ad1836 register
178 */
179#define AD1836_SPI_REG_SHFT 12
180#define AD1836_SPI_READ (1 << 11)
181#define AD1836_SPI_VAL_MSK 0x3FF
182
183/*
184 * write to the ad1836 register space
185 */
186
187static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg,
188 unsigned int value)
189{
190 u16 *reg_cache = codec->reg_cache;
191 int ret = 0;
192
193 if (value != reg_cache[reg]) {
194 unsigned short buf;
195 struct spi_transfer t = {
196 .tx_buf = &buf,
197 .len = 2,
198 };
199 struct spi_message m;
200
201 buf = (reg << AD1836_SPI_REG_SHFT) |
202 (value & AD1836_SPI_VAL_MSK);
203 spi_message_init(&m);
204 spi_message_add_tail(&t, &m);
205 ret = spi_sync(codec->control_data, &m);
206 if (ret == 0)
207 reg_cache[reg] = value;
208 }
209
210 return ret;
211}
212
213/*
214 * read from the ad1836 register space cache
215 */
216static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec,
217 unsigned int reg)
218{
219 u16 *reg_cache = codec->reg_cache;
220
221 if (reg >= codec->reg_cache_size)
222 return -EINVAL;
223
224 return reg_cache[reg];
225}
226
227static int __devinit ad1836_spi_probe(struct spi_device *spi)
228{
229 struct snd_soc_codec *codec;
230 struct ad1836_priv *ad1836;
231
232 ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
233 if (ad1836 == NULL)
234 return -ENOMEM;
235
236 codec = &ad1836->codec;
237 codec->control_data = spi;
238 codec->dev = &spi->dev;
239
240 dev_set_drvdata(&spi->dev, ad1836);
241
242 return ad1836_register(ad1836);
243}
244
245static int __devexit ad1836_spi_remove(struct spi_device *spi)
246{
247 struct ad1836_priv *ad1836 = dev_get_drvdata(&spi->dev);
248
249 ad1836_unregister(ad1836);
250 return 0;
251}
252
253static struct spi_driver ad1836_spi_driver = {
254 .driver = {
255 .name = "ad1836-spi",
256 .bus = &spi_bus_type,
257 .owner = THIS_MODULE,
258 },
259 .probe = ad1836_spi_probe,
260 .remove = __devexit_p(ad1836_spi_remove),
261};
262
263static struct snd_soc_dai_ops ad1836_dai_ops = {
264 .hw_params = ad1836_hw_params,
265 .set_fmt = ad1836_set_dai_fmt,
266};
267
268/* codec DAI instance */
269struct snd_soc_dai ad1836_dai = {
270 .name = "AD1836",
271 .playback = {
272 .stream_name = "Playback",
273 .channels_min = 2,
274 .channels_max = 6,
275 .rates = SNDRV_PCM_RATE_48000,
276 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
277 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
278 },
279 .capture = {
280 .stream_name = "Capture",
281 .channels_min = 2,
282 .channels_max = 4,
283 .rates = SNDRV_PCM_RATE_48000,
284 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
285 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
286 },
287 .ops = &ad1836_dai_ops,
288};
289EXPORT_SYMBOL_GPL(ad1836_dai);
290
291static int ad1836_register(struct ad1836_priv *ad1836)
292{
293 int ret;
294 struct snd_soc_codec *codec = &ad1836->codec;
295
296 if (ad1836_codec) {
297 dev_err(codec->dev, "Another ad1836 is registered\n");
298 return -EINVAL;
299 }
300
301 mutex_init(&codec->mutex);
302 INIT_LIST_HEAD(&codec->dapm_widgets);
303 INIT_LIST_HEAD(&codec->dapm_paths);
304 codec->private_data = ad1836;
305 codec->reg_cache = ad1836->reg_cache;
306 codec->reg_cache_size = AD1836_NUM_REGS;
307 codec->name = "AD1836";
308 codec->owner = THIS_MODULE;
309 codec->dai = &ad1836_dai;
310 codec->num_dai = 1;
311 codec->write = ad1836_write_reg;
312 codec->read = ad1836_read_reg_cache;
313 INIT_LIST_HEAD(&codec->dapm_widgets);
314 INIT_LIST_HEAD(&codec->dapm_paths);
315
316 ad1836_dai.dev = codec->dev;
317 ad1836_codec = codec;
318
319 /* default setting for ad1836 */
320 /* de-emphasis: 48kHz, power-on dac */
321 codec->write(codec, AD1836_DAC_CTRL1, 0x300);
322 /* unmute dac channels */
323 codec->write(codec, AD1836_DAC_CTRL2, 0x0);
324 /* high-pass filter enable, power-on adc */
325 codec->write(codec, AD1836_ADC_CTRL1, 0x100);
326 /* unmute adc channles, adc aux mode */
327 codec->write(codec, AD1836_ADC_CTRL2, 0x180);
328 /* left/right diff:PGA/MUX */
329 codec->write(codec, AD1836_ADC_CTRL3, 0x3A);
330 /* volume */
331 codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF);
332 codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF);
333 codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF);
334 codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF);
335 codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF);
336 codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF);
337
338 ret = snd_soc_register_codec(codec);
339 if (ret != 0) {
340 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
341 kfree(ad1836);
342 return ret;
343 }
344
345 ret = snd_soc_register_dai(&ad1836_dai);
346 if (ret != 0) {
347 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
348 snd_soc_unregister_codec(codec);
349 kfree(ad1836);
350 return ret;
351 }
352
353 return 0;
354}
355
356static void ad1836_unregister(struct ad1836_priv *ad1836)
357{
358 snd_soc_unregister_dai(&ad1836_dai);
359 snd_soc_unregister_codec(&ad1836->codec);
360 kfree(ad1836);
361 ad1836_codec = NULL;
362}
363
364static int ad1836_probe(struct platform_device *pdev)
365{
366 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
367 struct snd_soc_codec *codec;
368 int ret = 0;
369
370 if (ad1836_codec == NULL) {
371 dev_err(&pdev->dev, "Codec device not registered\n");
372 return -ENODEV;
373 }
374
375 socdev->card->codec = ad1836_codec;
376 codec = ad1836_codec;
377
378 /* register pcms */
379 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
380 if (ret < 0) {
381 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
382 goto pcm_err;
383 }
384
385 snd_soc_add_controls(codec, ad1836_snd_controls,
386 ARRAY_SIZE(ad1836_snd_controls));
387 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
388 ARRAY_SIZE(ad1836_dapm_widgets));
389 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
390 snd_soc_dapm_new_widgets(codec);
391
392 ret = snd_soc_init_card(socdev);
393 if (ret < 0) {
394 dev_err(codec->dev, "failed to register card: %d\n", ret);
395 goto card_err;
396 }
397
398 return ret;
399
400card_err:
401 snd_soc_free_pcms(socdev);
402 snd_soc_dapm_free(socdev);
403pcm_err:
404 return ret;
405}
406
407/* power down chip */
408static int ad1836_remove(struct platform_device *pdev)
409{
410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
411
412 snd_soc_free_pcms(socdev);
413 snd_soc_dapm_free(socdev);
414
415 return 0;
416}
417
418struct snd_soc_codec_device soc_codec_dev_ad1836 = {
419 .probe = ad1836_probe,
420 .remove = ad1836_remove,
421};
422EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
423
424static int __init ad1836_init(void)
425{
426 int ret;
427
428 ret = spi_register_driver(&ad1836_spi_driver);
429 if (ret != 0) {
430 printk(KERN_ERR "Failed to register ad1836 SPI driver: %d\n",
431 ret);
432 }
433
434 return ret;
435}
436module_init(ad1836_init);
437
438static void __exit ad1836_exit(void)
439{
440 spi_unregister_driver(&ad1836_spi_driver);
441}
442module_exit(ad1836_exit);
443
444MODULE_DESCRIPTION("ASoC ad1836 driver");
445MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
446MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
new file mode 100644
index 000000000000..7660ee6973c0
--- /dev/null
+++ b/sound/soc/codecs/ad1836.h
@@ -0,0 +1,64 @@
1/*
2 * File: sound/soc/codecs/ad1836.h
3 * Based on:
4 * Author: Barry Song <Barry.Song@analog.com>
5 *
6 * Created: Aug 04, 2009
7 * Description: definitions for AD1836 registers
8 *
9 * Modified:
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 */
18
19#ifndef __AD1836_H__
20#define __AD1836_H__
21
22#define AD1836_DAC_CTRL1 0
23#define AD1836_DAC_POWERDOWN 2
24#define AD1836_DAC_SERFMT_MASK 0xE0
25#define AD1836_DAC_SERFMT_PCK256 (0x4 << 5)
26#define AD1836_DAC_SERFMT_PCK128 (0x5 << 5)
27#define AD1836_DAC_WORD_LEN_MASK 0x18
28
29#define AD1836_DAC_CTRL2 1
30#define AD1836_DACL1_MUTE 0
31#define AD1836_DACR1_MUTE 1
32#define AD1836_DACL2_MUTE 2
33#define AD1836_DACR2_MUTE 3
34#define AD1836_DACL3_MUTE 4
35#define AD1836_DACR3_MUTE 5
36
37#define AD1836_DAC_L1_VOL 2
38#define AD1836_DAC_R1_VOL 3
39#define AD1836_DAC_L2_VOL 4
40#define AD1836_DAC_R2_VOL 5
41#define AD1836_DAC_L3_VOL 6
42#define AD1836_DAC_R3_VOL 7
43
44#define AD1836_ADC_CTRL1 12
45#define AD1836_ADC_POWERDOWN 7
46#define AD1836_ADC_HIGHPASS_FILTER 8
47
48#define AD1836_ADC_CTRL2 13
49#define AD1836_ADCL1_MUTE 0
50#define AD1836_ADCR1_MUTE 1
51#define AD1836_ADCL2_MUTE 2
52#define AD1836_ADCR2_MUTE 3
53#define AD1836_ADC_WORD_LEN_MASK 0x30
54#define AD1836_ADC_SERFMT_MASK (7 << 6)
55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
57
58#define AD1836_ADC_CTRL3 14
59
60#define AD1836_NUM_REGS 16
61
62extern struct snd_soc_dai ad1836_dai;
63extern struct snd_soc_codec_device soc_codec_dev_ad1836;
64#endif
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
new file mode 100644
index 000000000000..e62b27701a49
--- /dev/null
+++ b/sound/soc/codecs/ad1938.c
@@ -0,0 +1,682 @@
1/*
2 * File: sound/soc/codecs/ad1938.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: June 04 2009
6 * Description: Driver for AD1938 sound chip
7 *
8 * Modified:
9 * Copyright 2009 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/version.h>
32#include <linux/kernel.h>
33#include <linux/device.h>
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/initval.h>
38#include <sound/soc.h>
39#include <sound/tlv.h>
40#include <sound/soc-dapm.h>
41#include <linux/spi/spi.h>
42#include "ad1938.h"
43
44/* codec private data */
45struct ad1938_priv {
46 struct snd_soc_codec codec;
47 u8 reg_cache[AD1938_NUM_REGS];
48};
49
50static struct snd_soc_codec *ad1938_codec;
51struct snd_soc_codec_device soc_codec_dev_ad1938;
52static int ad1938_register(struct ad1938_priv *ad1938);
53static void ad1938_unregister(struct ad1938_priv *ad1938);
54
55/*
56 * AD1938 volume/mute/de-emphasis etc. controls
57 */
58static const char *ad1938_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
59
60static const struct soc_enum ad1938_deemp_enum =
61 SOC_ENUM_SINGLE(AD1938_DAC_CTRL2, 1, 4, ad1938_deemp);
62
63static const struct snd_kcontrol_new ad1938_snd_controls[] = {
64 /* DAC volume control */
65 SOC_DOUBLE_R("DAC1 Volume", AD1938_DAC_L1_VOL,
66 AD1938_DAC_R1_VOL, 0, 0xFF, 1),
67 SOC_DOUBLE_R("DAC2 Volume", AD1938_DAC_L2_VOL,
68 AD1938_DAC_R2_VOL, 0, 0xFF, 1),
69 SOC_DOUBLE_R("DAC3 Volume", AD1938_DAC_L3_VOL,
70 AD1938_DAC_R3_VOL, 0, 0xFF, 1),
71 SOC_DOUBLE_R("DAC4 Volume", AD1938_DAC_L4_VOL,
72 AD1938_DAC_R4_VOL, 0, 0xFF, 1),
73
74 /* ADC switch control */
75 SOC_DOUBLE("ADC1 Switch", AD1938_ADC_CTRL0, AD1938_ADCL1_MUTE,
76 AD1938_ADCR1_MUTE, 1, 1),
77 SOC_DOUBLE("ADC2 Switch", AD1938_ADC_CTRL0, AD1938_ADCL2_MUTE,
78 AD1938_ADCR2_MUTE, 1, 1),
79
80 /* DAC switch control */
81 SOC_DOUBLE("DAC1 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL1_MUTE,
82 AD1938_DACR1_MUTE, 1, 1),
83 SOC_DOUBLE("DAC2 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL2_MUTE,
84 AD1938_DACR2_MUTE, 1, 1),
85 SOC_DOUBLE("DAC3 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL3_MUTE,
86 AD1938_DACR3_MUTE, 1, 1),
87 SOC_DOUBLE("DAC4 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL4_MUTE,
88 AD1938_DACR4_MUTE, 1, 1),
89
90 /* ADC high-pass filter */
91 SOC_SINGLE("ADC High Pass Filter Switch", AD1938_ADC_CTRL0,
92 AD1938_ADC_HIGHPASS_FILTER, 1, 0),
93
94 /* DAC de-emphasis */
95 SOC_ENUM("Playback Deemphasis", ad1938_deemp_enum),
96};
97
98static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
99 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
100 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
101 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
102 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
103 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
104 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
105 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
106 SND_SOC_DAPM_INPUT("ADC1IN"),
107 SND_SOC_DAPM_INPUT("ADC2IN"),
108};
109
110static const struct snd_soc_dapm_route audio_paths[] = {
111 { "DAC", NULL, "ADC_PWR" },
112 { "ADC", NULL, "ADC_PWR" },
113 { "DAC1OUT", "DAC1 Switch", "DAC" },
114 { "DAC2OUT", "DAC2 Switch", "DAC" },
115 { "DAC3OUT", "DAC3 Switch", "DAC" },
116 { "DAC4OUT", "DAC4 Switch", "DAC" },
117 { "ADC", "ADC1 Switch", "ADC1IN" },
118 { "ADC", "ADC2 Switch", "ADC2IN" },
119};
120
121/*
122 * DAI ops entries
123 */
124
125static int ad1938_mute(struct snd_soc_dai *dai, int mute)
126{
127 struct snd_soc_codec *codec = dai->codec;
128 int reg;
129
130 reg = codec->read(codec, AD1938_DAC_CTRL2);
131 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
132 (~AD1938_DAC_MASTER_MUTE);
133 codec->write(codec, AD1938_DAC_CTRL2, reg);
134
135 return 0;
136}
137
138static inline int ad1938_pll_powerctrl(struct snd_soc_codec *codec, int cmd)
139{
140 int reg = codec->read(codec, AD1938_PLL_CLK_CTRL0);
141 reg = (cmd > 0) ? reg & (~AD1938_PLL_POWERDOWN) : reg |
142 AD1938_PLL_POWERDOWN;
143 codec->write(codec, AD1938_PLL_CLK_CTRL0, reg);
144
145 return 0;
146}
147
148static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
149 unsigned int mask, int slots, int width)
150{
151 struct snd_soc_codec *codec = dai->codec;
152 int dac_reg = codec->read(codec, AD1938_DAC_CTRL1);
153 int adc_reg = codec->read(codec, AD1938_ADC_CTRL2);
154
155 dac_reg &= ~AD1938_DAC_CHAN_MASK;
156 adc_reg &= ~AD1938_ADC_CHAN_MASK;
157
158 switch (slots) {
159 case 2:
160 dac_reg |= AD1938_DAC_2_CHANNELS << AD1938_DAC_CHAN_SHFT;
161 adc_reg |= AD1938_ADC_2_CHANNELS << AD1938_ADC_CHAN_SHFT;
162 break;
163 case 4:
164 dac_reg |= AD1938_DAC_4_CHANNELS << AD1938_DAC_CHAN_SHFT;
165 adc_reg |= AD1938_ADC_4_CHANNELS << AD1938_ADC_CHAN_SHFT;
166 break;
167 case 8:
168 dac_reg |= AD1938_DAC_8_CHANNELS << AD1938_DAC_CHAN_SHFT;
169 adc_reg |= AD1938_ADC_8_CHANNELS << AD1938_ADC_CHAN_SHFT;
170 break;
171 case 16:
172 dac_reg |= AD1938_DAC_16_CHANNELS << AD1938_DAC_CHAN_SHFT;
173 adc_reg |= AD1938_ADC_16_CHANNELS << AD1938_ADC_CHAN_SHFT;
174 break;
175 default:
176 return -EINVAL;
177 }
178
179 codec->write(codec, AD1938_DAC_CTRL1, dac_reg);
180 codec->write(codec, AD1938_ADC_CTRL2, adc_reg);
181
182 return 0;
183}
184
185static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
186 unsigned int fmt)
187{
188 struct snd_soc_codec *codec = codec_dai->codec;
189 int adc_reg, dac_reg;
190
191 adc_reg = codec->read(codec, AD1938_ADC_CTRL2);
192 dac_reg = codec->read(codec, AD1938_DAC_CTRL1);
193
194 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
195 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
196 */
197 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
198 case SND_SOC_DAIFMT_I2S:
199 adc_reg &= ~AD1938_ADC_SERFMT_MASK;
200 adc_reg |= AD1938_ADC_SERFMT_TDM;
201 break;
202 case SND_SOC_DAIFMT_DSP_A:
203 adc_reg &= ~AD1938_ADC_SERFMT_MASK;
204 adc_reg |= AD1938_ADC_SERFMT_AUX;
205 break;
206 default:
207 return -EINVAL;
208 }
209
210 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
211 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
212 adc_reg &= ~AD1938_ADC_LEFT_HIGH;
213 adc_reg &= ~AD1938_ADC_BCLK_INV;
214 dac_reg &= ~AD1938_DAC_LEFT_HIGH;
215 dac_reg &= ~AD1938_DAC_BCLK_INV;
216 break;
217 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
218 adc_reg |= AD1938_ADC_LEFT_HIGH;
219 adc_reg &= ~AD1938_ADC_BCLK_INV;
220 dac_reg |= AD1938_DAC_LEFT_HIGH;
221 dac_reg &= ~AD1938_DAC_BCLK_INV;
222 break;
223 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
224 adc_reg &= ~AD1938_ADC_LEFT_HIGH;
225 adc_reg |= AD1938_ADC_BCLK_INV;
226 dac_reg &= ~AD1938_DAC_LEFT_HIGH;
227 dac_reg |= AD1938_DAC_BCLK_INV;
228 break;
229
230 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
231 adc_reg |= AD1938_ADC_LEFT_HIGH;
232 adc_reg |= AD1938_ADC_BCLK_INV;
233 dac_reg |= AD1938_DAC_LEFT_HIGH;
234 dac_reg |= AD1938_DAC_BCLK_INV;
235 break;
236 default:
237 return -EINVAL;
238 }
239
240 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
241 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
242 adc_reg |= AD1938_ADC_LCR_MASTER;
243 adc_reg |= AD1938_ADC_BCLK_MASTER;
244 dac_reg |= AD1938_DAC_LCR_MASTER;
245 dac_reg |= AD1938_DAC_BCLK_MASTER;
246 break;
247 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
248 adc_reg |= AD1938_ADC_LCR_MASTER;
249 adc_reg &= ~AD1938_ADC_BCLK_MASTER;
250 dac_reg |= AD1938_DAC_LCR_MASTER;
251 dac_reg &= ~AD1938_DAC_BCLK_MASTER;
252 break;
253 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
254 adc_reg &= ~AD1938_ADC_LCR_MASTER;
255 adc_reg |= AD1938_ADC_BCLK_MASTER;
256 dac_reg &= ~AD1938_DAC_LCR_MASTER;
257 dac_reg |= AD1938_DAC_BCLK_MASTER;
258 break;
259 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
260 adc_reg &= ~AD1938_ADC_LCR_MASTER;
261 adc_reg &= ~AD1938_ADC_BCLK_MASTER;
262 dac_reg &= ~AD1938_DAC_LCR_MASTER;
263 dac_reg &= ~AD1938_DAC_BCLK_MASTER;
264 break;
265 default:
266 return -EINVAL;
267 }
268
269 codec->write(codec, AD1938_ADC_CTRL2, adc_reg);
270 codec->write(codec, AD1938_DAC_CTRL1, dac_reg);
271
272 return 0;
273}
274
275static int ad1938_hw_params(struct snd_pcm_substream *substream,
276 struct snd_pcm_hw_params *params,
277 struct snd_soc_dai *dai)
278{
279 int word_len = 0, reg = 0;
280
281 struct snd_soc_pcm_runtime *rtd = substream->private_data;
282 struct snd_soc_device *socdev = rtd->socdev;
283 struct snd_soc_codec *codec = socdev->card->codec;
284
285 /* bit size */
286 switch (params_format(params)) {
287 case SNDRV_PCM_FORMAT_S16_LE:
288 word_len = 3;
289 break;
290 case SNDRV_PCM_FORMAT_S20_3LE:
291 word_len = 1;
292 break;
293 case SNDRV_PCM_FORMAT_S24_LE:
294 case SNDRV_PCM_FORMAT_S32_LE:
295 word_len = 0;
296 break;
297 }
298
299 reg = codec->read(codec, AD1938_DAC_CTRL2);
300 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
301 codec->write(codec, AD1938_DAC_CTRL2, reg);
302
303 reg = codec->read(codec, AD1938_ADC_CTRL1);
304 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
305 codec->write(codec, AD1938_ADC_CTRL1, reg);
306
307 return 0;
308}
309
310static int ad1938_set_bias_level(struct snd_soc_codec *codec,
311 enum snd_soc_bias_level level)
312{
313 switch (level) {
314 case SND_SOC_BIAS_ON:
315 ad1938_pll_powerctrl(codec, 1);
316 break;
317 case SND_SOC_BIAS_PREPARE:
318 break;
319 case SND_SOC_BIAS_STANDBY:
320 case SND_SOC_BIAS_OFF:
321 ad1938_pll_powerctrl(codec, 0);
322 break;
323 }
324 codec->bias_level = level;
325 return 0;
326}
327
328/*
329 * interface to read/write ad1938 register
330 */
331
332#define AD1938_SPI_ADDR 0x4
333#define AD1938_SPI_READ 0x1
334#define AD1938_SPI_BUFLEN 3
335
336/*
337 * write to the ad1938 register space
338 */
339
340static int ad1938_write_reg(struct snd_soc_codec *codec, unsigned int reg,
341 unsigned int value)
342{
343 u8 *reg_cache = codec->reg_cache;
344 int ret = 0;
345
346 if (value != reg_cache[reg]) {
347 uint8_t buf[AD1938_SPI_BUFLEN];
348 struct spi_transfer t = {
349 .tx_buf = buf,
350 .len = AD1938_SPI_BUFLEN,
351 };
352 struct spi_message m;
353
354 buf[0] = AD1938_SPI_ADDR << 1;
355 buf[1] = reg;
356 buf[2] = value;
357 spi_message_init(&m);
358 spi_message_add_tail(&t, &m);
359 ret = spi_sync(codec->control_data, &m);
360 if (ret == 0)
361 reg_cache[reg] = value;
362 }
363
364 return ret;
365}
366
367/*
368 * read from the ad1938 register space cache
369 */
370
371static unsigned int ad1938_read_reg_cache(struct snd_soc_codec *codec,
372 unsigned int reg)
373{
374 u8 *reg_cache = codec->reg_cache;
375
376 if (reg >= codec->reg_cache_size)
377 return -EINVAL;
378
379 return reg_cache[reg];
380}
381
382/*
383 * read from the ad1938 register space
384 */
385
386static unsigned int ad1938_read_reg(struct snd_soc_codec *codec,
387 unsigned int reg)
388{
389 char w_buf[AD1938_SPI_BUFLEN];
390 char r_buf[AD1938_SPI_BUFLEN];
391 int ret;
392
393 struct spi_transfer t = {
394 .tx_buf = w_buf,
395 .rx_buf = r_buf,
396 .len = AD1938_SPI_BUFLEN,
397 };
398 struct spi_message m;
399
400 w_buf[0] = (AD1938_SPI_ADDR << 1) | AD1938_SPI_READ;
401 w_buf[1] = reg;
402 w_buf[2] = 0;
403
404 spi_message_init(&m);
405 spi_message_add_tail(&t, &m);
406 ret = spi_sync(codec->control_data, &m);
407 if (ret == 0)
408 return r_buf[2];
409 else
410 return -EIO;
411}
412
413static int ad1938_fill_cache(struct snd_soc_codec *codec)
414{
415 int i;
416 u8 *reg_cache = codec->reg_cache;
417 struct spi_device *spi = codec->control_data;
418
419 for (i = 0; i < codec->reg_cache_size; i++) {
420 int ret = ad1938_read_reg(codec, i);
421 if (ret == -EIO) {
422 dev_err(&spi->dev, "AD1938 SPI read failure\n");
423 return ret;
424 }
425 reg_cache[i] = ret;
426 }
427
428 return 0;
429}
430
431static int __devinit ad1938_spi_probe(struct spi_device *spi)
432{
433 struct snd_soc_codec *codec;
434 struct ad1938_priv *ad1938;
435
436 ad1938 = kzalloc(sizeof(struct ad1938_priv), GFP_KERNEL);
437 if (ad1938 == NULL)
438 return -ENOMEM;
439
440 codec = &ad1938->codec;
441 codec->control_data = spi;
442 codec->dev = &spi->dev;
443
444 dev_set_drvdata(&spi->dev, ad1938);
445
446 return ad1938_register(ad1938);
447}
448
449static int __devexit ad1938_spi_remove(struct spi_device *spi)
450{
451 struct ad1938_priv *ad1938 = dev_get_drvdata(&spi->dev);
452
453 ad1938_unregister(ad1938);
454 return 0;
455}
456
457static struct spi_driver ad1938_spi_driver = {
458 .driver = {
459 .name = "ad1938",
460 .bus = &spi_bus_type,
461 .owner = THIS_MODULE,
462 },
463 .probe = ad1938_spi_probe,
464 .remove = __devexit_p(ad1938_spi_remove),
465};
466
467static struct snd_soc_dai_ops ad1938_dai_ops = {
468 .hw_params = ad1938_hw_params,
469 .digital_mute = ad1938_mute,
470 .set_tdm_slot = ad1938_set_tdm_slot,
471 .set_fmt = ad1938_set_dai_fmt,
472};
473
474/* codec DAI instance */
475struct snd_soc_dai ad1938_dai = {
476 .name = "AD1938",
477 .playback = {
478 .stream_name = "Playback",
479 .channels_min = 2,
480 .channels_max = 8,
481 .rates = SNDRV_PCM_RATE_48000,
482 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
483 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
484 },
485 .capture = {
486 .stream_name = "Capture",
487 .channels_min = 2,
488 .channels_max = 4,
489 .rates = SNDRV_PCM_RATE_48000,
490 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
491 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
492 },
493 .ops = &ad1938_dai_ops,
494};
495EXPORT_SYMBOL_GPL(ad1938_dai);
496
497static int ad1938_register(struct ad1938_priv *ad1938)
498{
499 int ret;
500 struct snd_soc_codec *codec = &ad1938->codec;
501
502 if (ad1938_codec) {
503 dev_err(codec->dev, "Another ad1938 is registered\n");
504 return -EINVAL;
505 }
506
507 mutex_init(&codec->mutex);
508 INIT_LIST_HEAD(&codec->dapm_widgets);
509 INIT_LIST_HEAD(&codec->dapm_paths);
510 codec->private_data = ad1938;
511 codec->reg_cache = ad1938->reg_cache;
512 codec->reg_cache_size = AD1938_NUM_REGS;
513 codec->name = "AD1938";
514 codec->owner = THIS_MODULE;
515 codec->dai = &ad1938_dai;
516 codec->num_dai = 1;
517 codec->write = ad1938_write_reg;
518 codec->read = ad1938_read_reg_cache;
519 INIT_LIST_HEAD(&codec->dapm_widgets);
520 INIT_LIST_HEAD(&codec->dapm_paths);
521
522 ad1938_dai.dev = codec->dev;
523 ad1938_codec = codec;
524
525 /* default setting for ad1938 */
526
527 /* unmute dac channels */
528 codec->write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
529 /* de-emphasis: 48kHz, powedown dac */
530 codec->write(codec, AD1938_DAC_CTRL2, 0x1A);
531 /* powerdown dac, dac in tdm mode */
532 codec->write(codec, AD1938_DAC_CTRL0, 0x41);
533 /* high-pass filter enable */
534 codec->write(codec, AD1938_ADC_CTRL0, 0x3);
535 /* sata delay=1, adc aux mode */
536 codec->write(codec, AD1938_ADC_CTRL1, 0x43);
537 /* pll input: mclki/xi */
538 codec->write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
539 codec->write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
540
541 ad1938_fill_cache(codec);
542
543 ret = snd_soc_register_codec(codec);
544 if (ret != 0) {
545 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
546 kfree(ad1938);
547 return ret;
548 }
549
550 ret = snd_soc_register_dai(&ad1938_dai);
551 if (ret != 0) {
552 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
553 snd_soc_unregister_codec(codec);
554 kfree(ad1938);
555 return ret;
556 }
557
558 return 0;
559}
560
561static void ad1938_unregister(struct ad1938_priv *ad1938)
562{
563 ad1938_set_bias_level(&ad1938->codec, SND_SOC_BIAS_OFF);
564 snd_soc_unregister_dai(&ad1938_dai);
565 snd_soc_unregister_codec(&ad1938->codec);
566 kfree(ad1938);
567 ad1938_codec = NULL;
568}
569
570static int ad1938_probe(struct platform_device *pdev)
571{
572 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
573 struct snd_soc_codec *codec;
574 int ret = 0;
575
576 if (ad1938_codec == NULL) {
577 dev_err(&pdev->dev, "Codec device not registered\n");
578 return -ENODEV;
579 }
580
581 socdev->card->codec = ad1938_codec;
582 codec = ad1938_codec;
583
584 /* register pcms */
585 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
586 if (ret < 0) {
587 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
588 goto pcm_err;
589 }
590
591 snd_soc_add_controls(codec, ad1938_snd_controls,
592 ARRAY_SIZE(ad1938_snd_controls));
593 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets,
594 ARRAY_SIZE(ad1938_dapm_widgets));
595 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
596 snd_soc_dapm_new_widgets(codec);
597
598 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
599
600 ret = snd_soc_init_card(socdev);
601 if (ret < 0) {
602 dev_err(codec->dev, "failed to register card: %d\n", ret);
603 goto card_err;
604 }
605
606 return ret;
607
608card_err:
609 snd_soc_free_pcms(socdev);
610 snd_soc_dapm_free(socdev);
611pcm_err:
612 return ret;
613}
614
615/* power down chip */
616static int ad1938_remove(struct platform_device *pdev)
617{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
619
620 snd_soc_free_pcms(socdev);
621 snd_soc_dapm_free(socdev);
622
623 return 0;
624}
625
626#ifdef CONFIG_PM
627static int ad1938_suspend(struct platform_device *pdev,
628 pm_message_t state)
629{
630 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
631 struct snd_soc_codec *codec = socdev->card->codec;
632
633 ad1938_set_bias_level(codec, SND_SOC_BIAS_OFF);
634 return 0;
635}
636
637static int ad1938_resume(struct platform_device *pdev)
638{
639 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
640 struct snd_soc_codec *codec = socdev->card->codec;
641
642 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
643 ad1938_set_bias_level(codec, SND_SOC_BIAS_ON);
644
645 return 0;
646}
647#else
648#define ad1938_suspend NULL
649#define ad1938_resume NULL
650#endif
651
652struct snd_soc_codec_device soc_codec_dev_ad1938 = {
653 .probe = ad1938_probe,
654 .remove = ad1938_remove,
655 .suspend = ad1938_suspend,
656 .resume = ad1938_resume,
657};
658EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
659
660static int __init ad1938_init(void)
661{
662 int ret;
663
664 ret = spi_register_driver(&ad1938_spi_driver);
665 if (ret != 0) {
666 printk(KERN_ERR "Failed to register ad1938 SPI driver: %d\n",
667 ret);
668 }
669
670 return ret;
671}
672module_init(ad1938_init);
673
674static void __exit ad1938_exit(void)
675{
676 spi_unregister_driver(&ad1938_spi_driver);
677}
678module_exit(ad1938_exit);
679
680MODULE_DESCRIPTION("ASoC ad1938 driver");
681MODULE_AUTHOR("Barry Song ");
682MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1938.h b/sound/soc/codecs/ad1938.h
new file mode 100644
index 000000000000..fe3c48cd2d5b
--- /dev/null
+++ b/sound/soc/codecs/ad1938.h
@@ -0,0 +1,100 @@
1/*
2 * File: sound/soc/codecs/ad1836.h
3 * Based on:
4 * Author: Barry Song <Barry.Song@analog.com>
5 *
6 * Created: May 25, 2009
7 * Description: definitions for AD1938 registers
8 *
9 * Modified:
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#ifndef __AD1938_H__
30#define __AD1938_H__
31
32#define AD1938_PLL_CLK_CTRL0 0
33#define AD1938_PLL_POWERDOWN 0x01
34#define AD1938_PLL_CLK_CTRL1 1
35#define AD1938_DAC_CTRL0 2
36#define AD1938_DAC_POWERDOWN 0x01
37#define AD1938_DAC_SERFMT_MASK 0xC0
38#define AD1938_DAC_SERFMT_STEREO (0 << 6)
39#define AD1938_DAC_SERFMT_TDM (1 << 6)
40#define AD1938_DAC_CTRL1 3
41#define AD1938_DAC_2_CHANNELS 0
42#define AD1938_DAC_4_CHANNELS 1
43#define AD1938_DAC_8_CHANNELS 2
44#define AD1938_DAC_16_CHANNELS 3
45#define AD1938_DAC_CHAN_SHFT 1
46#define AD1938_DAC_CHAN_MASK (3 << AD1938_DAC_CHAN_SHFT)
47#define AD1938_DAC_LCR_MASTER (1 << 4)
48#define AD1938_DAC_BCLK_MASTER (1 << 5)
49#define AD1938_DAC_LEFT_HIGH (1 << 3)
50#define AD1938_DAC_BCLK_INV (1 << 7)
51#define AD1938_DAC_CTRL2 4
52#define AD1938_DAC_WORD_LEN_MASK 0xC
53#define AD1938_DAC_MASTER_MUTE 1
54#define AD1938_DAC_CHNL_MUTE 5
55#define AD1938_DACL1_MUTE 0
56#define AD1938_DACR1_MUTE 1
57#define AD1938_DACL2_MUTE 2
58#define AD1938_DACR2_MUTE 3
59#define AD1938_DACL3_MUTE 4
60#define AD1938_DACR3_MUTE 5
61#define AD1938_DACL4_MUTE 6
62#define AD1938_DACR4_MUTE 7
63#define AD1938_DAC_L1_VOL 6
64#define AD1938_DAC_R1_VOL 7
65#define AD1938_DAC_L2_VOL 8
66#define AD1938_DAC_R2_VOL 9
67#define AD1938_DAC_L3_VOL 10
68#define AD1938_DAC_R3_VOL 11
69#define AD1938_DAC_L4_VOL 12
70#define AD1938_DAC_R4_VOL 13
71#define AD1938_ADC_CTRL0 14
72#define AD1938_ADC_POWERDOWN 0x01
73#define AD1938_ADC_HIGHPASS_FILTER 1
74#define AD1938_ADCL1_MUTE 2
75#define AD1938_ADCR1_MUTE 3
76#define AD1938_ADCL2_MUTE 4
77#define AD1938_ADCR2_MUTE 5
78#define AD1938_ADC_CTRL1 15
79#define AD1938_ADC_SERFMT_MASK 0x60
80#define AD1938_ADC_SERFMT_STEREO (0 << 5)
81#define AD1938_ADC_SERFMT_TDM (1 << 2)
82#define AD1938_ADC_SERFMT_AUX (2 << 5)
83#define AD1938_ADC_WORD_LEN_MASK 0x3
84#define AD1938_ADC_CTRL2 16
85#define AD1938_ADC_2_CHANNELS 0
86#define AD1938_ADC_4_CHANNELS 1
87#define AD1938_ADC_8_CHANNELS 2
88#define AD1938_ADC_16_CHANNELS 3
89#define AD1938_ADC_CHAN_SHFT 4
90#define AD1938_ADC_CHAN_MASK (3 << AD1938_ADC_CHAN_SHFT)
91#define AD1938_ADC_LCR_MASTER (1 << 3)
92#define AD1938_ADC_BCLK_MASTER (1 << 6)
93#define AD1938_ADC_LEFT_HIGH (1 << 2)
94#define AD1938_ADC_BCLK_INV (1 << 1)
95
96#define AD1938_NUM_REGS 17
97
98extern struct snd_soc_dai ad1938_dai;
99extern struct snd_soc_codec_device soc_codec_dev_ad1938;
100#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index dd3380202766..0abec0d29a96 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -59,21 +59,6 @@ static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec,
59 return cache[reg]; 59 return cache[reg];
60} 60}
61 61
62static inline unsigned int ak4535_read(struct snd_soc_codec *codec,
63 unsigned int reg)
64{
65 u8 data;
66 data = reg;
67
68 if (codec->hw_write(codec->control_data, &data, 1) != 1)
69 return -EIO;
70
71 if (codec->hw_read(codec->control_data, &data, 1) != 1)
72 return -EIO;
73
74 return data;
75};
76
77/* 62/*
78 * write ak4535 register cache 63 * write ak4535 register cache
79 */ 64 */
@@ -635,7 +620,6 @@ static int ak4535_probe(struct platform_device *pdev)
635#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 620#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
636 if (setup->i2c_address) { 621 if (setup->i2c_address) {
637 codec->hw_write = (hw_write_t)i2c_master_send; 622 codec->hw_write = (hw_write_t)i2c_master_send;
638 codec->hw_read = (hw_read_t)i2c_master_recv;
639 ret = ak4535_add_i2c_device(pdev, setup); 623 ret = ak4535_add_i2c_device(pdev, setup);
640 } 624 }
641#endif 625#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index a32b8226c8a4..ca1e24a8f12a 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -806,15 +806,30 @@ static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
806{ 806{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client); 807 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
808 struct snd_soc_codec *codec = &cs4270->codec; 808 struct snd_soc_codec *codec = &cs4270->codec;
809 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
810 809
811 return snd_soc_write(codec, CS4270_PWRCTL, reg); 810 return snd_soc_suspend_device(codec->dev);
812} 811}
813 812
814static int cs4270_i2c_resume(struct i2c_client *client) 813static int cs4270_i2c_resume(struct i2c_client *client)
815{ 814{
816 struct cs4270_private *cs4270 = i2c_get_clientdata(client); 815 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
817 struct snd_soc_codec *codec = &cs4270->codec; 816 struct snd_soc_codec *codec = &cs4270->codec;
817
818 return snd_soc_resume_device(codec->dev);
819}
820
821static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
822{
823 struct snd_soc_codec *codec = cs4270_codec;
824 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
825
826 return snd_soc_write(codec, CS4270_PWRCTL, reg);
827}
828
829static int cs4270_soc_resume(struct platform_device *pdev)
830{
831 struct snd_soc_codec *codec = cs4270_codec;
832 struct i2c_client *i2c_client = codec->control_data;
818 int reg; 833 int reg;
819 834
820 /* In case the device was put to hard reset during sleep, we need to 835 /* In case the device was put to hard reset during sleep, we need to
@@ -825,7 +840,7 @@ static int cs4270_i2c_resume(struct i2c_client *client)
825 for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { 840 for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
826 u8 val = snd_soc_read(codec, reg); 841 u8 val = snd_soc_read(codec, reg);
827 842
828 if (i2c_smbus_write_byte_data(client, reg, val)) { 843 if (i2c_smbus_write_byte_data(i2c_client, reg, val)) {
829 dev_err(codec->dev, "i2c write failed\n"); 844 dev_err(codec->dev, "i2c write failed\n");
830 return -EIO; 845 return -EIO;
831 } 846 }
@@ -840,6 +855,8 @@ static int cs4270_i2c_resume(struct i2c_client *client)
840#else 855#else
841#define cs4270_i2c_suspend NULL 856#define cs4270_i2c_suspend NULL
842#define cs4270_i2c_resume NULL 857#define cs4270_i2c_resume NULL
858#define cs4270_soc_suspend NULL
859#define cs4270_soc_resume NULL
843#endif /* CONFIG_PM */ 860#endif /* CONFIG_PM */
844 861
845/* 862/*
@@ -868,7 +885,9 @@ static struct i2c_driver cs4270_i2c_driver = {
868 */ 885 */
869struct snd_soc_codec_device soc_codec_device_cs4270 = { 886struct snd_soc_codec_device soc_codec_device_cs4270 = {
870 .probe = cs4270_probe, 887 .probe = cs4270_probe,
871 .remove = cs4270_remove 888 .remove = cs4270_remove,
889 .suspend = cs4270_soc_suspend,
890 .resume = cs4270_soc_resume,
872}; 891};
873EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); 892EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
874 893
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
new file mode 100644
index 000000000000..38eac9c866e1
--- /dev/null
+++ b/sound/soc/codecs/cx20442.c
@@ -0,0 +1,501 @@
1/*
2 * cx20442.c -- CX20442 ALSA Soc Audio driver
3 *
4 * Copyright 2009 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
5 *
6 * Initially based on sound/soc/codecs/wm8400.c
7 * Copyright 2008, 2009 Wolfson Microelectronics PLC.
8 * Author: Mark Brown <broonie@opensource.wolfsonmicro.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#include <linux/tty.h>
17
18#include <sound/core.h>
19#include <sound/initval.h>
20#include <sound/soc-dapm.h>
21
22#include "cx20442.h"
23
24
25struct cx20442_priv {
26 struct snd_soc_codec codec;
27 u8 reg_cache[1];
28};
29
30#define CX20442_PM 0x0
31
32#define CX20442_TELIN 0
33#define CX20442_TELOUT 1
34#define CX20442_MIC 2
35#define CX20442_SPKOUT 3
36#define CX20442_AGC 4
37
38static const struct snd_soc_dapm_widget cx20442_dapm_widgets[] = {
39 SND_SOC_DAPM_OUTPUT("TELOUT"),
40 SND_SOC_DAPM_OUTPUT("SPKOUT"),
41 SND_SOC_DAPM_OUTPUT("AGCOUT"),
42
43 SND_SOC_DAPM_MIXER("SPKOUT Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
44
45 SND_SOC_DAPM_PGA("TELOUT Amp", CX20442_PM, CX20442_TELOUT, 0, NULL, 0),
46 SND_SOC_DAPM_PGA("SPKOUT Amp", CX20442_PM, CX20442_SPKOUT, 0, NULL, 0),
47 SND_SOC_DAPM_PGA("SPKOUT AGC", CX20442_PM, CX20442_AGC, 0, NULL, 0),
48
49 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
50 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
51
52 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
53
54 SND_SOC_DAPM_MICBIAS("TELIN Bias", CX20442_PM, CX20442_TELIN, 0),
55 SND_SOC_DAPM_MICBIAS("MIC Bias", CX20442_PM, CX20442_MIC, 0),
56
57 SND_SOC_DAPM_PGA("MIC AGC", CX20442_PM, CX20442_AGC, 0, NULL, 0),
58
59 SND_SOC_DAPM_INPUT("TELIN"),
60 SND_SOC_DAPM_INPUT("MIC"),
61 SND_SOC_DAPM_INPUT("AGCIN"),
62};
63
64static const struct snd_soc_dapm_route cx20442_audio_map[] = {
65 {"TELOUT", NULL, "TELOUT Amp"},
66
67 {"SPKOUT", NULL, "SPKOUT Mixer"},
68 {"SPKOUT Mixer", NULL, "SPKOUT Amp"},
69
70 {"TELOUT Amp", NULL, "DAC"},
71 {"SPKOUT Amp", NULL, "DAC"},
72
73 {"SPKOUT Mixer", NULL, "SPKOUT AGC"},
74 {"SPKOUT AGC", NULL, "AGCIN"},
75
76 {"AGCOUT", NULL, "MIC AGC"},
77 {"MIC AGC", NULL, "MIC"},
78
79 {"MIC Bias", NULL, "MIC"},
80 {"Input Mixer", NULL, "MIC Bias"},
81
82 {"TELIN Bias", NULL, "TELIN"},
83 {"Input Mixer", NULL, "TELIN Bias"},
84
85 {"ADC", NULL, "Input Mixer"},
86};
87
88static int cx20442_add_widgets(struct snd_soc_codec *codec)
89{
90 snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets,
91 ARRAY_SIZE(cx20442_dapm_widgets));
92
93 snd_soc_dapm_add_routes(codec, cx20442_audio_map,
94 ARRAY_SIZE(cx20442_audio_map));
95
96 snd_soc_dapm_new_widgets(codec);
97 return 0;
98}
99
100static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
101 unsigned int reg)
102{
103 u8 *reg_cache = codec->reg_cache;
104
105 if (reg >= codec->reg_cache_size)
106 return -EINVAL;
107
108 return reg_cache[reg];
109}
110
111enum v253_vls {
112 V253_VLS_NONE = 0,
113 V253_VLS_T,
114 V253_VLS_L,
115 V253_VLS_LT,
116 V253_VLS_S,
117 V253_VLS_ST,
118 V253_VLS_M,
119 V253_VLS_MST,
120 V253_VLS_S1,
121 V253_VLS_S1T,
122 V253_VLS_MS1T,
123 V253_VLS_M1,
124 V253_VLS_M1ST,
125 V253_VLS_M1S1T,
126 V253_VLS_H,
127 V253_VLS_HT,
128 V253_VLS_MS,
129 V253_VLS_MS1,
130 V253_VLS_M1S,
131 V253_VLS_M1S1,
132 V253_VLS_TEST,
133};
134
135static int cx20442_pm_to_v253_vls(u8 value)
136{
137 switch (value & ~(1 << CX20442_AGC)) {
138 case 0:
139 return V253_VLS_T;
140 case (1 << CX20442_SPKOUT):
141 case (1 << CX20442_MIC):
142 case (1 << CX20442_SPKOUT) | (1 << CX20442_MIC):
143 return V253_VLS_M1S1;
144 case (1 << CX20442_TELOUT):
145 case (1 << CX20442_TELIN):
146 case (1 << CX20442_TELOUT) | (1 << CX20442_TELIN):
147 return V253_VLS_L;
148 case (1 << CX20442_TELOUT) | (1 << CX20442_MIC):
149 return V253_VLS_NONE;
150 }
151 return -EINVAL;
152}
153static int cx20442_pm_to_v253_vsp(u8 value)
154{
155 switch (value & ~(1 << CX20442_AGC)) {
156 case (1 << CX20442_SPKOUT):
157 case (1 << CX20442_MIC):
158 case (1 << CX20442_SPKOUT) | (1 << CX20442_MIC):
159 return (bool)(value & (1 << CX20442_AGC));
160 }
161 return (value & (1 << CX20442_AGC)) ? -EINVAL : 0;
162}
163
164static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
165 unsigned int value)
166{
167 u8 *reg_cache = codec->reg_cache;
168 int vls, vsp, old, len;
169 char buf[18];
170
171 if (reg >= codec->reg_cache_size)
172 return -EINVAL;
173
174 /* hw_write and control_data pointers required for talking to the modem
175 * are expected to be set by the line discipline initialization code */
176 if (!codec->hw_write || !codec->control_data)
177 return -EIO;
178
179 old = reg_cache[reg];
180 reg_cache[reg] = value;
181
182 vls = cx20442_pm_to_v253_vls(value);
183 if (vls < 0)
184 return vls;
185
186 vsp = cx20442_pm_to_v253_vsp(value);
187 if (vsp < 0)
188 return vsp;
189
190 if ((vls == V253_VLS_T) ||
191 (vls == cx20442_pm_to_v253_vls(old))) {
192 if (vsp == cx20442_pm_to_v253_vsp(old))
193 return 0;
194 len = snprintf(buf, ARRAY_SIZE(buf), "at+vsp=%d\r", vsp);
195 } else if (vsp == cx20442_pm_to_v253_vsp(old))
196 len = snprintf(buf, ARRAY_SIZE(buf), "at+vls=%d\r", vls);
197 else
198 len = snprintf(buf, ARRAY_SIZE(buf),
199 "at+vls=%d;+vsp=%d\r", vls, vsp);
200
201 if (unlikely(len > (ARRAY_SIZE(buf) - 1)))
202 return -ENOMEM;
203
204 dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
205 if (codec->hw_write(codec->control_data, buf, len) != len)
206 return -EIO;
207
208 return 0;
209}
210
211
212/* Moved up here as line discipline referres it during initialization */
213static struct snd_soc_codec *cx20442_codec;
214
215
216/*
217 * Line discpline related code
218 *
219 * Any of the callback functions below can be used in two ways:
220 * 1) registerd by a machine driver as one of line discipline operations,
221 * 2) called from a machine's provided line discipline callback function
222 * in case when extra machine specific code must be run as well.
223 */
224
225/* Modem init: echo off, digital speaker off, quiet off, voice mode */
226static const char *v253_init = "ate0m0q0+fclass=8\r";
227
228/* Line discipline .open() */
229static int v253_open(struct tty_struct *tty)
230{
231 struct snd_soc_codec *codec = cx20442_codec;
232 int ret, len = strlen(v253_init);
233
234 /* Doesn't make sense without write callback */
235 if (!tty->ops->write)
236 return -EINVAL;
237
238 /* Pass the codec structure address for use by other ldisc callbacks */
239 tty->disc_data = codec;
240
241 if (tty->ops->write(tty, v253_init, len) != len) {
242 ret = -EIO;
243 goto err;
244 }
245 /* Actual setup will be performed after the modem responds. */
246 return 0;
247err:
248 tty->disc_data = NULL;
249 return ret;
250}
251
252/* Line discipline .close() */
253static void v253_close(struct tty_struct *tty)
254{
255 struct snd_soc_codec *codec = tty->disc_data;
256
257 tty->disc_data = NULL;
258
259 if (!codec)
260 return;
261
262 /* Prevent the codec driver from further accessing the modem */
263 codec->hw_write = NULL;
264 codec->control_data = NULL;
265 codec->pop_time = 0;
266}
267
268/* Line discipline .hangup() */
269static int v253_hangup(struct tty_struct *tty)
270{
271 v253_close(tty);
272 return 0;
273}
274
275/* Line discipline .receive_buf() */
276static void v253_receive(struct tty_struct *tty,
277 const unsigned char *cp, char *fp, int count)
278{
279 struct snd_soc_codec *codec = tty->disc_data;
280
281 if (!codec)
282 return;
283
284 if (!codec->control_data) {
285 /* First modem response, complete setup procedure */
286
287 /* Set up codec driver access to modem controls */
288 codec->control_data = tty;
289 codec->hw_write = (hw_write_t)tty->ops->write;
290 codec->pop_time = 1;
291 }
292}
293
294/* Line discipline .write_wakeup() */
295static void v253_wakeup(struct tty_struct *tty)
296{
297}
298
299struct tty_ldisc_ops v253_ops = {
300 .magic = TTY_LDISC_MAGIC,
301 .name = "cx20442",
302 .owner = THIS_MODULE,
303 .open = v253_open,
304 .close = v253_close,
305 .hangup = v253_hangup,
306 .receive_buf = v253_receive,
307 .write_wakeup = v253_wakeup,
308};
309EXPORT_SYMBOL_GPL(v253_ops);
310
311
312/*
313 * Codec DAI
314 */
315
316struct snd_soc_dai cx20442_dai = {
317 .name = "CX20442",
318 .playback = {
319 .stream_name = "Playback",
320 .channels_min = 1,
321 .channels_max = 1,
322 .rates = SNDRV_PCM_RATE_8000,
323 .formats = SNDRV_PCM_FMTBIT_S16_LE,
324 },
325 .capture = {
326 .stream_name = "Capture",
327 .channels_min = 1,
328 .channels_max = 1,
329 .rates = SNDRV_PCM_RATE_8000,
330 .formats = SNDRV_PCM_FMTBIT_S16_LE,
331 },
332};
333EXPORT_SYMBOL_GPL(cx20442_dai);
334
335static int cx20442_codec_probe(struct platform_device *pdev)
336{
337 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
338 struct snd_soc_codec *codec;
339 int ret;
340
341 if (!cx20442_codec) {
342 dev_err(&pdev->dev, "cx20442 not yet discovered\n");
343 return -ENODEV;
344 }
345 codec = cx20442_codec;
346
347 socdev->card->codec = codec;
348
349 /* register pcms */
350 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
351 if (ret < 0) {
352 dev_err(&pdev->dev, "failed to create pcms\n");
353 goto pcm_err;
354 }
355
356 cx20442_add_widgets(codec);
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:
370 return ret;
371}
372
373/* power down chip */
374static int cx20442_codec_remove(struct platform_device *pdev)
375{
376 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
377
378 snd_soc_free_pcms(socdev);
379 snd_soc_dapm_free(socdev);
380
381 return 0;
382}
383
384struct snd_soc_codec_device cx20442_codec_dev = {
385 .probe = cx20442_codec_probe,
386 .remove = cx20442_codec_remove,
387};
388EXPORT_SYMBOL_GPL(cx20442_codec_dev);
389
390static int cx20442_register(struct cx20442_priv *cx20442)
391{
392 struct snd_soc_codec *codec = &cx20442->codec;
393 int ret;
394
395 mutex_init(&codec->mutex);
396 INIT_LIST_HEAD(&codec->dapm_widgets);
397 INIT_LIST_HEAD(&codec->dapm_paths);
398
399 codec->name = "CX20442";
400 codec->owner = THIS_MODULE;
401 codec->private_data = cx20442;
402
403 codec->dai = &cx20442_dai;
404 codec->num_dai = 1;
405
406 codec->reg_cache = &cx20442->reg_cache;
407 codec->reg_cache_size = ARRAY_SIZE(cx20442->reg_cache);
408 codec->read = cx20442_read_reg_cache;
409 codec->write = cx20442_write;
410
411 codec->bias_level = SND_SOC_BIAS_OFF;
412
413 cx20442_dai.dev = codec->dev;
414
415 cx20442_codec = codec;
416
417 ret = snd_soc_register_codec(codec);
418 if (ret != 0) {
419 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
420 goto err;
421 }
422
423 ret = snd_soc_register_dai(&cx20442_dai);
424 if (ret != 0) {
425 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
426 goto err_codec;
427 }
428
429 return 0;
430
431err_codec:
432 snd_soc_unregister_codec(codec);
433err:
434 cx20442_codec = NULL;
435 kfree(cx20442);
436 return ret;
437}
438
439static void cx20442_unregister(struct cx20442_priv *cx20442)
440{
441 snd_soc_unregister_dai(&cx20442_dai);
442 snd_soc_unregister_codec(&cx20442->codec);
443
444 cx20442_codec = NULL;
445 kfree(cx20442);
446}
447
448static int cx20442_platform_probe(struct platform_device *pdev)
449{
450 struct cx20442_priv *cx20442;
451 struct snd_soc_codec *codec;
452
453 cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
454 if (cx20442 == NULL)
455 return -ENOMEM;
456
457 codec = &cx20442->codec;
458
459 codec->control_data = NULL;
460 codec->hw_write = NULL;
461 codec->pop_time = 0;
462
463 codec->dev = &pdev->dev;
464 platform_set_drvdata(pdev, cx20442);
465
466 return cx20442_register(cx20442);
467}
468
469static int __exit cx20442_platform_remove(struct platform_device *pdev)
470{
471 struct cx20442_priv *cx20442 = platform_get_drvdata(pdev);
472
473 cx20442_unregister(cx20442);
474 return 0;
475}
476
477static struct platform_driver cx20442_platform_driver = {
478 .driver = {
479 .name = "cx20442",
480 .owner = THIS_MODULE,
481 },
482 .probe = cx20442_platform_probe,
483 .remove = __exit_p(cx20442_platform_remove),
484};
485
486static int __init cx20442_init(void)
487{
488 return platform_driver_register(&cx20442_platform_driver);
489}
490module_init(cx20442_init);
491
492static void __exit cx20442_exit(void)
493{
494 platform_driver_unregister(&cx20442_platform_driver);
495}
496module_exit(cx20442_exit);
497
498MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
499MODULE_AUTHOR("Janusz Krzysztofik");
500MODULE_LICENSE("GPL");
501MODULE_ALIAS("platform:cx20442");
diff --git a/sound/soc/codecs/cx20442.h b/sound/soc/codecs/cx20442.h
new file mode 100644
index 000000000000..688a5eb62e17
--- /dev/null
+++ b/sound/soc/codecs/cx20442.h
@@ -0,0 +1,20 @@
1/*
2 * cx20442.h -- audio driver for CX20442
3 *
4 * Copyright 2009 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#ifndef _CX20442_CODEC_H
14#define _CX20442_CODEC_H
15
16extern struct snd_soc_dai cx20442_dai;
17extern struct snd_soc_codec_device cx20442_codec_dev;
18extern struct tty_ldisc_ops v253_ops;
19
20#endif
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
new file mode 100644
index 000000000000..9e7e964a5fa3
--- /dev/null
+++ b/sound/soc/codecs/max9877.c
@@ -0,0 +1,308 @@
1/*
2 * max9877.c -- amp driver for max9877
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 <sound/soc.h>
18#include <sound/tlv.h>
19
20#include "max9877.h"
21
22static struct i2c_client *i2c;
23
24static u8 max9877_regs[5] = { 0x40, 0x00, 0x00, 0x00, 0x49 };
25
26static void max9877_write_regs(void)
27{
28 unsigned int i;
29 u8 data[6];
30
31 data[0] = MAX9877_INPUT_MODE;
32 for (i = 0; i < ARRAY_SIZE(max9877_regs); i++)
33 data[i + 1] = max9877_regs[i];
34
35 if (i2c_master_send(i2c, data, 6) != 6)
36 dev_err(&i2c->dev, "i2c write failed\n");
37}
38
39static int max9877_get_reg(struct snd_kcontrol *kcontrol,
40 struct snd_ctl_elem_value *ucontrol)
41{
42 struct soc_mixer_control *mc =
43 (struct soc_mixer_control *)kcontrol->private_value;
44 unsigned int reg = mc->reg;
45 unsigned int shift = mc->shift;
46 unsigned int mask = mc->max;
47 unsigned int invert = mc->invert;
48
49 ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask;
50
51 if (invert)
52 ucontrol->value.integer.value[0] =
53 mask - ucontrol->value.integer.value[0];
54
55 return 0;
56}
57
58static int max9877_set_reg(struct snd_kcontrol *kcontrol,
59 struct snd_ctl_elem_value *ucontrol)
60{
61 struct soc_mixer_control *mc =
62 (struct soc_mixer_control *)kcontrol->private_value;
63 unsigned int reg = mc->reg;
64 unsigned int shift = mc->shift;
65 unsigned int mask = mc->max;
66 unsigned int invert = mc->invert;
67 unsigned int val = (ucontrol->value.integer.value[0] & mask);
68
69 if (invert)
70 val = mask - val;
71
72 if (((max9877_regs[reg] >> shift) & mask) == val)
73 return 0;
74
75 max9877_regs[reg] &= ~(mask << shift);
76 max9877_regs[reg] |= val << shift;
77 max9877_write_regs();
78
79 return 1;
80}
81
82static int max9877_get_2reg(struct snd_kcontrol *kcontrol,
83 struct snd_ctl_elem_value *ucontrol)
84{
85 struct soc_mixer_control *mc =
86 (struct soc_mixer_control *)kcontrol->private_value;
87 unsigned int reg = mc->reg;
88 unsigned int reg2 = mc->rreg;
89 unsigned int shift = mc->shift;
90 unsigned int mask = mc->max;
91
92 ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask;
93 ucontrol->value.integer.value[1] = (max9877_regs[reg2] >> shift) & mask;
94
95 return 0;
96}
97
98static int max9877_set_2reg(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_value *ucontrol)
100{
101 struct soc_mixer_control *mc =
102 (struct soc_mixer_control *)kcontrol->private_value;
103 unsigned int reg = mc->reg;
104 unsigned int reg2 = mc->rreg;
105 unsigned int shift = mc->shift;
106 unsigned int mask = mc->max;
107 unsigned int val = (ucontrol->value.integer.value[0] & mask);
108 unsigned int val2 = (ucontrol->value.integer.value[1] & mask);
109 unsigned int change = 1;
110
111 if (((max9877_regs[reg] >> shift) & mask) == val)
112 change = 0;
113
114 if (((max9877_regs[reg2] >> shift) & mask) == val2)
115 change = 0;
116
117 if (change) {
118 max9877_regs[reg] &= ~(mask << shift);
119 max9877_regs[reg] |= val << shift;
120 max9877_regs[reg2] &= ~(mask << shift);
121 max9877_regs[reg2] |= val2 << shift;
122 max9877_write_regs();
123 }
124
125 return change;
126}
127
128static int max9877_get_out_mode(struct snd_kcontrol *kcontrol,
129 struct snd_ctl_elem_value *ucontrol)
130{
131 u8 value = max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK;
132
133 if (value)
134 value -= 1;
135
136 ucontrol->value.integer.value[0] = value;
137 return 0;
138}
139
140static int max9877_set_out_mode(struct snd_kcontrol *kcontrol,
141 struct snd_ctl_elem_value *ucontrol)
142{
143 u8 value = ucontrol->value.integer.value[0];
144
145 value += 1;
146
147 if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK) == value)
148 return 0;
149
150 max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OUTMODE_MASK;
151 max9877_regs[MAX9877_OUTPUT_MODE] |= value;
152 max9877_write_regs();
153 return 1;
154}
155
156static int max9877_get_osc_mode(struct snd_kcontrol *kcontrol,
157 struct snd_ctl_elem_value *ucontrol)
158{
159 u8 value = (max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK);
160
161 value = value >> MAX9877_OSC_OFFSET;
162
163 ucontrol->value.integer.value[0] = value;
164 return 0;
165}
166
167static int max9877_set_osc_mode(struct snd_kcontrol *kcontrol,
168 struct snd_ctl_elem_value *ucontrol)
169{
170 u8 value = ucontrol->value.integer.value[0];
171
172 value = value << MAX9877_OSC_OFFSET;
173 if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK) == value)
174 return 0;
175
176 max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OSC_MASK;
177 max9877_regs[MAX9877_OUTPUT_MODE] |= value;
178 max9877_write_regs();
179 return 1;
180}
181
182static const unsigned int max9877_pgain_tlv[] = {
183 TLV_DB_RANGE_HEAD(2),
184 0, 1, TLV_DB_SCALE_ITEM(0, 900, 0),
185 2, 2, TLV_DB_SCALE_ITEM(2000, 0, 0),
186};
187
188static const unsigned int max9877_output_tlv[] = {
189 TLV_DB_RANGE_HEAD(4),
190 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1),
191 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0),
192 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0),
193 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0),
194};
195
196static const char *max9877_out_mode[] = {
197 "INA -> SPK",
198 "INA -> HP",
199 "INA -> SPK and HP",
200 "INB -> SPK",
201 "INB -> HP",
202 "INB -> SPK and HP",
203 "INA + INB -> SPK",
204 "INA + INB -> HP",
205 "INA + INB -> SPK and HP",
206};
207
208static const char *max9877_osc_mode[] = {
209 "1176KHz",
210 "1100KHz",
211 "700KHz",
212};
213
214static const struct soc_enum max9877_enum[] = {
215 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_out_mode), max9877_out_mode),
216 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_osc_mode), max9877_osc_mode),
217};
218
219static const struct snd_kcontrol_new max9877_controls[] = {
220 SOC_SINGLE_EXT_TLV("MAX9877 PGAINA Playback Volume",
221 MAX9877_INPUT_MODE, 0, 2, 0,
222 max9877_get_reg, max9877_set_reg, max9877_pgain_tlv),
223 SOC_SINGLE_EXT_TLV("MAX9877 PGAINB Playback Volume",
224 MAX9877_INPUT_MODE, 2, 2, 0,
225 max9877_get_reg, max9877_set_reg, max9877_pgain_tlv),
226 SOC_SINGLE_EXT_TLV("MAX9877 Amp Speaker Playback Volume",
227 MAX9877_SPK_VOLUME, 0, 31, 0,
228 max9877_get_reg, max9877_set_reg, max9877_output_tlv),
229 SOC_DOUBLE_R_EXT_TLV("MAX9877 Amp HP Playback Volume",
230 MAX9877_HPL_VOLUME, MAX9877_HPR_VOLUME, 0, 31, 0,
231 max9877_get_2reg, max9877_set_2reg, max9877_output_tlv),
232 SOC_SINGLE_EXT("MAX9877 INB Stereo Switch",
233 MAX9877_INPUT_MODE, 4, 1, 1,
234 max9877_get_reg, max9877_set_reg),
235 SOC_SINGLE_EXT("MAX9877 INA Stereo Switch",
236 MAX9877_INPUT_MODE, 5, 1, 1,
237 max9877_get_reg, max9877_set_reg),
238 SOC_SINGLE_EXT("MAX9877 Zero-crossing detection Switch",
239 MAX9877_INPUT_MODE, 6, 1, 0,
240 max9877_get_reg, max9877_set_reg),
241 SOC_SINGLE_EXT("MAX9877 Bypass Mode Switch",
242 MAX9877_OUTPUT_MODE, 6, 1, 0,
243 max9877_get_reg, max9877_set_reg),
244 SOC_SINGLE_EXT("MAX9877 Shutdown Mode Switch",
245 MAX9877_OUTPUT_MODE, 7, 1, 1,
246 max9877_get_reg, max9877_set_reg),
247 SOC_ENUM_EXT("MAX9877 Output Mode", max9877_enum[0],
248 max9877_get_out_mode, max9877_set_out_mode),
249 SOC_ENUM_EXT("MAX9877 Oscillator Mode", max9877_enum[1],
250 max9877_get_osc_mode, max9877_set_osc_mode),
251};
252
253/* This function is called from ASoC machine driver */
254int max9877_add_controls(struct snd_soc_codec *codec)
255{
256 return snd_soc_add_controls(codec, max9877_controls,
257 ARRAY_SIZE(max9877_controls));
258}
259EXPORT_SYMBOL_GPL(max9877_add_controls);
260
261static int __devinit max9877_i2c_probe(struct i2c_client *client,
262 const struct i2c_device_id *id)
263{
264 i2c = client;
265
266 max9877_write_regs();
267
268 return 0;
269}
270
271static __devexit int max9877_i2c_remove(struct i2c_client *client)
272{
273 i2c = NULL;
274
275 return 0;
276}
277
278static const struct i2c_device_id max9877_i2c_id[] = {
279 { "max9877", 0 },
280 { }
281};
282MODULE_DEVICE_TABLE(i2c, max9877_i2c_id);
283
284static struct i2c_driver max9877_i2c_driver = {
285 .driver = {
286 .name = "max9877",
287 .owner = THIS_MODULE,
288 },
289 .probe = max9877_i2c_probe,
290 .remove = __devexit_p(max9877_i2c_remove),
291 .id_table = max9877_i2c_id,
292};
293
294static int __init max9877_init(void)
295{
296 return i2c_add_driver(&max9877_i2c_driver);
297}
298module_init(max9877_init);
299
300static void __exit max9877_exit(void)
301{
302 i2c_del_driver(&max9877_i2c_driver);
303}
304module_exit(max9877_exit);
305
306MODULE_DESCRIPTION("ASoC MAX9877 amp driver");
307MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
308MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max9877.h b/sound/soc/codecs/max9877.h
new file mode 100644
index 000000000000..6da72290ac58
--- /dev/null
+++ b/sound/soc/codecs/max9877.h
@@ -0,0 +1,37 @@
1/*
2 * max9877.h -- amp driver for max9877
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 _MAX9877_H
15#define _MAX9877_H
16
17#define MAX9877_INPUT_MODE 0x00
18#define MAX9877_SPK_VOLUME 0x01
19#define MAX9877_HPL_VOLUME 0x02
20#define MAX9877_HPR_VOLUME 0x03
21#define MAX9877_OUTPUT_MODE 0x04
22
23/* MAX9877_INPUT_MODE */
24#define MAX9877_INB (1 << 4)
25#define MAX9877_INA (1 << 5)
26#define MAX9877_ZCD (1 << 6)
27
28/* MAX9877_OUTPUT_MODE */
29#define MAX9877_OUTMODE_MASK (15 << 0)
30#define MAX9877_OSC_MASK (3 << 4)
31#define MAX9877_OSC_OFFSET 4
32#define MAX9877_BYPASS (1 << 6)
33#define MAX9877_SHDN (1 << 7)
34
35extern int max9877_add_controls(struct snd_soc_codec *codec);
36
37#endif
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
new file mode 100644
index 000000000000..a63191141052
--- /dev/null
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -0,0 +1,74 @@
1/*
2 * ALSA SoC SPDIF DIT driver
3 *
4 * This driver is used by controllers which can operate in DIT (SPDI/F) where
5 * no codec is needed. This file provides stub codec that can be used
6 * in these configurations. TI DaVinci Audio controller uses this driver.
7 *
8 * Author: Steve Chen, <schen@mvista.com>
9 * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
10 * Copyright: (C) 2009 Texas Instruments, India
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/module.h>
18#include <linux/moduleparam.h>
19#include <sound/soc.h>
20#include <sound/pcm.h>
21
22#include "spdif_transciever.h"
23
24MODULE_LICENSE("GPL");
25
26#define STUB_RATES SNDRV_PCM_RATE_8000_96000
27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
28
29struct snd_soc_dai dit_stub_dai = {
30 .name = "DIT",
31 .playback = {
32 .stream_name = "Playback",
33 .channels_min = 1,
34 .channels_max = 384,
35 .rates = STUB_RATES,
36 .formats = STUB_FORMATS,
37 },
38};
39EXPORT_SYMBOL_GPL(dit_stub_dai);
40
41static int spdif_dit_probe(struct platform_device *pdev)
42{
43 dit_stub_dai.dev = &pdev->dev;
44 return snd_soc_register_dai(&dit_stub_dai);
45}
46
47static int spdif_dit_remove(struct platform_device *pdev)
48{
49 snd_soc_unregister_dai(&dit_stub_dai);
50 return 0;
51}
52
53static struct platform_driver spdif_dit_driver = {
54 .probe = spdif_dit_probe,
55 .remove = spdif_dit_remove,
56 .driver = {
57 .name = "spdif-dit",
58 .owner = THIS_MODULE,
59 },
60};
61
62static int __init dit_modinit(void)
63{
64 return platform_driver_register(&spdif_dit_driver);
65}
66
67static void __exit dit_exit(void)
68{
69 platform_driver_unregister(&spdif_dit_driver);
70}
71
72module_init(dit_modinit);
73module_exit(dit_exit);
74
diff --git a/sound/soc/codecs/spdif_transciever.h b/sound/soc/codecs/spdif_transciever.h
new file mode 100644
index 000000000000..296f2eb6c4ef
--- /dev/null
+++ b/sound/soc/codecs/spdif_transciever.h
@@ -0,0 +1,17 @@
1/*
2 * ALSA SoC DIT/DIR driver header
3 *
4 * Author: Steve Chen, <schen@mvista.com>
5 * Copyright: (C) 2008 MontaVista Software, Inc., <source@mvista.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CODEC_STUBS_H
13#define CODEC_STUBS_H
14
15extern struct snd_soc_dai dit_stub_dai;
16
17#endif /* CODEC_STUBS_H */
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 87f606c76822..c550750c79c0 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -336,15 +336,17 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
336 master_runtime->sample_bits, 336 master_runtime->sample_bits,
337 master_runtime->rate); 337 master_runtime->rate);
338 338
339 snd_pcm_hw_constraint_minmax(substream->runtime, 339 if (master_runtime->rate != 0)
340 SNDRV_PCM_HW_PARAM_RATE, 340 snd_pcm_hw_constraint_minmax(substream->runtime,
341 master_runtime->rate, 341 SNDRV_PCM_HW_PARAM_RATE,
342 master_runtime->rate); 342 master_runtime->rate,
343 343 master_runtime->rate);
344 snd_pcm_hw_constraint_minmax(substream->runtime, 344
345 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 345 if (master_runtime->sample_bits != 0)
346 master_runtime->sample_bits, 346 snd_pcm_hw_constraint_minmax(substream->runtime,
347 master_runtime->sample_bits); 347 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
348 master_runtime->sample_bits,
349 master_runtime->sample_bits);
348 350
349 ssm2602->slave_substream = substream; 351 ssm2602->slave_substream = substream;
350 } else 352 } else
@@ -372,6 +374,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
372 struct snd_soc_device *socdev = rtd->socdev; 374 struct snd_soc_device *socdev = rtd->socdev;
373 struct snd_soc_codec *codec = socdev->card->codec; 375 struct snd_soc_codec *codec = socdev->card->codec;
374 struct ssm2602_priv *ssm2602 = codec->private_data; 376 struct ssm2602_priv *ssm2602 = codec->private_data;
377
375 /* deactivate */ 378 /* deactivate */
376 if (!codec->active) 379 if (!codec->active)
377 ssm2602_write(codec, SSM2602_ACTIVE, 0); 380 ssm2602_write(codec, SSM2602_ACTIVE, 0);
@@ -497,11 +500,9 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
497 return 0; 500 return 0;
498} 501}
499 502
500#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 503#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\
501 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ 504 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
502 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ 505 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
503 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
504 SNDRV_PCM_RATE_96000)
505 506
506#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 507#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
507 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 508 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
new file mode 100644
index 000000000000..befc6488c39a
--- /dev/null
+++ b/sound/soc/codecs/stac9766.c
@@ -0,0 +1,463 @@
1/*
2 * stac9766.c -- ALSA SoC STAC9766 codec support
3 *
4 * Copyright 2009 Jon Smirl, Digispeaker
5 * Author: Jon Smirl <jonsmirl@gmail.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 * Features:-
13 *
14 * o Support for AC97 Codec, S/PDIF
15 */
16
17#include <linux/init.h>
18#include <linux/module.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/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/tlv.h>
27#include <sound/soc-of-simple.h>
28
29#include "stac9766.h"
30
31#define STAC9766_VERSION "0.10"
32
33/*
34 * STAC9766 register cache
35 */
36static const u16 stac9766_reg[] = {
37 0x6A90, 0x8000, 0x8000, 0x8000, /* 6 */
38 0x0000, 0x0000, 0x8008, 0x8008, /* e */
39 0x8808, 0x8808, 0x8808, 0x8808, /* 16 */
40 0x8808, 0x0000, 0x8000, 0x0000, /* 1e */
41 0x0000, 0x0000, 0x0000, 0x000f, /* 26 */
42 0x0a05, 0x0400, 0xbb80, 0x0000, /* 2e */
43 0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */
44 0x0000, 0x2000, 0x0000, 0x0100, /* 3e */
45 0x0000, 0x0000, 0x0080, 0x0000, /* 46 */
46 0x0000, 0x0000, 0x0003, 0xffff, /* 4e */
47 0x0000, 0x0000, 0x0000, 0x0000, /* 56 */
48 0x4000, 0x0000, 0x0000, 0x0000, /* 5e */
49 0x1201, 0xFFFF, 0xFFFF, 0x0000, /* 66 */
50 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */
51 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */
52 0x0000, 0x0000, 0x0000, 0x0000, /* 7e */
53};
54
55static const char *stac9766_record_mux[] = {"Mic", "CD", "Video", "AUX",
56 "Line", "Stereo Mix", "Mono Mix", "Phone"};
57static const char *stac9766_mono_mux[] = {"Mix", "Mic"};
58static const char *stac9766_mic_mux[] = {"Mic1", "Mic2"};
59static const char *stac9766_SPDIF_mux[] = {"PCM", "ADC Record"};
60static const char *stac9766_popbypass_mux[] = {"Normal", "Bypass Mixer"};
61static const char *stac9766_record_all_mux[] = {"All analog",
62 "Analog plus DAC"};
63static const char *stac9766_boost1[] = {"0dB", "10dB"};
64static const char *stac9766_boost2[] = {"0dB", "20dB"};
65static const char *stac9766_stereo_mic[] = {"Off", "On"};
66
67static const struct soc_enum stac9766_record_enum =
68 SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, stac9766_record_mux);
69static const struct soc_enum stac9766_mono_enum =
70 SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 9, 2, stac9766_mono_mux);
71static const struct soc_enum stac9766_mic_enum =
72 SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, stac9766_mic_mux);
73static const struct soc_enum stac9766_SPDIF_enum =
74 SOC_ENUM_SINGLE(AC97_STAC_DA_CONTROL, 1, 2, stac9766_SPDIF_mux);
75static const struct soc_enum stac9766_popbypass_enum =
76 SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, stac9766_popbypass_mux);
77static const struct soc_enum stac9766_record_all_enum =
78 SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 12, 2,
79 stac9766_record_all_mux);
80static const struct soc_enum stac9766_boost1_enum =
81 SOC_ENUM_SINGLE(AC97_MIC, 6, 2, stac9766_boost1); /* 0/10dB */
82static const struct soc_enum stac9766_boost2_enum =
83 SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 2, 2, stac9766_boost2); /* 0/20dB */
84static const struct soc_enum stac9766_stereo_mic_enum =
85 SOC_ENUM_SINGLE(AC97_STAC_STEREO_MIC, 2, 1, stac9766_stereo_mic);
86
87static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0);
88static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250);
89static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0);
90static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200);
91
92static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
93 SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv),
94 SOC_SINGLE("Speaker Switch", AC97_MASTER, 15, 1, 1),
95 SOC_DOUBLE_TLV("Headphone Volume", AC97_HEADPHONE, 8, 0, 31, 1,
96 master_tlv),
97 SOC_SINGLE("Headphone Switch", AC97_HEADPHONE, 15, 1, 1),
98 SOC_SINGLE_TLV("Mono Out Volume", AC97_MASTER_MONO, 0, 31, 1,
99 master_tlv),
100 SOC_SINGLE("Mono Out Switch", AC97_MASTER_MONO, 15, 1, 1),
101
102 SOC_DOUBLE_TLV("Record Volume", AC97_REC_GAIN, 8, 0, 15, 0, record_tlv),
103 SOC_SINGLE("Record Switch", AC97_REC_GAIN, 15, 1, 1),
104
105
106 SOC_SINGLE_TLV("Beep Volume", AC97_PC_BEEP, 1, 15, 1, beep_tlv),
107 SOC_SINGLE("Beep Switch", AC97_PC_BEEP, 15, 1, 1),
108 SOC_SINGLE("Beep Frequency", AC97_PC_BEEP, 5, 127, 1),
109 SOC_SINGLE_TLV("Phone Volume", AC97_PHONE, 0, 31, 1, mix_tlv),
110 SOC_SINGLE("Phone Switch", AC97_PHONE, 15, 1, 1),
111
112 SOC_ENUM("Mic Boost1", stac9766_boost1_enum),
113 SOC_ENUM("Mic Boost2", stac9766_boost2_enum),
114 SOC_SINGLE_TLV("Mic Volume", AC97_MIC, 0, 31, 1, mix_tlv),
115 SOC_SINGLE("Mic Switch", AC97_MIC, 15, 1, 1),
116 SOC_ENUM("Stereo Mic", stac9766_stereo_mic_enum),
117
118 SOC_DOUBLE_TLV("Line Volume", AC97_LINE, 8, 0, 31, 1, mix_tlv),
119 SOC_SINGLE("Line Switch", AC97_LINE, 15, 1, 1),
120 SOC_DOUBLE_TLV("CD Volume", AC97_CD, 8, 0, 31, 1, mix_tlv),
121 SOC_SINGLE("CD Switch", AC97_CD, 15, 1, 1),
122 SOC_DOUBLE_TLV("AUX Volume", AC97_AUX, 8, 0, 31, 1, mix_tlv),
123 SOC_SINGLE("AUX Switch", AC97_AUX, 15, 1, 1),
124 SOC_DOUBLE_TLV("Video Volume", AC97_VIDEO, 8, 0, 31, 1, mix_tlv),
125 SOC_SINGLE("Video Switch", AC97_VIDEO, 15, 1, 1),
126
127 SOC_DOUBLE_TLV("DAC Volume", AC97_PCM, 8, 0, 31, 1, mix_tlv),
128 SOC_SINGLE("DAC Switch", AC97_PCM, 15, 1, 1),
129 SOC_SINGLE("Loopback Test Switch", AC97_GENERAL_PURPOSE, 7, 1, 0),
130 SOC_SINGLE("3D Volume", AC97_3D_CONTROL, 3, 2, 1),
131 SOC_SINGLE("3D Switch", AC97_GENERAL_PURPOSE, 13, 1, 0),
132
133 SOC_ENUM("SPDIF Mux", stac9766_SPDIF_enum),
134 SOC_ENUM("Mic1/2 Mux", stac9766_mic_enum),
135 SOC_ENUM("Record All Mux", stac9766_record_all_enum),
136 SOC_ENUM("Record Mux", stac9766_record_enum),
137 SOC_ENUM("Mono Mux", stac9766_mono_enum),
138 SOC_ENUM("Pop Bypass Mux", stac9766_popbypass_enum),
139};
140
141static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
142 unsigned int val)
143{
144 u16 *cache = codec->reg_cache;
145
146 if (reg > AC97_STAC_PAGE0) {
147 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
148 soc_ac97_ops.write(codec->ac97, reg, val);
149 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
150 return 0;
151 }
152 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
153 return -EIO;
154
155 soc_ac97_ops.write(codec->ac97, reg, val);
156 cache[reg / 2] = val;
157 return 0;
158}
159
160static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
161 unsigned int reg)
162{
163 u16 val = 0, *cache = codec->reg_cache;
164
165 if (reg > AC97_STAC_PAGE0) {
166 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
167 val = soc_ac97_ops.read(codec->ac97, reg - AC97_STAC_PAGE0);
168 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
169 return val;
170 }
171 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
172 return -EIO;
173
174 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
175 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
176 reg == AC97_VENDOR_ID2) {
177
178 val = soc_ac97_ops.read(codec->ac97, reg);
179 return val;
180 }
181 return cache[reg / 2];
182}
183
184static int ac97_analog_prepare(struct snd_pcm_substream *substream,
185 struct snd_soc_dai *dai)
186{
187 struct snd_soc_codec *codec = dai->codec;
188 struct snd_pcm_runtime *runtime = substream->runtime;
189 unsigned short reg, vra;
190
191 vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
192
193 vra |= 0x1; /* enable variable rate audio */
194
195 stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
196
197 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
198 reg = AC97_PCM_FRONT_DAC_RATE;
199 else
200 reg = AC97_PCM_LR_ADC_RATE;
201
202 return stac9766_ac97_write(codec, reg, runtime->rate);
203}
204
205static int ac97_digital_prepare(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
207{
208 struct snd_soc_codec *codec = dai->codec;
209 struct snd_pcm_runtime *runtime = substream->runtime;
210 unsigned short reg, vra;
211
212 stac9766_ac97_write(codec, AC97_SPDIF, 0x2002);
213
214 vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
215 vra |= 0x5; /* Enable VRA and SPDIF out */
216
217 stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
218
219 reg = AC97_PCM_FRONT_DAC_RATE;
220
221 return stac9766_ac97_write(codec, reg, runtime->rate);
222}
223
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,
241 enum snd_soc_bias_level level)
242{
243 switch (level) {
244 case SND_SOC_BIAS_ON: /* full On */
245 case SND_SOC_BIAS_PREPARE: /* partial On */
246 case SND_SOC_BIAS_STANDBY: /* Off, with power */
247 stac9766_ac97_write(codec, AC97_POWERDOWN, 0x0000);
248 break;
249 case SND_SOC_BIAS_OFF: /* Off, without power */
250 /* disable everything including AC link */
251 stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
252 break;
253 }
254 codec->bias_level = level;
255 return 0;
256}
257
258static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
259{
260 if (try_warm && soc_ac97_ops.warm_reset) {
261 soc_ac97_ops.warm_reset(codec->ac97);
262 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])
263 return 1;
264 }
265
266 soc_ac97_ops.reset(codec->ac97);
267 if (soc_ac97_ops.warm_reset)
268 soc_ac97_ops.warm_reset(codec->ac97);
269 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])
270 return -EIO;
271 return 0;
272}
273
274static int stac9766_codec_suspend(struct platform_device *pdev,
275 pm_message_t state)
276{
277 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
278 struct snd_soc_codec *codec = socdev->card->codec;
279
280 stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);
281 return 0;
282}
283
284static int stac9766_codec_resume(struct platform_device *pdev)
285{
286 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
287 struct snd_soc_codec *codec = socdev->card->codec;
288 u16 id, reset;
289
290 reset = 0;
291 /* give the codec an AC97 warm reset to start the link */
292reset:
293 if (reset > 5) {
294 printk(KERN_ERR "stac9766 failed to resume");
295 return -EIO;
296 }
297 codec->ac97->bus->ops->warm_reset(codec->ac97);
298 id = soc_ac97_ops.read(codec->ac97, AC97_VENDOR_ID2);
299 if (id != 0x4c13) {
300 stac9766_reset(codec, 0);
301 reset++;
302 goto reset;
303 }
304 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
305
306 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
307 stac9766_set_bias_level(codec, SND_SOC_BIAS_ON);
308
309 return 0;
310}
311
312static struct snd_soc_dai_ops stac9766_dai_ops_analog = {
313 .prepare = ac97_analog_prepare,
314};
315
316static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
317 .prepare = ac97_digital_prepare,
318 .trigger = ac97_digital_trigger,
319};
320
321struct snd_soc_dai stac9766_dai[] = {
322{
323 .name = "stac9766 analog",
324 .id = 0,
325 .ac97_control = 1,
326
327 /* stream cababilities */
328 .playback = {
329 .stream_name = "stac9766 analog",
330 .channels_min = 1,
331 .channels_max = 2,
332 .rates = SNDRV_PCM_RATE_8000_48000,
333 .formats = SND_SOC_STD_AC97_FMTS,
334 },
335 .capture = {
336 .stream_name = "stac9766 analog",
337 .channels_min = 1,
338 .channels_max = 2,
339 .rates = SNDRV_PCM_RATE_8000_48000,
340 .formats = SND_SOC_STD_AC97_FMTS,
341 },
342 /* alsa ops */
343 .ops = &stac9766_dai_ops_analog,
344},
345{
346 .name = "stac9766 IEC958",
347 .id = 1,
348 .ac97_control = 1,
349
350 /* stream cababilities */
351 .playback = {
352 .stream_name = "stac9766 IEC958",
353 .channels_min = 1,
354 .channels_max = 2,
355 .rates = SNDRV_PCM_RATE_32000 | \
356 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
357 .formats = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE,
358 },
359 /* alsa ops */
360 .ops = &stac9766_dai_ops_digital,
361}
362};
363EXPORT_SYMBOL_GPL(stac9766_dai);
364
365static int stac9766_codec_probe(struct platform_device *pdev)
366{
367 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
368 struct snd_soc_codec *codec;
369 int ret = 0;
370
371 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
372
373 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
374 if (socdev->card->codec == NULL)
375 return -ENOMEM;
376 codec = socdev->card->codec;
377 mutex_init(&codec->mutex);
378
379 codec->reg_cache = kmemdup(stac9766_reg, sizeof(stac9766_reg),
380 GFP_KERNEL);
381 if (codec->reg_cache == NULL) {
382 ret = -ENOMEM;
383 goto cache_err;
384 }
385 codec->reg_cache_size = sizeof(stac9766_reg);
386 codec->reg_cache_step = 2;
387
388 codec->name = "STAC9766";
389 codec->owner = THIS_MODULE;
390 codec->dai = stac9766_dai;
391 codec->num_dai = ARRAY_SIZE(stac9766_dai);
392 codec->write = stac9766_ac97_write;
393 codec->read = stac9766_ac97_read;
394 codec->set_bias_level = stac9766_set_bias_level;
395 INIT_LIST_HEAD(&codec->dapm_widgets);
396 INIT_LIST_HEAD(&codec->dapm_paths);
397
398 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
399 if (ret < 0)
400 goto codec_err;
401
402 /* register pcms */
403 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
404 if (ret < 0)
405 goto pcm_err;
406
407 /* do a cold reset for the controller and then try
408 * a warm reset followed by an optional cold reset for codec */
409 stac9766_reset(codec, 0);
410 ret = stac9766_reset(codec, 1);
411 if (ret < 0) {
412 printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n");
413 goto reset_err;
414 }
415
416 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
417
418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls,
419 ARRAY_SIZE(stac9766_snd_ac97_controls));
420
421 ret = snd_soc_init_card(socdev);
422 if (ret < 0)
423 goto reset_err;
424 return 0;
425
426reset_err:
427 snd_soc_free_pcms(socdev);
428pcm_err:
429 snd_soc_free_ac97_codec(codec);
430codec_err:
431 kfree(codec->private_data);
432cache_err:
433 kfree(socdev->card->codec);
434 socdev->card->codec = NULL;
435 return ret;
436}
437
438static int stac9766_codec_remove(struct platform_device *pdev)
439{
440 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
441 struct snd_soc_codec *codec = socdev->card->codec;
442
443 if (codec == NULL)
444 return 0;
445
446 snd_soc_free_pcms(socdev);
447 snd_soc_free_ac97_codec(codec);
448 kfree(codec->reg_cache);
449 kfree(codec);
450 return 0;
451}
452
453struct snd_soc_codec_device soc_codec_dev_stac9766 = {
454 .probe = stac9766_codec_probe,
455 .remove = stac9766_codec_remove,
456 .suspend = stac9766_codec_suspend,
457 .resume = stac9766_codec_resume,
458};
459EXPORT_SYMBOL_GPL(soc_codec_dev_stac9766);
460
461MODULE_DESCRIPTION("ASoC stac9766 driver");
462MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
463MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/stac9766.h b/sound/soc/codecs/stac9766.h
new file mode 100644
index 000000000000..65642eb8393e
--- /dev/null
+++ b/sound/soc/codecs/stac9766.h
@@ -0,0 +1,21 @@
1/*
2 * stac9766.h -- STAC9766 Soc Audio driver
3 */
4
5#ifndef _STAC9766_H
6#define _STAC9766_H
7
8#define AC97_STAC_PAGE0 0x1000
9#define AC97_STAC_DA_CONTROL (AC97_STAC_PAGE0 | 0x6A)
10#define AC97_STAC_ANALOG_SPECIAL (AC97_STAC_PAGE0 | 0x6E)
11#define AC97_STAC_STEREO_MIC 0x78
12
13/* STAC9766 DAI ID's */
14#define STAC9766_DAI_AC97_ANALOG 0
15#define STAC9766_DAI_AC97_DIGITAL 1
16
17extern struct snd_soc_dai stac9766_dai[];
18extern struct snd_soc_codec_device soc_codec_dev_stac9766;
19
20
21#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 21f69df9994c..0b8dcb5cd729 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -86,7 +86,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
86 */ 86 */
87 87
88 if ((reg < 0 || reg > 9) && (reg != 15)) { 88 if ((reg < 0 || reg > 9) && (reg != 15)) {
89 printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg); 89 printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
90 return -1; 90 return -1;
91 } 91 }
92 92
@@ -98,7 +98,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
98 if (codec->hw_write(codec->control_data, data, 2) == 2) 98 if (codec->hw_write(codec->control_data, data, 2) == 2)
99 return 0; 99 return 0;
100 100
101 printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__, 101 printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__,
102 value, reg); 102 value, reg);
103 103
104 return -EIO; 104 return -EIO;
@@ -273,14 +273,14 @@ static const unsigned short sr_valid_mask[] = {
273 * Every divisor is a factor of 11*12 273 * Every divisor is a factor of 11*12
274 */ 274 */
275#define SR_MULT (11*12) 275#define SR_MULT (11*12)
276#define A(x) (x) ? (SR_MULT/x) : 0 276#define A(x) (SR_MULT/x)
277static const unsigned char sr_adc_mult_table[] = { 277static const unsigned char sr_adc_mult_table[] = {
278 A(2), A(2), A(12), A(12), A(0), A(0), A(3), A(1), 278 A(2), A(2), A(12), A(12), 0, 0, A(3), A(1),
279 A(2), A(2), A(11), A(11), A(0), A(0), A(0), A(1) 279 A(2), A(2), A(11), A(11), 0, 0, 0, A(1)
280}; 280};
281static const unsigned char sr_dac_mult_table[] = { 281static const unsigned char sr_dac_mult_table[] = {
282 A(2), A(12), A(2), A(12), A(0), A(0), A(3), A(1), 282 A(2), A(12), A(2), A(12), 0, 0, A(3), A(1),
283 A(2), A(11), A(2), A(11), A(0), A(0), A(0), A(1) 283 A(2), A(11), A(2), A(11), 0, 0, 0, A(1)
284}; 284};
285 285
286static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc, 286static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc,
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index ab099f482487..126b15b18aeb 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -145,8 +145,8 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
145 u8 *value) 145 u8 *value)
146{ 146{
147 *value = reg & 0xff; 147 *value = reg & 0xff;
148 if (codec->hw_read(codec->control_data, value, 1) != 1) 148
149 return -EIO; 149 value[0] = i2c_smbus_read_byte_data(codec->control_data, value[0]);
150 150
151 aic3x_write_reg_cache(codec, reg, *value); 151 aic3x_write_reg_cache(codec, reg, *value);
152 return 0; 152 return 0;
@@ -767,6 +767,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
768 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 768 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
769 u16 pll_d = 1; 769 u16 pll_d = 1;
770 u8 reg;
770 771
771 /* select data word length */ 772 /* select data word length */
772 data = 773 data =
@@ -801,8 +802,16 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
801 pll_q &= 0xf; 802 pll_q &= 0xf;
802 aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT); 803 aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
803 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV); 804 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
804 } else 805 /* disable PLL if it is bypassed */
806 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
807 aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE);
808
809 } else {
805 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV); 810 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
811 /* enable PLL when it is used */
812 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
813 aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE);
814 }
806 815
807 /* Route Left DAC to left channel input and 816 /* Route Left DAC to left channel input and
808 * right DAC to right channel input */ 817 * right DAC to right channel input */
@@ -1316,12 +1325,6 @@ static struct i2c_driver aic3x_i2c_driver = {
1316 .id_table = aic3x_i2c_id, 1325 .id_table = aic3x_i2c_id,
1317}; 1326};
1318 1327
1319static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
1320{
1321 value[0] = i2c_smbus_read_byte_data(client, value[0]);
1322 return (len == 1);
1323}
1324
1325static int aic3x_add_i2c_device(struct platform_device *pdev, 1328static int aic3x_add_i2c_device(struct platform_device *pdev,
1326 const struct aic3x_setup_data *setup) 1329 const struct aic3x_setup_data *setup)
1327{ 1330{
@@ -1394,7 +1397,6 @@ static int aic3x_probe(struct platform_device *pdev)
1394#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1397#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1395 if (setup->i2c_address) { 1398 if (setup->i2c_address) {
1396 codec->hw_write = (hw_write_t) i2c_master_send; 1399 codec->hw_write = (hw_write_t) i2c_master_send;
1397 codec->hw_read = (hw_read_t) aic3x_i2c_read;
1398 ret = aic3x_add_i2c_device(pdev, setup); 1400 ret = aic3x_add_i2c_device(pdev, setup);
1399 } 1401 }
1400#else 1402#else
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 9197fdd0a29d..4df7c6c61c76 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -115,6 +115,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
115 0x00, /* REG_VIBRA_PWM_SET (0x47) */ 115 0x00, /* REG_VIBRA_PWM_SET (0x47) */
116 0x00, /* REG_ANAMIC_GAIN (0x48) */ 116 0x00, /* REG_ANAMIC_GAIN (0x48) */
117 0x00, /* REG_MISC_SET_2 (0x49) */ 117 0x00, /* REG_MISC_SET_2 (0x49) */
118 0x00, /* REG_SW_SHADOW (0x4A) - Shadow, non HW register */
118}; 119};
119 120
120/* codec private data */ 121/* codec private data */
@@ -172,7 +173,11 @@ static int twl4030_write(struct snd_soc_codec *codec,
172 unsigned int reg, unsigned int value) 173 unsigned int reg, unsigned int value)
173{ 174{
174 twl4030_write_reg_cache(codec, reg, value); 175 twl4030_write_reg_cache(codec, reg, value);
175 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); 176 if (likely(reg < TWL4030_REG_SW_SHADOW))
177 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value,
178 reg);
179 else
180 return 0;
176} 181}
177 182
178static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 183static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
@@ -199,6 +204,7 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
199 204
200static void twl4030_init_chip(struct snd_soc_codec *codec) 205static void twl4030_init_chip(struct snd_soc_codec *codec)
201{ 206{
207 u8 *cache = codec->reg_cache;
202 int i; 208 int i;
203 209
204 /* clear CODECPDZ prior to setting register defaults */ 210 /* clear CODECPDZ prior to setting register defaults */
@@ -206,7 +212,7 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
206 212
207 /* set all audio section registers to reasonable defaults */ 213 /* set all audio section registers to reasonable defaults */
208 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) 214 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
209 twl4030_write(codec, i, twl4030_reg[i]); 215 twl4030_write(codec, i, cache[i]);
210 216
211} 217}
212 218
@@ -219,55 +225,11 @@ static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute)
219 return; 225 return;
220 226
221 if (mute) { 227 if (mute) {
222 /* Bypass the reg_cache and mute the volumes
223 * Headset mute is done in it's own event handler
224 * Things to mute: Earpiece, PreDrivL/R, CarkitL/R
225 */
226 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL);
227 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
228 reg_val & (~TWL4030_EAR_GAIN),
229 TWL4030_REG_EAR_CTL);
230
231 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL);
232 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
233 reg_val & (~TWL4030_PREDL_GAIN),
234 TWL4030_REG_PREDL_CTL);
235 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL);
236 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
237 reg_val & (~TWL4030_PREDR_GAIN),
238 TWL4030_REG_PREDL_CTL);
239
240 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL);
241 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
242 reg_val & (~TWL4030_PRECKL_GAIN),
243 TWL4030_REG_PRECKL_CTL);
244 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL);
245 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
246 reg_val & (~TWL4030_PRECKR_GAIN),
247 TWL4030_REG_PRECKR_CTL);
248
249 /* Disable PLL */ 228 /* Disable PLL */
250 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 229 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
251 reg_val &= ~TWL4030_APLL_EN; 230 reg_val &= ~TWL4030_APLL_EN;
252 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); 231 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
253 } else { 232 } else {
254 /* Restore the volumes
255 * Headset mute is done in it's own event handler
256 * Things to restore: Earpiece, PreDrivL/R, CarkitL/R
257 */
258 twl4030_write(codec, TWL4030_REG_EAR_CTL,
259 twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL));
260
261 twl4030_write(codec, TWL4030_REG_PREDL_CTL,
262 twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL));
263 twl4030_write(codec, TWL4030_REG_PREDR_CTL,
264 twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL));
265
266 twl4030_write(codec, TWL4030_REG_PRECKL_CTL,
267 twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL));
268 twl4030_write(codec, TWL4030_REG_PRECKR_CTL,
269 twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL));
270
271 /* Enable PLL */ 233 /* Enable PLL */
272 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 234 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
273 reg_val |= TWL4030_APLL_EN; 235 reg_val |= TWL4030_APLL_EN;
@@ -390,6 +352,10 @@ static const struct soc_enum twl4030_handsfreel_enum =
390static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control = 352static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
391SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum); 353SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
392 354
355/* Handsfree Left virtual mute */
356static const struct snd_kcontrol_new twl4030_dapm_handsfreelmute_control =
357 SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 0, 1, 0);
358
393/* Handsfree Right */ 359/* Handsfree Right */
394static const char *twl4030_handsfreer_texts[] = 360static const char *twl4030_handsfreer_texts[] =
395 {"Voice", "AudioR1", "AudioR2", "AudioL2"}; 361 {"Voice", "AudioR1", "AudioR2", "AudioL2"};
@@ -402,6 +368,10 @@ static const struct soc_enum twl4030_handsfreer_enum =
402static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = 368static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
403SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum); 369SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
404 370
371/* Handsfree Right virtual mute */
372static const struct snd_kcontrol_new twl4030_dapm_handsfreermute_control =
373 SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 1, 1, 0);
374
405/* Vibra */ 375/* Vibra */
406/* Vibra audio path selection */ 376/* Vibra audio path selection */
407static const char *twl4030_vibra_texts[] = 377static const char *twl4030_vibra_texts[] =
@@ -429,16 +399,20 @@ SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
429 399
430/* Left analog microphone selection */ 400/* Left analog microphone selection */
431static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = { 401static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = {
432 SOC_DAPM_SINGLE("Main mic", TWL4030_REG_ANAMICL, 0, 1, 0), 402 SOC_DAPM_SINGLE("Main Mic Capture Switch",
433 SOC_DAPM_SINGLE("Headset mic", TWL4030_REG_ANAMICL, 1, 1, 0), 403 TWL4030_REG_ANAMICL, 0, 1, 0),
434 SOC_DAPM_SINGLE("AUXL", TWL4030_REG_ANAMICL, 2, 1, 0), 404 SOC_DAPM_SINGLE("Headset Mic Capture Switch",
435 SOC_DAPM_SINGLE("Carkit mic", TWL4030_REG_ANAMICL, 3, 1, 0), 405 TWL4030_REG_ANAMICL, 1, 1, 0),
406 SOC_DAPM_SINGLE("AUXL Capture Switch",
407 TWL4030_REG_ANAMICL, 2, 1, 0),
408 SOC_DAPM_SINGLE("Carkit Mic Capture Switch",
409 TWL4030_REG_ANAMICL, 3, 1, 0),
436}; 410};
437 411
438/* Right analog microphone selection */ 412/* Right analog microphone selection */
439static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = { 413static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = {
440 SOC_DAPM_SINGLE("Sub mic", TWL4030_REG_ANAMICR, 0, 1, 0), 414 SOC_DAPM_SINGLE("Sub Mic Capture Switch", TWL4030_REG_ANAMICR, 0, 1, 0),
441 SOC_DAPM_SINGLE("AUXR", TWL4030_REG_ANAMICR, 2, 1, 0), 415 SOC_DAPM_SINGLE("AUXR Capture Switch", TWL4030_REG_ANAMICR, 2, 1, 0),
442}; 416};
443 417
444/* TX1 L/R Analog/Digital microphone selection */ 418/* TX1 L/R Analog/Digital microphone selection */
@@ -546,32 +520,104 @@ static int micpath_event(struct snd_soc_dapm_widget *w,
546 return 0; 520 return 0;
547} 521}
548 522
549static int handsfree_event(struct snd_soc_dapm_widget *w, 523/*
550 struct snd_kcontrol *kcontrol, int event) 524 * Output PGA builder:
525 * Handle the muting and unmuting of the given output (turning off the
526 * amplifier associated with the output pin)
527 * On mute bypass the reg_cache and mute the volume
528 * On unmute: restore the register content
529 * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R
530 */
531#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
532static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
533 struct snd_kcontrol *kcontrol, int event) \
534{ \
535 u8 reg_val; \
536 \
537 switch (event) { \
538 case SND_SOC_DAPM_POST_PMU: \
539 twl4030_write(w->codec, reg, \
540 twl4030_read_reg_cache(w->codec, reg)); \
541 break; \
542 case SND_SOC_DAPM_POST_PMD: \
543 reg_val = twl4030_read_reg_cache(w->codec, reg); \
544 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
545 reg_val & (~mask), \
546 reg); \
547 break; \
548 } \
549 return 0; \
550}
551
552TWL4030_OUTPUT_PGA(earpiece, TWL4030_REG_EAR_CTL, TWL4030_EAR_GAIN);
553TWL4030_OUTPUT_PGA(predrivel, TWL4030_REG_PREDL_CTL, TWL4030_PREDL_GAIN);
554TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
555TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
556TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
557
558static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
551{ 559{
552 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
553 unsigned char hs_ctl; 560 unsigned char hs_ctl;
554 561
555 hs_ctl = twl4030_read_reg_cache(w->codec, e->reg); 562 hs_ctl = twl4030_read_reg_cache(codec, reg);
556 563
557 if (hs_ctl & TWL4030_HF_CTL_REF_EN) { 564 if (ramp) {
565 /* HF ramp-up */
566 hs_ctl |= TWL4030_HF_CTL_REF_EN;
567 twl4030_write(codec, reg, hs_ctl);
568 udelay(10);
558 hs_ctl |= TWL4030_HF_CTL_RAMP_EN; 569 hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
559 twl4030_write(w->codec, e->reg, hs_ctl); 570 twl4030_write(codec, reg, hs_ctl);
571 udelay(40);
560 hs_ctl |= TWL4030_HF_CTL_LOOP_EN; 572 hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
561 twl4030_write(w->codec, e->reg, hs_ctl);
562 hs_ctl |= TWL4030_HF_CTL_HB_EN; 573 hs_ctl |= TWL4030_HF_CTL_HB_EN;
563 twl4030_write(w->codec, e->reg, hs_ctl); 574 twl4030_write(codec, reg, hs_ctl);
564 } else { 575 } else {
565 hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN 576 /* HF ramp-down */
566 | TWL4030_HF_CTL_HB_EN); 577 hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
567 twl4030_write(w->codec, e->reg, hs_ctl); 578 hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
579 twl4030_write(codec, reg, hs_ctl);
580 hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
581 twl4030_write(codec, reg, hs_ctl);
582 udelay(40);
583 hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
584 twl4030_write(codec, reg, hs_ctl);
568 } 585 }
586}
569 587
588static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
589 struct snd_kcontrol *kcontrol, int event)
590{
591 switch (event) {
592 case SND_SOC_DAPM_POST_PMU:
593 handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1);
594 break;
595 case SND_SOC_DAPM_POST_PMD:
596 handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0);
597 break;
598 }
599 return 0;
600}
601
602static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
603 struct snd_kcontrol *kcontrol, int event)
604{
605 switch (event) {
606 case SND_SOC_DAPM_POST_PMU:
607 handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1);
608 break;
609 case SND_SOC_DAPM_POST_PMD:
610 handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0);
611 break;
612 }
570 return 0; 613 return 0;
571} 614}
572 615
573static void headset_ramp(struct snd_soc_codec *codec, int ramp) 616static void headset_ramp(struct snd_soc_codec *codec, int ramp)
574{ 617{
618 struct snd_soc_device *socdev = codec->socdev;
619 struct twl4030_setup_data *setup = socdev->codec_data;
620
575 unsigned char hs_gain, hs_pop; 621 unsigned char hs_gain, hs_pop;
576 struct twl4030_priv *twl4030 = codec->private_data; 622 struct twl4030_priv *twl4030 = codec->private_data;
577 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 623 /* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -581,6 +627,17 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
581 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); 627 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
582 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 628 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
583 629
630 /* Enable external mute control, this dramatically reduces
631 * the pop-noise */
632 if (setup && setup->hs_extmute) {
633 if (setup->set_hs_extmute) {
634 setup->set_hs_extmute(1);
635 } else {
636 hs_pop |= TWL4030_EXTMUTE;
637 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
638 }
639 }
640
584 if (ramp) { 641 if (ramp) {
585 /* Headset ramp-up according to the TRM */ 642 /* Headset ramp-up according to the TRM */
586 hs_pop |= TWL4030_VMID_EN; 643 hs_pop |= TWL4030_VMID_EN;
@@ -588,6 +645,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
588 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain); 645 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain);
589 hs_pop |= TWL4030_RAMP_EN; 646 hs_pop |= TWL4030_RAMP_EN;
590 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 647 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
648 /* Wait ramp delay time + 1, so the VMID can settle */
649 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
650 twl4030->sysclk) + 1);
591 } else { 651 } else {
592 /* Headset ramp-down _not_ according to 652 /* Headset ramp-down _not_ according to
593 * the TRM, but in a way that it is working */ 653 * the TRM, but in a way that it is working */
@@ -604,6 +664,16 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
604 hs_pop &= ~TWL4030_VMID_EN; 664 hs_pop &= ~TWL4030_VMID_EN;
605 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 665 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
606 } 666 }
667
668 /* Disable external mute */
669 if (setup && setup->hs_extmute) {
670 if (setup->set_hs_extmute) {
671 setup->set_hs_extmute(0);
672 } else {
673 hs_pop &= ~TWL4030_EXTMUTE;
674 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
675 }
676 }
607} 677}
608 678
609static int headsetlpga_event(struct snd_soc_dapm_widget *w, 679static int headsetlpga_event(struct snd_soc_dapm_widget *w,
@@ -664,7 +734,19 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
664 734
665 reg = twl4030_read_reg_cache(w->codec, m->reg); 735 reg = twl4030_read_reg_cache(w->codec, m->reg);
666 736
667 if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) { 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) {
668 /* Analog bypass */ 750 /* Analog bypass */
669 if (reg & (1 << m->shift)) 751 if (reg & (1 << m->shift))
670 twl4030->bypass_state |= 752 twl4030->bypass_state |=
@@ -678,12 +760,6 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
678 twl4030->bypass_state |= (1 << 4); 760 twl4030->bypass_state |= (1 << 4);
679 else 761 else
680 twl4030->bypass_state &= ~(1 << 4); 762 twl4030->bypass_state &= ~(1 << 4);
681 } else if (m->reg == TWL4030_REG_VSTPGA) {
682 /* Voice digital bypass */
683 if (reg)
684 twl4030->bypass_state |= (1 << 5);
685 else
686 twl4030->bypass_state &= ~(1 << 5);
687 } else { 763 } else {
688 /* Digital bypass */ 764 /* Digital bypass */
689 if (reg & (0x7 << m->shift)) 765 if (reg & (0x7 << m->shift))
@@ -876,7 +952,7 @@ static const struct soc_enum twl4030_op_modes_enum =
876 ARRAY_SIZE(twl4030_op_modes_texts), 952 ARRAY_SIZE(twl4030_op_modes_texts),
877 twl4030_op_modes_texts); 953 twl4030_op_modes_texts);
878 954
879int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, 955static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
880 struct snd_ctl_elem_value *ucontrol) 956 struct snd_ctl_elem_value *ucontrol)
881{ 957{
882 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 958 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -957,6 +1033,16 @@ static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
957 */ 1033 */
958static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0); 1034static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
959 1035
1036/* AVADC clock priority */
1037static const char *twl4030_avadc_clk_priority_texts[] = {
1038 "Voice high priority", "HiFi high priority"
1039};
1040
1041static const struct soc_enum twl4030_avadc_clk_priority_enum =
1042 SOC_ENUM_SINGLE(TWL4030_REG_AVADC_CTL, 2,
1043 ARRAY_SIZE(twl4030_avadc_clk_priority_texts),
1044 twl4030_avadc_clk_priority_texts);
1045
960static const char *twl4030_rampdelay_texts[] = { 1046static const char *twl4030_rampdelay_texts[] = {
961 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms", 1047 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms",
962 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms", 1048 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms",
@@ -1058,6 +1144,8 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1058 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN, 1144 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
1059 0, 3, 5, 0, input_gain_tlv), 1145 0, 3, 5, 0, input_gain_tlv),
1060 1146
1147 SOC_ENUM("AVADC Clock Priority", twl4030_avadc_clk_priority_enum),
1148
1061 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum), 1149 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
1062 1150
1063 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), 1151 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
@@ -1160,13 +1248,22 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1160 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1248 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
1161 &twl4030_dapm_earpiece_controls[0], 1249 &twl4030_dapm_earpiece_controls[0],
1162 ARRAY_SIZE(twl4030_dapm_earpiece_controls)), 1250 ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
1251 SND_SOC_DAPM_PGA_E("Earpiece PGA", SND_SOC_NOPM,
1252 0, 0, NULL, 0, earpiecepga_event,
1253 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1163 /* PreDrivL/R */ 1254 /* PreDrivL/R */
1164 SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0, 1255 SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
1165 &twl4030_dapm_predrivel_controls[0], 1256 &twl4030_dapm_predrivel_controls[0],
1166 ARRAY_SIZE(twl4030_dapm_predrivel_controls)), 1257 ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
1258 SND_SOC_DAPM_PGA_E("PredriveL PGA", SND_SOC_NOPM,
1259 0, 0, NULL, 0, predrivelpga_event,
1260 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1167 SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0, 1261 SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
1168 &twl4030_dapm_predriver_controls[0], 1262 &twl4030_dapm_predriver_controls[0],
1169 ARRAY_SIZE(twl4030_dapm_predriver_controls)), 1263 ARRAY_SIZE(twl4030_dapm_predriver_controls)),
1264 SND_SOC_DAPM_PGA_E("PredriveR PGA", SND_SOC_NOPM,
1265 0, 0, NULL, 0, predriverpga_event,
1266 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1170 /* HeadsetL/R */ 1267 /* HeadsetL/R */
1171 SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0, 1268 SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
1172 &twl4030_dapm_hsol_controls[0], 1269 &twl4030_dapm_hsol_controls[0],
@@ -1184,18 +1281,32 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1184 SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0, 1281 SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
1185 &twl4030_dapm_carkitl_controls[0], 1282 &twl4030_dapm_carkitl_controls[0],
1186 ARRAY_SIZE(twl4030_dapm_carkitl_controls)), 1283 ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
1284 SND_SOC_DAPM_PGA_E("CarkitL PGA", SND_SOC_NOPM,
1285 0, 0, NULL, 0, carkitlpga_event,
1286 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1187 SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0, 1287 SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
1188 &twl4030_dapm_carkitr_controls[0], 1288 &twl4030_dapm_carkitr_controls[0],
1189 ARRAY_SIZE(twl4030_dapm_carkitr_controls)), 1289 ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
1290 SND_SOC_DAPM_PGA_E("CarkitR PGA", SND_SOC_NOPM,
1291 0, 0, NULL, 0, carkitrpga_event,
1292 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1190 1293
1191 /* Output MUX controls */ 1294 /* Output MUX controls */
1192 /* HandsfreeL/R */ 1295 /* HandsfreeL/R */
1193 SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0, 1296 SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
1194 &twl4030_dapm_handsfreel_control, handsfree_event, 1297 &twl4030_dapm_handsfreel_control),
1195 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1298 SND_SOC_DAPM_SWITCH("HandsfreeL", SND_SOC_NOPM, 0, 0,
1196 SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0, 1299 &twl4030_dapm_handsfreelmute_control),
1197 &twl4030_dapm_handsfreer_control, handsfree_event, 1300 SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
1198 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1301 0, 0, NULL, 0, handsfreelpga_event,
1302 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1303 SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
1304 &twl4030_dapm_handsfreer_control),
1305 SND_SOC_DAPM_SWITCH("HandsfreeR", SND_SOC_NOPM, 0, 0,
1306 &twl4030_dapm_handsfreermute_control),
1307 SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
1308 0, 0, NULL, 0, handsfreerpga_event,
1309 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1199 /* Vibra */ 1310 /* Vibra */
1200 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, 1311 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1201 &twl4030_dapm_vibra_control), 1312 &twl4030_dapm_vibra_control),
@@ -1226,11 +1337,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1226 SND_SOC_DAPM_POST_REG), 1337 SND_SOC_DAPM_POST_REG),
1227 1338
1228 /* Analog input mixers for the capture amplifiers */ 1339 /* Analog input mixers for the capture amplifiers */
1229 SND_SOC_DAPM_MIXER("Analog Left Capture Route", 1340 SND_SOC_DAPM_MIXER("Analog Left",
1230 TWL4030_REG_ANAMICL, 4, 0, 1341 TWL4030_REG_ANAMICL, 4, 0,
1231 &twl4030_dapm_analoglmic_controls[0], 1342 &twl4030_dapm_analoglmic_controls[0],
1232 ARRAY_SIZE(twl4030_dapm_analoglmic_controls)), 1343 ARRAY_SIZE(twl4030_dapm_analoglmic_controls)),
1233 SND_SOC_DAPM_MIXER("Analog Right Capture Route", 1344 SND_SOC_DAPM_MIXER("Analog Right",
1234 TWL4030_REG_ANAMICR, 4, 0, 1345 TWL4030_REG_ANAMICR, 4, 0,
1235 &twl4030_dapm_analogrmic_controls[0], 1346 &twl4030_dapm_analogrmic_controls[0],
1236 ARRAY_SIZE(twl4030_dapm_analogrmic_controls)), 1347 ARRAY_SIZE(twl4030_dapm_analogrmic_controls)),
@@ -1270,16 +1381,19 @@ static const struct snd_soc_dapm_route intercon[] = {
1270 {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1381 {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1271 {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1382 {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1272 {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1383 {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1384 {"Earpiece PGA", NULL, "Earpiece Mixer"},
1273 /* PreDrivL */ 1385 /* PreDrivL */
1274 {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1386 {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"},
1275 {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1387 {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1276 {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1388 {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1277 {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1389 {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1390 {"PredriveL PGA", NULL, "PredriveL Mixer"},
1278 /* PreDrivR */ 1391 /* PreDrivR */
1279 {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"}, 1392 {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"},
1280 {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1393 {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1281 {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1394 {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1282 {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1395 {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1396 {"PredriveR PGA", NULL, "PredriveR Mixer"},
1283 /* HeadsetL */ 1397 /* HeadsetL */
1284 {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1398 {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"},
1285 {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1399 {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
@@ -1294,20 +1408,26 @@ static const struct snd_soc_dapm_route intercon[] = {
1294 {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1408 {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"},
1295 {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1409 {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1296 {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1410 {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1411 {"CarkitL PGA", NULL, "CarkitL Mixer"},
1297 /* CarkitR */ 1412 /* CarkitR */
1298 {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"}, 1413 {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"},
1299 {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1414 {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1300 {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1415 {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1416 {"CarkitR PGA", NULL, "CarkitR Mixer"},
1301 /* HandsfreeL */ 1417 /* HandsfreeL */
1302 {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"}, 1418 {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"},
1303 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"}, 1419 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
1304 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"}, 1420 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
1305 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"}, 1421 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
1422 {"HandsfreeL", "Switch", "HandsfreeL Mux"},
1423 {"HandsfreeL PGA", NULL, "HandsfreeL"},
1306 /* HandsfreeR */ 1424 /* HandsfreeR */
1307 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"}, 1425 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
1308 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"}, 1426 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
1309 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"}, 1427 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
1310 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"}, 1428 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
1429 {"HandsfreeR", "Switch", "HandsfreeR Mux"},
1430 {"HandsfreeR PGA", NULL, "HandsfreeR"},
1311 /* Vibra */ 1431 /* Vibra */
1312 {"Vibra Mux", "AudioL1", "DAC Left1"}, 1432 {"Vibra Mux", "AudioL1", "DAC Left1"},
1313 {"Vibra Mux", "AudioR1", "DAC Right1"}, 1433 {"Vibra Mux", "AudioR1", "DAC Right1"},
@@ -1317,29 +1437,29 @@ static const struct snd_soc_dapm_route intercon[] = {
1317 /* outputs */ 1437 /* outputs */
1318 {"OUTL", NULL, "Analog L2 Playback Mixer"}, 1438 {"OUTL", NULL, "Analog L2 Playback Mixer"},
1319 {"OUTR", NULL, "Analog R2 Playback Mixer"}, 1439 {"OUTR", NULL, "Analog R2 Playback Mixer"},
1320 {"EARPIECE", NULL, "Earpiece Mixer"}, 1440 {"EARPIECE", NULL, "Earpiece PGA"},
1321 {"PREDRIVEL", NULL, "PredriveL Mixer"}, 1441 {"PREDRIVEL", NULL, "PredriveL PGA"},
1322 {"PREDRIVER", NULL, "PredriveR Mixer"}, 1442 {"PREDRIVER", NULL, "PredriveR PGA"},
1323 {"HSOL", NULL, "HeadsetL PGA"}, 1443 {"HSOL", NULL, "HeadsetL PGA"},
1324 {"HSOR", NULL, "HeadsetR PGA"}, 1444 {"HSOR", NULL, "HeadsetR PGA"},
1325 {"CARKITL", NULL, "CarkitL Mixer"}, 1445 {"CARKITL", NULL, "CarkitL PGA"},
1326 {"CARKITR", NULL, "CarkitR Mixer"}, 1446 {"CARKITR", NULL, "CarkitR PGA"},
1327 {"HFL", NULL, "HandsfreeL Mux"}, 1447 {"HFL", NULL, "HandsfreeL PGA"},
1328 {"HFR", NULL, "HandsfreeR Mux"}, 1448 {"HFR", NULL, "HandsfreeR PGA"},
1329 {"Vibra Route", "Audio", "Vibra Mux"}, 1449 {"Vibra Route", "Audio", "Vibra Mux"},
1330 {"VIBRA", NULL, "Vibra Route"}, 1450 {"VIBRA", NULL, "Vibra Route"},
1331 1451
1332 /* Capture path */ 1452 /* Capture path */
1333 {"Analog Left Capture Route", "Main mic", "MAINMIC"}, 1453 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
1334 {"Analog Left Capture Route", "Headset mic", "HSMIC"}, 1454 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
1335 {"Analog Left Capture Route", "AUXL", "AUXL"}, 1455 {"Analog Left", "AUXL Capture Switch", "AUXL"},
1336 {"Analog Left Capture Route", "Carkit mic", "CARKITMIC"}, 1456 {"Analog Left", "Carkit Mic Capture Switch", "CARKITMIC"},
1337 1457
1338 {"Analog Right Capture Route", "Sub mic", "SUBMIC"}, 1458 {"Analog Right", "Sub Mic Capture Switch", "SUBMIC"},
1339 {"Analog Right Capture Route", "AUXR", "AUXR"}, 1459 {"Analog Right", "AUXR Capture Switch", "AUXR"},
1340 1460
1341 {"ADC Physical Left", NULL, "Analog Left Capture Route"}, 1461 {"ADC Physical Left", NULL, "Analog Left"},
1342 {"ADC Physical Right", NULL, "Analog Right Capture Route"}, 1462 {"ADC Physical Right", NULL, "Analog Right"},
1343 1463
1344 {"Digimic0 Enable", NULL, "DIGIMIC0"}, 1464 {"Digimic0 Enable", NULL, "DIGIMIC0"},
1345 {"Digimic1 Enable", NULL, "DIGIMIC1"}, 1465 {"Digimic1 Enable", NULL, "DIGIMIC1"},
@@ -1363,11 +1483,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1363 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1483 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1364 1484
1365 /* Analog bypass routes */ 1485 /* Analog bypass routes */
1366 {"Right1 Analog Loopback", "Switch", "Analog Right Capture Route"}, 1486 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1367 {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, 1487 {"Left1 Analog Loopback", "Switch", "Analog Left"},
1368 {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, 1488 {"Right2 Analog Loopback", "Switch", "Analog Right"},
1369 {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, 1489 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1370 {"Voice Analog Loopback", "Switch", "Analog Left Capture Route"}, 1490 {"Voice Analog Loopback", "Switch", "Analog Left"},
1371 1491
1372 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1492 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1373 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1493 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
@@ -1549,9 +1669,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1549 1669
1550 /* If the substream has 4 channel, do the necessary setup */ 1670 /* If the substream has 4 channel, do the necessary setup */
1551 if (params_channels(params) == 4) { 1671 if (params_channels(params) == 4) {
1552 /* Safety check: are we in the correct operating mode? */ 1672 format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1553 if ((twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & 1673 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
1554 TWL4030_OPTION_1)) 1674
1675 /* Safety check: are we in the correct operating mode and
1676 * the interface is in TDM mode? */
1677 if ((mode & TWL4030_OPTION_1) &&
1678 ((format & TWL4030_AIF_FORMAT) == TWL4030_AIF_FORMAT_TDM))
1555 twl4030_tdm_enable(codec, substream->stream, 1); 1679 twl4030_tdm_enable(codec, substream->stream, 1);
1556 else 1680 else
1557 return -EINVAL; 1681 return -EINVAL;
@@ -1740,6 +1864,19 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1740 return 0; 1864 return 0;
1741} 1865}
1742 1866
1867static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
1868{
1869 struct snd_soc_codec *codec = dai->codec;
1870 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1871
1872 if (tristate)
1873 reg |= TWL4030_AIF_TRI_EN;
1874 else
1875 reg &= ~TWL4030_AIF_TRI_EN;
1876
1877 return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
1878}
1879
1743/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R 1880/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
1744 * (VTXL, VTXR) for uplink has to be enabled/disabled. */ 1881 * (VTXL, VTXR) for uplink has to be enabled/disabled. */
1745static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, 1882static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
@@ -1882,7 +2019,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1882 2019
1883 /* set master/slave audio interface */ 2020 /* set master/slave audio interface */
1884 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 2021 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1885 case SND_SOC_DAIFMT_CBS_CFM: 2022 case SND_SOC_DAIFMT_CBM_CFM:
1886 format &= ~(TWL4030_VIF_SLAVE_EN); 2023 format &= ~(TWL4030_VIF_SLAVE_EN);
1887 break; 2024 break;
1888 case SND_SOC_DAIFMT_CBS_CFS: 2025 case SND_SOC_DAIFMT_CBS_CFS:
@@ -1914,6 +2051,19 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1914 return 0; 2051 return 0;
1915} 2052}
1916 2053
2054static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2055{
2056 struct snd_soc_codec *codec = dai->codec;
2057 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
2058
2059 if (tristate)
2060 reg |= TWL4030_VIF_TRI_EN;
2061 else
2062 reg &= ~TWL4030_VIF_TRI_EN;
2063
2064 return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
2065}
2066
1917#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) 2067#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
1918#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) 2068#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
1919 2069
@@ -1923,6 +2073,7 @@ static struct snd_soc_dai_ops twl4030_dai_ops = {
1923 .hw_params = twl4030_hw_params, 2073 .hw_params = twl4030_hw_params,
1924 .set_sysclk = twl4030_set_dai_sysclk, 2074 .set_sysclk = twl4030_set_dai_sysclk,
1925 .set_fmt = twl4030_set_dai_fmt, 2075 .set_fmt = twl4030_set_dai_fmt,
2076 .set_tristate = twl4030_set_tristate,
1926}; 2077};
1927 2078
1928static struct snd_soc_dai_ops twl4030_dai_voice_ops = { 2079static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
@@ -1931,6 +2082,7 @@ static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
1931 .hw_params = twl4030_voice_hw_params, 2082 .hw_params = twl4030_voice_hw_params,
1932 .set_sysclk = twl4030_voice_set_dai_sysclk, 2083 .set_sysclk = twl4030_voice_set_dai_sysclk,
1933 .set_fmt = twl4030_voice_set_dai_fmt, 2084 .set_fmt = twl4030_voice_set_dai_fmt,
2085 .set_tristate = twl4030_voice_set_tristate,
1934}; 2086};
1935 2087
1936struct snd_soc_dai twl4030_dai[] = { 2088struct snd_soc_dai twl4030_dai[] = {
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 48326e2bd9de..2b4bfa23f985 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -92,8 +92,9 @@
92#define TWL4030_REG_VIBRA_PWM_SET 0x47 92#define TWL4030_REG_VIBRA_PWM_SET 0x47
93#define TWL4030_REG_ANAMIC_GAIN 0x48 93#define TWL4030_REG_ANAMIC_GAIN 0x48
94#define TWL4030_REG_MISC_SET_2 0x49 94#define TWL4030_REG_MISC_SET_2 0x49
95#define TWL4030_REG_SW_SHADOW 0x4A
95 96
96#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1) 97#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
97 98
98/* Bitfield Definitions */ 99/* Bitfield Definitions */
99 100
@@ -260,6 +261,10 @@
260#define TWL4030_SMOOTH_ANAVOL_EN 0x02 261#define TWL4030_SMOOTH_ANAVOL_EN 0x02
261#define TWL4030_DIGMIC_LR_SWAP_EN 0x01 262#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
262 263
264/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
265#define TWL4030_HFL_EN 0x01
266#define TWL4030_HFR_EN 0x02
267
263#define TWL4030_DAI_HIFI 0 268#define TWL4030_DAI_HIFI 0
264#define TWL4030_DAI_VOICE 1 269#define TWL4030_DAI_VOICE 1
265 270
@@ -269,6 +274,8 @@ extern struct snd_soc_codec_device soc_codec_dev_twl4030;
269struct twl4030_setup_data { 274struct twl4030_setup_data {
270 unsigned int ramp_delay_value; 275 unsigned int ramp_delay_value;
271 unsigned int sysclk; 276 unsigned int sysclk;
277 unsigned int hs_extmute:1;
278 void (*set_hs_extmute)(int mute);
272}; 279};
273 280
274#endif /* End of __TWL4030_AUDIO_H__ */ 281#endif /* End of __TWL4030_AUDIO_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index ddefb8f80145..269b108e1de6 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -101,7 +101,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); 101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
102 102
103 if (reg >= UDA134X_REGS_NUM) { 103 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %d", 104 printk(KERN_ERR "%s unkown register: reg: %u",
105 __func__, reg); 105 __func__, reg);
106 return -EINVAL; 106 return -EINVAL;
107 } 107 }
@@ -296,7 +296,7 @@ static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
296 struct snd_soc_codec *codec = codec_dai->codec; 296 struct snd_soc_codec *codec = codec_dai->codec;
297 struct uda134x_priv *uda134x = codec->private_data; 297 struct uda134x_priv *uda134x = codec->private_data;
298 298
299 pr_debug("%s clk_id: %d, freq: %d, dir: %d\n", __func__, 299 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
300 clk_id, freq, dir); 300 clk_id, freq, dir);
301 301
302 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable 302 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 5b21594e0e58..92ec03442154 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -5,9 +5,7 @@
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 * 7 *
8 * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com> 8 * Copyright (c) 2007-2009 Philipp Zabel <philipp.zabel@gmail.com>
9 * Improved support for DAPM and audio routing/mixing capabilities,
10 * added TLV support.
11 * 9 *
12 * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC 10 * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC
13 * codec model. 11 * codec model.
@@ -19,26 +17,32 @@
19#include <linux/module.h> 17#include <linux/module.h>
20#include <linux/init.h> 18#include <linux/init.h>
21#include <linux/types.h> 19#include <linux/types.h>
22#include <linux/string.h>
23#include <linux/slab.h> 20#include <linux/slab.h>
24#include <linux/errno.h> 21#include <linux/errno.h>
25#include <linux/ioctl.h> 22#include <linux/gpio.h>
26#include <linux/delay.h> 23#include <linux/delay.h>
27#include <linux/i2c.h> 24#include <linux/i2c.h>
28#include <linux/workqueue.h> 25#include <linux/workqueue.h>
29#include <sound/core.h> 26#include <sound/core.h>
30#include <sound/control.h> 27#include <sound/control.h>
31#include <sound/initval.h> 28#include <sound/initval.h>
32#include <sound/info.h>
33#include <sound/soc.h> 29#include <sound/soc.h>
34#include <sound/soc-dapm.h> 30#include <sound/soc-dapm.h>
35#include <sound/tlv.h> 31#include <sound/tlv.h>
32#include <sound/uda1380.h>
36 33
37#include "uda1380.h" 34#include "uda1380.h"
38 35
39static struct work_struct uda1380_work;
40static struct snd_soc_codec *uda1380_codec; 36static struct snd_soc_codec *uda1380_codec;
41 37
38/* codec private data */
39struct uda1380_priv {
40 struct snd_soc_codec codec;
41 u16 reg_cache[UDA1380_CACHEREGNUM];
42 unsigned int dac_clk;
43 struct work_struct work;
44};
45
42/* 46/*
43 * uda1380 register cache 47 * uda1380 register cache
44 */ 48 */
@@ -473,6 +477,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
473 struct snd_soc_pcm_runtime *rtd = substream->private_data; 477 struct snd_soc_pcm_runtime *rtd = substream->private_data;
474 struct snd_soc_device *socdev = rtd->socdev; 478 struct snd_soc_device *socdev = rtd->socdev;
475 struct snd_soc_codec *codec = socdev->card->codec; 479 struct snd_soc_codec *codec = socdev->card->codec;
480 struct uda1380_priv *uda1380 = codec->private_data;
476 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); 481 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
477 482
478 switch (cmd) { 483 switch (cmd) {
@@ -480,13 +485,13 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
480 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 485 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
481 uda1380_write_reg_cache(codec, UDA1380_MIXER, 486 uda1380_write_reg_cache(codec, UDA1380_MIXER,
482 mixer & ~R14_SILENCE); 487 mixer & ~R14_SILENCE);
483 schedule_work(&uda1380_work); 488 schedule_work(&uda1380->work);
484 break; 489 break;
485 case SNDRV_PCM_TRIGGER_STOP: 490 case SNDRV_PCM_TRIGGER_STOP:
486 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 491 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
487 uda1380_write_reg_cache(codec, UDA1380_MIXER, 492 uda1380_write_reg_cache(codec, UDA1380_MIXER,
488 mixer | R14_SILENCE); 493 mixer | R14_SILENCE);
489 schedule_work(&uda1380_work); 494 schedule_work(&uda1380->work);
490 break; 495 break;
491 } 496 }
492 return 0; 497 return 0;
@@ -670,44 +675,33 @@ static int uda1380_resume(struct platform_device *pdev)
670 return 0; 675 return 0;
671} 676}
672 677
673/* 678static int uda1380_probe(struct platform_device *pdev)
674 * initialise the UDA1380 driver
675 * register mixer and dsp interfaces with the kernel
676 */
677static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
678{ 679{
679 struct snd_soc_codec *codec = socdev->card->codec; 680 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
681 struct snd_soc_codec *codec;
682 struct uda1380_platform_data *pdata;
680 int ret = 0; 683 int ret = 0;
681 684
682 codec->name = "UDA1380"; 685 if (uda1380_codec == NULL) {
683 codec->owner = THIS_MODULE; 686 dev_err(&pdev->dev, "Codec device not registered\n");
684 codec->read = uda1380_read_reg_cache; 687 return -ENODEV;
685 codec->write = uda1380_write; 688 }
686 codec->set_bias_level = uda1380_set_bias_level;
687 codec->dai = uda1380_dai;
688 codec->num_dai = ARRAY_SIZE(uda1380_dai);
689 codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg),
690 GFP_KERNEL);
691 if (codec->reg_cache == NULL)
692 return -ENOMEM;
693 codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
694 codec->reg_cache_step = 1;
695 uda1380_reset(codec);
696 689
697 uda1380_codec = codec; 690 socdev->card->codec = uda1380_codec;
698 INIT_WORK(&uda1380_work, uda1380_flush_work); 691 codec = uda1380_codec;
692 pdata = codec->dev->platform_data;
699 693
700 /* register pcms */ 694 /* register pcms */
701 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 695 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
702 if (ret < 0) { 696 if (ret < 0) {
703 pr_err("uda1380: failed to create pcms\n"); 697 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
704 goto pcm_err; 698 goto pcm_err;
705 } 699 }
706 700
707 /* power on device */ 701 /* power on device */
708 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 702 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
709 /* set clock input */ 703 /* set clock input */
710 switch (dac_clk) { 704 switch (pdata->dac_clk) {
711 case UDA1380_DAC_CLK_SYSCLK: 705 case UDA1380_DAC_CLK_SYSCLK:
712 uda1380_write(codec, UDA1380_CLK, 0); 706 uda1380_write(codec, UDA1380_CLK, 0);
713 break; 707 break;
@@ -716,13 +710,12 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
716 break; 710 break;
717 } 711 }
718 712
719 /* uda1380 init */
720 snd_soc_add_controls(codec, uda1380_snd_controls, 713 snd_soc_add_controls(codec, uda1380_snd_controls,
721 ARRAY_SIZE(uda1380_snd_controls)); 714 ARRAY_SIZE(uda1380_snd_controls));
722 uda1380_add_widgets(codec); 715 uda1380_add_widgets(codec);
723 ret = snd_soc_init_card(socdev); 716 ret = snd_soc_init_card(socdev);
724 if (ret < 0) { 717 if (ret < 0) {
725 pr_err("uda1380: failed to register card\n"); 718 dev_err(codec->dev, "failed to register card: %d\n", ret);
726 goto card_err; 719 goto card_err;
727 } 720 }
728 721
@@ -732,165 +725,201 @@ card_err:
732 snd_soc_free_pcms(socdev); 725 snd_soc_free_pcms(socdev);
733 snd_soc_dapm_free(socdev); 726 snd_soc_dapm_free(socdev);
734pcm_err: 727pcm_err:
735 kfree(codec->reg_cache);
736 return ret; 728 return ret;
737} 729}
738 730
739static struct snd_soc_device *uda1380_socdev; 731/* power down chip */
740 732static int uda1380_remove(struct platform_device *pdev)
741#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
742
743static int uda1380_i2c_probe(struct i2c_client *i2c,
744 const struct i2c_device_id *id)
745{ 733{
746 struct snd_soc_device *socdev = uda1380_socdev; 734 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
747 struct uda1380_setup_data *setup = socdev->codec_data;
748 struct snd_soc_codec *codec = socdev->card->codec; 735 struct snd_soc_codec *codec = socdev->card->codec;
749 int ret;
750
751 i2c_set_clientdata(i2c, codec);
752 codec->control_data = i2c;
753 736
754 ret = uda1380_init(socdev, setup->dac_clk); 737 if (codec->control_data)
755 if (ret < 0) 738 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
756 pr_err("uda1380: failed to initialise UDA1380\n");
757 739
758 return ret; 740 snd_soc_free_pcms(socdev);
759} 741 snd_soc_dapm_free(socdev);
760 742
761static int uda1380_i2c_remove(struct i2c_client *client)
762{
763 struct snd_soc_codec *codec = i2c_get_clientdata(client);
764 kfree(codec->reg_cache);
765 return 0; 743 return 0;
766} 744}
767 745
768static const struct i2c_device_id uda1380_i2c_id[] = { 746struct snd_soc_codec_device soc_codec_dev_uda1380 = {
769 { "uda1380", 0 }, 747 .probe = uda1380_probe,
770 { } 748 .remove = uda1380_remove,
771}; 749 .suspend = uda1380_suspend,
772MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id); 750 .resume = uda1380_resume,
773
774static struct i2c_driver uda1380_i2c_driver = {
775 .driver = {
776 .name = "UDA1380 I2C Codec",
777 .owner = THIS_MODULE,
778 },
779 .probe = uda1380_i2c_probe,
780 .remove = uda1380_i2c_remove,
781 .id_table = uda1380_i2c_id,
782}; 751};
752EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
783 753
784static int uda1380_add_i2c_device(struct platform_device *pdev, 754static int uda1380_register(struct uda1380_priv *uda1380)
785 const struct uda1380_setup_data *setup)
786{ 755{
787 struct i2c_board_info info; 756 int ret, i;
788 struct i2c_adapter *adapter; 757 struct snd_soc_codec *codec = &uda1380->codec;
789 struct i2c_client *client; 758 struct uda1380_platform_data *pdata = codec->dev->platform_data;
790 int ret;
791 759
792 ret = i2c_add_driver(&uda1380_i2c_driver); 760 if (uda1380_codec) {
793 if (ret != 0) { 761 dev_err(codec->dev, "Another UDA1380 is registered\n");
794 dev_err(&pdev->dev, "can't add i2c driver\n"); 762 return -EINVAL;
795 return ret; 763 }
764
765 if (!pdata || !pdata->gpio_power || !pdata->gpio_reset)
766 return -EINVAL;
767
768 ret = gpio_request(pdata->gpio_power, "uda1380 power");
769 if (ret)
770 goto err_out;
771 ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
772 if (ret)
773 goto err_gpio;
774
775 gpio_direction_output(pdata->gpio_power, 1);
776
777 /* we may need to have the clock running here - pH5 */
778 gpio_direction_output(pdata->gpio_reset, 1);
779 udelay(5);
780 gpio_set_value(pdata->gpio_reset, 0);
781
782 mutex_init(&codec->mutex);
783 INIT_LIST_HEAD(&codec->dapm_widgets);
784 INIT_LIST_HEAD(&codec->dapm_paths);
785
786 codec->private_data = uda1380;
787 codec->name = "UDA1380";
788 codec->owner = THIS_MODULE;
789 codec->read = uda1380_read_reg_cache;
790 codec->write = uda1380_write;
791 codec->bias_level = SND_SOC_BIAS_OFF;
792 codec->set_bias_level = uda1380_set_bias_level;
793 codec->dai = uda1380_dai;
794 codec->num_dai = ARRAY_SIZE(uda1380_dai);
795 codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
796 codec->reg_cache = &uda1380->reg_cache;
797 codec->reg_cache_step = 1;
798
799 memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg));
800
801 ret = uda1380_reset(codec);
802 if (ret < 0) {
803 dev_err(codec->dev, "Failed to issue reset\n");
804 goto err_reset;
796 } 805 }
797 806
798 memset(&info, 0, sizeof(struct i2c_board_info)); 807 INIT_WORK(&uda1380->work, uda1380_flush_work);
799 info.addr = setup->i2c_address; 808
800 strlcpy(info.type, "uda1380", I2C_NAME_SIZE); 809 for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++)
810 uda1380_dai[i].dev = codec->dev;
801 811
802 adapter = i2c_get_adapter(setup->i2c_bus); 812 uda1380_codec = codec;
803 if (!adapter) { 813
804 dev_err(&pdev->dev, "can't get i2c adapter %d\n", 814 ret = snd_soc_register_codec(codec);
805 setup->i2c_bus); 815 if (ret != 0) {
806 goto err_driver; 816 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
817 goto err_reset;
807 } 818 }
808 819
809 client = i2c_new_device(adapter, &info); 820 ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
810 i2c_put_adapter(adapter); 821 if (ret != 0) {
811 if (!client) { 822 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
812 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", 823 goto err_dai;
813 (unsigned int)info.addr);
814 goto err_driver;
815 } 824 }
816 825
817 return 0; 826 return 0;
818 827
819err_driver: 828err_dai:
820 i2c_del_driver(&uda1380_i2c_driver); 829 snd_soc_unregister_codec(codec);
821 return -ENODEV; 830err_reset:
831 gpio_set_value(pdata->gpio_power, 0);
832 gpio_free(pdata->gpio_reset);
833err_gpio:
834 gpio_free(pdata->gpio_power);
835err_out:
836 return ret;
822} 837}
823#endif
824 838
825static int uda1380_probe(struct platform_device *pdev) 839static void uda1380_unregister(struct uda1380_priv *uda1380)
826{ 840{
827 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 841 struct snd_soc_codec *codec = &uda1380->codec;
828 struct uda1380_setup_data *setup; 842 struct uda1380_platform_data *pdata = codec->dev->platform_data;
843
844 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
845 snd_soc_unregister_codec(&uda1380->codec);
846
847 gpio_set_value(pdata->gpio_power, 0);
848 gpio_free(pdata->gpio_reset);
849 gpio_free(pdata->gpio_power);
850
851 kfree(uda1380);
852 uda1380_codec = NULL;
853}
854
855#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
856static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
857 const struct i2c_device_id *id)
858{
859 struct uda1380_priv *uda1380;
829 struct snd_soc_codec *codec; 860 struct snd_soc_codec *codec;
830 int ret; 861 int ret;
831 862
832 setup = socdev->codec_data; 863 uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
833 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 864 if (uda1380 == NULL)
834 if (codec == NULL)
835 return -ENOMEM; 865 return -ENOMEM;
836 866
837 socdev->card->codec = codec; 867 codec = &uda1380->codec;
838 mutex_init(&codec->mutex); 868 codec->hw_write = (hw_write_t)i2c_master_send;
839 INIT_LIST_HEAD(&codec->dapm_widgets);
840 INIT_LIST_HEAD(&codec->dapm_paths);
841 869
842 uda1380_socdev = socdev; 870 i2c_set_clientdata(i2c, uda1380);
843 ret = -ENODEV; 871 codec->control_data = i2c;
844 872
845#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 873 codec->dev = &i2c->dev;
846 if (setup->i2c_address) {
847 codec->hw_write = (hw_write_t)i2c_master_send;
848 ret = uda1380_add_i2c_device(pdev, setup);
849 }
850#endif
851 874
875 ret = uda1380_register(uda1380);
852 if (ret != 0) 876 if (ret != 0)
853 kfree(codec); 877 kfree(uda1380);
878
854 return ret; 879 return ret;
855} 880}
856 881
857/* power down chip */ 882static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
858static int uda1380_remove(struct platform_device *pdev)
859{ 883{
860 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 884 struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c);
861 struct snd_soc_codec *codec = socdev->card->codec; 885 uda1380_unregister(uda1380);
862
863 if (codec->control_data)
864 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
865
866 snd_soc_free_pcms(socdev);
867 snd_soc_dapm_free(socdev);
868#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
869 i2c_unregister_device(codec->control_data);
870 i2c_del_driver(&uda1380_i2c_driver);
871#endif
872 kfree(codec);
873
874 return 0; 886 return 0;
875} 887}
876 888
877struct snd_soc_codec_device soc_codec_dev_uda1380 = { 889static const struct i2c_device_id uda1380_i2c_id[] = {
878 .probe = uda1380_probe, 890 { "uda1380", 0 },
879 .remove = uda1380_remove, 891 { }
880 .suspend = uda1380_suspend,
881 .resume = uda1380_resume,
882}; 892};
883EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); 893MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
894
895static struct i2c_driver uda1380_i2c_driver = {
896 .driver = {
897 .name = "UDA1380 I2C Codec",
898 .owner = THIS_MODULE,
899 },
900 .probe = uda1380_i2c_probe,
901 .remove = __devexit_p(uda1380_i2c_remove),
902 .id_table = uda1380_i2c_id,
903};
904#endif
884 905
885static int __init uda1380_modinit(void) 906static int __init uda1380_modinit(void)
886{ 907{
887 return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 908 int ret;
909#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
910 ret = i2c_add_driver(&uda1380_i2c_driver);
911 if (ret != 0)
912 pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
913#endif
914 return 0;
888} 915}
889module_init(uda1380_modinit); 916module_init(uda1380_modinit);
890 917
891static void __exit uda1380_exit(void) 918static void __exit uda1380_exit(void)
892{ 919{
893 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 920#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
921 i2c_del_driver(&uda1380_i2c_driver);
922#endif
894} 923}
895module_exit(uda1380_exit); 924module_exit(uda1380_exit);
896 925
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
index c55c17a52a12..9cefa8a54770 100644
--- a/sound/soc/codecs/uda1380.h
+++ b/sound/soc/codecs/uda1380.h
@@ -72,14 +72,6 @@
72#define R22_SKIP_DCFIL 0x0002 72#define R22_SKIP_DCFIL 0x0002
73#define R23_AGC_EN 0x0001 73#define R23_AGC_EN 0x0001
74 74
75struct uda1380_setup_data {
76 int i2c_bus;
77 unsigned short i2c_address;
78 int dac_clk;
79#define UDA1380_DAC_CLK_SYSCLK 0
80#define UDA1380_DAC_CLK_WSPLL 1
81};
82
83#define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */ 75#define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */
84#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */ 76#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */
85#define UDA1380_DAI_CAPTURE 2 /* capture DAI */ 77#define UDA1380_DAI_CAPTURE 2 /* capture DAI */
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 0275321ff8ab..4ded0e3a35e0 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -406,7 +406,6 @@ static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
406static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" }; 406static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
407static const char *wm8350_dacmutem[] = { "Normal", "Soft" }; 407static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
408static const char *wm8350_dacmutes[] = { "Fast", "Slow" }; 408static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
409static const char *wm8350_dacfilter[] = { "Normal", "Sloping" };
410static const char *wm8350_adcfilter[] = { "None", "High Pass" }; 409static const char *wm8350_adcfilter[] = { "None", "High Pass" };
411static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" }; 410static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
412static const char *wm8350_lr[] = { "Left", "Right" }; 411static const char *wm8350_lr[] = { "Left", "Right" };
@@ -416,7 +415,6 @@ static const struct soc_enum wm8350_enum[] = {
416 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol), 415 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
417 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem), 416 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
418 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes), 417 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
419 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 12, 2, wm8350_dacfilter),
420 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter), 418 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
421 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp), 419 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
422 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol), 420 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
@@ -444,10 +442,9 @@ static const struct snd_kcontrol_new wm8350_snd_controls[] = {
444 0, 255, 0, dac_pcm_tlv), 442 0, 255, 0, dac_pcm_tlv),
445 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]), 443 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
446 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]), 444 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
447 SOC_ENUM("Playback PCM Filter", wm8350_enum[4]), 445 SOC_ENUM("Capture PCM Filter", wm8350_enum[4]),
448 SOC_ENUM("Capture PCM Filter", wm8350_enum[5]), 446 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]),
449 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[6]), 447 SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]),
450 SOC_ENUM("Capture ADC Inversion", wm8350_enum[7]),
451 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume", 448 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume",
452 WM8350_ADC_DIGITAL_VOLUME_L, 449 WM8350_ADC_DIGITAL_VOLUME_L,
453 WM8350_ADC_DIGITAL_VOLUME_R, 450 WM8350_ADC_DIGITAL_VOLUME_R,
@@ -993,6 +990,7 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
993 struct snd_soc_dai *codec_dai) 990 struct snd_soc_dai *codec_dai)
994{ 991{
995 struct snd_soc_codec *codec = codec_dai->codec; 992 struct snd_soc_codec *codec = codec_dai->codec;
993 struct wm8350 *wm8350 = codec->control_data;
996 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) & 994 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
997 ~WM8350_AIF_WL_MASK; 995 ~WM8350_AIF_WL_MASK;
998 996
@@ -1012,6 +1010,19 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
1012 } 1010 }
1013 1011
1014 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface); 1012 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
1013
1014 /* The sloping stopband filter is recommended for use with
1015 * lower sample rates to improve performance.
1016 */
1017 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1018 if (params_rate(params) < 24000)
1019 wm8350_set_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
1020 WM8350_DAC_SB_FILT);
1021 else
1022 wm8350_clear_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
1023 WM8350_DAC_SB_FILT);
1024 }
1025
1015 return 0; 1026 return 0;
1016} 1027}
1017 1028
@@ -1108,7 +1119,7 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1108 if (ret < 0) 1119 if (ret < 0)
1109 return ret; 1120 return ret;
1110 dev_dbg(wm8350->dev, 1121 dev_dbg(wm8350->dev,
1111 "FLL in %d FLL out %d N 0x%x K 0x%x div %d ratio %d", 1122 "FLL in %u FLL out %u N 0x%x K 0x%x div %d ratio %d",
1112 freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div, 1123 freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
1113 fll_div.ratio); 1124 fll_div.ratio);
1114 1125
@@ -1660,6 +1671,21 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1660 return 0; 1671 return 0;
1661} 1672}
1662 1673
1674#ifdef CONFIG_PM
1675static int wm8350_codec_suspend(struct platform_device *pdev, pm_message_t m)
1676{
1677 return snd_soc_suspend_device(&pdev->dev);
1678}
1679
1680static int wm8350_codec_resume(struct platform_device *pdev)
1681{
1682 return snd_soc_resume_device(&pdev->dev);
1683}
1684#else
1685#define wm8350_codec_suspend NULL
1686#define wm8350_codec_resume NULL
1687#endif
1688
1663static struct platform_driver wm8350_codec_driver = { 1689static struct platform_driver wm8350_codec_driver = {
1664 .driver = { 1690 .driver = {
1665 .name = "wm8350-codec", 1691 .name = "wm8350-codec",
@@ -1667,6 +1693,8 @@ static struct platform_driver wm8350_codec_driver = {
1667 }, 1693 },
1668 .probe = wm8350_codec_probe, 1694 .probe = wm8350_codec_probe,
1669 .remove = __devexit_p(wm8350_codec_remove), 1695 .remove = __devexit_p(wm8350_codec_remove),
1696 .suspend = wm8350_codec_suspend,
1697 .resume = wm8350_codec_resume,
1670}; 1698};
1671 1699
1672static __init int wm8350_init(void) 1700static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index e4547de8eec2..b9ef4d915221 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -954,7 +954,7 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
954 factors->outdiv *= 2; 954 factors->outdiv *= 2;
955 if (factors->outdiv > 32) { 955 if (factors->outdiv > 32) {
956 dev_err(wm8400->wm8400->dev, 956 dev_err(wm8400->wm8400->dev,
957 "Unsupported FLL output frequency %dHz\n", 957 "Unsupported FLL output frequency %uHz\n",
958 Fout); 958 Fout);
959 return -EINVAL; 959 return -EINVAL;
960 } 960 }
@@ -1003,7 +1003,7 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
1003 factors->k = K / 10; 1003 factors->k = K / 10;
1004 1004
1005 dev_dbg(wm8400->wm8400->dev, 1005 dev_dbg(wm8400->wm8400->dev,
1006 "FLL: Fref=%d Fout=%d N=%x K=%x, FRATIO=%x OUTDIV=%x\n", 1006 "FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
1007 Fref, Fout, 1007 Fref, Fout,
1008 factors->n, factors->k, factors->fratio, factors->outdiv); 1008 factors->n, factors->k, factors->fratio, factors->outdiv);
1009 1009
@@ -1022,10 +1022,15 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1022 if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out) 1022 if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out)
1023 return 0; 1023 return 0;
1024 1024
1025 if (freq_out != 0) { 1025 if (freq_out) {
1026 ret = fll_factors(wm8400, &factors, freq_in, freq_out); 1026 ret = fll_factors(wm8400, &factors, freq_in, freq_out);
1027 if (ret != 0) 1027 if (ret != 0)
1028 return ret; 1028 return ret;
1029 } else {
1030 /* Bodge GCC 4.4.0 uninitialised variable warning - it
1031 * doesn't seem capable of working out that we exit if
1032 * freq_out is 0 before any of the uses. */
1033 memset(&factors, 0, sizeof(factors));
1029 } 1034 }
1030 1035
1031 wm8400->fll_out = freq_out; 1036 wm8400->fll_out = freq_out;
@@ -1040,7 +1045,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1040 reg &= ~WM8400_FLL_OSC_ENA; 1045 reg &= ~WM8400_FLL_OSC_ENA;
1041 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); 1046 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg);
1042 1047
1043 if (freq_out == 0) 1048 if (!freq_out)
1044 return 0; 1049 return 0;
1045 1050
1046 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK); 1051 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
@@ -1553,6 +1558,21 @@ static int __exit wm8400_codec_remove(struct platform_device *dev)
1553 return 0; 1558 return 0;
1554} 1559}
1555 1560
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
1556static struct platform_driver wm8400_codec_driver = { 1576static struct platform_driver wm8400_codec_driver = {
1557 .driver = { 1577 .driver = {
1558 .name = "wm8400-codec", 1578 .name = "wm8400-codec",
@@ -1560,6 +1580,8 @@ static struct platform_driver wm8400_codec_driver = {
1560 }, 1580 },
1561 .probe = wm8400_codec_probe, 1581 .probe = wm8400_codec_probe,
1562 .remove = __exit_p(wm8400_codec_remove), 1582 .remove = __exit_p(wm8400_codec_remove),
1583 .suspend = wm8400_pdev_suspend,
1584 .resume = wm8400_pdev_resume,
1563}; 1585};
1564 1586
1565static int __init wm8400_codec_init(void) 1587static int __init wm8400_codec_init(void)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 6a4cea09c45d..060d5d06ba95 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -58,55 +58,7 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
58#define WM8510_POWER1_BIASEN 0x08 58#define WM8510_POWER1_BIASEN 0x08
59#define WM8510_POWER1_BUFIOEN 0x10 59#define WM8510_POWER1_BUFIOEN 0x10
60 60
61/* 61#define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0)
62 * read wm8510 register cache
63 */
64static inline unsigned int wm8510_read_reg_cache(struct snd_soc_codec *codec,
65 unsigned int reg)
66{
67 u16 *cache = codec->reg_cache;
68 if (reg == WM8510_RESET)
69 return 0;
70 if (reg >= WM8510_CACHEREGNUM)
71 return -1;
72 return cache[reg];
73}
74
75/*
76 * write wm8510 register cache
77 */
78static inline void wm8510_write_reg_cache(struct snd_soc_codec *codec,
79 u16 reg, unsigned int value)
80{
81 u16 *cache = codec->reg_cache;
82 if (reg >= WM8510_CACHEREGNUM)
83 return;
84 cache[reg] = value;
85}
86
87/*
88 * write to the WM8510 register space
89 */
90static int wm8510_write(struct snd_soc_codec *codec, unsigned int reg,
91 unsigned int value)
92{
93 u8 data[2];
94
95 /* data is
96 * D15..D9 WM8510 register offset
97 * D8...D0 register data
98 */
99 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
100 data[1] = value & 0x00ff;
101
102 wm8510_write_reg_cache(codec, reg, value);
103 if (codec->hw_write(codec->control_data, data, 2) == 2)
104 return 0;
105 else
106 return -EIO;
107}
108
109#define wm8510_reset(c) wm8510_write(c, WM8510_RESET, 0)
110 62
111static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" }; 63static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
112static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" }; 64static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
@@ -298,7 +250,7 @@ static void pll_factors(unsigned int target, unsigned int source)
298 250
299 if ((Ndiv < 6) || (Ndiv > 12)) 251 if ((Ndiv < 6) || (Ndiv > 12))
300 printk(KERN_WARNING 252 printk(KERN_WARNING
301 "WM8510 N value %d outwith recommended range!d\n", 253 "WM8510 N value %u outwith recommended range!d\n",
302 Ndiv); 254 Ndiv);
303 255
304 pll_div.n = Ndiv; 256 pll_div.n = Ndiv;
@@ -327,27 +279,27 @@ static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai,
327 279
328 if (freq_in == 0 || freq_out == 0) { 280 if (freq_in == 0 || freq_out == 0) {
329 /* Clock CODEC directly from MCLK */ 281 /* Clock CODEC directly from MCLK */
330 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK); 282 reg = snd_soc_read(codec, WM8510_CLOCK);
331 wm8510_write(codec, WM8510_CLOCK, reg & 0x0ff); 283 snd_soc_write(codec, WM8510_CLOCK, reg & 0x0ff);
332 284
333 /* Turn off PLL */ 285 /* Turn off PLL */
334 reg = wm8510_read_reg_cache(codec, WM8510_POWER1); 286 reg = snd_soc_read(codec, WM8510_POWER1);
335 wm8510_write(codec, WM8510_POWER1, reg & 0x1df); 287 snd_soc_write(codec, WM8510_POWER1, reg & 0x1df);
336 return 0; 288 return 0;
337 } 289 }
338 290
339 pll_factors(freq_out*4, freq_in); 291 pll_factors(freq_out*4, freq_in);
340 292
341 wm8510_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n); 293 snd_soc_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
342 wm8510_write(codec, WM8510_PLLK1, pll_div.k >> 18); 294 snd_soc_write(codec, WM8510_PLLK1, pll_div.k >> 18);
343 wm8510_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff); 295 snd_soc_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
344 wm8510_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff); 296 snd_soc_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff);
345 reg = wm8510_read_reg_cache(codec, WM8510_POWER1); 297 reg = snd_soc_read(codec, WM8510_POWER1);
346 wm8510_write(codec, WM8510_POWER1, reg | 0x020); 298 snd_soc_write(codec, WM8510_POWER1, reg | 0x020);
347 299
348 /* Run CODEC from PLL instead of MCLK */ 300 /* Run CODEC from PLL instead of MCLK */
349 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK); 301 reg = snd_soc_read(codec, WM8510_CLOCK);
350 wm8510_write(codec, WM8510_CLOCK, reg | 0x100); 302 snd_soc_write(codec, WM8510_CLOCK, reg | 0x100);
351 303
352 return 0; 304 return 0;
353} 305}
@@ -363,24 +315,24 @@ static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
363 315
364 switch (div_id) { 316 switch (div_id) {
365 case WM8510_OPCLKDIV: 317 case WM8510_OPCLKDIV:
366 reg = wm8510_read_reg_cache(codec, WM8510_GPIO) & 0x1cf; 318 reg = snd_soc_read(codec, WM8510_GPIO) & 0x1cf;
367 wm8510_write(codec, WM8510_GPIO, reg | div); 319 snd_soc_write(codec, WM8510_GPIO, reg | div);
368 break; 320 break;
369 case WM8510_MCLKDIV: 321 case WM8510_MCLKDIV:
370 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x11f; 322 reg = snd_soc_read(codec, WM8510_CLOCK) & 0x11f;
371 wm8510_write(codec, WM8510_CLOCK, reg | div); 323 snd_soc_write(codec, WM8510_CLOCK, reg | div);
372 break; 324 break;
373 case WM8510_ADCCLK: 325 case WM8510_ADCCLK:
374 reg = wm8510_read_reg_cache(codec, WM8510_ADC) & 0x1f7; 326 reg = snd_soc_read(codec, WM8510_ADC) & 0x1f7;
375 wm8510_write(codec, WM8510_ADC, reg | div); 327 snd_soc_write(codec, WM8510_ADC, reg | div);
376 break; 328 break;
377 case WM8510_DACCLK: 329 case WM8510_DACCLK:
378 reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0x1f7; 330 reg = snd_soc_read(codec, WM8510_DAC) & 0x1f7;
379 wm8510_write(codec, WM8510_DAC, reg | div); 331 snd_soc_write(codec, WM8510_DAC, reg | div);
380 break; 332 break;
381 case WM8510_BCLKDIV: 333 case WM8510_BCLKDIV:
382 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1e3; 334 reg = snd_soc_read(codec, WM8510_CLOCK) & 0x1e3;
383 wm8510_write(codec, WM8510_CLOCK, reg | div); 335 snd_soc_write(codec, WM8510_CLOCK, reg | div);
384 break; 336 break;
385 default: 337 default:
386 return -EINVAL; 338 return -EINVAL;
@@ -394,7 +346,7 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
394{ 346{
395 struct snd_soc_codec *codec = codec_dai->codec; 347 struct snd_soc_codec *codec = codec_dai->codec;
396 u16 iface = 0; 348 u16 iface = 0;
397 u16 clk = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1fe; 349 u16 clk = snd_soc_read(codec, WM8510_CLOCK) & 0x1fe;
398 350
399 /* set master/slave audio interface */ 351 /* set master/slave audio interface */
400 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 352 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -441,8 +393,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
441 return -EINVAL; 393 return -EINVAL;
442 } 394 }
443 395
444 wm8510_write(codec, WM8510_IFACE, iface); 396 snd_soc_write(codec, WM8510_IFACE, iface);
445 wm8510_write(codec, WM8510_CLOCK, clk); 397 snd_soc_write(codec, WM8510_CLOCK, clk);
446 return 0; 398 return 0;
447} 399}
448 400
@@ -453,8 +405,8 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
453 struct snd_soc_pcm_runtime *rtd = substream->private_data; 405 struct snd_soc_pcm_runtime *rtd = substream->private_data;
454 struct snd_soc_device *socdev = rtd->socdev; 406 struct snd_soc_device *socdev = rtd->socdev;
455 struct snd_soc_codec *codec = socdev->card->codec; 407 struct snd_soc_codec *codec = socdev->card->codec;
456 u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f; 408 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
457 u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1; 409 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
458 410
459 /* bit size */ 411 /* bit size */
460 switch (params_format(params)) { 412 switch (params_format(params)) {
@@ -493,20 +445,20 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
493 break; 445 break;
494 } 446 }
495 447
496 wm8510_write(codec, WM8510_IFACE, iface); 448 snd_soc_write(codec, WM8510_IFACE, iface);
497 wm8510_write(codec, WM8510_ADD, adn); 449 snd_soc_write(codec, WM8510_ADD, adn);
498 return 0; 450 return 0;
499} 451}
500 452
501static int wm8510_mute(struct snd_soc_dai *dai, int mute) 453static int wm8510_mute(struct snd_soc_dai *dai, int mute)
502{ 454{
503 struct snd_soc_codec *codec = dai->codec; 455 struct snd_soc_codec *codec = dai->codec;
504 u16 mute_reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0xffbf; 456 u16 mute_reg = snd_soc_read(codec, WM8510_DAC) & 0xffbf;
505 457
506 if (mute) 458 if (mute)
507 wm8510_write(codec, WM8510_DAC, mute_reg | 0x40); 459 snd_soc_write(codec, WM8510_DAC, mute_reg | 0x40);
508 else 460 else
509 wm8510_write(codec, WM8510_DAC, mute_reg); 461 snd_soc_write(codec, WM8510_DAC, mute_reg);
510 return 0; 462 return 0;
511} 463}
512 464
@@ -514,13 +466,13 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
514static int wm8510_set_bias_level(struct snd_soc_codec *codec, 466static int wm8510_set_bias_level(struct snd_soc_codec *codec,
515 enum snd_soc_bias_level level) 467 enum snd_soc_bias_level level)
516{ 468{
517 u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3; 469 u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
518 470
519 switch (level) { 471 switch (level) {
520 case SND_SOC_BIAS_ON: 472 case SND_SOC_BIAS_ON:
521 case SND_SOC_BIAS_PREPARE: 473 case SND_SOC_BIAS_PREPARE:
522 power1 |= 0x1; /* VMID 50k */ 474 power1 |= 0x1; /* VMID 50k */
523 wm8510_write(codec, WM8510_POWER1, power1); 475 snd_soc_write(codec, WM8510_POWER1, power1);
524 break; 476 break;
525 477
526 case SND_SOC_BIAS_STANDBY: 478 case SND_SOC_BIAS_STANDBY:
@@ -528,18 +480,18 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
528 480
529 if (codec->bias_level == SND_SOC_BIAS_OFF) { 481 if (codec->bias_level == SND_SOC_BIAS_OFF) {
530 /* Initial cap charge at VMID 5k */ 482 /* Initial cap charge at VMID 5k */
531 wm8510_write(codec, WM8510_POWER1, power1 | 0x3); 483 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
532 mdelay(100); 484 mdelay(100);
533 } 485 }
534 486
535 power1 |= 0x2; /* VMID 500k */ 487 power1 |= 0x2; /* VMID 500k */
536 wm8510_write(codec, WM8510_POWER1, power1); 488 snd_soc_write(codec, WM8510_POWER1, power1);
537 break; 489 break;
538 490
539 case SND_SOC_BIAS_OFF: 491 case SND_SOC_BIAS_OFF:
540 wm8510_write(codec, WM8510_POWER1, 0); 492 snd_soc_write(codec, WM8510_POWER1, 0);
541 wm8510_write(codec, WM8510_POWER2, 0); 493 snd_soc_write(codec, WM8510_POWER2, 0);
542 wm8510_write(codec, WM8510_POWER3, 0); 494 snd_soc_write(codec, WM8510_POWER3, 0);
543 break; 495 break;
544 } 496 }
545 497
@@ -577,6 +529,7 @@ struct snd_soc_dai wm8510_dai = {
577 .rates = WM8510_RATES, 529 .rates = WM8510_RATES,
578 .formats = WM8510_FORMATS,}, 530 .formats = WM8510_FORMATS,},
579 .ops = &wm8510_dai_ops, 531 .ops = &wm8510_dai_ops,
532 .symmetric_rates = 1,
580}; 533};
581EXPORT_SYMBOL_GPL(wm8510_dai); 534EXPORT_SYMBOL_GPL(wm8510_dai);
582 535
@@ -612,15 +565,14 @@ static int wm8510_resume(struct platform_device *pdev)
612 * initialise the WM8510 driver 565 * initialise the WM8510 driver
613 * register the mixer and dsp interfaces with the kernel 566 * register the mixer and dsp interfaces with the kernel
614 */ 567 */
615static int wm8510_init(struct snd_soc_device *socdev) 568static int wm8510_init(struct snd_soc_device *socdev,
569 enum snd_soc_control_type control)
616{ 570{
617 struct snd_soc_codec *codec = socdev->card->codec; 571 struct snd_soc_codec *codec = socdev->card->codec;
618 int ret = 0; 572 int ret = 0;
619 573
620 codec->name = "WM8510"; 574 codec->name = "WM8510";
621 codec->owner = THIS_MODULE; 575 codec->owner = THIS_MODULE;
622 codec->read = wm8510_read_reg_cache;
623 codec->write = wm8510_write;
624 codec->set_bias_level = wm8510_set_bias_level; 576 codec->set_bias_level = wm8510_set_bias_level;
625 codec->dai = &wm8510_dai; 577 codec->dai = &wm8510_dai;
626 codec->num_dai = 1; 578 codec->num_dai = 1;
@@ -630,13 +582,20 @@ static int wm8510_init(struct snd_soc_device *socdev)
630 if (codec->reg_cache == NULL) 582 if (codec->reg_cache == NULL)
631 return -ENOMEM; 583 return -ENOMEM;
632 584
585 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
586 if (ret < 0) {
587 printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n",
588 ret);
589 goto err;
590 }
591
633 wm8510_reset(codec); 592 wm8510_reset(codec);
634 593
635 /* register pcms */ 594 /* register pcms */
636 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 595 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
637 if (ret < 0) { 596 if (ret < 0) {
638 printk(KERN_ERR "wm8510: failed to create pcms\n"); 597 printk(KERN_ERR "wm8510: failed to create pcms\n");
639 goto pcm_err; 598 goto err;
640 } 599 }
641 600
642 /* power on device */ 601 /* power on device */
@@ -655,7 +614,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
655card_err: 614card_err:
656 snd_soc_free_pcms(socdev); 615 snd_soc_free_pcms(socdev);
657 snd_soc_dapm_free(socdev); 616 snd_soc_dapm_free(socdev);
658pcm_err: 617err:
659 kfree(codec->reg_cache); 618 kfree(codec->reg_cache);
660 return ret; 619 return ret;
661} 620}
@@ -678,7 +637,7 @@ static int wm8510_i2c_probe(struct i2c_client *i2c,
678 i2c_set_clientdata(i2c, codec); 637 i2c_set_clientdata(i2c, codec);
679 codec->control_data = i2c; 638 codec->control_data = i2c;
680 639
681 ret = wm8510_init(socdev); 640 ret = wm8510_init(socdev, SND_SOC_I2C);
682 if (ret < 0) 641 if (ret < 0)
683 pr_err("failed to initialise WM8510\n"); 642 pr_err("failed to initialise WM8510\n");
684 643
@@ -758,7 +717,7 @@ static int __devinit wm8510_spi_probe(struct spi_device *spi)
758 717
759 codec->control_data = spi; 718 codec->control_data = spi;
760 719
761 ret = wm8510_init(socdev); 720 ret = wm8510_init(socdev, SND_SOC_SPI);
762 if (ret < 0) 721 if (ret < 0)
763 dev_err(&spi->dev, "failed to initialise WM8510\n"); 722 dev_err(&spi->dev, "failed to initialise WM8510\n");
764 723
@@ -779,30 +738,6 @@ static struct spi_driver wm8510_spi_driver = {
779 .probe = wm8510_spi_probe, 738 .probe = wm8510_spi_probe,
780 .remove = __devexit_p(wm8510_spi_remove), 739 .remove = __devexit_p(wm8510_spi_remove),
781}; 740};
782
783static int wm8510_spi_write(struct spi_device *spi, const char *data, int len)
784{
785 struct spi_transfer t;
786 struct spi_message m;
787 u8 msg[2];
788
789 if (len <= 0)
790 return 0;
791
792 msg[0] = data[0];
793 msg[1] = data[1];
794
795 spi_message_init(&m);
796 memset(&t, 0, (sizeof t));
797
798 t.tx_buf = &msg[0];
799 t.len = len;
800
801 spi_message_add_tail(&t, &m);
802 spi_sync(spi, &m);
803
804 return len;
805}
806#endif /* CONFIG_SPI_MASTER */ 741#endif /* CONFIG_SPI_MASTER */
807 742
808static int wm8510_probe(struct platform_device *pdev) 743static int wm8510_probe(struct platform_device *pdev)
@@ -827,13 +762,11 @@ static int wm8510_probe(struct platform_device *pdev)
827 wm8510_socdev = socdev; 762 wm8510_socdev = socdev;
828#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 763#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
829 if (setup->i2c_address) { 764 if (setup->i2c_address) {
830 codec->hw_write = (hw_write_t)i2c_master_send;
831 ret = wm8510_add_i2c_device(pdev, setup); 765 ret = wm8510_add_i2c_device(pdev, setup);
832 } 766 }
833#endif 767#endif
834#if defined(CONFIG_SPI_MASTER) 768#if defined(CONFIG_SPI_MASTER)
835 if (setup->spi) { 769 if (setup->spi) {
836 codec->hw_write = (hw_write_t)wm8510_spi_write;
837 ret = spi_register_driver(&wm8510_spi_driver); 770 ret = spi_register_driver(&wm8510_spi_driver);
838 if (ret != 0) 771 if (ret != 0)
839 printk(KERN_ERR "can't add spi driver"); 772 printk(KERN_ERR "can't add spi driver");
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
new file mode 100644
index 000000000000..25870a4652fb
--- /dev/null
+++ b/sound/soc/codecs/wm8523.c
@@ -0,0 +1,699 @@
1/*
2 * wm8523.c -- WM8523 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29
30#include "wm8523.h"
31
32static struct snd_soc_codec *wm8523_codec;
33struct snd_soc_codec_device soc_codec_dev_wm8523;
34
35#define WM8523_NUM_SUPPLIES 2
36static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
37 "AVDD",
38 "LINEVDD",
39};
40
41#define WM8523_NUM_RATES 7
42
43/* codec private data */
44struct wm8523_priv {
45 struct snd_soc_codec codec;
46 u16 reg_cache[WM8523_REGISTER_COUNT];
47 struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
48 unsigned int sysclk;
49 unsigned int rate_constraint_list[WM8523_NUM_RATES];
50 struct snd_pcm_hw_constraint_list rate_constraint;
51};
52
53static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = {
54 0x8523, /* R0 - DEVICE_ID */
55 0x0001, /* R1 - REVISION */
56 0x0000, /* R2 - PSCTRL1 */
57 0x1812, /* R3 - AIF_CTRL1 */
58 0x0000, /* R4 - AIF_CTRL2 */
59 0x0001, /* R5 - DAC_CTRL3 */
60 0x0190, /* R6 - DAC_GAINL */
61 0x0190, /* R7 - DAC_GAINR */
62 0x0000, /* R8 - ZERO_DETECT */
63};
64
65static int wm8523_volatile_register(unsigned int reg)
66{
67 switch (reg) {
68 case WM8523_DEVICE_ID:
69 case WM8523_REVISION:
70 return 1;
71 default:
72 return 0;
73 }
74}
75
76static int wm8523_reset(struct snd_soc_codec *codec)
77{
78 return snd_soc_write(codec, WM8523_DEVICE_ID, 0);
79}
80
81static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);
82
83static const char *wm8523_zd_count_text[] = {
84 "1024",
85 "2048",
86};
87
88static const struct soc_enum wm8523_zc_count =
89 SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text);
90
91static const struct snd_kcontrol_new wm8523_snd_controls[] = {
92SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
93 0, 448, 0, dac_tlv),
94SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
95SOC_SINGLE("Playback Deemphasis Switch", WM8523_AIF_CTRL1, 8, 1, 0),
96SOC_DOUBLE("Playback Switch", WM8523_DAC_CTRL3, 2, 3, 1, 1),
97SOC_SINGLE("Volume Ramp Up Switch", WM8523_DAC_CTRL3, 1, 1, 0),
98SOC_SINGLE("Volume Ramp Down Switch", WM8523_DAC_CTRL3, 0, 1, 0),
99SOC_ENUM("Zero Detect Count", wm8523_zc_count),
100};
101
102static const struct snd_soc_dapm_widget wm8523_dapm_widgets[] = {
103SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
104SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
105SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
106};
107
108static const struct snd_soc_dapm_route intercon[] = {
109 { "LINEVOUTL", NULL, "DAC" },
110 { "LINEVOUTR", NULL, "DAC" },
111};
112
113static int wm8523_add_widgets(struct snd_soc_codec *codec)
114{
115 snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets,
116 ARRAY_SIZE(wm8523_dapm_widgets));
117
118 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
119
120 snd_soc_dapm_new_widgets(codec);
121 return 0;
122}
123
124static struct {
125 int value;
126 int ratio;
127} lrclk_ratios[WM8523_NUM_RATES] = {
128 { 1, 128 },
129 { 2, 192 },
130 { 3, 256 },
131 { 4, 384 },
132 { 5, 512 },
133 { 6, 768 },
134 { 7, 1152 },
135};
136
137static int wm8523_startup(struct snd_pcm_substream *substream,
138 struct snd_soc_dai *dai)
139{
140 struct snd_soc_codec *codec = dai->codec;
141 struct wm8523_priv *wm8523 = codec->private_data;
142
143 /* The set of sample rates that can be supported depends on the
144 * MCLK supplied to the CODEC - enforce this.
145 */
146 if (!wm8523->sysclk) {
147 dev_err(codec->dev,
148 "No MCLK configured, call set_sysclk() on init\n");
149 return -EINVAL;
150 }
151
152 return 0;
153 snd_pcm_hw_constraint_list(substream->runtime, 0,
154 SNDRV_PCM_HW_PARAM_RATE,
155 &wm8523->rate_constraint);
156
157 return 0;
158}
159
160static int wm8523_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params,
162 struct snd_soc_dai *dai)
163{
164 struct snd_soc_pcm_runtime *rtd = substream->private_data;
165 struct snd_soc_device *socdev = rtd->socdev;
166 struct snd_soc_codec *codec = socdev->card->codec;
167 struct wm8523_priv *wm8523 = codec->private_data;
168 int i;
169 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
170 u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);
171
172 /* Find a supported LRCLK ratio */
173 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
174 if (wm8523->sysclk / params_rate(params) ==
175 lrclk_ratios[i].ratio)
176 break;
177 }
178
179 /* Should never happen, should be handled by constraints */
180 if (i == ARRAY_SIZE(lrclk_ratios)) {
181 dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
182 wm8523->sysclk / params_rate(params));
183 return -EINVAL;
184 }
185
186 aifctrl2 &= ~WM8523_SR_MASK;
187 aifctrl2 |= lrclk_ratios[i].value;
188
189 aifctrl1 &= ~WM8523_WL_MASK;
190 switch (params_format(params)) {
191 case SNDRV_PCM_FORMAT_S16_LE:
192 break;
193 case SNDRV_PCM_FORMAT_S20_3LE:
194 aifctrl1 |= 0x8;
195 break;
196 case SNDRV_PCM_FORMAT_S24_LE:
197 aifctrl1 |= 0x10;
198 break;
199 case SNDRV_PCM_FORMAT_S32_LE:
200 aifctrl1 |= 0x18;
201 break;
202 }
203
204 snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
205 snd_soc_write(codec, WM8523_AIF_CTRL2, aifctrl2);
206
207 return 0;
208}
209
210static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
211 int clk_id, unsigned int freq, int dir)
212{
213 struct snd_soc_codec *codec = codec_dai->codec;
214 struct wm8523_priv *wm8523 = codec->private_data;
215 unsigned int val;
216 int i;
217
218 wm8523->sysclk = freq;
219
220 wm8523->rate_constraint.count = 0;
221 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
222 val = freq / lrclk_ratios[i].ratio;
223 /* Check that it's a standard rate since core can't
224 * cope with others and having the odd rates confuses
225 * constraint matching.
226 */
227 switch (val) {
228 case 8000:
229 case 11025:
230 case 16000:
231 case 22050:
232 case 32000:
233 case 44100:
234 case 48000:
235 case 64000:
236 case 88200:
237 case 96000:
238 case 176400:
239 case 192000:
240 dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
241 val);
242 wm8523->rate_constraint_list[i] = val;
243 wm8523->rate_constraint.count++;
244 break;
245 default:
246 dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
247 val);
248 }
249 }
250
251 /* Need at least one supported rate... */
252 if (wm8523->rate_constraint.count == 0)
253 return -EINVAL;
254
255 return 0;
256}
257
258
259static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
260 unsigned int fmt)
261{
262 struct snd_soc_codec *codec = codec_dai->codec;
263 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
264
265 aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK |
266 WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK);
267
268 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
269 case SND_SOC_DAIFMT_CBM_CFM:
270 aifctrl1 |= WM8523_AIF_MSTR;
271 break;
272 case SND_SOC_DAIFMT_CBS_CFS:
273 break;
274 default:
275 return -EINVAL;
276 }
277
278 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
279 case SND_SOC_DAIFMT_I2S:
280 aifctrl1 |= 0x0002;
281 break;
282 case SND_SOC_DAIFMT_RIGHT_J:
283 break;
284 case SND_SOC_DAIFMT_LEFT_J:
285 aifctrl1 |= 0x0001;
286 break;
287 case SND_SOC_DAIFMT_DSP_A:
288 aifctrl1 |= 0x0003;
289 break;
290 case SND_SOC_DAIFMT_DSP_B:
291 aifctrl1 |= 0x0023;
292 break;
293 default:
294 return -EINVAL;
295 }
296
297 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
298 case SND_SOC_DAIFMT_NB_NF:
299 break;
300 case SND_SOC_DAIFMT_IB_IF:
301 aifctrl1 |= WM8523_BCLK_INV | WM8523_LRCLK_INV;
302 break;
303 case SND_SOC_DAIFMT_IB_NF:
304 aifctrl1 |= WM8523_BCLK_INV;
305 break;
306 case SND_SOC_DAIFMT_NB_IF:
307 aifctrl1 |= WM8523_LRCLK_INV;
308 break;
309 default:
310 return -EINVAL;
311 }
312
313 snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
314
315 return 0;
316}
317
318static int wm8523_set_bias_level(struct snd_soc_codec *codec,
319 enum snd_soc_bias_level level)
320{
321 struct wm8523_priv *wm8523 = codec->private_data;
322 int ret, i;
323
324 switch (level) {
325 case SND_SOC_BIAS_ON:
326 break;
327
328 case SND_SOC_BIAS_PREPARE:
329 /* Full power on */
330 snd_soc_update_bits(codec, WM8523_PSCTRL1,
331 WM8523_SYS_ENA_MASK, 3);
332 break;
333
334 case SND_SOC_BIAS_STANDBY:
335 if (codec->bias_level == SND_SOC_BIAS_OFF) {
336 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
337 wm8523->supplies);
338 if (ret != 0) {
339 dev_err(codec->dev,
340 "Failed to enable supplies: %d\n",
341 ret);
342 return ret;
343 }
344
345 /* Initial power up */
346 snd_soc_update_bits(codec, WM8523_PSCTRL1,
347 WM8523_SYS_ENA_MASK, 1);
348
349 /* Sync back default/cached values */
350 for (i = WM8523_AIF_CTRL1;
351 i < WM8523_MAX_REGISTER; i++)
352 snd_soc_write(codec, i, wm8523->reg_cache[i]);
353
354
355 msleep(100);
356 }
357
358 /* Power up to mute */
359 snd_soc_update_bits(codec, WM8523_PSCTRL1,
360 WM8523_SYS_ENA_MASK, 2);
361
362 break;
363
364 case SND_SOC_BIAS_OFF:
365 /* The chip runs through the power down sequence for us. */
366 snd_soc_update_bits(codec, WM8523_PSCTRL1,
367 WM8523_SYS_ENA_MASK, 0);
368 msleep(100);
369
370 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies),
371 wm8523->supplies);
372 break;
373 }
374 codec->bias_level = level;
375 return 0;
376}
377
378#define WM8523_RATES SNDRV_PCM_RATE_8000_192000
379
380#define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
381 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
382
383static struct snd_soc_dai_ops wm8523_dai_ops = {
384 .startup = wm8523_startup,
385 .hw_params = wm8523_hw_params,
386 .set_sysclk = wm8523_set_dai_sysclk,
387 .set_fmt = wm8523_set_dai_fmt,
388};
389
390struct snd_soc_dai wm8523_dai = {
391 .name = "WM8523",
392 .playback = {
393 .stream_name = "Playback",
394 .channels_min = 2, /* Mono modes not yet supported */
395 .channels_max = 2,
396 .rates = WM8523_RATES,
397 .formats = WM8523_FORMATS,
398 },
399 .ops = &wm8523_dai_ops,
400};
401EXPORT_SYMBOL_GPL(wm8523_dai);
402
403#ifdef CONFIG_PM
404static int wm8523_suspend(struct platform_device *pdev, pm_message_t state)
405{
406 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
407 struct snd_soc_codec *codec = socdev->card->codec;
408
409 wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
410 return 0;
411}
412
413static int wm8523_resume(struct platform_device *pdev)
414{
415 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
416 struct snd_soc_codec *codec = socdev->card->codec;
417
418 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
419
420 return 0;
421}
422#else
423#define wm8523_suspend NULL
424#define wm8523_resume NULL
425#endif
426
427static int wm8523_probe(struct platform_device *pdev)
428{
429 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
430 struct snd_soc_codec *codec;
431 int ret = 0;
432
433 if (wm8523_codec == NULL) {
434 dev_err(&pdev->dev, "Codec device not registered\n");
435 return -ENODEV;
436 }
437
438 socdev->card->codec = wm8523_codec;
439 codec = wm8523_codec;
440
441 /* register pcms */
442 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
443 if (ret < 0) {
444 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
445 goto pcm_err;
446 }
447
448 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls));
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
457 return ret;
458
459card_err:
460 snd_soc_free_pcms(socdev);
461 snd_soc_dapm_free(socdev);
462pcm_err:
463 return ret;
464}
465
466static int wm8523_remove(struct platform_device *pdev)
467{
468 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
469
470 snd_soc_free_pcms(socdev);
471 snd_soc_dapm_free(socdev);
472
473 return 0;
474}
475
476struct snd_soc_codec_device soc_codec_dev_wm8523 = {
477 .probe = wm8523_probe,
478 .remove = wm8523_remove,
479 .suspend = wm8523_suspend,
480 .resume = wm8523_resume,
481};
482EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523);
483
484static int wm8523_register(struct wm8523_priv *wm8523,
485 enum snd_soc_control_type control)
486{
487 int ret;
488 struct snd_soc_codec *codec = &wm8523->codec;
489 int i;
490
491 if (wm8523_codec) {
492 dev_err(codec->dev, "Another WM8523 is registered\n");
493 return -EINVAL;
494 }
495
496 mutex_init(&codec->mutex);
497 INIT_LIST_HEAD(&codec->dapm_widgets);
498 INIT_LIST_HEAD(&codec->dapm_paths);
499
500 codec->private_data = wm8523;
501 codec->name = "WM8523";
502 codec->owner = THIS_MODULE;
503 codec->bias_level = SND_SOC_BIAS_OFF;
504 codec->set_bias_level = wm8523_set_bias_level;
505 codec->dai = &wm8523_dai;
506 codec->num_dai = 1;
507 codec->reg_cache_size = WM8523_REGISTER_COUNT;
508 codec->reg_cache = &wm8523->reg_cache;
509 codec->volatile_register = wm8523_volatile_register;
510
511 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
512 wm8523->rate_constraint.count =
513 ARRAY_SIZE(wm8523->rate_constraint_list);
514
515 memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg));
516
517 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
518 if (ret != 0) {
519 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
520 goto err;
521 }
522
523 for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
524 wm8523->supplies[i].supply = wm8523_supply_names[i];
525
526 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8523->supplies),
527 wm8523->supplies);
528 if (ret != 0) {
529 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
530 goto err;
531 }
532
533 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
534 wm8523->supplies);
535 if (ret != 0) {
536 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
537 goto err_get;
538 }
539
540 ret = snd_soc_read(codec, WM8523_DEVICE_ID);
541 if (ret < 0) {
542 dev_err(codec->dev, "Failed to read ID register\n");
543 goto err_enable;
544 }
545 if (ret != wm8523_reg[WM8523_DEVICE_ID]) {
546 dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret);
547 ret = -EINVAL;
548 goto err_enable;
549 }
550
551 ret = snd_soc_read(codec, WM8523_REVISION);
552 if (ret < 0) {
553 dev_err(codec->dev, "Failed to read revision register\n");
554 goto err_enable;
555 }
556 dev_info(codec->dev, "revision %c\n",
557 (ret & WM8523_CHIP_REV_MASK) + 'A');
558
559 ret = wm8523_reset(codec);
560 if (ret < 0) {
561 dev_err(codec->dev, "Failed to issue reset\n");
562 goto err_enable;
563 }
564
565 wm8523_dai.dev = codec->dev;
566
567 /* Change some default settings - latch VU and enable ZC */
568 wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
569 wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
570
571 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
572
573 /* Bias level configuration will have done an extra enable */
574 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
575
576 wm8523_codec = codec;
577
578 ret = snd_soc_register_codec(codec);
579 if (ret != 0) {
580 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
581 return ret;
582 }
583
584 ret = snd_soc_register_dai(&wm8523_dai);
585 if (ret != 0) {
586 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
587 snd_soc_unregister_codec(codec);
588 return ret;
589 }
590
591 return 0;
592
593err_enable:
594 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
595err_get:
596 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
597err:
598 kfree(wm8523);
599 return ret;
600}
601
602static void wm8523_unregister(struct wm8523_priv *wm8523)
603{
604 wm8523_set_bias_level(&wm8523->codec, SND_SOC_BIAS_OFF);
605 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
606 snd_soc_unregister_dai(&wm8523_dai);
607 snd_soc_unregister_codec(&wm8523->codec);
608 kfree(wm8523);
609 wm8523_codec = NULL;
610}
611
612#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
613static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
614 const struct i2c_device_id *id)
615{
616 struct wm8523_priv *wm8523;
617 struct snd_soc_codec *codec;
618
619 wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
620 if (wm8523 == NULL)
621 return -ENOMEM;
622
623 codec = &wm8523->codec;
624 codec->hw_write = (hw_write_t)i2c_master_send;
625
626 i2c_set_clientdata(i2c, wm8523);
627 codec->control_data = i2c;
628
629 codec->dev = &i2c->dev;
630
631 return wm8523_register(wm8523, SND_SOC_I2C);
632}
633
634static __devexit int wm8523_i2c_remove(struct i2c_client *client)
635{
636 struct wm8523_priv *wm8523 = i2c_get_clientdata(client);
637 wm8523_unregister(wm8523);
638 return 0;
639}
640
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[] = {
657 { "wm8523", 0 },
658 { }
659};
660MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
661
662static struct i2c_driver wm8523_i2c_driver = {
663 .driver = {
664 .name = "WM8523",
665 .owner = THIS_MODULE,
666 },
667 .probe = wm8523_i2c_probe,
668 .remove = __devexit_p(wm8523_i2c_remove),
669 .suspend = wm8523_i2c_suspend,
670 .resume = wm8523_i2c_resume,
671 .id_table = wm8523_i2c_id,
672};
673#endif
674
675static int __init wm8523_modinit(void)
676{
677 int ret;
678#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
679 ret = i2c_add_driver(&wm8523_i2c_driver);
680 if (ret != 0) {
681 printk(KERN_ERR "Failed to register WM8523 I2C driver: %d\n",
682 ret);
683 }
684#endif
685 return 0;
686}
687module_init(wm8523_modinit);
688
689static void __exit wm8523_exit(void)
690{
691#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
692 i2c_del_driver(&wm8523_i2c_driver);
693#endif
694}
695module_exit(wm8523_exit);
696
697MODULE_DESCRIPTION("ASoC WM8523 driver");
698MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
699MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8523.h b/sound/soc/codecs/wm8523.h
new file mode 100644
index 000000000000..1aa9ce3e1357
--- /dev/null
+++ b/sound/soc/codecs/wm8523.h
@@ -0,0 +1,160 @@
1/*
2 * wm8523.h -- WM8423 ASoC driver
3 *
4 * Copyright 2009 Wolfson Microelectronics, plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * Based on wm8753.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 _WM8523_H
16#define _WM8523_H
17
18/*
19 * Register values.
20 */
21#define WM8523_DEVICE_ID 0x00
22#define WM8523_REVISION 0x01
23#define WM8523_PSCTRL1 0x02
24#define WM8523_AIF_CTRL1 0x03
25#define WM8523_AIF_CTRL2 0x04
26#define WM8523_DAC_CTRL3 0x05
27#define WM8523_DAC_GAINL 0x06
28#define WM8523_DAC_GAINR 0x07
29#define WM8523_ZERO_DETECT 0x08
30
31#define WM8523_REGISTER_COUNT 9
32#define WM8523_MAX_REGISTER 0x08
33
34/*
35 * Field Definitions.
36 */
37
38/*
39 * R0 (0x00) - DEVICE_ID
40 */
41#define WM8523_CHIP_ID_MASK 0xFFFF /* CHIP_ID - [15:0] */
42#define WM8523_CHIP_ID_SHIFT 0 /* CHIP_ID - [15:0] */
43#define WM8523_CHIP_ID_WIDTH 16 /* CHIP_ID - [15:0] */
44
45/*
46 * R1 (0x01) - REVISION
47 */
48#define WM8523_CHIP_REV_MASK 0x0007 /* CHIP_REV - [2:0] */
49#define WM8523_CHIP_REV_SHIFT 0 /* CHIP_REV - [2:0] */
50#define WM8523_CHIP_REV_WIDTH 3 /* CHIP_REV - [2:0] */
51
52/*
53 * R2 (0x02) - PSCTRL1
54 */
55#define WM8523_SYS_ENA_MASK 0x0003 /* SYS_ENA - [1:0] */
56#define WM8523_SYS_ENA_SHIFT 0 /* SYS_ENA - [1:0] */
57#define WM8523_SYS_ENA_WIDTH 2 /* SYS_ENA - [1:0] */
58
59/*
60 * R3 (0x03) - AIF_CTRL1
61 */
62#define WM8523_TDM_MODE_MASK 0x1800 /* TDM_MODE - [12:11] */
63#define WM8523_TDM_MODE_SHIFT 11 /* TDM_MODE - [12:11] */
64#define WM8523_TDM_MODE_WIDTH 2 /* TDM_MODE - [12:11] */
65#define WM8523_TDM_SLOT_MASK 0x0600 /* TDM_SLOT - [10:9] */
66#define WM8523_TDM_SLOT_SHIFT 9 /* TDM_SLOT - [10:9] */
67#define WM8523_TDM_SLOT_WIDTH 2 /* TDM_SLOT - [10:9] */
68#define WM8523_DEEMPH 0x0100 /* DEEMPH */
69#define WM8523_DEEMPH_MASK 0x0100 /* DEEMPH */
70#define WM8523_DEEMPH_SHIFT 8 /* DEEMPH */
71#define WM8523_DEEMPH_WIDTH 1 /* DEEMPH */
72#define WM8523_AIF_MSTR 0x0080 /* AIF_MSTR */
73#define WM8523_AIF_MSTR_MASK 0x0080 /* AIF_MSTR */
74#define WM8523_AIF_MSTR_SHIFT 7 /* AIF_MSTR */
75#define WM8523_AIF_MSTR_WIDTH 1 /* AIF_MSTR */
76#define WM8523_LRCLK_INV 0x0040 /* LRCLK_INV */
77#define WM8523_LRCLK_INV_MASK 0x0040 /* LRCLK_INV */
78#define WM8523_LRCLK_INV_SHIFT 6 /* LRCLK_INV */
79#define WM8523_LRCLK_INV_WIDTH 1 /* LRCLK_INV */
80#define WM8523_BCLK_INV 0x0020 /* BCLK_INV */
81#define WM8523_BCLK_INV_MASK 0x0020 /* BCLK_INV */
82#define WM8523_BCLK_INV_SHIFT 5 /* BCLK_INV */
83#define WM8523_BCLK_INV_WIDTH 1 /* BCLK_INV */
84#define WM8523_WL_MASK 0x0018 /* WL - [4:3] */
85#define WM8523_WL_SHIFT 3 /* WL - [4:3] */
86#define WM8523_WL_WIDTH 2 /* WL - [4:3] */
87#define WM8523_FMT_MASK 0x0007 /* FMT - [2:0] */
88#define WM8523_FMT_SHIFT 0 /* FMT - [2:0] */
89#define WM8523_FMT_WIDTH 3 /* FMT - [2:0] */
90
91/*
92 * R4 (0x04) - AIF_CTRL2
93 */
94#define WM8523_DAC_OP_MUX_MASK 0x00C0 /* DAC_OP_MUX - [7:6] */
95#define WM8523_DAC_OP_MUX_SHIFT 6 /* DAC_OP_MUX - [7:6] */
96#define WM8523_DAC_OP_MUX_WIDTH 2 /* DAC_OP_MUX - [7:6] */
97#define WM8523_BCLKDIV_MASK 0x0038 /* BCLKDIV - [5:3] */
98#define WM8523_BCLKDIV_SHIFT 3 /* BCLKDIV - [5:3] */
99#define WM8523_BCLKDIV_WIDTH 3 /* BCLKDIV - [5:3] */
100#define WM8523_SR_MASK 0x0007 /* SR - [2:0] */
101#define WM8523_SR_SHIFT 0 /* SR - [2:0] */
102#define WM8523_SR_WIDTH 3 /* SR - [2:0] */
103
104/*
105 * R5 (0x05) - DAC_CTRL3
106 */
107#define WM8523_ZC 0x0010 /* ZC */
108#define WM8523_ZC_MASK 0x0010 /* ZC */
109#define WM8523_ZC_SHIFT 4 /* ZC */
110#define WM8523_ZC_WIDTH 1 /* ZC */
111#define WM8523_DACR 0x0008 /* DACR */
112#define WM8523_DACR_MASK 0x0008 /* DACR */
113#define WM8523_DACR_SHIFT 3 /* DACR */
114#define WM8523_DACR_WIDTH 1 /* DACR */
115#define WM8523_DACL 0x0004 /* DACL */
116#define WM8523_DACL_MASK 0x0004 /* DACL */
117#define WM8523_DACL_SHIFT 2 /* DACL */
118#define WM8523_DACL_WIDTH 1 /* DACL */
119#define WM8523_VOL_UP_RAMP 0x0002 /* VOL_UP_RAMP */
120#define WM8523_VOL_UP_RAMP_MASK 0x0002 /* VOL_UP_RAMP */
121#define WM8523_VOL_UP_RAMP_SHIFT 1 /* VOL_UP_RAMP */
122#define WM8523_VOL_UP_RAMP_WIDTH 1 /* VOL_UP_RAMP */
123#define WM8523_VOL_DOWN_RAMP 0x0001 /* VOL_DOWN_RAMP */
124#define WM8523_VOL_DOWN_RAMP_MASK 0x0001 /* VOL_DOWN_RAMP */
125#define WM8523_VOL_DOWN_RAMP_SHIFT 0 /* VOL_DOWN_RAMP */
126#define WM8523_VOL_DOWN_RAMP_WIDTH 1 /* VOL_DOWN_RAMP */
127
128/*
129 * R6 (0x06) - DAC_GAINL
130 */
131#define WM8523_DACL_VU 0x0200 /* DACL_VU */
132#define WM8523_DACL_VU_MASK 0x0200 /* DACL_VU */
133#define WM8523_DACL_VU_SHIFT 9 /* DACL_VU */
134#define WM8523_DACL_VU_WIDTH 1 /* DACL_VU */
135#define WM8523_DACL_VOL_MASK 0x01FF /* DACL_VOL - [8:0] */
136#define WM8523_DACL_VOL_SHIFT 0 /* DACL_VOL - [8:0] */
137#define WM8523_DACL_VOL_WIDTH 9 /* DACL_VOL - [8:0] */
138
139/*
140 * R7 (0x07) - DAC_GAINR
141 */
142#define WM8523_DACR_VU 0x0200 /* DACR_VU */
143#define WM8523_DACR_VU_MASK 0x0200 /* DACR_VU */
144#define WM8523_DACR_VU_SHIFT 9 /* DACR_VU */
145#define WM8523_DACR_VU_WIDTH 1 /* DACR_VU */
146#define WM8523_DACR_VOL_MASK 0x01FF /* DACR_VOL - [8:0] */
147#define WM8523_DACR_VOL_SHIFT 0 /* DACR_VOL - [8:0] */
148#define WM8523_DACR_VOL_WIDTH 9 /* DACR_VOL - [8:0] */
149
150/*
151 * R8 (0x08) - ZERO_DETECT
152 */
153#define WM8523_ZD_COUNT_MASK 0x0003 /* ZD_COUNT - [1:0] */
154#define WM8523_ZD_COUNT_SHIFT 0 /* ZD_COUNT - [1:0] */
155#define WM8523_ZD_COUNT_WIDTH 2 /* ZD_COUNT - [1:0] */
156
157extern struct snd_soc_dai wm8523_dai;
158extern struct snd_soc_codec_device soc_codec_dev_wm8523;
159
160#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 9f6be3d31ac0..d5473473a1e3 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -24,6 +24,8 @@
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/regulator/consumer.h>
28
27#include <sound/core.h> 29#include <sound/core.h>
28#include <sound/pcm.h> 30#include <sound/pcm.h>
29#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -187,82 +189,22 @@ struct pll_state {
187 unsigned int out; 189 unsigned int out;
188}; 190};
189 191
192#define WM8580_NUM_SUPPLIES 3
193static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
194 "AVDD",
195 "DVDD",
196 "PVDD",
197};
198
190/* codec private data */ 199/* codec private data */
191struct wm8580_priv { 200struct wm8580_priv {
192 struct snd_soc_codec codec; 201 struct snd_soc_codec codec;
202 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
193 u16 reg_cache[WM8580_MAX_REGISTER + 1]; 203 u16 reg_cache[WM8580_MAX_REGISTER + 1];
194 struct pll_state a; 204 struct pll_state a;
195 struct pll_state b; 205 struct pll_state b;
196}; 206};
197 207
198
199/*
200 * read wm8580 register cache
201 */
202static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
203 unsigned int reg)
204{
205 u16 *cache = codec->reg_cache;
206 BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
207 return cache[reg];
208}
209
210/*
211 * write wm8580 register cache
212 */
213static inline void wm8580_write_reg_cache(struct snd_soc_codec *codec,
214 unsigned int reg, unsigned int value)
215{
216 u16 *cache = codec->reg_cache;
217
218 cache[reg] = value;
219}
220
221/*
222 * write to the WM8580 register space
223 */
224static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
225 unsigned int value)
226{
227 u8 data[2];
228
229 BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
230
231 /* Registers are 9 bits wide */
232 value &= 0x1ff;
233
234 switch (reg) {
235 case WM8580_RESET:
236 /* Uncached */
237 break;
238 default:
239 if (value == wm8580_read_reg_cache(codec, reg))
240 return 0;
241 }
242
243 /* data is
244 * D15..D9 WM8580 register offset
245 * D8...D0 register data
246 */
247 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
248 data[1] = value & 0x00ff;
249
250 wm8580_write_reg_cache(codec, reg, value);
251 if (codec->hw_write(codec->control_data, data, 2) == 2)
252 return 0;
253 else
254 return -EIO;
255}
256
257static inline unsigned int wm8580_read(struct snd_soc_codec *codec,
258 unsigned int reg)
259{
260 switch (reg) {
261 default:
262 return wm8580_read_reg_cache(codec, reg);
263 }
264}
265
266static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); 208static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
267 209
268static int wm8580_out_vu(struct snd_kcontrol *kcontrol, 210static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
@@ -271,25 +213,22 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
271 struct soc_mixer_control *mc = 213 struct soc_mixer_control *mc =
272 (struct soc_mixer_control *)kcontrol->private_value; 214 (struct soc_mixer_control *)kcontrol->private_value;
273 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 215 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
216 u16 *reg_cache = codec->reg_cache;
274 unsigned int reg = mc->reg; 217 unsigned int reg = mc->reg;
275 unsigned int reg2 = mc->rreg; 218 unsigned int reg2 = mc->rreg;
276 int ret; 219 int ret;
277 u16 val;
278 220
279 /* Clear the register cache so we write without VU set */ 221 /* Clear the register cache so we write without VU set */
280 wm8580_write_reg_cache(codec, reg, 0); 222 reg_cache[reg] = 0;
281 wm8580_write_reg_cache(codec, reg2, 0); 223 reg_cache[reg2] = 0;
282 224
283 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 225 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
284 if (ret < 0) 226 if (ret < 0)
285 return ret; 227 return ret;
286 228
287 /* Now write again with the volume update bit set */ 229 /* Now write again with the volume update bit set */
288 val = wm8580_read_reg_cache(codec, reg); 230 snd_soc_update_bits(codec, reg, 0x100, 0x100);
289 wm8580_write(codec, reg, val | 0x0100); 231 snd_soc_update_bits(codec, reg2, 0x100, 0x100);
290
291 val = wm8580_read_reg_cache(codec, reg2);
292 wm8580_write(codec, reg2, val | 0x0100);
293 232
294 return 0; 233 return 0;
295} 234}
@@ -415,7 +354,7 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
415 unsigned int K, Ndiv, Nmod; 354 unsigned int K, Ndiv, Nmod;
416 int i; 355 int i;
417 356
418 pr_debug("wm8580: PLL %dHz->%dHz\n", source, target); 357 pr_debug("wm8580: PLL %uHz->%uHz\n", source, target);
419 358
420 /* Scale the output frequency up; the PLL should run in the 359 /* Scale the output frequency up; the PLL should run in the
421 * region of 90-100MHz. 360 * region of 90-100MHz.
@@ -447,7 +386,7 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
447 386
448 if ((Ndiv < 5) || (Ndiv > 13)) { 387 if ((Ndiv < 5) || (Ndiv > 13)) {
449 printk(KERN_ERR 388 printk(KERN_ERR
450 "WM8580 N=%d outside supported range\n", Ndiv); 389 "WM8580 N=%u outside supported range\n", Ndiv);
451 return -EINVAL; 390 return -EINVAL;
452 } 391 }
453 392
@@ -512,27 +451,27 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
512 /* Always disable the PLL - it is not safe to leave it running 451 /* Always disable the PLL - it is not safe to leave it running
513 * while reprogramming it. 452 * while reprogramming it.
514 */ 453 */
515 reg = wm8580_read(codec, WM8580_PWRDN2); 454 reg = snd_soc_read(codec, WM8580_PWRDN2);
516 wm8580_write(codec, WM8580_PWRDN2, reg | pwr_mask); 455 snd_soc_write(codec, WM8580_PWRDN2, reg | pwr_mask);
517 456
518 if (!freq_in || !freq_out) 457 if (!freq_in || !freq_out)
519 return 0; 458 return 0;
520 459
521 wm8580_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff); 460 snd_soc_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
522 wm8580_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff); 461 snd_soc_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff);
523 wm8580_write(codec, WM8580_PLLA3 + offset, 462 snd_soc_write(codec, WM8580_PLLA3 + offset,
524 (pll_div.k >> 18 & 0xf) | (pll_div.n << 4)); 463 (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
525 464
526 reg = wm8580_read(codec, WM8580_PLLA4 + offset); 465 reg = snd_soc_read(codec, WM8580_PLLA4 + offset);
527 reg &= ~0x3f; 466 reg &= ~0x3f;
528 reg |= pll_div.prescale | pll_div.postscale << 1 | 467 reg |= pll_div.prescale | pll_div.postscale << 1 |
529 pll_div.freqmode << 3; 468 pll_div.freqmode << 3;
530 469
531 wm8580_write(codec, WM8580_PLLA4 + offset, reg); 470 snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
532 471
533 /* All done, turn it on */ 472 /* All done, turn it on */
534 reg = wm8580_read(codec, WM8580_PWRDN2); 473 reg = snd_soc_read(codec, WM8580_PWRDN2);
535 wm8580_write(codec, WM8580_PWRDN2, reg & ~pwr_mask); 474 snd_soc_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
536 475
537 return 0; 476 return 0;
538} 477}
@@ -547,7 +486,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
547 struct snd_soc_pcm_runtime *rtd = substream->private_data; 486 struct snd_soc_pcm_runtime *rtd = substream->private_data;
548 struct snd_soc_device *socdev = rtd->socdev; 487 struct snd_soc_device *socdev = rtd->socdev;
549 struct snd_soc_codec *codec = socdev->card->codec; 488 struct snd_soc_codec *codec = socdev->card->codec;
550 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id); 489 u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id);
551 490
552 paifb &= ~WM8580_AIF_LENGTH_MASK; 491 paifb &= ~WM8580_AIF_LENGTH_MASK;
553 /* bit size */ 492 /* bit size */
@@ -567,7 +506,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
567 return -EINVAL; 506 return -EINVAL;
568 } 507 }
569 508
570 wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb); 509 snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb);
571 return 0; 510 return 0;
572} 511}
573 512
@@ -579,8 +518,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
579 unsigned int aifb; 518 unsigned int aifb;
580 int can_invert_lrclk; 519 int can_invert_lrclk;
581 520
582 aifa = wm8580_read(codec, WM8580_PAIF1 + codec_dai->id); 521 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id);
583 aifb = wm8580_read(codec, WM8580_PAIF3 + codec_dai->id); 522 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id);
584 523
585 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); 524 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
586 525
@@ -646,8 +585,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
646 return -EINVAL; 585 return -EINVAL;
647 } 586 }
648 587
649 wm8580_write(codec, WM8580_PAIF1 + codec_dai->id, aifa); 588 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
650 wm8580_write(codec, WM8580_PAIF3 + codec_dai->id, aifb); 589 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
651 590
652 return 0; 591 return 0;
653} 592}
@@ -660,7 +599,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
660 599
661 switch (div_id) { 600 switch (div_id) {
662 case WM8580_MCLK: 601 case WM8580_MCLK:
663 reg = wm8580_read(codec, WM8580_PLLB4); 602 reg = snd_soc_read(codec, WM8580_PLLB4);
664 reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK; 603 reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
665 604
666 switch (div) { 605 switch (div) {
@@ -682,11 +621,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
682 default: 621 default:
683 return -EINVAL; 622 return -EINVAL;
684 } 623 }
685 wm8580_write(codec, WM8580_PLLB4, reg); 624 snd_soc_write(codec, WM8580_PLLB4, reg);
686 break; 625 break;
687 626
688 case WM8580_DAC_CLKSEL: 627 case WM8580_DAC_CLKSEL:
689 reg = wm8580_read(codec, WM8580_CLKSEL); 628 reg = snd_soc_read(codec, WM8580_CLKSEL);
690 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK; 629 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
691 630
692 switch (div) { 631 switch (div) {
@@ -704,11 +643,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
704 default: 643 default:
705 return -EINVAL; 644 return -EINVAL;
706 } 645 }
707 wm8580_write(codec, WM8580_CLKSEL, reg); 646 snd_soc_write(codec, WM8580_CLKSEL, reg);
708 break; 647 break;
709 648
710 case WM8580_CLKOUTSRC: 649 case WM8580_CLKOUTSRC:
711 reg = wm8580_read(codec, WM8580_PLLB4); 650 reg = snd_soc_read(codec, WM8580_PLLB4);
712 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK; 651 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
713 652
714 switch (div) { 653 switch (div) {
@@ -730,7 +669,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
730 default: 669 default:
731 return -EINVAL; 670 return -EINVAL;
732 } 671 }
733 wm8580_write(codec, WM8580_PLLB4, reg); 672 snd_soc_write(codec, WM8580_PLLB4, reg);
734 break; 673 break;
735 674
736 default: 675 default:
@@ -745,14 +684,14 @@ static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
745 struct snd_soc_codec *codec = codec_dai->codec; 684 struct snd_soc_codec *codec = codec_dai->codec;
746 unsigned int reg; 685 unsigned int reg;
747 686
748 reg = wm8580_read(codec, WM8580_DAC_CONTROL5); 687 reg = snd_soc_read(codec, WM8580_DAC_CONTROL5);
749 688
750 if (mute) 689 if (mute)
751 reg |= WM8580_DAC_CONTROL5_MUTEALL; 690 reg |= WM8580_DAC_CONTROL5_MUTEALL;
752 else 691 else
753 reg &= ~WM8580_DAC_CONTROL5_MUTEALL; 692 reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
754 693
755 wm8580_write(codec, WM8580_DAC_CONTROL5, reg); 694 snd_soc_write(codec, WM8580_DAC_CONTROL5, reg);
756 695
757 return 0; 696 return 0;
758} 697}
@@ -769,20 +708,20 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
769 case SND_SOC_BIAS_STANDBY: 708 case SND_SOC_BIAS_STANDBY:
770 if (codec->bias_level == SND_SOC_BIAS_OFF) { 709 if (codec->bias_level == SND_SOC_BIAS_OFF) {
771 /* Power up and get individual control of the DACs */ 710 /* Power up and get individual control of the DACs */
772 reg = wm8580_read(codec, WM8580_PWRDN1); 711 reg = snd_soc_read(codec, WM8580_PWRDN1);
773 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); 712 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
774 wm8580_write(codec, WM8580_PWRDN1, reg); 713 snd_soc_write(codec, WM8580_PWRDN1, reg);
775 714
776 /* Make VMID high impedence */ 715 /* Make VMID high impedence */
777 reg = wm8580_read(codec, WM8580_ADC_CONTROL1); 716 reg = snd_soc_read(codec, WM8580_ADC_CONTROL1);
778 reg &= ~0x100; 717 reg &= ~0x100;
779 wm8580_write(codec, WM8580_ADC_CONTROL1, reg); 718 snd_soc_write(codec, WM8580_ADC_CONTROL1, reg);
780 } 719 }
781 break; 720 break;
782 721
783 case SND_SOC_BIAS_OFF: 722 case SND_SOC_BIAS_OFF:
784 reg = wm8580_read(codec, WM8580_PWRDN1); 723 reg = snd_soc_read(codec, WM8580_PWRDN1);
785 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 724 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
786 break; 725 break;
787 } 726 }
788 codec->bias_level = level; 727 codec->bias_level = level;
@@ -893,7 +832,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8580 = {
893}; 832};
894EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); 833EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
895 834
896static int wm8580_register(struct wm8580_priv *wm8580) 835static int wm8580_register(struct wm8580_priv *wm8580,
836 enum snd_soc_control_type control)
897{ 837{
898 int ret, i; 838 int ret, i;
899 struct snd_soc_codec *codec = &wm8580->codec; 839 struct snd_soc_codec *codec = &wm8580->codec;
@@ -911,8 +851,6 @@ static int wm8580_register(struct wm8580_priv *wm8580)
911 codec->private_data = wm8580; 851 codec->private_data = wm8580;
912 codec->name = "WM8580"; 852 codec->name = "WM8580";
913 codec->owner = THIS_MODULE; 853 codec->owner = THIS_MODULE;
914 codec->read = wm8580_read_reg_cache;
915 codec->write = wm8580_write;
916 codec->bias_level = SND_SOC_BIAS_OFF; 854 codec->bias_level = SND_SOC_BIAS_OFF;
917 codec->set_bias_level = wm8580_set_bias_level; 855 codec->set_bias_level = wm8580_set_bias_level;
918 codec->dai = wm8580_dai; 856 codec->dai = wm8580_dai;
@@ -922,11 +860,34 @@ static int wm8580_register(struct wm8580_priv *wm8580)
922 860
923 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg)); 861 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
924 862
863 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
864 if (ret < 0) {
865 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
866 goto err;
867 }
868
869 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
870 wm8580->supplies[i].supply = wm8580_supply_names[i];
871
872 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8580->supplies),
873 wm8580->supplies);
874 if (ret != 0) {
875 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
876 goto err;
877 }
878
879 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
880 wm8580->supplies);
881 if (ret != 0) {
882 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
883 goto err_regulator_get;
884 }
885
925 /* Get the codec into a known state */ 886 /* Get the codec into a known state */
926 ret = wm8580_write(codec, WM8580_RESET, 0); 887 ret = snd_soc_write(codec, WM8580_RESET, 0);
927 if (ret != 0) { 888 if (ret != 0) {
928 dev_err(codec->dev, "Failed to reset codec: %d\n", ret); 889 dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
929 goto err; 890 goto err_regulator_enable;
930 } 891 }
931 892
932 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++) 893 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
@@ -939,7 +900,7 @@ static int wm8580_register(struct wm8580_priv *wm8580)
939 ret = snd_soc_register_codec(codec); 900 ret = snd_soc_register_codec(codec);
940 if (ret != 0) { 901 if (ret != 0) {
941 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 902 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
942 goto err; 903 goto err_regulator_enable;
943 } 904 }
944 905
945 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 906 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
@@ -952,6 +913,10 @@ static int wm8580_register(struct wm8580_priv *wm8580)
952 913
953err_codec: 914err_codec:
954 snd_soc_unregister_codec(codec); 915 snd_soc_unregister_codec(codec);
916err_regulator_enable:
917 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
918err_regulator_get:
919 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
955err: 920err:
956 kfree(wm8580); 921 kfree(wm8580);
957 return ret; 922 return ret;
@@ -962,6 +927,8 @@ static void wm8580_unregister(struct wm8580_priv *wm8580)
962 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); 927 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF);
963 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 928 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
964 snd_soc_unregister_codec(&wm8580->codec); 929 snd_soc_unregister_codec(&wm8580->codec);
930 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
931 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
965 kfree(wm8580); 932 kfree(wm8580);
966 wm8580_codec = NULL; 933 wm8580_codec = NULL;
967} 934}
@@ -978,14 +945,13 @@ static int wm8580_i2c_probe(struct i2c_client *i2c,
978 return -ENOMEM; 945 return -ENOMEM;
979 946
980 codec = &wm8580->codec; 947 codec = &wm8580->codec;
981 codec->hw_write = (hw_write_t)i2c_master_send;
982 948
983 i2c_set_clientdata(i2c, wm8580); 949 i2c_set_clientdata(i2c, wm8580);
984 codec->control_data = i2c; 950 codec->control_data = i2c;
985 951
986 codec->dev = &i2c->dev; 952 codec->dev = &i2c->dev;
987 953
988 return wm8580_register(wm8580); 954 return wm8580_register(wm8580, SND_SOC_I2C);
989} 955}
990 956
991static int wm8580_i2c_remove(struct i2c_client *client) 957static int wm8580_i2c_remove(struct i2c_client *client)
@@ -995,6 +961,21 @@ static int wm8580_i2c_remove(struct i2c_client *client)
995 return 0; 961 return 0;
996} 962}
997 963
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
998static const struct i2c_device_id wm8580_i2c_id[] = { 979static const struct i2c_device_id wm8580_i2c_id[] = {
999 { "wm8580", 0 }, 980 { "wm8580", 0 },
1000 { } 981 { }
@@ -1008,6 +989,8 @@ static struct i2c_driver wm8580_i2c_driver = {
1008 }, 989 },
1009 .probe = wm8580_i2c_probe, 990 .probe = wm8580_i2c_probe,
1010 .remove = wm8580_i2c_remove, 991 .remove = wm8580_i2c_remove,
992 .suspend = wm8580_i2c_suspend,
993 .resume = wm8580_i2c_resume,
1011 .id_table = wm8580_i2c_id, 994 .id_table = wm8580_i2c_id,
1012}; 995};
1013#endif 996#endif
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index e7ff2121ede9..16e969a762c3 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -43,45 +43,6 @@ static const u16 wm8728_reg_defaults[] = {
43 0x100, 43 0x100,
44}; 44};
45 45
46static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec,
47 unsigned int reg)
48{
49 u16 *cache = codec->reg_cache;
50 BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults));
51 return cache[reg];
52}
53
54static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec,
55 u16 reg, unsigned int value)
56{
57 u16 *cache = codec->reg_cache;
58 BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults));
59 cache[reg] = value;
60}
61
62/*
63 * write to the WM8728 register space
64 */
65static int wm8728_write(struct snd_soc_codec *codec, unsigned int reg,
66 unsigned int value)
67{
68 u8 data[2];
69
70 /* data is
71 * D15..D9 WM8728 register offset
72 * D8...D0 register data
73 */
74 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
75 data[1] = value & 0x00ff;
76
77 wm8728_write_reg_cache(codec, reg, value);
78
79 if (codec->hw_write(codec->control_data, data, 2) == 2)
80 return 0;
81 else
82 return -EIO;
83}
84
85static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1); 46static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
86 47
87static const struct snd_kcontrol_new wm8728_snd_controls[] = { 48static const struct snd_kcontrol_new wm8728_snd_controls[] = {
@@ -121,12 +82,12 @@ static int wm8728_add_widgets(struct snd_soc_codec *codec)
121static int wm8728_mute(struct snd_soc_dai *dai, int mute) 82static int wm8728_mute(struct snd_soc_dai *dai, int mute)
122{ 83{
123 struct snd_soc_codec *codec = dai->codec; 84 struct snd_soc_codec *codec = dai->codec;
124 u16 mute_reg = wm8728_read_reg_cache(codec, WM8728_DACCTL); 85 u16 mute_reg = snd_soc_read(codec, WM8728_DACCTL);
125 86
126 if (mute) 87 if (mute)
127 wm8728_write(codec, WM8728_DACCTL, mute_reg | 1); 88 snd_soc_write(codec, WM8728_DACCTL, mute_reg | 1);
128 else 89 else
129 wm8728_write(codec, WM8728_DACCTL, mute_reg & ~1); 90 snd_soc_write(codec, WM8728_DACCTL, mute_reg & ~1);
130 91
131 return 0; 92 return 0;
132} 93}
@@ -138,7 +99,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
138 struct snd_soc_pcm_runtime *rtd = substream->private_data; 99 struct snd_soc_pcm_runtime *rtd = substream->private_data;
139 struct snd_soc_device *socdev = rtd->socdev; 100 struct snd_soc_device *socdev = rtd->socdev;
140 struct snd_soc_codec *codec = socdev->card->codec; 101 struct snd_soc_codec *codec = socdev->card->codec;
141 u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL); 102 u16 dac = snd_soc_read(codec, WM8728_DACCTL);
142 103
143 dac &= ~0x18; 104 dac &= ~0x18;
144 105
@@ -155,7 +116,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
155 return -EINVAL; 116 return -EINVAL;
156 } 117 }
157 118
158 wm8728_write(codec, WM8728_DACCTL, dac); 119 snd_soc_write(codec, WM8728_DACCTL, dac);
159 120
160 return 0; 121 return 0;
161} 122}
@@ -164,7 +125,7 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
164 unsigned int fmt) 125 unsigned int fmt)
165{ 126{
166 struct snd_soc_codec *codec = codec_dai->codec; 127 struct snd_soc_codec *codec = codec_dai->codec;
167 u16 iface = wm8728_read_reg_cache(codec, WM8728_IFCTL); 128 u16 iface = snd_soc_read(codec, WM8728_IFCTL);
168 129
169 /* Currently only I2S is supported by the driver, though the 130 /* Currently only I2S is supported by the driver, though the
170 * hardware is more flexible. 131 * hardware is more flexible.
@@ -204,7 +165,7 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
204 return -EINVAL; 165 return -EINVAL;
205 } 166 }
206 167
207 wm8728_write(codec, WM8728_IFCTL, iface); 168 snd_soc_write(codec, WM8728_IFCTL, iface);
208 return 0; 169 return 0;
209} 170}
210 171
@@ -220,19 +181,19 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
220 case SND_SOC_BIAS_STANDBY: 181 case SND_SOC_BIAS_STANDBY:
221 if (codec->bias_level == SND_SOC_BIAS_OFF) { 182 if (codec->bias_level == SND_SOC_BIAS_OFF) {
222 /* Power everything up... */ 183 /* Power everything up... */
223 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL); 184 reg = snd_soc_read(codec, WM8728_DACCTL);
224 wm8728_write(codec, WM8728_DACCTL, reg & ~0x4); 185 snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
225 186
226 /* ..then sync in the register cache. */ 187 /* ..then sync in the register cache. */
227 for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++) 188 for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
228 wm8728_write(codec, i, 189 snd_soc_write(codec, i,
229 wm8728_read_reg_cache(codec, i)); 190 snd_soc_read(codec, i));
230 } 191 }
231 break; 192 break;
232 193
233 case SND_SOC_BIAS_OFF: 194 case SND_SOC_BIAS_OFF:
234 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL); 195 reg = snd_soc_read(codec, WM8728_DACCTL);
235 wm8728_write(codec, WM8728_DACCTL, reg | 0x4); 196 snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
236 break; 197 break;
237 } 198 }
238 codec->bias_level = level; 199 codec->bias_level = level;
@@ -287,15 +248,14 @@ static int wm8728_resume(struct platform_device *pdev)
287 * initialise the WM8728 driver 248 * initialise the WM8728 driver
288 * register the mixer and dsp interfaces with the kernel 249 * register the mixer and dsp interfaces with the kernel
289 */ 250 */
290static int wm8728_init(struct snd_soc_device *socdev) 251static int wm8728_init(struct snd_soc_device *socdev,
252 enum snd_soc_control_type control)
291{ 253{
292 struct snd_soc_codec *codec = socdev->card->codec; 254 struct snd_soc_codec *codec = socdev->card->codec;
293 int ret = 0; 255 int ret = 0;
294 256
295 codec->name = "WM8728"; 257 codec->name = "WM8728";
296 codec->owner = THIS_MODULE; 258 codec->owner = THIS_MODULE;
297 codec->read = wm8728_read_reg_cache;
298 codec->write = wm8728_write;
299 codec->set_bias_level = wm8728_set_bias_level; 259 codec->set_bias_level = wm8728_set_bias_level;
300 codec->dai = &wm8728_dai; 260 codec->dai = &wm8728_dai;
301 codec->num_dai = 1; 261 codec->num_dai = 1;
@@ -307,11 +267,18 @@ static int wm8728_init(struct snd_soc_device *socdev)
307 if (codec->reg_cache == NULL) 267 if (codec->reg_cache == NULL)
308 return -ENOMEM; 268 return -ENOMEM;
309 269
270 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
271 if (ret < 0) {
272 printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
273 ret);
274 goto err;
275 }
276
310 /* register pcms */ 277 /* register pcms */
311 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 278 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
312 if (ret < 0) { 279 if (ret < 0) {
313 printk(KERN_ERR "wm8728: failed to create pcms\n"); 280 printk(KERN_ERR "wm8728: failed to create pcms\n");
314 goto pcm_err; 281 goto err;
315 } 282 }
316 283
317 /* power on device */ 284 /* power on device */
@@ -331,7 +298,7 @@ static int wm8728_init(struct snd_soc_device *socdev)
331card_err: 298card_err:
332 snd_soc_free_pcms(socdev); 299 snd_soc_free_pcms(socdev);
333 snd_soc_dapm_free(socdev); 300 snd_soc_dapm_free(socdev);
334pcm_err: 301err:
335 kfree(codec->reg_cache); 302 kfree(codec->reg_cache);
336 return ret; 303 return ret;
337} 304}
@@ -357,7 +324,7 @@ static int wm8728_i2c_probe(struct i2c_client *i2c,
357 i2c_set_clientdata(i2c, codec); 324 i2c_set_clientdata(i2c, codec);
358 codec->control_data = i2c; 325 codec->control_data = i2c;
359 326
360 ret = wm8728_init(socdev); 327 ret = wm8728_init(socdev, SND_SOC_I2C);
361 if (ret < 0) 328 if (ret < 0)
362 pr_err("failed to initialise WM8728\n"); 329 pr_err("failed to initialise WM8728\n");
363 330
@@ -437,7 +404,7 @@ static int __devinit wm8728_spi_probe(struct spi_device *spi)
437 404
438 codec->control_data = spi; 405 codec->control_data = spi;
439 406
440 ret = wm8728_init(socdev); 407 ret = wm8728_init(socdev, SND_SOC_SPI);
441 if (ret < 0) 408 if (ret < 0)
442 dev_err(&spi->dev, "failed to initialise WM8728\n"); 409 dev_err(&spi->dev, "failed to initialise WM8728\n");
443 410
@@ -458,30 +425,6 @@ static struct spi_driver wm8728_spi_driver = {
458 .probe = wm8728_spi_probe, 425 .probe = wm8728_spi_probe,
459 .remove = __devexit_p(wm8728_spi_remove), 426 .remove = __devexit_p(wm8728_spi_remove),
460}; 427};
461
462static int wm8728_spi_write(struct spi_device *spi, const char *data, int len)
463{
464 struct spi_transfer t;
465 struct spi_message m;
466 u8 msg[2];
467
468 if (len <= 0)
469 return 0;
470
471 msg[0] = data[0];
472 msg[1] = data[1];
473
474 spi_message_init(&m);
475 memset(&t, 0, (sizeof t));
476
477 t.tx_buf = &msg[0];
478 t.len = len;
479
480 spi_message_add_tail(&t, &m);
481 spi_sync(spi, &m);
482
483 return len;
484}
485#endif /* CONFIG_SPI_MASTER */ 428#endif /* CONFIG_SPI_MASTER */
486 429
487static int wm8728_probe(struct platform_device *pdev) 430static int wm8728_probe(struct platform_device *pdev)
@@ -506,13 +449,11 @@ static int wm8728_probe(struct platform_device *pdev)
506 449
507#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 450#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
508 if (setup->i2c_address) { 451 if (setup->i2c_address) {
509 codec->hw_write = (hw_write_t)i2c_master_send;
510 ret = wm8728_add_i2c_device(pdev, setup); 452 ret = wm8728_add_i2c_device(pdev, setup);
511 } 453 }
512#endif 454#endif
513#if defined(CONFIG_SPI_MASTER) 455#if defined(CONFIG_SPI_MASTER)
514 if (setup->spi) { 456 if (setup->spi) {
515 codec->hw_write = (hw_write_t)wm8728_spi_write;
516 ret = spi_register_driver(&wm8728_spi_driver); 457 ret = spi_register_driver(&wm8728_spi_driver);
517 if (ret != 0) 458 if (ret != 0)
518 printk(KERN_ERR "can't add spi driver"); 459 printk(KERN_ERR "can't add spi driver");
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 7a205876ef4f..d3fd4f28d96e 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -26,6 +26,7 @@
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h> 27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <sound/tlv.h>
29 30
30#include "wm8731.h" 31#include "wm8731.h"
31 32
@@ -39,9 +40,6 @@ struct wm8731_priv {
39 unsigned int sysclk; 40 unsigned int sysclk;
40}; 41};
41 42
42#ifdef CONFIG_SPI_MASTER
43static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
44#endif
45 43
46/* 44/*
47 * wm8731 register cache 45 * wm8731 register cache
@@ -50,60 +48,12 @@ static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
50 * There is no point in caching the reset register 48 * There is no point in caching the reset register
51 */ 49 */
52static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { 50static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
53 0x0097, 0x0097, 0x0079, 0x0079, 51 0x0097, 0x0097, 0x0079, 0x0079,
54 0x000a, 0x0008, 0x009f, 0x000a, 52 0x000a, 0x0008, 0x009f, 0x000a,
55 0x0000, 0x0000 53 0x0000, 0x0000
56}; 54};
57 55
58/* 56#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
59 * read wm8731 register cache
60 */
61static inline unsigned int wm8731_read_reg_cache(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 u16 *cache = codec->reg_cache;
65 if (reg == WM8731_RESET)
66 return 0;
67 if (reg >= WM8731_CACHEREGNUM)
68 return -1;
69 return cache[reg];
70}
71
72/*
73 * write wm8731 register cache
74 */
75static inline void wm8731_write_reg_cache(struct snd_soc_codec *codec,
76 u16 reg, unsigned int value)
77{
78 u16 *cache = codec->reg_cache;
79 if (reg >= WM8731_CACHEREGNUM)
80 return;
81 cache[reg] = value;
82}
83
84/*
85 * write to the WM8731 register space
86 */
87static int wm8731_write(struct snd_soc_codec *codec, unsigned int reg,
88 unsigned int value)
89{
90 u8 data[2];
91
92 /* data is
93 * D15..D9 WM8731 register offset
94 * D8...D0 register data
95 */
96 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
97 data[1] = value & 0x00ff;
98
99 wm8731_write_reg_cache(codec, reg, value);
100 if (codec->hw_write(codec->control_data, data, 2) == 2)
101 return 0;
102 else
103 return -EIO;
104}
105
106#define wm8731_reset(c) wm8731_write(c, WM8731_RESET, 0)
107 57
108static const char *wm8731_input_select[] = {"Line In", "Mic"}; 58static const char *wm8731_input_select[] = {"Line In", "Mic"};
109static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 59static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
@@ -113,20 +63,26 @@ static const struct soc_enum wm8731_enum[] = {
113 SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph), 63 SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph),
114}; 64};
115 65
66static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
67static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
68static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
69
116static const struct snd_kcontrol_new wm8731_snd_controls[] = { 70static const struct snd_kcontrol_new wm8731_snd_controls[] = {
117 71
118SOC_DOUBLE_R("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V, 72SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V,
119 0, 127, 0), 73 0, 127, 0, out_tlv),
120SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V, 74SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V,
121 7, 1, 0), 75 7, 1, 0),
122 76
123SOC_DOUBLE_R("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0), 77SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
78 in_tlv),
124SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), 79SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
125 80
126SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0), 81SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0),
127SOC_SINGLE("Capture Mic Switch", WM8731_APANA, 1, 1, 1), 82SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
128 83
129SOC_SINGLE("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1), 84SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
85 sidetone_tlv),
130 86
131SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), 87SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
132SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), 88SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
@@ -260,12 +216,12 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
260 struct snd_soc_device *socdev = rtd->socdev; 216 struct snd_soc_device *socdev = rtd->socdev;
261 struct snd_soc_codec *codec = socdev->card->codec; 217 struct snd_soc_codec *codec = socdev->card->codec;
262 struct wm8731_priv *wm8731 = codec->private_data; 218 struct wm8731_priv *wm8731 = codec->private_data;
263 u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3; 219 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
264 int i = get_coeff(wm8731->sysclk, params_rate(params)); 220 int i = get_coeff(wm8731->sysclk, params_rate(params));
265 u16 srate = (coeff_div[i].sr << 2) | 221 u16 srate = (coeff_div[i].sr << 2) |
266 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 222 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
267 223
268 wm8731_write(codec, WM8731_SRATE, srate); 224 snd_soc_write(codec, WM8731_SRATE, srate);
269 225
270 /* bit size */ 226 /* bit size */
271 switch (params_format(params)) { 227 switch (params_format(params)) {
@@ -279,7 +235,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
279 break; 235 break;
280 } 236 }
281 237
282 wm8731_write(codec, WM8731_IFACE, iface); 238 snd_soc_write(codec, WM8731_IFACE, iface);
283 return 0; 239 return 0;
284} 240}
285 241
@@ -291,7 +247,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
291 struct snd_soc_codec *codec = socdev->card->codec; 247 struct snd_soc_codec *codec = socdev->card->codec;
292 248
293 /* set active */ 249 /* set active */
294 wm8731_write(codec, WM8731_ACTIVE, 0x0001); 250 snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
295 251
296 return 0; 252 return 0;
297} 253}
@@ -306,19 +262,19 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream,
306 /* deactivate */ 262 /* deactivate */
307 if (!codec->active) { 263 if (!codec->active) {
308 udelay(50); 264 udelay(50);
309 wm8731_write(codec, WM8731_ACTIVE, 0x0); 265 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
310 } 266 }
311} 267}
312 268
313static int wm8731_mute(struct snd_soc_dai *dai, int mute) 269static int wm8731_mute(struct snd_soc_dai *dai, int mute)
314{ 270{
315 struct snd_soc_codec *codec = dai->codec; 271 struct snd_soc_codec *codec = dai->codec;
316 u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7; 272 u16 mute_reg = snd_soc_read(codec, WM8731_APDIGI) & 0xfff7;
317 273
318 if (mute) 274 if (mute)
319 wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8); 275 snd_soc_write(codec, WM8731_APDIGI, mute_reg | 0x8);
320 else 276 else
321 wm8731_write(codec, WM8731_APDIGI, mute_reg); 277 snd_soc_write(codec, WM8731_APDIGI, mute_reg);
322 return 0; 278 return 0;
323} 279}
324 280
@@ -396,7 +352,7 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
396 } 352 }
397 353
398 /* set iface */ 354 /* set iface */
399 wm8731_write(codec, WM8731_IFACE, iface); 355 snd_soc_write(codec, WM8731_IFACE, iface);
400 return 0; 356 return 0;
401} 357}
402 358
@@ -412,12 +368,12 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
412 break; 368 break;
413 case SND_SOC_BIAS_STANDBY: 369 case SND_SOC_BIAS_STANDBY:
414 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 370 /* Clear PWROFF, gate CLKOUT, everything else as-is */
415 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; 371 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
416 wm8731_write(codec, WM8731_PWR, reg | 0x0040); 372 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
417 break; 373 break;
418 case SND_SOC_BIAS_OFF: 374 case SND_SOC_BIAS_OFF:
419 wm8731_write(codec, WM8731_ACTIVE, 0x0); 375 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
420 wm8731_write(codec, WM8731_PWR, 0xffff); 376 snd_soc_write(codec, WM8731_PWR, 0xffff);
421 break; 377 break;
422 } 378 }
423 codec->bias_level = level; 379 codec->bias_level = level;
@@ -457,15 +413,17 @@ struct snd_soc_dai wm8731_dai = {
457 .rates = WM8731_RATES, 413 .rates = WM8731_RATES,
458 .formats = WM8731_FORMATS,}, 414 .formats = WM8731_FORMATS,},
459 .ops = &wm8731_dai_ops, 415 .ops = &wm8731_dai_ops,
416 .symmetric_rates = 1,
460}; 417};
461EXPORT_SYMBOL_GPL(wm8731_dai); 418EXPORT_SYMBOL_GPL(wm8731_dai);
462 419
420#ifdef CONFIG_PM
463static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 421static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
464{ 422{
465 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 423 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
466 struct snd_soc_codec *codec = socdev->card->codec; 424 struct snd_soc_codec *codec = socdev->card->codec;
467 425
468 wm8731_write(codec, WM8731_ACTIVE, 0x0); 426 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
469 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 427 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
470 return 0; 428 return 0;
471} 429}
@@ -488,6 +446,10 @@ static int wm8731_resume(struct platform_device *pdev)
488 wm8731_set_bias_level(codec, codec->suspend_bias_level); 446 wm8731_set_bias_level(codec, codec->suspend_bias_level);
489 return 0; 447 return 0;
490} 448}
449#else
450#define wm8731_suspend NULL
451#define wm8731_resume NULL
452#endif
491 453
492static int wm8731_probe(struct platform_device *pdev) 454static int wm8731_probe(struct platform_device *pdev)
493{ 455{
@@ -547,15 +509,16 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
547}; 509};
548EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 510EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
549 511
550static int wm8731_register(struct wm8731_priv *wm8731) 512static int wm8731_register(struct wm8731_priv *wm8731,
513 enum snd_soc_control_type control)
551{ 514{
552 int ret; 515 int ret;
553 struct snd_soc_codec *codec = &wm8731->codec; 516 struct snd_soc_codec *codec = &wm8731->codec;
554 u16 reg;
555 517
556 if (wm8731_codec) { 518 if (wm8731_codec) {
557 dev_err(codec->dev, "Another WM8731 is registered\n"); 519 dev_err(codec->dev, "Another WM8731 is registered\n");
558 return -EINVAL; 520 ret = -EINVAL;
521 goto err;
559 } 522 }
560 523
561 mutex_init(&codec->mutex); 524 mutex_init(&codec->mutex);
@@ -565,8 +528,6 @@ static int wm8731_register(struct wm8731_priv *wm8731)
565 codec->private_data = wm8731; 528 codec->private_data = wm8731;
566 codec->name = "WM8731"; 529 codec->name = "WM8731";
567 codec->owner = THIS_MODULE; 530 codec->owner = THIS_MODULE;
568 codec->read = wm8731_read_reg_cache;
569 codec->write = wm8731_write;
570 codec->bias_level = SND_SOC_BIAS_OFF; 531 codec->bias_level = SND_SOC_BIAS_OFF;
571 codec->set_bias_level = wm8731_set_bias_level; 532 codec->set_bias_level = wm8731_set_bias_level;
572 codec->dai = &wm8731_dai; 533 codec->dai = &wm8731_dai;
@@ -576,10 +537,16 @@ static int wm8731_register(struct wm8731_priv *wm8731)
576 537
577 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); 538 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
578 539
540 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
541 if (ret < 0) {
542 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
543 goto err;
544 }
545
579 ret = wm8731_reset(codec); 546 ret = wm8731_reset(codec);
580 if (ret < 0) { 547 if (ret < 0) {
581 dev_err(codec->dev, "Failed to issue reset\n"); 548 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
582 return ret; 549 goto err;
583 } 550 }
584 551
585 wm8731_dai.dev = codec->dev; 552 wm8731_dai.dev = codec->dev;
@@ -587,35 +554,36 @@ static int wm8731_register(struct wm8731_priv *wm8731)
587 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 554 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
588 555
589 /* Latch the update bits */ 556 /* Latch the update bits */
590 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); 557 snd_soc_update_bits(codec, WM8731_LOUT1V, 0x100, 0);
591 wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100); 558 snd_soc_update_bits(codec, WM8731_ROUT1V, 0x100, 0);
592 reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); 559 snd_soc_update_bits(codec, WM8731_LINVOL, 0x100, 0);
593 wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100); 560 snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
594 reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
595 wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
596 reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
597 wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
598 561
599 /* Disable bypass path by default */ 562 /* Disable bypass path by default */
600 reg = wm8731_read_reg_cache(codec, WM8731_APANA); 563 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
601 wm8731_write(codec, WM8731_APANA, reg & ~0x4);
602 564
603 wm8731_codec = codec; 565 wm8731_codec = codec;
604 566
605 ret = snd_soc_register_codec(codec); 567 ret = snd_soc_register_codec(codec);
606 if (ret != 0) { 568 if (ret != 0) {
607 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 569 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
608 return ret; 570 goto err;
609 } 571 }
610 572
611 ret = snd_soc_register_dai(&wm8731_dai); 573 ret = snd_soc_register_dai(&wm8731_dai);
612 if (ret != 0) { 574 if (ret != 0) {
613 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 575 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
614 snd_soc_unregister_codec(codec); 576 snd_soc_unregister_codec(codec);
615 return ret; 577 goto err_codec;
616 } 578 }
617 579
618 return 0; 580 return 0;
581
582err_codec:
583 snd_soc_unregister_codec(codec);
584err:
585 kfree(wm8731);
586 return ret;
619} 587}
620 588
621static void wm8731_unregister(struct wm8731_priv *wm8731) 589static void wm8731_unregister(struct wm8731_priv *wm8731)
@@ -628,30 +596,6 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
628} 596}
629 597
630#if defined(CONFIG_SPI_MASTER) 598#if defined(CONFIG_SPI_MASTER)
631static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
632{
633 struct spi_transfer t;
634 struct spi_message m;
635 u8 msg[2];
636
637 if (len <= 0)
638 return 0;
639
640 msg[0] = data[0];
641 msg[1] = data[1];
642
643 spi_message_init(&m);
644 memset(&t, 0, (sizeof t));
645
646 t.tx_buf = &msg[0];
647 t.len = len;
648
649 spi_message_add_tail(&t, &m);
650 spi_sync(spi, &m);
651
652 return len;
653}
654
655static int __devinit wm8731_spi_probe(struct spi_device *spi) 599static int __devinit wm8731_spi_probe(struct spi_device *spi)
656{ 600{
657 struct snd_soc_codec *codec; 601 struct snd_soc_codec *codec;
@@ -663,12 +607,11 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
663 607
664 codec = &wm8731->codec; 608 codec = &wm8731->codec;
665 codec->control_data = spi; 609 codec->control_data = spi;
666 codec->hw_write = (hw_write_t)wm8731_spi_write;
667 codec->dev = &spi->dev; 610 codec->dev = &spi->dev;
668 611
669 dev_set_drvdata(&spi->dev, wm8731); 612 dev_set_drvdata(&spi->dev, wm8731);
670 613
671 return wm8731_register(wm8731); 614 return wm8731_register(wm8731, SND_SOC_SPI);
672} 615}
673 616
674static int __devexit wm8731_spi_remove(struct spi_device *spi) 617static int __devexit wm8731_spi_remove(struct spi_device *spi)
@@ -680,6 +623,21 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
680 return 0; 623 return 0;
681} 624}
682 625
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
683static struct spi_driver wm8731_spi_driver = { 641static struct spi_driver wm8731_spi_driver = {
684 .driver = { 642 .driver = {
685 .name = "wm8731", 643 .name = "wm8731",
@@ -687,6 +645,8 @@ static struct spi_driver wm8731_spi_driver = {
687 .owner = THIS_MODULE, 645 .owner = THIS_MODULE,
688 }, 646 },
689 .probe = wm8731_spi_probe, 647 .probe = wm8731_spi_probe,
648 .suspend = wm8731_spi_suspend,
649 .resume = wm8731_spi_resume,
690 .remove = __devexit_p(wm8731_spi_remove), 650 .remove = __devexit_p(wm8731_spi_remove),
691}; 651};
692#endif /* CONFIG_SPI_MASTER */ 652#endif /* CONFIG_SPI_MASTER */
@@ -703,14 +663,13 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
703 return -ENOMEM; 663 return -ENOMEM;
704 664
705 codec = &wm8731->codec; 665 codec = &wm8731->codec;
706 codec->hw_write = (hw_write_t)i2c_master_send;
707 666
708 i2c_set_clientdata(i2c, wm8731); 667 i2c_set_clientdata(i2c, wm8731);
709 codec->control_data = i2c; 668 codec->control_data = i2c;
710 669
711 codec->dev = &i2c->dev; 670 codec->dev = &i2c->dev;
712 671
713 return wm8731_register(wm8731); 672 return wm8731_register(wm8731, SND_SOC_I2C);
714} 673}
715 674
716static __devexit int wm8731_i2c_remove(struct i2c_client *client) 675static __devexit int wm8731_i2c_remove(struct i2c_client *client)
@@ -720,6 +679,21 @@ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
720 return 0; 679 return 0;
721} 680}
722 681
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
723static const struct i2c_device_id wm8731_i2c_id[] = { 697static const struct i2c_device_id wm8731_i2c_id[] = {
724 { "wm8731", 0 }, 698 { "wm8731", 0 },
725 { } 699 { }
@@ -733,6 +707,8 @@ static struct i2c_driver wm8731_i2c_driver = {
733 }, 707 },
734 .probe = wm8731_i2c_probe, 708 .probe = wm8731_i2c_probe,
735 .remove = __devexit_p(wm8731_i2c_remove), 709 .remove = __devexit_p(wm8731_i2c_remove),
710 .suspend = wm8731_i2c_suspend,
711 .resume = wm8731_i2c_resume,
736 .id_table = wm8731_i2c_id, 712 .id_table = wm8731_i2c_id,
737}; 713};
738#endif 714#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index b64509b01a49..4ba1e7e93fb4 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -55,50 +55,7 @@ static const u16 wm8750_reg[] = {
55 0x0079, 0x0079, 0x0079, /* 40 */ 55 0x0079, 0x0079, 0x0079, /* 40 */
56}; 56};
57 57
58/* 58#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
59 * read wm8750 register cache
60 */
61static inline unsigned int wm8750_read_reg_cache(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 u16 *cache = codec->reg_cache;
65 if (reg > WM8750_CACHE_REGNUM)
66 return -1;
67 return cache[reg];
68}
69
70/*
71 * write wm8750 register cache
72 */
73static inline void wm8750_write_reg_cache(struct snd_soc_codec *codec,
74 unsigned int reg, unsigned int value)
75{
76 u16 *cache = codec->reg_cache;
77 if (reg > WM8750_CACHE_REGNUM)
78 return;
79 cache[reg] = value;
80}
81
82static int wm8750_write(struct snd_soc_codec *codec, unsigned int reg,
83 unsigned int value)
84{
85 u8 data[2];
86
87 /* data is
88 * D15..D9 WM8753 register offset
89 * D8...D0 register data
90 */
91 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
92 data[1] = value & 0x00ff;
93
94 wm8750_write_reg_cache(codec, reg, value);
95 if (codec->hw_write(codec->control_data, data, 2) == 2)
96 return 0;
97 else
98 return -EIO;
99}
100
101#define wm8750_reset(c) wm8750_write(c, WM8750_RESET, 0)
102 59
103/* 60/*
104 * WM8750 Controls 61 * WM8750 Controls
@@ -594,7 +551,7 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
594 return -EINVAL; 551 return -EINVAL;
595 } 552 }
596 553
597 wm8750_write(codec, WM8750_IFACE, iface); 554 snd_soc_write(codec, WM8750_IFACE, iface);
598 return 0; 555 return 0;
599} 556}
600 557
@@ -606,8 +563,8 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
606 struct snd_soc_device *socdev = rtd->socdev; 563 struct snd_soc_device *socdev = rtd->socdev;
607 struct snd_soc_codec *codec = socdev->card->codec; 564 struct snd_soc_codec *codec = socdev->card->codec;
608 struct wm8750_priv *wm8750 = codec->private_data; 565 struct wm8750_priv *wm8750 = codec->private_data;
609 u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; 566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
610 u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; 567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
611 int coeff = get_coeff(wm8750->sysclk, params_rate(params)); 568 int coeff = get_coeff(wm8750->sysclk, params_rate(params));
612 569
613 /* bit size */ 570 /* bit size */
@@ -626,9 +583,9 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
626 } 583 }
627 584
628 /* set iface & srate */ 585 /* set iface & srate */
629 wm8750_write(codec, WM8750_IFACE, iface); 586 snd_soc_write(codec, WM8750_IFACE, iface);
630 if (coeff >= 0) 587 if (coeff >= 0)
631 wm8750_write(codec, WM8750_SRATE, srate | 588 snd_soc_write(codec, WM8750_SRATE, srate |
632 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); 589 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
633 590
634 return 0; 591 return 0;
@@ -637,35 +594,35 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
637static int wm8750_mute(struct snd_soc_dai *dai, int mute) 594static int wm8750_mute(struct snd_soc_dai *dai, int mute)
638{ 595{
639 struct snd_soc_codec *codec = dai->codec; 596 struct snd_soc_codec *codec = dai->codec;
640 u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; 597 u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
641 598
642 if (mute) 599 if (mute)
643 wm8750_write(codec, WM8750_ADCDAC, mute_reg | 0x8); 600 snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
644 else 601 else
645 wm8750_write(codec, WM8750_ADCDAC, mute_reg); 602 snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
646 return 0; 603 return 0;
647} 604}
648 605
649static int wm8750_set_bias_level(struct snd_soc_codec *codec, 606static int wm8750_set_bias_level(struct snd_soc_codec *codec,
650 enum snd_soc_bias_level level) 607 enum snd_soc_bias_level level)
651{ 608{
652 u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; 609 u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
653 610
654 switch (level) { 611 switch (level) {
655 case SND_SOC_BIAS_ON: 612 case SND_SOC_BIAS_ON:
656 /* set vmid to 50k and unmute dac */ 613 /* set vmid to 50k and unmute dac */
657 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
658 break; 615 break;
659 case SND_SOC_BIAS_PREPARE: 616 case SND_SOC_BIAS_PREPARE:
660 /* set vmid to 5k for quick power up */ 617 /* set vmid to 5k for quick power up */
661 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 618 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
662 break; 619 break;
663 case SND_SOC_BIAS_STANDBY: 620 case SND_SOC_BIAS_STANDBY:
664 /* mute dac and set vmid to 500k, enable VREF */ 621 /* mute dac and set vmid to 500k, enable VREF */
665 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
666 break; 623 break;
667 case SND_SOC_BIAS_OFF: 624 case SND_SOC_BIAS_OFF:
668 wm8750_write(codec, WM8750_PWR1, 0x0001); 625 snd_soc_write(codec, WM8750_PWR1, 0x0001);
669 break; 626 break;
670 } 627 }
671 codec->bias_level = level; 628 codec->bias_level = level;
@@ -754,15 +711,14 @@ static int wm8750_resume(struct platform_device *pdev)
754 * initialise the WM8750 driver 711 * initialise the WM8750 driver
755 * register the mixer and dsp interfaces with the kernel 712 * register the mixer and dsp interfaces with the kernel
756 */ 713 */
757static int wm8750_init(struct snd_soc_device *socdev) 714static int wm8750_init(struct snd_soc_device *socdev,
715 enum snd_soc_control_type control)
758{ 716{
759 struct snd_soc_codec *codec = socdev->card->codec; 717 struct snd_soc_codec *codec = socdev->card->codec;
760 int reg, ret = 0; 718 int reg, ret = 0;
761 719
762 codec->name = "WM8750"; 720 codec->name = "WM8750";
763 codec->owner = THIS_MODULE; 721 codec->owner = THIS_MODULE;
764 codec->read = wm8750_read_reg_cache;
765 codec->write = wm8750_write;
766 codec->set_bias_level = wm8750_set_bias_level; 722 codec->set_bias_level = wm8750_set_bias_level;
767 codec->dai = &wm8750_dai; 723 codec->dai = &wm8750_dai;
768 codec->num_dai = 1; 724 codec->num_dai = 1;
@@ -771,13 +727,23 @@ static int wm8750_init(struct snd_soc_device *socdev)
771 if (codec->reg_cache == NULL) 727 if (codec->reg_cache == NULL)
772 return -ENOMEM; 728 return -ENOMEM;
773 729
774 wm8750_reset(codec); 730 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
731 if (ret < 0) {
732 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
733 goto err;
734 }
735
736 ret = wm8750_reset(codec);
737 if (ret < 0) {
738 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
739 goto err;
740 }
775 741
776 /* register pcms */ 742 /* register pcms */
777 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 743 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
778 if (ret < 0) { 744 if (ret < 0) {
779 printk(KERN_ERR "wm8750: failed to create pcms\n"); 745 printk(KERN_ERR "wm8750: failed to create pcms\n");
780 goto pcm_err; 746 goto err;
781 } 747 }
782 748
783 /* charge output caps */ 749 /* charge output caps */
@@ -786,22 +752,22 @@ static int wm8750_init(struct snd_soc_device *socdev)
786 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); 752 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
787 753
788 /* set the update bits */ 754 /* set the update bits */
789 reg = wm8750_read_reg_cache(codec, WM8750_LDAC); 755 reg = snd_soc_read(codec, WM8750_LDAC);
790 wm8750_write(codec, WM8750_LDAC, reg | 0x0100); 756 snd_soc_write(codec, WM8750_LDAC, reg | 0x0100);
791 reg = wm8750_read_reg_cache(codec, WM8750_RDAC); 757 reg = snd_soc_read(codec, WM8750_RDAC);
792 wm8750_write(codec, WM8750_RDAC, reg | 0x0100); 758 snd_soc_write(codec, WM8750_RDAC, reg | 0x0100);
793 reg = wm8750_read_reg_cache(codec, WM8750_LOUT1V); 759 reg = snd_soc_read(codec, WM8750_LOUT1V);
794 wm8750_write(codec, WM8750_LOUT1V, reg | 0x0100); 760 snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100);
795 reg = wm8750_read_reg_cache(codec, WM8750_ROUT1V); 761 reg = snd_soc_read(codec, WM8750_ROUT1V);
796 wm8750_write(codec, WM8750_ROUT1V, reg | 0x0100); 762 snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100);
797 reg = wm8750_read_reg_cache(codec, WM8750_LOUT2V); 763 reg = snd_soc_read(codec, WM8750_LOUT2V);
798 wm8750_write(codec, WM8750_LOUT2V, reg | 0x0100); 764 snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100);
799 reg = wm8750_read_reg_cache(codec, WM8750_ROUT2V); 765 reg = snd_soc_read(codec, WM8750_ROUT2V);
800 wm8750_write(codec, WM8750_ROUT2V, reg | 0x0100); 766 snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100);
801 reg = wm8750_read_reg_cache(codec, WM8750_LINVOL); 767 reg = snd_soc_read(codec, WM8750_LINVOL);
802 wm8750_write(codec, WM8750_LINVOL, reg | 0x0100); 768 snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100);
803 reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); 769 reg = snd_soc_read(codec, WM8750_RINVOL);
804 wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); 770 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
805 771
806 snd_soc_add_controls(codec, wm8750_snd_controls, 772 snd_soc_add_controls(codec, wm8750_snd_controls,
807 ARRAY_SIZE(wm8750_snd_controls)); 773 ARRAY_SIZE(wm8750_snd_controls));
@@ -816,7 +782,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
816card_err: 782card_err:
817 snd_soc_free_pcms(socdev); 783 snd_soc_free_pcms(socdev);
818 snd_soc_dapm_free(socdev); 784 snd_soc_dapm_free(socdev);
819pcm_err: 785err:
820 kfree(codec->reg_cache); 786 kfree(codec->reg_cache);
821 return ret; 787 return ret;
822} 788}
@@ -844,7 +810,7 @@ static int wm8750_i2c_probe(struct i2c_client *i2c,
844 i2c_set_clientdata(i2c, codec); 810 i2c_set_clientdata(i2c, codec);
845 codec->control_data = i2c; 811 codec->control_data = i2c;
846 812
847 ret = wm8750_init(socdev); 813 ret = wm8750_init(socdev, SND_SOC_I2C);
848 if (ret < 0) 814 if (ret < 0)
849 pr_err("failed to initialise WM8750\n"); 815 pr_err("failed to initialise WM8750\n");
850 816
@@ -924,7 +890,7 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi)
924 890
925 codec->control_data = spi; 891 codec->control_data = spi;
926 892
927 ret = wm8750_init(socdev); 893 ret = wm8750_init(socdev, SND_SOC_SPI);
928 if (ret < 0) 894 if (ret < 0)
929 dev_err(&spi->dev, "failed to initialise WM8750\n"); 895 dev_err(&spi->dev, "failed to initialise WM8750\n");
930 896
@@ -945,30 +911,6 @@ static struct spi_driver wm8750_spi_driver = {
945 .probe = wm8750_spi_probe, 911 .probe = wm8750_spi_probe,
946 .remove = __devexit_p(wm8750_spi_remove), 912 .remove = __devexit_p(wm8750_spi_remove),
947}; 913};
948
949static int wm8750_spi_write(struct spi_device *spi, const char *data, int len)
950{
951 struct spi_transfer t;
952 struct spi_message m;
953 u8 msg[2];
954
955 if (len <= 0)
956 return 0;
957
958 msg[0] = data[0];
959 msg[1] = data[1];
960
961 spi_message_init(&m);
962 memset(&t, 0, (sizeof t));
963
964 t.tx_buf = &msg[0];
965 t.len = len;
966
967 spi_message_add_tail(&t, &m);
968 spi_sync(spi, &m);
969
970 return len;
971}
972#endif 914#endif
973 915
974static int wm8750_probe(struct platform_device *pdev) 916static int wm8750_probe(struct platform_device *pdev)
@@ -1002,13 +944,11 @@ static int wm8750_probe(struct platform_device *pdev)
1002 944
1003#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 945#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1004 if (setup->i2c_address) { 946 if (setup->i2c_address) {
1005 codec->hw_write = (hw_write_t)i2c_master_send;
1006 ret = wm8750_add_i2c_device(pdev, setup); 947 ret = wm8750_add_i2c_device(pdev, setup);
1007 } 948 }
1008#endif 949#endif
1009#if defined(CONFIG_SPI_MASTER) 950#if defined(CONFIG_SPI_MASTER)
1010 if (setup->spi) { 951 if (setup->spi) {
1011 codec->hw_write = (hw_write_t)wm8750_spi_write;
1012 ret = spi_register_driver(&wm8750_spi_driver); 952 ret = spi_register_driver(&wm8750_spi_driver);
1013 if (ret != 0) 953 if (ret != 0)
1014 printk(KERN_ERR "can't add spi driver"); 954 printk(KERN_ERR "can't add spi driver");
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index d121e58cae2b..d80d414cfbbd 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -79,7 +79,7 @@ static const u16 wm8753_reg[] = {
79 0x0097, 0x0097, 0x0000, 0x0004, 79 0x0097, 0x0097, 0x0000, 0x0004,
80 0x0000, 0x0083, 0x0024, 0x01ba, 80 0x0000, 0x0083, 0x0024, 0x01ba,
81 0x0000, 0x0083, 0x0024, 0x01ba, 81 0x0000, 0x0083, 0x0024, 0x01ba,
82 0x0000, 0x0000 82 0x0000, 0x0000, 0x0000
83}; 83};
84 84
85/* codec private data */ 85/* codec private data */
@@ -703,7 +703,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
703 703
704 if ((Ndiv < 6) || (Ndiv > 12)) 704 if ((Ndiv < 6) || (Ndiv > 12))
705 printk(KERN_WARNING 705 printk(KERN_WARNING
706 "wm8753: unsupported N = %d\n", Ndiv); 706 "wm8753: unsupported N = %u\n", Ndiv);
707 707
708 pll_div->n = Ndiv; 708 pll_div->n = Ndiv;
709 Nmod = target % source; 709 Nmod = target % source;
@@ -1660,11 +1660,11 @@ static int wm8753_register(struct wm8753_priv *wm8753)
1660 codec->set_bias_level = wm8753_set_bias_level; 1660 codec->set_bias_level = wm8753_set_bias_level;
1661 codec->dai = wm8753_dai; 1661 codec->dai = wm8753_dai;
1662 codec->num_dai = 2; 1662 codec->num_dai = 2;
1663 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache); 1663 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1;
1664 codec->reg_cache = &wm8753->reg_cache; 1664 codec->reg_cache = &wm8753->reg_cache;
1665 codec->private_data = wm8753; 1665 codec->private_data = wm8753;
1666 1666
1667 memcpy(codec->reg_cache, wm8753_reg, sizeof(codec->reg_cache)); 1667 memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
1668 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); 1668 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1669 1669
1670 ret = wm8753_reset(codec); 1670 ret = wm8753_reset(codec);
@@ -1766,6 +1766,21 @@ static int wm8753_i2c_remove(struct i2c_client *client)
1766 return 0; 1766 return 0;
1767} 1767}
1768 1768
1769#ifdef CONFIG_PM
1770static int wm8753_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1771{
1772 return snd_soc_suspend_device(&client->dev);
1773}
1774
1775static int wm8753_i2c_resume(struct i2c_client *client)
1776{
1777 return snd_soc_resume_device(&client->dev);
1778}
1779#else
1780#define wm8753_i2c_suspend NULL
1781#define wm8753_i2c_resume NULL
1782#endif
1783
1769static const struct i2c_device_id wm8753_i2c_id[] = { 1784static const struct i2c_device_id wm8753_i2c_id[] = {
1770 { "wm8753", 0 }, 1785 { "wm8753", 0 },
1771 { } 1786 { }
@@ -1779,6 +1794,8 @@ static struct i2c_driver wm8753_i2c_driver = {
1779 }, 1794 },
1780 .probe = wm8753_i2c_probe, 1795 .probe = wm8753_i2c_probe,
1781 .remove = wm8753_i2c_remove, 1796 .remove = wm8753_i2c_remove,
1797 .suspend = wm8753_i2c_suspend,
1798 .resume = wm8753_i2c_resume,
1782 .id_table = wm8753_i2c_id, 1799 .id_table = wm8753_i2c_id,
1783}; 1800};
1784#endif 1801#endif
@@ -1834,6 +1851,22 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1834 return 0; 1851 return 0;
1835} 1852}
1836 1853
1854#ifdef CONFIG_PM
1855static int wm8753_spi_suspend(struct spi_device *spi, pm_message_t msg)
1856{
1857 return snd_soc_suspend_device(&spi->dev);
1858}
1859
1860static int wm8753_spi_resume(struct spi_device *spi)
1861{
1862 return snd_soc_resume_device(&spi->dev);
1863}
1864
1865#else
1866#define wm8753_spi_suspend NULL
1867#define wm8753_spi_resume NULL
1868#endif
1869
1837static struct spi_driver wm8753_spi_driver = { 1870static struct spi_driver wm8753_spi_driver = {
1838 .driver = { 1871 .driver = {
1839 .name = "wm8753", 1872 .name = "wm8753",
@@ -1842,6 +1875,8 @@ static struct spi_driver wm8753_spi_driver = {
1842 }, 1875 },
1843 .probe = wm8753_spi_probe, 1876 .probe = wm8753_spi_probe,
1844 .remove = __devexit_p(wm8753_spi_remove), 1877 .remove = __devexit_p(wm8753_spi_remove),
1878 .suspend = wm8753_spi_suspend,
1879 .resume = wm8753_spi_resume,
1845}; 1880};
1846#endif 1881#endif
1847 1882
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
new file mode 100644
index 000000000000..a9829aa26e53
--- /dev/null
+++ b/sound/soc/codecs/wm8776.c
@@ -0,0 +1,744 @@
1/*
2 * wm8776.c -- WM8776 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 * TODO: Input ALC/limiter support
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 <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 "wm8776.h"
32
33static struct snd_soc_codec *wm8776_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8776;
35
36/* codec private data */
37struct wm8776_priv {
38 struct snd_soc_codec codec;
39 u16 reg_cache[WM8776_CACHEREGNUM];
40 int sysclk[2];
41};
42
43#ifdef CONFIG_SPI_MASTER
44static int wm8776_spi_write(struct spi_device *spi, const char *data, int len);
45#endif
46
47static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
48 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */
49 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */
50 0x22, 0x22, 0x22, 0x08, 0xcf, /* 14 */
51 0xcf, 0x7b, 0x00, 0x32, 0x00, /* 19 */
52 0xa6, 0x01, 0x01
53};
54
55static int wm8776_reset(struct snd_soc_codec *codec)
56{
57 return snd_soc_write(codec, WM8776_RESET, 0);
58}
59
60static const DECLARE_TLV_DB_SCALE(hp_tlv, -12100, 100, 1);
61static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
62static const DECLARE_TLV_DB_SCALE(adc_tlv, -10350, 50, 1);
63
64static const struct snd_kcontrol_new wm8776_snd_controls[] = {
65SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8776_HPLVOL, WM8776_HPRVOL,
66 0, 127, 0, hp_tlv),
67SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8776_DACLVOL, WM8776_DACRVOL,
68 0, 255, 0, dac_tlv),
69SOC_SINGLE("Digital Playback ZC Switch", WM8776_DACCTRL1, 0, 1, 0),
70
71SOC_SINGLE("Deemphasis Switch", WM8776_DACCTRL2, 0, 1, 0),
72
73SOC_DOUBLE_R_TLV("Capture Volume", WM8776_ADCLVOL, WM8776_ADCRVOL,
74 0, 255, 0, adc_tlv),
75SOC_DOUBLE("Capture Switch", WM8776_ADCMUX, 7, 6, 1, 1),
76SOC_DOUBLE_R("Capture ZC Switch", WM8776_ADCLVOL, WM8776_ADCRVOL, 8, 1, 0),
77SOC_SINGLE("Capture HPF Switch", WM8776_ADCIFCTRL, 8, 1, 1),
78};
79
80static const struct snd_kcontrol_new inmix_controls[] = {
81SOC_DAPM_SINGLE("AIN1 Switch", WM8776_ADCMUX, 0, 1, 0),
82SOC_DAPM_SINGLE("AIN2 Switch", WM8776_ADCMUX, 1, 1, 0),
83SOC_DAPM_SINGLE("AIN3 Switch", WM8776_ADCMUX, 2, 1, 0),
84SOC_DAPM_SINGLE("AIN4 Switch", WM8776_ADCMUX, 3, 1, 0),
85SOC_DAPM_SINGLE("AIN5 Switch", WM8776_ADCMUX, 4, 1, 0),
86};
87
88static const struct snd_kcontrol_new outmix_controls[] = {
89SOC_DAPM_SINGLE("DAC Switch", WM8776_OUTMUX, 0, 1, 0),
90SOC_DAPM_SINGLE("AUX Switch", WM8776_OUTMUX, 1, 1, 0),
91SOC_DAPM_SINGLE("Bypass Switch", WM8776_OUTMUX, 2, 1, 0),
92};
93
94static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = {
95SND_SOC_DAPM_INPUT("AUX"),
96SND_SOC_DAPM_INPUT("AUX"),
97
98SND_SOC_DAPM_INPUT("AIN1"),
99SND_SOC_DAPM_INPUT("AIN2"),
100SND_SOC_DAPM_INPUT("AIN3"),
101SND_SOC_DAPM_INPUT("AIN4"),
102SND_SOC_DAPM_INPUT("AIN5"),
103
104SND_SOC_DAPM_MIXER("Input Mixer", WM8776_PWRDOWN, 6, 1,
105 inmix_controls, ARRAY_SIZE(inmix_controls)),
106
107SND_SOC_DAPM_ADC("ADC", "Capture", WM8776_PWRDOWN, 1, 1),
108SND_SOC_DAPM_DAC("DAC", "Playback", WM8776_PWRDOWN, 2, 1),
109
110SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
111 outmix_controls, ARRAY_SIZE(outmix_controls)),
112
113SND_SOC_DAPM_PGA("Headphone PGA", WM8776_PWRDOWN, 3, 1, NULL, 0),
114
115SND_SOC_DAPM_OUTPUT("VOUT"),
116
117SND_SOC_DAPM_OUTPUT("HPOUTL"),
118SND_SOC_DAPM_OUTPUT("HPOUTR"),
119};
120
121static const struct snd_soc_dapm_route routes[] = {
122 { "Input Mixer", "AIN1 Switch", "AIN1" },
123 { "Input Mixer", "AIN2 Switch", "AIN2" },
124 { "Input Mixer", "AIN3 Switch", "AIN3" },
125 { "Input Mixer", "AIN4 Switch", "AIN4" },
126 { "Input Mixer", "AIN5 Switch", "AIN5" },
127
128 { "ADC", NULL, "Input Mixer" },
129
130 { "Output Mixer", "DAC Switch", "DAC" },
131 { "Output Mixer", "AUX Switch", "AUX" },
132 { "Output Mixer", "Bypass Switch", "Input Mixer" },
133
134 { "VOUT", NULL, "Output Mixer" },
135
136 { "Headphone PGA", NULL, "Output Mixer" },
137
138 { "HPOUTL", NULL, "Headphone PGA" },
139 { "HPOUTR", NULL, "Headphone PGA" },
140};
141
142static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
143{
144 struct snd_soc_codec *codec = dai->codec;
145 int reg, iface, master;
146
147 switch (dai->id) {
148 case WM8776_DAI_DAC:
149 reg = WM8776_DACIFCTRL;
150 master = 0x80;
151 break;
152 case WM8776_DAI_ADC:
153 reg = WM8776_ADCIFCTRL;
154 master = 0x100;
155 break;
156 default:
157 return -EINVAL;
158 }
159
160 iface = 0;
161
162 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
163 case SND_SOC_DAIFMT_CBM_CFM:
164 break;
165 case SND_SOC_DAIFMT_CBS_CFS:
166 master = 0;
167 break;
168 default:
169 return -EINVAL;
170 }
171
172 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
173 case SND_SOC_DAIFMT_I2S:
174 iface |= 0x0002;
175 break;
176 case SND_SOC_DAIFMT_RIGHT_J:
177 break;
178 case SND_SOC_DAIFMT_LEFT_J:
179 iface |= 0x0001;
180 break;
181 /* FIXME: CHECK A/B */
182 case SND_SOC_DAIFMT_DSP_A:
183 iface |= 0x0003;
184 break;
185 case SND_SOC_DAIFMT_DSP_B:
186 iface |= 0x0007;
187 break;
188 default:
189 return -EINVAL;
190 }
191
192 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
193 case SND_SOC_DAIFMT_NB_NF:
194 break;
195 case SND_SOC_DAIFMT_IB_IF:
196 iface |= 0x00c;
197 break;
198 case SND_SOC_DAIFMT_IB_NF:
199 iface |= 0x008;
200 break;
201 case SND_SOC_DAIFMT_NB_IF:
202 iface |= 0x004;
203 break;
204 default:
205 return -EINVAL;
206 }
207
208 /* Finally, write out the values */
209 snd_soc_update_bits(codec, reg, 0xf, iface);
210 snd_soc_update_bits(codec, WM8776_MSTRCTRL, 0x180, master);
211
212 return 0;
213}
214
215static int mclk_ratios[] = {
216 128,
217 192,
218 256,
219 384,
220 512,
221 768,
222};
223
224static int wm8776_hw_params(struct snd_pcm_substream *substream,
225 struct snd_pcm_hw_params *params,
226 struct snd_soc_dai *dai)
227{
228 struct snd_soc_codec *codec = dai->codec;
229 struct wm8776_priv *wm8776 = codec->private_data;
230 int iface_reg, iface;
231 int ratio_shift, master;
232 int i;
233
234 iface = 0;
235
236 switch (dai->id) {
237 case WM8776_DAI_DAC:
238 iface_reg = WM8776_DACIFCTRL;
239 master = 0x80;
240 ratio_shift = 4;
241 break;
242 case WM8776_DAI_ADC:
243 iface_reg = WM8776_ADCIFCTRL;
244 master = 0x100;
245 ratio_shift = 0;
246 break;
247 default:
248 return -EINVAL;
249 }
250
251
252 /* Set word length */
253 switch (params_format(params)) {
254 case SNDRV_PCM_FORMAT_S16_LE:
255 break;
256 case SNDRV_PCM_FORMAT_S20_3LE:
257 iface |= 0x10;
258 break;
259 case SNDRV_PCM_FORMAT_S24_LE:
260 iface |= 0x20;
261 break;
262 case SNDRV_PCM_FORMAT_S32_LE:
263 iface |= 0x30;
264 break;
265 }
266
267 /* Only need to set MCLK/LRCLK ratio if we're master */
268 if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) {
269 for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) {
270 if (wm8776->sysclk[dai->id] / params_rate(params)
271 == mclk_ratios[i])
272 break;
273 }
274
275 if (i == ARRAY_SIZE(mclk_ratios)) {
276 dev_err(codec->dev,
277 "Unable to configure MCLK ratio %d/%d\n",
278 wm8776->sysclk[dai->id], params_rate(params));
279 return -EINVAL;
280 }
281
282 dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
283
284 snd_soc_update_bits(codec, WM8776_MSTRCTRL,
285 0x7 << ratio_shift, i << ratio_shift);
286 } else {
287 dev_dbg(codec->dev, "DAI in slave mode\n");
288 }
289
290 snd_soc_update_bits(codec, iface_reg, 0x30, iface);
291
292 return 0;
293}
294
295static int wm8776_mute(struct snd_soc_dai *dai, int mute)
296{
297 struct snd_soc_codec *codec = dai->codec;
298
299 return snd_soc_write(codec, WM8776_DACMUTE, !!mute);
300}
301
302static int wm8776_set_sysclk(struct snd_soc_dai *dai,
303 int clk_id, unsigned int freq, int dir)
304{
305 struct snd_soc_codec *codec = dai->codec;
306 struct wm8776_priv *wm8776 = codec->private_data;
307
308 BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk));
309
310 wm8776->sysclk[dai->id] = freq;
311
312 return 0;
313}
314
315static int wm8776_set_bias_level(struct snd_soc_codec *codec,
316 enum snd_soc_bias_level level)
317{
318 switch (level) {
319 case SND_SOC_BIAS_ON:
320 break;
321 case SND_SOC_BIAS_PREPARE:
322 break;
323 case SND_SOC_BIAS_STANDBY:
324 if (codec->bias_level == SND_SOC_BIAS_OFF) {
325 /* Disable the global powerdown; DAPM does the rest */
326 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
327 }
328
329 break;
330 case SND_SOC_BIAS_OFF:
331 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 1);
332 break;
333 }
334
335 codec->bias_level = level;
336 return 0;
337}
338
339#define WM8776_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
340 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
341 SNDRV_PCM_RATE_96000)
342
343
344#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
345 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
346
347static struct snd_soc_dai_ops wm8776_dac_ops = {
348 .digital_mute = wm8776_mute,
349 .hw_params = wm8776_hw_params,
350 .set_fmt = wm8776_set_fmt,
351 .set_sysclk = wm8776_set_sysclk,
352};
353
354static struct snd_soc_dai_ops wm8776_adc_ops = {
355 .hw_params = wm8776_hw_params,
356 .set_fmt = wm8776_set_fmt,
357 .set_sysclk = wm8776_set_sysclk,
358};
359
360struct snd_soc_dai wm8776_dai[] = {
361 {
362 .name = "WM8776 Playback",
363 .id = WM8776_DAI_DAC,
364 .playback = {
365 .stream_name = "Playback",
366 .channels_min = 2,
367 .channels_max = 2,
368 .rates = WM8776_RATES,
369 .formats = WM8776_FORMATS,
370 },
371 .ops = &wm8776_dac_ops,
372 },
373 {
374 .name = "WM8776 Capture",
375 .id = WM8776_DAI_ADC,
376 .capture = {
377 .stream_name = "Capture",
378 .channels_min = 2,
379 .channels_max = 2,
380 .rates = WM8776_RATES,
381 .formats = WM8776_FORMATS,
382 },
383 .ops = &wm8776_adc_ops,
384 },
385};
386EXPORT_SYMBOL_GPL(wm8776_dai);
387
388#ifdef CONFIG_PM
389static int wm8776_suspend(struct platform_device *pdev, pm_message_t state)
390{
391 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
392 struct snd_soc_codec *codec = socdev->card->codec;
393
394 wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
395
396 return 0;
397}
398
399static int wm8776_resume(struct platform_device *pdev)
400{
401 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
402 struct snd_soc_codec *codec = socdev->card->codec;
403 int i;
404 u8 data[2];
405 u16 *cache = codec->reg_cache;
406
407 /* Sync reg_cache with the hardware */
408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
409 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
410 data[1] = cache[i] & 0x00ff;
411 codec->hw_write(codec->control_data, data, 2);
412 }
413
414 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
415
416 return 0;
417}
418#else
419#define wm8776_suspend NULL
420#define wm8776_resume NULL
421#endif
422
423static int wm8776_probe(struct platform_device *pdev)
424{
425 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
426 struct snd_soc_codec *codec;
427 int ret = 0;
428
429 if (wm8776_codec == NULL) {
430 dev_err(&pdev->dev, "Codec device not registered\n");
431 return -ENODEV;
432 }
433
434 socdev->card->codec = wm8776_codec;
435 codec = wm8776_codec;
436
437 /* register pcms */
438 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
439 if (ret < 0) {
440 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
441 goto pcm_err;
442 }
443
444 snd_soc_add_controls(codec, wm8776_snd_controls,
445 ARRAY_SIZE(wm8776_snd_controls));
446 snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets,
447 ARRAY_SIZE(wm8776_dapm_widgets));
448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
449
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;
457
458card_err:
459 snd_soc_free_pcms(socdev);
460 snd_soc_dapm_free(socdev);
461pcm_err:
462 return ret;
463}
464
465/* power down chip */
466static int wm8776_remove(struct platform_device *pdev)
467{
468 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
469
470 snd_soc_free_pcms(socdev);
471 snd_soc_dapm_free(socdev);
472
473 return 0;
474}
475
476struct snd_soc_codec_device soc_codec_dev_wm8776 = {
477 .probe = wm8776_probe,
478 .remove = wm8776_remove,
479 .suspend = wm8776_suspend,
480 .resume = wm8776_resume,
481};
482EXPORT_SYMBOL_GPL(soc_codec_dev_wm8776);
483
484static int wm8776_register(struct wm8776_priv *wm8776,
485 enum snd_soc_control_type control)
486{
487 int ret, i;
488 struct snd_soc_codec *codec = &wm8776->codec;
489
490 if (wm8776_codec) {
491 dev_err(codec->dev, "Another WM8776 is registered\n");
492 ret = -EINVAL;
493 goto err;
494 }
495
496 mutex_init(&codec->mutex);
497 INIT_LIST_HEAD(&codec->dapm_widgets);
498 INIT_LIST_HEAD(&codec->dapm_paths);
499
500 codec->private_data = wm8776;
501 codec->name = "WM8776";
502 codec->owner = THIS_MODULE;
503 codec->bias_level = SND_SOC_BIAS_OFF;
504 codec->set_bias_level = wm8776_set_bias_level;
505 codec->dai = wm8776_dai;
506 codec->num_dai = ARRAY_SIZE(wm8776_dai);
507 codec->reg_cache_size = WM8776_CACHEREGNUM;
508 codec->reg_cache = &wm8776->reg_cache;
509
510 memcpy(codec->reg_cache, wm8776_reg, sizeof(wm8776_reg));
511
512 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
513 if (ret < 0) {
514 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
515 goto err;
516 }
517
518 for (i = 0; i < ARRAY_SIZE(wm8776_dai); i++)
519 wm8776_dai[i].dev = codec->dev;
520
521 ret = wm8776_reset(codec);
522 if (ret < 0) {
523 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
524 goto err;
525 }
526
527 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
528
529 /* Latch the update bits; right channel only since we always
530 * update both. */
531 snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
532 snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
533
534 wm8776_codec = codec;
535
536 ret = snd_soc_register_codec(codec);
537 if (ret != 0) {
538 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
539 goto err;
540 }
541
542 ret = snd_soc_register_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
543 if (ret != 0) {
544 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
545 goto err_codec;
546 }
547
548 return 0;
549
550err_codec:
551 snd_soc_unregister_codec(codec);
552err:
553 kfree(wm8776);
554 return ret;
555}
556
557static void wm8776_unregister(struct wm8776_priv *wm8776)
558{
559 wm8776_set_bias_level(&wm8776->codec, SND_SOC_BIAS_OFF);
560 snd_soc_unregister_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
561 snd_soc_unregister_codec(&wm8776->codec);
562 kfree(wm8776);
563 wm8776_codec = NULL;
564}
565
566#if defined(CONFIG_SPI_MASTER)
567static int wm8776_spi_write(struct spi_device *spi, const char *data, int len)
568{
569 struct spi_transfer t;
570 struct spi_message m;
571 u8 msg[2];
572
573 if (len <= 0)
574 return 0;
575
576 msg[0] = data[0];
577 msg[1] = data[1];
578
579 spi_message_init(&m);
580 memset(&t, 0, (sizeof t));
581
582 t.tx_buf = &msg[0];
583 t.len = len;
584
585 spi_message_add_tail(&t, &m);
586 spi_sync(spi, &m);
587
588 return len;
589}
590
591static int __devinit wm8776_spi_probe(struct spi_device *spi)
592{
593 struct snd_soc_codec *codec;
594 struct wm8776_priv *wm8776;
595
596 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
597 if (wm8776 == NULL)
598 return -ENOMEM;
599
600 codec = &wm8776->codec;
601 codec->control_data = spi;
602 codec->hw_write = (hw_write_t)wm8776_spi_write;
603 codec->dev = &spi->dev;
604
605 dev_set_drvdata(&spi->dev, wm8776);
606
607 return wm8776_register(wm8776, SND_SOC_SPI);
608}
609
610static int __devexit wm8776_spi_remove(struct spi_device *spi)
611{
612 struct wm8776_priv *wm8776 = dev_get_drvdata(&spi->dev);
613
614 wm8776_unregister(wm8776);
615
616 return 0;
617}
618
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 = {
635 .driver = {
636 .name = "wm8776",
637 .bus = &spi_bus_type,
638 .owner = THIS_MODULE,
639 },
640 .probe = wm8776_spi_probe,
641 .suspend = wm8776_spi_suspend,
642 .resume = wm8776_spi_resume,
643 .remove = __devexit_p(wm8776_spi_remove),
644};
645#endif /* CONFIG_SPI_MASTER */
646
647#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
648static __devinit int wm8776_i2c_probe(struct i2c_client *i2c,
649 const struct i2c_device_id *id)
650{
651 struct wm8776_priv *wm8776;
652 struct snd_soc_codec *codec;
653
654 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
655 if (wm8776 == NULL)
656 return -ENOMEM;
657
658 codec = &wm8776->codec;
659 codec->hw_write = (hw_write_t)i2c_master_send;
660
661 i2c_set_clientdata(i2c, wm8776);
662 codec->control_data = i2c;
663
664 codec->dev = &i2c->dev;
665
666 return wm8776_register(wm8776, SND_SOC_I2C);
667}
668
669static __devexit int wm8776_i2c_remove(struct i2c_client *client)
670{
671 struct wm8776_priv *wm8776 = i2c_get_clientdata(client);
672 wm8776_unregister(wm8776);
673 return 0;
674}
675
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[] = {
692 { "wm8776", 0 },
693 { }
694};
695MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
696
697static struct i2c_driver wm8776_i2c_driver = {
698 .driver = {
699 .name = "wm8776",
700 .owner = THIS_MODULE,
701 },
702 .probe = wm8776_i2c_probe,
703 .remove = __devexit_p(wm8776_i2c_remove),
704 .suspend = wm8776_i2c_suspend,
705 .resume = wm8776_i2c_resume,
706 .id_table = wm8776_i2c_id,
707};
708#endif
709
710static int __init wm8776_modinit(void)
711{
712 int ret;
713#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
714 ret = i2c_add_driver(&wm8776_i2c_driver);
715 if (ret != 0) {
716 printk(KERN_ERR "Failed to register WM8776 I2C driver: %d\n",
717 ret);
718 }
719#endif
720#if defined(CONFIG_SPI_MASTER)
721 ret = spi_register_driver(&wm8776_spi_driver);
722 if (ret != 0) {
723 printk(KERN_ERR "Failed to register WM8776 SPI driver: %d\n",
724 ret);
725 }
726#endif
727 return 0;
728}
729module_init(wm8776_modinit);
730
731static void __exit wm8776_exit(void)
732{
733#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
734 i2c_del_driver(&wm8776_i2c_driver);
735#endif
736#if defined(CONFIG_SPI_MASTER)
737 spi_unregister_driver(&wm8776_spi_driver);
738#endif
739}
740module_exit(wm8776_exit);
741
742MODULE_DESCRIPTION("ASoC WM8776 driver");
743MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
744MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8776.h b/sound/soc/codecs/wm8776.h
new file mode 100644
index 000000000000..6606d25d2d83
--- /dev/null
+++ b/sound/soc/codecs/wm8776.h
@@ -0,0 +1,51 @@
1/*
2 * wm8776.h -- WM8776 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 _WM8776_H
14#define _WM8776_H
15
16/* Registers */
17
18#define WM8776_HPLVOL 0x00
19#define WM8776_HPRVOL 0x01
20#define WM8776_HPMASTER 0x02
21#define WM8776_DACLVOL 0x03
22#define WM8776_DACRVOL 0x04
23#define WM8776_DACMASTER 0x05
24#define WM8776_PHASESWAP 0x06
25#define WM8776_DACCTRL1 0x07
26#define WM8776_DACMUTE 0x08
27#define WM8776_DACCTRL2 0x09
28#define WM8776_DACIFCTRL 0x0a
29#define WM8776_ADCIFCTRL 0x0b
30#define WM8776_MSTRCTRL 0x0c
31#define WM8776_PWRDOWN 0x0d
32#define WM8776_ADCLVOL 0x0e
33#define WM8776_ADCRVOL 0x0f
34#define WM8776_ALCCTRL1 0x10
35#define WM8776_ALCCTRL2 0x11
36#define WM8776_ALCCTRL3 0x12
37#define WM8776_NOISEGATE 0x13
38#define WM8776_LIMITER 0x14
39#define WM8776_ADCMUX 0x15
40#define WM8776_OUTMUX 0x16
41#define WM8776_RESET 0x17
42
43#define WM8776_CACHEREGNUM 0x17
44
45#define WM8776_DAI_DAC 0
46#define WM8776_DAI_ADC 1
47
48extern struct snd_soc_dai wm8776_dai[];
49extern struct snd_soc_codec_device soc_codec_dev_wm8776;
50
51#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 46c5ea1ff921..5e9c855c0036 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -116,6 +116,7 @@
116#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c 116#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
117 117
118#define WM8900_REG_DACCTRL_MUTE 0x004 118#define WM8900_REG_DACCTRL_MUTE 0x004
119#define WM8900_REG_DACCTRL_DAC_SB_FILT 0x100
119#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400 120#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400
120 121
121#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800 122#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800
@@ -182,111 +183,20 @@ static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
182 /* Remaining registers all zero */ 183 /* Remaining registers all zero */
183}; 184};
184 185
185/* 186static int wm8900_volatile_register(unsigned int reg)
186 * read wm8900 register cache
187 */
188static inline unsigned int wm8900_read_reg_cache(struct snd_soc_codec *codec,
189 unsigned int reg)
190{
191 u16 *cache = codec->reg_cache;
192
193 BUG_ON(reg >= WM8900_MAXREG);
194
195 if (reg == WM8900_REG_ID)
196 return 0;
197
198 return cache[reg];
199}
200
201/*
202 * write wm8900 register cache
203 */
204static inline void wm8900_write_reg_cache(struct snd_soc_codec *codec,
205 u16 reg, unsigned int value)
206{
207 u16 *cache = codec->reg_cache;
208
209 BUG_ON(reg >= WM8900_MAXREG);
210
211 cache[reg] = value;
212}
213
214/*
215 * write to the WM8900 register space
216 */
217static int wm8900_write(struct snd_soc_codec *codec, unsigned int reg,
218 unsigned int value)
219{
220 u8 data[3];
221
222 if (value == wm8900_read_reg_cache(codec, reg))
223 return 0;
224
225 /* data is
226 * D15..D9 WM8900 register offset
227 * D8...D0 register data
228 */
229 data[0] = reg;
230 data[1] = value >> 8;
231 data[2] = value & 0x00ff;
232
233 wm8900_write_reg_cache(codec, reg, value);
234 if (codec->hw_write(codec->control_data, data, 3) == 3)
235 return 0;
236 else
237 return -EIO;
238}
239
240/*
241 * Read from the wm8900.
242 */
243static unsigned int wm8900_chip_read(struct snd_soc_codec *codec, u8 reg)
244{
245 struct i2c_msg xfer[2];
246 u16 data;
247 int ret;
248 struct i2c_client *client = codec->control_data;
249
250 BUG_ON(reg != WM8900_REG_ID && reg != WM8900_REG_POWER1);
251
252 /* Write register */
253 xfer[0].addr = client->addr;
254 xfer[0].flags = 0;
255 xfer[0].len = 1;
256 xfer[0].buf = &reg;
257
258 /* Read data */
259 xfer[1].addr = client->addr;
260 xfer[1].flags = I2C_M_RD;
261 xfer[1].len = 2;
262 xfer[1].buf = (u8 *)&data;
263
264 ret = i2c_transfer(client->adapter, xfer, 2);
265 if (ret != 2) {
266 printk(KERN_CRIT "i2c_transfer returned %d\n", ret);
267 return 0;
268 }
269
270 return (data >> 8) | ((data & 0xff) << 8);
271}
272
273/*
274 * Read from the WM8900 register space. Most registers can't be read
275 * and are therefore supplied from cache.
276 */
277static unsigned int wm8900_read(struct snd_soc_codec *codec, unsigned int reg)
278{ 187{
279 switch (reg) { 188 switch (reg) {
280 case WM8900_REG_ID: 189 case WM8900_REG_ID:
281 return wm8900_chip_read(codec, reg); 190 case WM8900_REG_POWER1:
191 return 1;
282 default: 192 default:
283 return wm8900_read_reg_cache(codec, reg); 193 return 0;
284 } 194 }
285} 195}
286 196
287static void wm8900_reset(struct snd_soc_codec *codec) 197static void wm8900_reset(struct snd_soc_codec *codec)
288{ 198{
289 wm8900_write(codec, WM8900_REG_RESET, 0); 199 snd_soc_write(codec, WM8900_REG_RESET, 0);
290 200
291 memcpy(codec->reg_cache, wm8900_reg_defaults, 201 memcpy(codec->reg_cache, wm8900_reg_defaults,
292 sizeof(codec->reg_cache)); 202 sizeof(codec->reg_cache));
@@ -296,14 +206,14 @@ static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
296 struct snd_kcontrol *kcontrol, int event) 206 struct snd_kcontrol *kcontrol, int event)
297{ 207{
298 struct snd_soc_codec *codec = w->codec; 208 struct snd_soc_codec *codec = w->codec;
299 u16 hpctl1 = wm8900_read(codec, WM8900_REG_HPCTL1); 209 u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1);
300 210
301 switch (event) { 211 switch (event) {
302 case SND_SOC_DAPM_PRE_PMU: 212 case SND_SOC_DAPM_PRE_PMU:
303 /* Clamp headphone outputs */ 213 /* Clamp headphone outputs */
304 hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP | 214 hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
305 WM8900_REG_HPCTL1_HP_CLAMP_OP; 215 WM8900_REG_HPCTL1_HP_CLAMP_OP;
306 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 216 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
307 break; 217 break;
308 218
309 case SND_SOC_DAPM_POST_PMU: 219 case SND_SOC_DAPM_POST_PMU:
@@ -312,41 +222,41 @@ static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
312 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT | 222 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
313 WM8900_REG_HPCTL1_HP_SHORT2 | 223 WM8900_REG_HPCTL1_HP_SHORT2 |
314 WM8900_REG_HPCTL1_HP_IPSTAGE_ENA; 224 WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
315 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 225 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
316 226
317 msleep(400); 227 msleep(400);
318 228
319 /* Enable the output stage */ 229 /* Enable the output stage */
320 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP; 230 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
321 hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA; 231 hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
322 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 232 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
323 233
324 /* Remove the shorts */ 234 /* Remove the shorts */
325 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2; 235 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
326 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 236 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
327 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT; 237 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
328 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 238 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
329 break; 239 break;
330 240
331 case SND_SOC_DAPM_PRE_PMD: 241 case SND_SOC_DAPM_PRE_PMD:
332 /* Short the output */ 242 /* Short the output */
333 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT; 243 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
334 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 244 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
335 245
336 /* Disable the output stage */ 246 /* Disable the output stage */
337 hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA; 247 hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
338 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 248 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
339 249
340 /* Clamp the outputs and power down input */ 250 /* Clamp the outputs and power down input */
341 hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP | 251 hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
342 WM8900_REG_HPCTL1_HP_CLAMP_OP; 252 WM8900_REG_HPCTL1_HP_CLAMP_OP;
343 hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA; 253 hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
344 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 254 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
345 break; 255 break;
346 256
347 case SND_SOC_DAPM_POST_PMD: 257 case SND_SOC_DAPM_POST_PMD:
348 /* Disable everything */ 258 /* Disable everything */
349 wm8900_write(codec, WM8900_REG_HPCTL1, 0); 259 snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
350 break; 260 break;
351 261
352 default: 262 default:
@@ -439,7 +349,6 @@ SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1),
439SOC_ENUM("DAC Mute Rate", dac_mute_rate), 349SOC_ENUM("DAC Mute Rate", dac_mute_rate),
440SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0), 350SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0),
441SOC_ENUM("DAC Deemphasis", dac_deemphasis), 351SOC_ENUM("DAC Deemphasis", dac_deemphasis),
442SOC_SINGLE("DAC Sloping Stopband Filter Switch", WM8900_REG_DACCTRL, 8, 1, 0),
443SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL, 352SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL,
444 12, 1, 0), 353 12, 1, 0),
445 354
@@ -723,7 +632,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
723 struct snd_soc_codec *codec = socdev->card->codec; 632 struct snd_soc_codec *codec = socdev->card->codec;
724 u16 reg; 633 u16 reg;
725 634
726 reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60; 635 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
727 636
728 switch (params_format(params)) { 637 switch (params_format(params)) {
729 case SNDRV_PCM_FORMAT_S16_LE: 638 case SNDRV_PCM_FORMAT_S16_LE:
@@ -741,7 +650,18 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
741 return -EINVAL; 650 return -EINVAL;
742 } 651 }
743 652
744 wm8900_write(codec, WM8900_REG_AUDIO1, reg); 653 snd_soc_write(codec, WM8900_REG_AUDIO1, reg);
654
655 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
656 reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
657
658 if (params_rate(params) <= 24000)
659 reg |= WM8900_REG_DACCTRL_DAC_SB_FILT;
660 else
661 reg &= ~WM8900_REG_DACCTRL_DAC_SB_FILT;
662
663 snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
664 }
745 665
746 return 0; 666 return 0;
747} 667}
@@ -778,11 +698,11 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
778 } 698 }
779 699
780 if (target > 100000000) 700 if (target > 100000000)
781 printk(KERN_WARNING "wm8900: FLL rate %d out of range, Fref=%d" 701 printk(KERN_WARNING "wm8900: FLL rate %u out of range, Fref=%u"
782 " Fout=%d\n", target, Fref, Fout); 702 " Fout=%u\n", target, Fref, Fout);
783 if (div > 32) { 703 if (div > 32) {
784 printk(KERN_ERR "wm8900: Invalid FLL division rate %u, " 704 printk(KERN_ERR "wm8900: Invalid FLL division rate %u, "
785 "Fref=%d, Fout=%d, target=%d\n", 705 "Fref=%u, Fout=%u, target=%u\n",
786 div, Fref, Fout, target); 706 div, Fref, Fout, target);
787 return -EINVAL; 707 return -EINVAL;
788 } 708 }
@@ -834,18 +754,18 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
834 return 0; 754 return 0;
835 755
836 /* The digital side should be disabled during any change. */ 756 /* The digital side should be disabled during any change. */
837 reg = wm8900_read(codec, WM8900_REG_POWER1); 757 reg = snd_soc_read(codec, WM8900_REG_POWER1);
838 wm8900_write(codec, WM8900_REG_POWER1, 758 snd_soc_write(codec, WM8900_REG_POWER1,
839 reg & (~WM8900_REG_POWER1_FLL_ENA)); 759 reg & (~WM8900_REG_POWER1_FLL_ENA));
840 760
841 /* Disable the FLL? */ 761 /* Disable the FLL? */
842 if (!freq_in || !freq_out) { 762 if (!freq_in || !freq_out) {
843 reg = wm8900_read(codec, WM8900_REG_CLOCKING1); 763 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
844 wm8900_write(codec, WM8900_REG_CLOCKING1, 764 snd_soc_write(codec, WM8900_REG_CLOCKING1,
845 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC)); 765 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC));
846 766
847 reg = wm8900_read(codec, WM8900_REG_FLLCTL1); 767 reg = snd_soc_read(codec, WM8900_REG_FLLCTL1);
848 wm8900_write(codec, WM8900_REG_FLLCTL1, 768 snd_soc_write(codec, WM8900_REG_FLLCTL1,
849 reg & (~WM8900_REG_FLLCTL1_OSC_ENA)); 769 reg & (~WM8900_REG_FLLCTL1_OSC_ENA));
850 770
851 wm8900->fll_in = freq_in; 771 wm8900->fll_in = freq_in;
@@ -862,33 +782,33 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
862 782
863 /* The osclilator *MUST* be enabled before we enable the 783 /* The osclilator *MUST* be enabled before we enable the
864 * digital circuit. */ 784 * digital circuit. */
865 wm8900_write(codec, WM8900_REG_FLLCTL1, 785 snd_soc_write(codec, WM8900_REG_FLLCTL1,
866 fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA); 786 fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA);
867 787
868 wm8900_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5); 788 snd_soc_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
869 wm8900_write(codec, WM8900_REG_FLLCTL5, 789 snd_soc_write(codec, WM8900_REG_FLLCTL5,
870 (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f)); 790 (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f));
871 791
872 if (fll_div.k) { 792 if (fll_div.k) {
873 wm8900_write(codec, WM8900_REG_FLLCTL2, 793 snd_soc_write(codec, WM8900_REG_FLLCTL2,
874 (fll_div.k >> 8) | 0x100); 794 (fll_div.k >> 8) | 0x100);
875 wm8900_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff); 795 snd_soc_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
876 } else 796 } else
877 wm8900_write(codec, WM8900_REG_FLLCTL2, 0); 797 snd_soc_write(codec, WM8900_REG_FLLCTL2, 0);
878 798
879 if (fll_div.fll_slow_lock_ref) 799 if (fll_div.fll_slow_lock_ref)
880 wm8900_write(codec, WM8900_REG_FLLCTL6, 800 snd_soc_write(codec, WM8900_REG_FLLCTL6,
881 WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF); 801 WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF);
882 else 802 else
883 wm8900_write(codec, WM8900_REG_FLLCTL6, 0); 803 snd_soc_write(codec, WM8900_REG_FLLCTL6, 0);
884 804
885 reg = wm8900_read(codec, WM8900_REG_POWER1); 805 reg = snd_soc_read(codec, WM8900_REG_POWER1);
886 wm8900_write(codec, WM8900_REG_POWER1, 806 snd_soc_write(codec, WM8900_REG_POWER1,
887 reg | WM8900_REG_POWER1_FLL_ENA); 807 reg | WM8900_REG_POWER1_FLL_ENA);
888 808
889reenable: 809reenable:
890 reg = wm8900_read(codec, WM8900_REG_CLOCKING1); 810 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
891 wm8900_write(codec, WM8900_REG_CLOCKING1, 811 snd_soc_write(codec, WM8900_REG_CLOCKING1,
892 reg | WM8900_REG_CLOCKING1_MCLK_SRC); 812 reg | WM8900_REG_CLOCKING1_MCLK_SRC);
893 813
894 return 0; 814 return 0;
@@ -908,38 +828,38 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
908 828
909 switch (div_id) { 829 switch (div_id) {
910 case WM8900_BCLK_DIV: 830 case WM8900_BCLK_DIV:
911 reg = wm8900_read(codec, WM8900_REG_CLOCKING1); 831 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
912 wm8900_write(codec, WM8900_REG_CLOCKING1, 832 snd_soc_write(codec, WM8900_REG_CLOCKING1,
913 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK)); 833 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK));
914 break; 834 break;
915 case WM8900_OPCLK_DIV: 835 case WM8900_OPCLK_DIV:
916 reg = wm8900_read(codec, WM8900_REG_CLOCKING1); 836 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
917 wm8900_write(codec, WM8900_REG_CLOCKING1, 837 snd_soc_write(codec, WM8900_REG_CLOCKING1,
918 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK)); 838 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK));
919 break; 839 break;
920 case WM8900_DAC_LRCLK: 840 case WM8900_DAC_LRCLK:
921 reg = wm8900_read(codec, WM8900_REG_AUDIO4); 841 reg = snd_soc_read(codec, WM8900_REG_AUDIO4);
922 wm8900_write(codec, WM8900_REG_AUDIO4, 842 snd_soc_write(codec, WM8900_REG_AUDIO4,
923 div | (reg & WM8900_LRC_MASK)); 843 div | (reg & WM8900_LRC_MASK));
924 break; 844 break;
925 case WM8900_ADC_LRCLK: 845 case WM8900_ADC_LRCLK:
926 reg = wm8900_read(codec, WM8900_REG_AUDIO3); 846 reg = snd_soc_read(codec, WM8900_REG_AUDIO3);
927 wm8900_write(codec, WM8900_REG_AUDIO3, 847 snd_soc_write(codec, WM8900_REG_AUDIO3,
928 div | (reg & WM8900_LRC_MASK)); 848 div | (reg & WM8900_LRC_MASK));
929 break; 849 break;
930 case WM8900_DAC_CLKDIV: 850 case WM8900_DAC_CLKDIV:
931 reg = wm8900_read(codec, WM8900_REG_CLOCKING2); 851 reg = snd_soc_read(codec, WM8900_REG_CLOCKING2);
932 wm8900_write(codec, WM8900_REG_CLOCKING2, 852 snd_soc_write(codec, WM8900_REG_CLOCKING2,
933 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV)); 853 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV));
934 break; 854 break;
935 case WM8900_ADC_CLKDIV: 855 case WM8900_ADC_CLKDIV:
936 reg = wm8900_read(codec, WM8900_REG_CLOCKING2); 856 reg = snd_soc_read(codec, WM8900_REG_CLOCKING2);
937 wm8900_write(codec, WM8900_REG_CLOCKING2, 857 snd_soc_write(codec, WM8900_REG_CLOCKING2,
938 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV)); 858 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV));
939 break; 859 break;
940 case WM8900_LRCLK_MODE: 860 case WM8900_LRCLK_MODE:
941 reg = wm8900_read(codec, WM8900_REG_DACCTRL); 861 reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
942 wm8900_write(codec, WM8900_REG_DACCTRL, 862 snd_soc_write(codec, WM8900_REG_DACCTRL,
943 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE)); 863 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE));
944 break; 864 break;
945 default: 865 default:
@@ -956,10 +876,10 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
956 struct snd_soc_codec *codec = codec_dai->codec; 876 struct snd_soc_codec *codec = codec_dai->codec;
957 unsigned int clocking1, aif1, aif3, aif4; 877 unsigned int clocking1, aif1, aif3, aif4;
958 878
959 clocking1 = wm8900_read(codec, WM8900_REG_CLOCKING1); 879 clocking1 = snd_soc_read(codec, WM8900_REG_CLOCKING1);
960 aif1 = wm8900_read(codec, WM8900_REG_AUDIO1); 880 aif1 = snd_soc_read(codec, WM8900_REG_AUDIO1);
961 aif3 = wm8900_read(codec, WM8900_REG_AUDIO3); 881 aif3 = snd_soc_read(codec, WM8900_REG_AUDIO3);
962 aif4 = wm8900_read(codec, WM8900_REG_AUDIO4); 882 aif4 = snd_soc_read(codec, WM8900_REG_AUDIO4);
963 883
964 /* set master/slave audio interface */ 884 /* set master/slave audio interface */
965 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 885 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1055,10 +975,10 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
1055 return -EINVAL; 975 return -EINVAL;
1056 } 976 }
1057 977
1058 wm8900_write(codec, WM8900_REG_CLOCKING1, clocking1); 978 snd_soc_write(codec, WM8900_REG_CLOCKING1, clocking1);
1059 wm8900_write(codec, WM8900_REG_AUDIO1, aif1); 979 snd_soc_write(codec, WM8900_REG_AUDIO1, aif1);
1060 wm8900_write(codec, WM8900_REG_AUDIO3, aif3); 980 snd_soc_write(codec, WM8900_REG_AUDIO3, aif3);
1061 wm8900_write(codec, WM8900_REG_AUDIO4, aif4); 981 snd_soc_write(codec, WM8900_REG_AUDIO4, aif4);
1062 982
1063 return 0; 983 return 0;
1064} 984}
@@ -1068,14 +988,14 @@ static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1068 struct snd_soc_codec *codec = codec_dai->codec; 988 struct snd_soc_codec *codec = codec_dai->codec;
1069 u16 reg; 989 u16 reg;
1070 990
1071 reg = wm8900_read(codec, WM8900_REG_DACCTRL); 991 reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
1072 992
1073 if (mute) 993 if (mute)
1074 reg |= WM8900_REG_DACCTRL_MUTE; 994 reg |= WM8900_REG_DACCTRL_MUTE;
1075 else 995 else
1076 reg &= ~WM8900_REG_DACCTRL_MUTE; 996 reg &= ~WM8900_REG_DACCTRL_MUTE;
1077 997
1078 wm8900_write(codec, WM8900_REG_DACCTRL, reg); 998 snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
1079 999
1080 return 0; 1000 return 0;
1081} 1001}
@@ -1124,11 +1044,11 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1124 switch (level) { 1044 switch (level) {
1125 case SND_SOC_BIAS_ON: 1045 case SND_SOC_BIAS_ON:
1126 /* Enable thermal shutdown */ 1046 /* Enable thermal shutdown */
1127 reg = wm8900_read(codec, WM8900_REG_GPIO); 1047 reg = snd_soc_read(codec, WM8900_REG_GPIO);
1128 wm8900_write(codec, WM8900_REG_GPIO, 1048 snd_soc_write(codec, WM8900_REG_GPIO,
1129 reg | WM8900_REG_GPIO_TEMP_ENA); 1049 reg | WM8900_REG_GPIO_TEMP_ENA);
1130 reg = wm8900_read(codec, WM8900_REG_ADDCTL); 1050 reg = snd_soc_read(codec, WM8900_REG_ADDCTL);
1131 wm8900_write(codec, WM8900_REG_ADDCTL, 1051 snd_soc_write(codec, WM8900_REG_ADDCTL,
1132 reg | WM8900_REG_ADDCTL_TEMP_SD); 1052 reg | WM8900_REG_ADDCTL_TEMP_SD);
1133 break; 1053 break;
1134 1054
@@ -1139,69 +1059,69 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1139 /* Charge capacitors if initial power up */ 1059 /* Charge capacitors if initial power up */
1140 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1060 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1141 /* STARTUP_BIAS_ENA on */ 1061 /* STARTUP_BIAS_ENA on */
1142 wm8900_write(codec, WM8900_REG_POWER1, 1062 snd_soc_write(codec, WM8900_REG_POWER1,
1143 WM8900_REG_POWER1_STARTUP_BIAS_ENA); 1063 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1144 1064
1145 /* Startup bias mode */ 1065 /* Startup bias mode */
1146 wm8900_write(codec, WM8900_REG_ADDCTL, 1066 snd_soc_write(codec, WM8900_REG_ADDCTL,
1147 WM8900_REG_ADDCTL_BIAS_SRC | 1067 WM8900_REG_ADDCTL_BIAS_SRC |
1148 WM8900_REG_ADDCTL_VMID_SOFTST); 1068 WM8900_REG_ADDCTL_VMID_SOFTST);
1149 1069
1150 /* VMID 2x50k */ 1070 /* VMID 2x50k */
1151 wm8900_write(codec, WM8900_REG_POWER1, 1071 snd_soc_write(codec, WM8900_REG_POWER1,
1152 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1); 1072 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1);
1153 1073
1154 /* Allow capacitors to charge */ 1074 /* Allow capacitors to charge */
1155 schedule_timeout_interruptible(msecs_to_jiffies(400)); 1075 schedule_timeout_interruptible(msecs_to_jiffies(400));
1156 1076
1157 /* Enable bias */ 1077 /* Enable bias */
1158 wm8900_write(codec, WM8900_REG_POWER1, 1078 snd_soc_write(codec, WM8900_REG_POWER1,
1159 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 1079 WM8900_REG_POWER1_STARTUP_BIAS_ENA |
1160 WM8900_REG_POWER1_BIAS_ENA | 0x1); 1080 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1161 1081
1162 wm8900_write(codec, WM8900_REG_ADDCTL, 0); 1082 snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
1163 1083
1164 wm8900_write(codec, WM8900_REG_POWER1, 1084 snd_soc_write(codec, WM8900_REG_POWER1,
1165 WM8900_REG_POWER1_BIAS_ENA | 0x1); 1085 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1166 } 1086 }
1167 1087
1168 reg = wm8900_read(codec, WM8900_REG_POWER1); 1088 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1169 wm8900_write(codec, WM8900_REG_POWER1, 1089 snd_soc_write(codec, WM8900_REG_POWER1,
1170 (reg & WM8900_REG_POWER1_FLL_ENA) | 1090 (reg & WM8900_REG_POWER1_FLL_ENA) |
1171 WM8900_REG_POWER1_BIAS_ENA | 0x1); 1091 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1172 wm8900_write(codec, WM8900_REG_POWER2, 1092 snd_soc_write(codec, WM8900_REG_POWER2,
1173 WM8900_REG_POWER2_SYSCLK_ENA); 1093 WM8900_REG_POWER2_SYSCLK_ENA);
1174 wm8900_write(codec, WM8900_REG_POWER3, 0); 1094 snd_soc_write(codec, WM8900_REG_POWER3, 0);
1175 break; 1095 break;
1176 1096
1177 case SND_SOC_BIAS_OFF: 1097 case SND_SOC_BIAS_OFF:
1178 /* Startup bias enable */ 1098 /* Startup bias enable */
1179 reg = wm8900_read(codec, WM8900_REG_POWER1); 1099 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1180 wm8900_write(codec, WM8900_REG_POWER1, 1100 snd_soc_write(codec, WM8900_REG_POWER1,
1181 reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA); 1101 reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1182 wm8900_write(codec, WM8900_REG_ADDCTL, 1102 snd_soc_write(codec, WM8900_REG_ADDCTL,
1183 WM8900_REG_ADDCTL_BIAS_SRC | 1103 WM8900_REG_ADDCTL_BIAS_SRC |
1184 WM8900_REG_ADDCTL_VMID_SOFTST); 1104 WM8900_REG_ADDCTL_VMID_SOFTST);
1185 1105
1186 /* Discharge caps */ 1106 /* Discharge caps */
1187 wm8900_write(codec, WM8900_REG_POWER1, 1107 snd_soc_write(codec, WM8900_REG_POWER1,
1188 WM8900_REG_POWER1_STARTUP_BIAS_ENA); 1108 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1189 schedule_timeout_interruptible(msecs_to_jiffies(500)); 1109 schedule_timeout_interruptible(msecs_to_jiffies(500));
1190 1110
1191 /* Remove clamp */ 1111 /* Remove clamp */
1192 wm8900_write(codec, WM8900_REG_HPCTL1, 0); 1112 snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
1193 1113
1194 /* Power down */ 1114 /* Power down */
1195 wm8900_write(codec, WM8900_REG_ADDCTL, 0); 1115 snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
1196 wm8900_write(codec, WM8900_REG_POWER1, 0); 1116 snd_soc_write(codec, WM8900_REG_POWER1, 0);
1197 wm8900_write(codec, WM8900_REG_POWER2, 0); 1117 snd_soc_write(codec, WM8900_REG_POWER2, 0);
1198 wm8900_write(codec, WM8900_REG_POWER3, 0); 1118 snd_soc_write(codec, WM8900_REG_POWER3, 0);
1199 1119
1200 /* Need to let things settle before stopping the clock 1120 /* Need to let things settle before stopping the clock
1201 * to ensure that restart works, see "Stopping the 1121 * to ensure that restart works, see "Stopping the
1202 * master clock" in the datasheet. */ 1122 * master clock" in the datasheet. */
1203 schedule_timeout_interruptible(msecs_to_jiffies(1)); 1123 schedule_timeout_interruptible(msecs_to_jiffies(1));
1204 wm8900_write(codec, WM8900_REG_POWER2, 1124 snd_soc_write(codec, WM8900_REG_POWER2,
1205 WM8900_REG_POWER2_SYSCLK_ENA); 1125 WM8900_REG_POWER2_SYSCLK_ENA);
1206 break; 1126 break;
1207 } 1127 }
@@ -1264,7 +1184,7 @@ static int wm8900_resume(struct platform_device *pdev)
1264 1184
1265 if (cache) { 1185 if (cache) {
1266 for (i = 0; i < WM8900_MAXREG; i++) 1186 for (i = 0; i < WM8900_MAXREG; i++)
1267 wm8900_write(codec, i, cache[i]); 1187 snd_soc_write(codec, i, cache[i]);
1268 kfree(cache); 1188 kfree(cache);
1269 } else 1189 } else
1270 dev_err(&pdev->dev, "Unable to allocate register cache\n"); 1190 dev_err(&pdev->dev, "Unable to allocate register cache\n");
@@ -1297,16 +1217,20 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1297 1217
1298 codec->name = "WM8900"; 1218 codec->name = "WM8900";
1299 codec->owner = THIS_MODULE; 1219 codec->owner = THIS_MODULE;
1300 codec->read = wm8900_read;
1301 codec->write = wm8900_write;
1302 codec->dai = &wm8900_dai; 1220 codec->dai = &wm8900_dai;
1303 codec->num_dai = 1; 1221 codec->num_dai = 1;
1304 codec->hw_write = (hw_write_t)i2c_master_send;
1305 codec->control_data = i2c; 1222 codec->control_data = i2c;
1306 codec->set_bias_level = wm8900_set_bias_level; 1223 codec->set_bias_level = wm8900_set_bias_level;
1224 codec->volatile_register = wm8900_volatile_register;
1307 codec->dev = &i2c->dev; 1225 codec->dev = &i2c->dev;
1308 1226
1309 reg = wm8900_read(codec, WM8900_REG_ID); 1227 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1228 if (ret != 0) {
1229 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret);
1230 goto err;
1231 }
1232
1233 reg = snd_soc_read(codec, WM8900_REG_ID);
1310 if (reg != 0x8900) { 1234 if (reg != 0x8900) {
1311 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg); 1235 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
1312 ret = -ENODEV; 1236 ret = -ENODEV;
@@ -1314,7 +1238,7 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1314 } 1238 }
1315 1239
1316 /* Read back from the chip */ 1240 /* Read back from the chip */
1317 reg = wm8900_chip_read(codec, WM8900_REG_POWER1); 1241 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1318 reg = (reg >> 12) & 0xf; 1242 reg = (reg >> 12) & 0xf;
1319 dev_info(&i2c->dev, "WM8900 revision %d\n", reg); 1243 dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
1320 1244
@@ -1324,29 +1248,29 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1324 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1248 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1325 1249
1326 /* Latch the volume update bits */ 1250 /* Latch the volume update bits */
1327 wm8900_write(codec, WM8900_REG_LINVOL, 1251 snd_soc_write(codec, WM8900_REG_LINVOL,
1328 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100); 1252 snd_soc_read(codec, WM8900_REG_LINVOL) | 0x100);
1329 wm8900_write(codec, WM8900_REG_RINVOL, 1253 snd_soc_write(codec, WM8900_REG_RINVOL,
1330 wm8900_read(codec, WM8900_REG_RINVOL) | 0x100); 1254 snd_soc_read(codec, WM8900_REG_RINVOL) | 0x100);
1331 wm8900_write(codec, WM8900_REG_LOUT1CTL, 1255 snd_soc_write(codec, WM8900_REG_LOUT1CTL,
1332 wm8900_read(codec, WM8900_REG_LOUT1CTL) | 0x100); 1256 snd_soc_read(codec, WM8900_REG_LOUT1CTL) | 0x100);
1333 wm8900_write(codec, WM8900_REG_ROUT1CTL, 1257 snd_soc_write(codec, WM8900_REG_ROUT1CTL,
1334 wm8900_read(codec, WM8900_REG_ROUT1CTL) | 0x100); 1258 snd_soc_read(codec, WM8900_REG_ROUT1CTL) | 0x100);
1335 wm8900_write(codec, WM8900_REG_LOUT2CTL, 1259 snd_soc_write(codec, WM8900_REG_LOUT2CTL,
1336 wm8900_read(codec, WM8900_REG_LOUT2CTL) | 0x100); 1260 snd_soc_read(codec, WM8900_REG_LOUT2CTL) | 0x100);
1337 wm8900_write(codec, WM8900_REG_ROUT2CTL, 1261 snd_soc_write(codec, WM8900_REG_ROUT2CTL,
1338 wm8900_read(codec, WM8900_REG_ROUT2CTL) | 0x100); 1262 snd_soc_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
1339 wm8900_write(codec, WM8900_REG_LDAC_DV, 1263 snd_soc_write(codec, WM8900_REG_LDAC_DV,
1340 wm8900_read(codec, WM8900_REG_LDAC_DV) | 0x100); 1264 snd_soc_read(codec, WM8900_REG_LDAC_DV) | 0x100);
1341 wm8900_write(codec, WM8900_REG_RDAC_DV, 1265 snd_soc_write(codec, WM8900_REG_RDAC_DV,
1342 wm8900_read(codec, WM8900_REG_RDAC_DV) | 0x100); 1266 snd_soc_read(codec, WM8900_REG_RDAC_DV) | 0x100);
1343 wm8900_write(codec, WM8900_REG_LADC_DV, 1267 snd_soc_write(codec, WM8900_REG_LADC_DV,
1344 wm8900_read(codec, WM8900_REG_LADC_DV) | 0x100); 1268 snd_soc_read(codec, WM8900_REG_LADC_DV) | 0x100);
1345 wm8900_write(codec, WM8900_REG_RADC_DV, 1269 snd_soc_write(codec, WM8900_REG_RADC_DV,
1346 wm8900_read(codec, WM8900_REG_RADC_DV) | 0x100); 1270 snd_soc_read(codec, WM8900_REG_RADC_DV) | 0x100);
1347 1271
1348 /* Set the DAC and mixer output bias */ 1272 /* Set the DAC and mixer output bias */
1349 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1273 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1350 1274
1351 wm8900_dai.dev = &i2c->dev; 1275 wm8900_dai.dev = &i2c->dev;
1352 1276
@@ -1388,6 +1312,21 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1388 return 0; 1312 return 0;
1389} 1313}
1390 1314
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
1391static const struct i2c_device_id wm8900_i2c_id[] = { 1330static const struct i2c_device_id wm8900_i2c_id[] = {
1392 { "wm8900", 0 }, 1331 { "wm8900", 0 },
1393 { } 1332 { }
@@ -1401,6 +1340,8 @@ static struct i2c_driver wm8900_i2c_driver = {
1401 }, 1340 },
1402 .probe = wm8900_i2c_probe, 1341 .probe = wm8900_i2c_probe,
1403 .remove = __devexit_p(wm8900_i2c_remove), 1342 .remove = __devexit_p(wm8900_i2c_remove),
1343 .suspend = wm8900_i2c_suspend,
1344 .resume = wm8900_i2c_resume,
1404 .id_table = wm8900_i2c_id, 1345 .id_table = wm8900_i2c_id,
1405}; 1346};
1406 1347
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index d8a9222fbf74..fe1307b500cf 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -225,94 +225,18 @@ struct wm8903_priv {
225 struct snd_pcm_substream *slave_substream; 225 struct snd_pcm_substream *slave_substream;
226}; 226};
227 227
228 228static int wm8903_volatile_register(unsigned int reg)
229static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
230 unsigned int reg)
231{
232 u16 *cache = codec->reg_cache;
233
234 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
235
236 return cache[reg];
237}
238
239static unsigned int wm8903_hw_read(struct snd_soc_codec *codec, u8 reg)
240{
241 struct i2c_msg xfer[2];
242 u16 data;
243 int ret;
244 struct i2c_client *client = codec->control_data;
245
246 /* Write register */
247 xfer[0].addr = client->addr;
248 xfer[0].flags = 0;
249 xfer[0].len = 1;
250 xfer[0].buf = &reg;
251
252 /* Read data */
253 xfer[1].addr = client->addr;
254 xfer[1].flags = I2C_M_RD;
255 xfer[1].len = 2;
256 xfer[1].buf = (u8 *)&data;
257
258 ret = i2c_transfer(client->adapter, xfer, 2);
259 if (ret != 2) {
260 pr_err("i2c_transfer returned %d\n", ret);
261 return 0;
262 }
263
264 return (data >> 8) | ((data & 0xff) << 8);
265}
266
267static unsigned int wm8903_read(struct snd_soc_codec *codec,
268 unsigned int reg)
269{ 229{
270 switch (reg) { 230 switch (reg) {
271 case WM8903_SW_RESET_AND_ID: 231 case WM8903_SW_RESET_AND_ID:
272 case WM8903_REVISION_NUMBER: 232 case WM8903_REVISION_NUMBER:
273 case WM8903_INTERRUPT_STATUS_1: 233 case WM8903_INTERRUPT_STATUS_1:
274 case WM8903_WRITE_SEQUENCER_4: 234 case WM8903_WRITE_SEQUENCER_4:
275 return wm8903_hw_read(codec, reg); 235 return 1;
276 236
277 default: 237 default:
278 return wm8903_read_reg_cache(codec, reg);
279 }
280}
281
282static void wm8903_write_reg_cache(struct snd_soc_codec *codec,
283 u16 reg, unsigned int value)
284{
285 u16 *cache = codec->reg_cache;
286
287 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
288
289 switch (reg) {
290 case WM8903_SW_RESET_AND_ID:
291 case WM8903_REVISION_NUMBER:
292 break;
293
294 default:
295 cache[reg] = value;
296 break;
297 }
298}
299
300static int wm8903_write(struct snd_soc_codec *codec, unsigned int reg,
301 unsigned int value)
302{
303 u8 data[3];
304
305 wm8903_write_reg_cache(codec, reg, value);
306
307 /* Data format is 1 byte of address followed by 2 bytes of data */
308 data[0] = reg;
309 data[1] = (value >> 8) & 0xff;
310 data[2] = value & 0xff;
311
312 if (codec->hw_write(codec->control_data, data, 3) == 2)
313 return 0; 238 return 0;
314 else 239 }
315 return -EIO;
316} 240}
317 241
318static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start) 242static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
@@ -323,13 +247,13 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
323 BUG_ON(start > 48); 247 BUG_ON(start > 48);
324 248
325 /* Enable the sequencer */ 249 /* Enable the sequencer */
326 reg[0] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_0); 250 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
327 reg[0] |= WM8903_WSEQ_ENA; 251 reg[0] |= WM8903_WSEQ_ENA;
328 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); 252 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
329 253
330 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start); 254 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
331 255
332 wm8903_write(codec, WM8903_WRITE_SEQUENCER_3, 256 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
333 start | WM8903_WSEQ_START); 257 start | WM8903_WSEQ_START);
334 258
335 /* Wait for it to complete. If we have the interrupt wired up then 259 /* Wait for it to complete. If we have the interrupt wired up then
@@ -339,13 +263,13 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
339 do { 263 do {
340 msleep(10); 264 msleep(10);
341 265
342 reg[4] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_4); 266 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
343 } while (reg[4] & WM8903_WSEQ_BUSY); 267 } while (reg[4] & WM8903_WSEQ_BUSY);
344 268
345 dev_dbg(&i2c->dev, "Sequence complete\n"); 269 dev_dbg(&i2c->dev, "Sequence complete\n");
346 270
347 /* Disable the sequencer again */ 271 /* Disable the sequencer again */
348 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, 272 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
349 reg[0] & ~WM8903_WSEQ_ENA); 273 reg[0] & ~WM8903_WSEQ_ENA);
350 274
351 return 0; 275 return 0;
@@ -357,12 +281,12 @@ static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
357 281
358 /* There really ought to be something better we can do here :/ */ 282 /* There really ought to be something better we can do here :/ */
359 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++) 283 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
360 cache[i] = wm8903_hw_read(codec, i); 284 cache[i] = codec->hw_read(codec, i);
361} 285}
362 286
363static void wm8903_reset(struct snd_soc_codec *codec) 287static void wm8903_reset(struct snd_soc_codec *codec)
364{ 288{
365 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0); 289 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0);
366 memcpy(codec->reg_cache, wm8903_reg_defaults, 290 memcpy(codec->reg_cache, wm8903_reg_defaults,
367 sizeof(wm8903_reg_defaults)); 291 sizeof(wm8903_reg_defaults));
368} 292}
@@ -423,52 +347,52 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
423 } 347 }
424 348
425 if (event & SND_SOC_DAPM_PRE_PMU) { 349 if (event & SND_SOC_DAPM_PRE_PMU) {
426 val = wm8903_read(codec, reg); 350 val = snd_soc_read(codec, reg);
427 351
428 /* Short the output */ 352 /* Short the output */
429 val &= ~(WM8903_OUTPUT_SHORT << shift); 353 val &= ~(WM8903_OUTPUT_SHORT << shift);
430 wm8903_write(codec, reg, val); 354 snd_soc_write(codec, reg, val);
431 } 355 }
432 356
433 if (event & SND_SOC_DAPM_POST_PMU) { 357 if (event & SND_SOC_DAPM_POST_PMU) {
434 val = wm8903_read(codec, reg); 358 val = snd_soc_read(codec, reg);
435 359
436 val |= (WM8903_OUTPUT_IN << shift); 360 val |= (WM8903_OUTPUT_IN << shift);
437 wm8903_write(codec, reg, val); 361 snd_soc_write(codec, reg, val);
438 362
439 val |= (WM8903_OUTPUT_INT << shift); 363 val |= (WM8903_OUTPUT_INT << shift);
440 wm8903_write(codec, reg, val); 364 snd_soc_write(codec, reg, val);
441 365
442 /* Turn on the output ENA_OUTP */ 366 /* Turn on the output ENA_OUTP */
443 val |= (WM8903_OUTPUT_OUT << shift); 367 val |= (WM8903_OUTPUT_OUT << shift);
444 wm8903_write(codec, reg, val); 368 snd_soc_write(codec, reg, val);
445 369
446 /* Enable the DC servo */ 370 /* Enable the DC servo */
447 dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0); 371 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0);
448 dcs_reg |= dcs_bit; 372 dcs_reg |= dcs_bit;
449 wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg); 373 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
450 374
451 /* Remove the short */ 375 /* Remove the short */
452 val |= (WM8903_OUTPUT_SHORT << shift); 376 val |= (WM8903_OUTPUT_SHORT << shift);
453 wm8903_write(codec, reg, val); 377 snd_soc_write(codec, reg, val);
454 } 378 }
455 379
456 if (event & SND_SOC_DAPM_PRE_PMD) { 380 if (event & SND_SOC_DAPM_PRE_PMD) {
457 val = wm8903_read(codec, reg); 381 val = snd_soc_read(codec, reg);
458 382
459 /* Short the output */ 383 /* Short the output */
460 val &= ~(WM8903_OUTPUT_SHORT << shift); 384 val &= ~(WM8903_OUTPUT_SHORT << shift);
461 wm8903_write(codec, reg, val); 385 snd_soc_write(codec, reg, val);
462 386
463 /* Disable the DC servo */ 387 /* Disable the DC servo */
464 dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0); 388 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0);
465 dcs_reg &= ~dcs_bit; 389 dcs_reg &= ~dcs_bit;
466 wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg); 390 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
467 391
468 /* Then disable the intermediate and output stages */ 392 /* Then disable the intermediate and output stages */
469 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | 393 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
470 WM8903_OUTPUT_IN) << shift); 394 WM8903_OUTPUT_IN) << shift);
471 wm8903_write(codec, reg, val); 395 snd_soc_write(codec, reg, val);
472 } 396 }
473 397
474 return 0; 398 return 0;
@@ -492,13 +416,13 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
492 u16 reg; 416 u16 reg;
493 int ret; 417 int ret;
494 418
495 reg = wm8903_read(codec, WM8903_CLASS_W_0); 419 reg = snd_soc_read(codec, WM8903_CLASS_W_0);
496 420
497 /* Turn it off if we're about to enable bypass */ 421 /* Turn it off if we're about to enable bypass */
498 if (ucontrol->value.integer.value[0]) { 422 if (ucontrol->value.integer.value[0]) {
499 if (wm8903->class_w_users == 0) { 423 if (wm8903->class_w_users == 0) {
500 dev_dbg(&i2c->dev, "Disabling Class W\n"); 424 dev_dbg(&i2c->dev, "Disabling Class W\n");
501 wm8903_write(codec, WM8903_CLASS_W_0, reg & 425 snd_soc_write(codec, WM8903_CLASS_W_0, reg &
502 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V)); 426 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
503 } 427 }
504 wm8903->class_w_users++; 428 wm8903->class_w_users++;
@@ -511,7 +435,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
511 if (!ucontrol->value.integer.value[0]) { 435 if (!ucontrol->value.integer.value[0]) {
512 if (wm8903->class_w_users == 1) { 436 if (wm8903->class_w_users == 1) {
513 dev_dbg(&i2c->dev, "Enabling Class W\n"); 437 dev_dbg(&i2c->dev, "Enabling Class W\n");
514 wm8903_write(codec, WM8903_CLASS_W_0, reg | 438 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
515 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 439 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
516 } 440 }
517 wm8903->class_w_users--; 441 wm8903->class_w_users--;
@@ -715,8 +639,6 @@ SOC_ENUM("DAC Soft Mute Rate", soft_mute),
715SOC_ENUM("DAC Mute Mode", mute_mode), 639SOC_ENUM("DAC Mute Mode", mute_mode),
716SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), 640SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
717SOC_ENUM("DAC De-emphasis", dac_deemphasis), 641SOC_ENUM("DAC De-emphasis", dac_deemphasis),
718SOC_SINGLE("DAC Sloping Stopband Filter Switch",
719 WM8903_DAC_DIGITAL_1, 11, 1, 0),
720SOC_ENUM("DAC Companding Mode", dac_companding), 642SOC_ENUM("DAC Companding Mode", dac_companding),
721SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), 643SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
722 644
@@ -1011,55 +933,55 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1011 switch (level) { 933 switch (level) {
1012 case SND_SOC_BIAS_ON: 934 case SND_SOC_BIAS_ON:
1013 case SND_SOC_BIAS_PREPARE: 935 case SND_SOC_BIAS_PREPARE:
1014 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0); 936 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
1015 reg &= ~(WM8903_VMID_RES_MASK); 937 reg &= ~(WM8903_VMID_RES_MASK);
1016 reg |= WM8903_VMID_RES_50K; 938 reg |= WM8903_VMID_RES_50K;
1017 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg); 939 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1018 break; 940 break;
1019 941
1020 case SND_SOC_BIAS_STANDBY: 942 case SND_SOC_BIAS_STANDBY:
1021 if (codec->bias_level == SND_SOC_BIAS_OFF) { 943 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1022 wm8903_write(codec, WM8903_CLOCK_RATES_2, 944 snd_soc_write(codec, WM8903_CLOCK_RATES_2,
1023 WM8903_CLK_SYS_ENA); 945 WM8903_CLK_SYS_ENA);
1024 946
1025 /* Change DC servo dither level in startup sequence */ 947 /* Change DC servo dither level in startup sequence */
1026 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); 948 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11);
1027 wm8903_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); 949 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257);
1028 wm8903_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); 950 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2);
1029 951
1030 wm8903_run_sequence(codec, 0); 952 wm8903_run_sequence(codec, 0);
1031 wm8903_sync_reg_cache(codec, codec->reg_cache); 953 wm8903_sync_reg_cache(codec, codec->reg_cache);
1032 954
1033 /* Enable low impedence charge pump output */ 955 /* Enable low impedence charge pump output */
1034 reg = wm8903_read(codec, 956 reg = snd_soc_read(codec,
1035 WM8903_CONTROL_INTERFACE_TEST_1); 957 WM8903_CONTROL_INTERFACE_TEST_1);
1036 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, 958 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
1037 reg | WM8903_TEST_KEY); 959 reg | WM8903_TEST_KEY);
1038 reg2 = wm8903_read(codec, WM8903_CHARGE_PUMP_TEST_1); 960 reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1);
1039 wm8903_write(codec, WM8903_CHARGE_PUMP_TEST_1, 961 snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1,
1040 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK); 962 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
1041 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, 963 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
1042 reg); 964 reg);
1043 965
1044 /* By default no bypass paths are enabled so 966 /* By default no bypass paths are enabled so
1045 * enable Class W support. 967 * enable Class W support.
1046 */ 968 */
1047 dev_dbg(&i2c->dev, "Enabling Class W\n"); 969 dev_dbg(&i2c->dev, "Enabling Class W\n");
1048 wm8903_write(codec, WM8903_CLASS_W_0, reg | 970 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
1049 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 971 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
1050 } 972 }
1051 973
1052 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0); 974 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
1053 reg &= ~(WM8903_VMID_RES_MASK); 975 reg &= ~(WM8903_VMID_RES_MASK);
1054 reg |= WM8903_VMID_RES_250K; 976 reg |= WM8903_VMID_RES_250K;
1055 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg); 977 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1056 break; 978 break;
1057 979
1058 case SND_SOC_BIAS_OFF: 980 case SND_SOC_BIAS_OFF:
1059 wm8903_run_sequence(codec, 32); 981 wm8903_run_sequence(codec, 32);
1060 reg = wm8903_read(codec, WM8903_CLOCK_RATES_2); 982 reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2);
1061 reg &= ~WM8903_CLK_SYS_ENA; 983 reg &= ~WM8903_CLK_SYS_ENA;
1062 wm8903_write(codec, WM8903_CLOCK_RATES_2, reg); 984 snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg);
1063 break; 985 break;
1064 } 986 }
1065 987
@@ -1083,7 +1005,7 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
1083 unsigned int fmt) 1005 unsigned int fmt)
1084{ 1006{
1085 struct snd_soc_codec *codec = codec_dai->codec; 1007 struct snd_soc_codec *codec = codec_dai->codec;
1086 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1); 1008 u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
1087 1009
1088 aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK | 1010 aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK |
1089 WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV); 1011 WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV);
@@ -1161,7 +1083,7 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
1161 return -EINVAL; 1083 return -EINVAL;
1162 } 1084 }
1163 1085
1164 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); 1086 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1165 1087
1166 return 0; 1088 return 0;
1167} 1089}
@@ -1171,14 +1093,14 @@ static int wm8903_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1171 struct snd_soc_codec *codec = codec_dai->codec; 1093 struct snd_soc_codec *codec = codec_dai->codec;
1172 u16 reg; 1094 u16 reg;
1173 1095
1174 reg = wm8903_read(codec, WM8903_DAC_DIGITAL_1); 1096 reg = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1175 1097
1176 if (mute) 1098 if (mute)
1177 reg |= WM8903_DAC_MUTE; 1099 reg |= WM8903_DAC_MUTE;
1178 else 1100 else
1179 reg &= ~WM8903_DAC_MUTE; 1101 reg &= ~WM8903_DAC_MUTE;
1180 1102
1181 wm8903_write(codec, WM8903_DAC_DIGITAL_1, reg); 1103 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, reg);
1182 1104
1183 return 0; 1105 return 0;
1184} 1106}
@@ -1257,22 +1179,18 @@ static struct {
1257 int div; 1179 int div;
1258} bclk_divs[] = { 1180} bclk_divs[] = {
1259 { 10, 0 }, 1181 { 10, 0 },
1260 { 15, 1 },
1261 { 20, 2 }, 1182 { 20, 2 },
1262 { 30, 3 }, 1183 { 30, 3 },
1263 { 40, 4 }, 1184 { 40, 4 },
1264 { 50, 5 }, 1185 { 50, 5 },
1265 { 55, 6 },
1266 { 60, 7 }, 1186 { 60, 7 },
1267 { 80, 8 }, 1187 { 80, 8 },
1268 { 100, 9 }, 1188 { 100, 9 },
1269 { 110, 10 },
1270 { 120, 11 }, 1189 { 120, 11 },
1271 { 160, 12 }, 1190 { 160, 12 },
1272 { 200, 13 }, 1191 { 200, 13 },
1273 { 220, 14 }, 1192 { 220, 14 },
1274 { 240, 15 }, 1193 { 240, 15 },
1275 { 250, 16 },
1276 { 300, 17 }, 1194 { 300, 17 },
1277 { 320, 18 }, 1195 { 320, 18 },
1278 { 440, 19 }, 1196 { 440, 19 },
@@ -1372,17 +1290,24 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1372 int cur_val; 1290 int cur_val;
1373 int clk_sys; 1291 int clk_sys;
1374 1292
1375 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1); 1293 u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
1376 u16 aif2 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_2); 1294 u16 aif2 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_2);
1377 u16 aif3 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_3); 1295 u16 aif3 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_3);
1378 u16 clock0 = wm8903_read(codec, WM8903_CLOCK_RATES_0); 1296 u16 clock0 = snd_soc_read(codec, WM8903_CLOCK_RATES_0);
1379 u16 clock1 = wm8903_read(codec, WM8903_CLOCK_RATES_1); 1297 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
1298 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1380 1299
1381 if (substream == wm8903->slave_substream) { 1300 if (substream == wm8903->slave_substream) {
1382 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); 1301 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
1383 return 0; 1302 return 0;
1384 } 1303 }
1385 1304
1305 /* Enable sloping stopband filter for low sample rates */
1306 if (fs <= 24000)
1307 dac_digital1 |= WM8903_DAC_SB_FILT;
1308 else
1309 dac_digital1 &= ~WM8903_DAC_SB_FILT;
1310
1386 /* Configure sample rate logic for DSP - choose nearest rate */ 1311 /* Configure sample rate logic for DSP - choose nearest rate */
1387 dsp_config = 0; 1312 dsp_config = 0;
1388 best_val = abs(sample_rates[dsp_config].rate - fs); 1313 best_val = abs(sample_rates[dsp_config].rate - fs);
@@ -1502,11 +1427,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1502 aif2 |= bclk_divs[bclk_div].div; 1427 aif2 |= bclk_divs[bclk_div].div;
1503 aif3 |= bclk / fs; 1428 aif3 |= bclk / fs;
1504 1429
1505 wm8903_write(codec, WM8903_CLOCK_RATES_0, clock0); 1430 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
1506 wm8903_write(codec, WM8903_CLOCK_RATES_1, clock1); 1431 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
1507 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); 1432 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1508 wm8903_write(codec, WM8903_AUDIO_INTERFACE_2, aif2); 1433 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
1509 wm8903_write(codec, WM8903_AUDIO_INTERFACE_3, aif3); 1434 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
1435 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, dac_digital1);
1510 1436
1511 return 0; 1437 return 0;
1512} 1438}
@@ -1591,7 +1517,7 @@ static int wm8903_resume(struct platform_device *pdev)
1591 if (tmp_cache) { 1517 if (tmp_cache) {
1592 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++) 1518 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
1593 if (tmp_cache[i] != reg_cache[i]) 1519 if (tmp_cache[i] != reg_cache[i])
1594 wm8903_write(codec, i, tmp_cache[i]); 1520 snd_soc_write(codec, i, tmp_cache[i]);
1595 } else { 1521 } else {
1596 dev_err(&i2c->dev, "Failed to allocate temporary cache\n"); 1522 dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
1597 } 1523 }
@@ -1622,9 +1548,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1622 codec->dev = &i2c->dev; 1548 codec->dev = &i2c->dev;
1623 codec->name = "WM8903"; 1549 codec->name = "WM8903";
1624 codec->owner = THIS_MODULE; 1550 codec->owner = THIS_MODULE;
1625 codec->read = wm8903_read;
1626 codec->write = wm8903_write;
1627 codec->hw_write = (hw_write_t)i2c_master_send;
1628 codec->bias_level = SND_SOC_BIAS_OFF; 1551 codec->bias_level = SND_SOC_BIAS_OFF;
1629 codec->set_bias_level = wm8903_set_bias_level; 1552 codec->set_bias_level = wm8903_set_bias_level;
1630 codec->dai = &wm8903_dai; 1553 codec->dai = &wm8903_dai;
@@ -1632,18 +1555,25 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1632 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache); 1555 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1633 codec->reg_cache = &wm8903->reg_cache[0]; 1556 codec->reg_cache = &wm8903->reg_cache[0];
1634 codec->private_data = wm8903; 1557 codec->private_data = wm8903;
1558 codec->volatile_register = wm8903_volatile_register;
1635 1559
1636 i2c_set_clientdata(i2c, codec); 1560 i2c_set_clientdata(i2c, codec);
1637 codec->control_data = i2c; 1561 codec->control_data = i2c;
1638 1562
1639 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID); 1563 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1564 if (ret != 0) {
1565 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret);
1566 goto err;
1567 }
1568
1569 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
1640 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1570 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1641 dev_err(&i2c->dev, 1571 dev_err(&i2c->dev,
1642 "Device with ID register %x is not a WM8903\n", val); 1572 "Device with ID register %x is not a WM8903\n", val);
1643 return -ENODEV; 1573 return -ENODEV;
1644 } 1574 }
1645 1575
1646 val = wm8903_read(codec, WM8903_REVISION_NUMBER); 1576 val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
1647 dev_info(&i2c->dev, "WM8903 revision %d\n", 1577 dev_info(&i2c->dev, "WM8903 revision %d\n",
1648 val & WM8903_CHIP_REV_MASK); 1578 val & WM8903_CHIP_REV_MASK);
1649 1579
@@ -1653,35 +1583,35 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1653 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1583 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1654 1584
1655 /* Latch volume update bits */ 1585 /* Latch volume update bits */
1656 val = wm8903_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT); 1586 val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
1657 val |= WM8903_ADCVU; 1587 val |= WM8903_ADCVU;
1658 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val); 1588 snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
1659 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val); 1589 snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
1660 1590
1661 val = wm8903_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT); 1591 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
1662 val |= WM8903_DACVU; 1592 val |= WM8903_DACVU;
1663 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val); 1593 snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
1664 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val); 1594 snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
1665 1595
1666 val = wm8903_read(codec, WM8903_ANALOGUE_OUT1_LEFT); 1596 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
1667 val |= WM8903_HPOUTVU; 1597 val |= WM8903_HPOUTVU;
1668 wm8903_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val); 1598 snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
1669 wm8903_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val); 1599 snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
1670 1600
1671 val = wm8903_read(codec, WM8903_ANALOGUE_OUT2_LEFT); 1601 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
1672 val |= WM8903_LINEOUTVU; 1602 val |= WM8903_LINEOUTVU;
1673 wm8903_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val); 1603 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
1674 wm8903_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val); 1604 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
1675 1605
1676 val = wm8903_read(codec, WM8903_ANALOGUE_OUT3_LEFT); 1606 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
1677 val |= WM8903_SPKVU; 1607 val |= WM8903_SPKVU;
1678 wm8903_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val); 1608 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
1679 wm8903_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); 1609 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1680 1610
1681 /* Enable DAC soft mute by default */ 1611 /* Enable DAC soft mute by default */
1682 val = wm8903_read(codec, WM8903_DAC_DIGITAL_1); 1612 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1683 val |= WM8903_DAC_MUTEMODE; 1613 val |= WM8903_DAC_MUTEMODE;
1684 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val); 1614 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val);
1685 1615
1686 wm8903_dai.dev = &i2c->dev; 1616 wm8903_dai.dev = &i2c->dev;
1687 wm8903_codec = codec; 1617 wm8903_codec = codec;
@@ -1725,6 +1655,21 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1725 return 0; 1655 return 0;
1726} 1656}
1727 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
1728/* i2c codec control layer */ 1673/* i2c codec control layer */
1729static const struct i2c_device_id wm8903_i2c_id[] = { 1674static const struct i2c_device_id wm8903_i2c_id[] = {
1730 { "wm8903", 0 }, 1675 { "wm8903", 0 },
@@ -1739,6 +1684,8 @@ static struct i2c_driver wm8903_i2c_driver = {
1739 }, 1684 },
1740 .probe = wm8903_i2c_probe, 1685 .probe = wm8903_i2c_probe,
1741 .remove = __devexit_p(wm8903_i2c_remove), 1686 .remove = __devexit_p(wm8903_i2c_remove),
1687 .suspend = wm8903_i2c_suspend,
1688 .resume = wm8903_i2c_resume,
1742 .id_table = wm8903_i2c_id, 1689 .id_table = wm8903_i2c_id,
1743}; 1690};
1744 1691
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index b8e17d6bc1f7..da97aae475a2 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -106,50 +106,6 @@ static u16 wm8940_reg_defaults[] = {
106 0x0000, /* Mono Mixer Control */ 106 0x0000, /* Mono Mixer Control */
107}; 107};
108 108
109static inline unsigned int wm8940_read_reg_cache(struct snd_soc_codec *codec,
110 unsigned int reg)
111{
112 u16 *cache = codec->reg_cache;
113
114 if (reg >= ARRAY_SIZE(wm8940_reg_defaults))
115 return -1;
116
117 return cache[reg];
118}
119
120static inline int wm8940_write_reg_cache(struct snd_soc_codec *codec,
121 u16 reg, unsigned int value)
122{
123 u16 *cache = codec->reg_cache;
124
125 if (reg >= ARRAY_SIZE(wm8940_reg_defaults))
126 return -1;
127
128 cache[reg] = value;
129
130 return 0;
131}
132
133static int wm8940_write(struct snd_soc_codec *codec, unsigned int reg,
134 unsigned int value)
135{
136 int ret;
137 u8 data[3] = { reg,
138 (value & 0xff00) >> 8,
139 (value & 0x00ff)
140 };
141
142 wm8940_write_reg_cache(codec, reg, value);
143
144 ret = codec->hw_write(codec->control_data, data, 3);
145
146 if (ret < 0)
147 return ret;
148 else if (ret != 3)
149 return -EIO;
150 return 0;
151}
152
153static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" }; 109static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" };
154static const struct soc_enum wm8940_adc_companding_enum 110static const struct soc_enum wm8940_adc_companding_enum
155= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding); 111= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding);
@@ -348,14 +304,14 @@ error_ret:
348 return ret; 304 return ret;
349} 305}
350 306
351#define wm8940_reset(c) wm8940_write(c, WM8940_SOFTRESET, 0); 307#define wm8940_reset(c) snd_soc_write(c, WM8940_SOFTRESET, 0);
352 308
353static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai, 309static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
354 unsigned int fmt) 310 unsigned int fmt)
355{ 311{
356 struct snd_soc_codec *codec = codec_dai->codec; 312 struct snd_soc_codec *codec = codec_dai->codec;
357 u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFE67; 313 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFE67;
358 u16 clk = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0x1fe; 314 u16 clk = snd_soc_read(codec, WM8940_CLOCK) & 0x1fe;
359 315
360 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 316 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
361 case SND_SOC_DAIFMT_CBM_CFM: 317 case SND_SOC_DAIFMT_CBM_CFM:
@@ -366,7 +322,7 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
366 default: 322 default:
367 return -EINVAL; 323 return -EINVAL;
368 } 324 }
369 wm8940_write(codec, WM8940_CLOCK, clk); 325 snd_soc_write(codec, WM8940_CLOCK, clk);
370 326
371 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 327 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
372 case SND_SOC_DAIFMT_I2S: 328 case SND_SOC_DAIFMT_I2S:
@@ -399,7 +355,7 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
399 break; 355 break;
400 } 356 }
401 357
402 wm8940_write(codec, WM8940_IFACE, iface); 358 snd_soc_write(codec, WM8940_IFACE, iface);
403 359
404 return 0; 360 return 0;
405} 361}
@@ -411,9 +367,9 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
411 struct snd_soc_pcm_runtime *rtd = substream->private_data; 367 struct snd_soc_pcm_runtime *rtd = substream->private_data;
412 struct snd_soc_device *socdev = rtd->socdev; 368 struct snd_soc_device *socdev = rtd->socdev;
413 struct snd_soc_codec *codec = socdev->card->codec; 369 struct snd_soc_codec *codec = socdev->card->codec;
414 u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFD9F; 370 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
415 u16 addcntrl = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFF1; 371 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
416 u16 companding = wm8940_read_reg_cache(codec, 372 u16 companding = snd_soc_read(codec,
417 WM8940_COMPANDINGCTL) & 0xFFDF; 373 WM8940_COMPANDINGCTL) & 0xFFDF;
418 int ret; 374 int ret;
419 375
@@ -442,7 +398,7 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
442 case SNDRV_PCM_RATE_48000: 398 case SNDRV_PCM_RATE_48000:
443 break; 399 break;
444 } 400 }
445 ret = wm8940_write(codec, WM8940_ADDCNTRL, addcntrl); 401 ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
446 if (ret) 402 if (ret)
447 goto error_ret; 403 goto error_ret;
448 404
@@ -462,10 +418,10 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
462 iface |= (3 << 5); 418 iface |= (3 << 5);
463 break; 419 break;
464 } 420 }
465 ret = wm8940_write(codec, WM8940_COMPANDINGCTL, companding); 421 ret = snd_soc_write(codec, WM8940_COMPANDINGCTL, companding);
466 if (ret) 422 if (ret)
467 goto error_ret; 423 goto error_ret;
468 ret = wm8940_write(codec, WM8940_IFACE, iface); 424 ret = snd_soc_write(codec, WM8940_IFACE, iface);
469 425
470error_ret: 426error_ret:
471 return ret; 427 return ret;
@@ -474,19 +430,19 @@ error_ret:
474static int wm8940_mute(struct snd_soc_dai *dai, int mute) 430static int wm8940_mute(struct snd_soc_dai *dai, int mute)
475{ 431{
476 struct snd_soc_codec *codec = dai->codec; 432 struct snd_soc_codec *codec = dai->codec;
477 u16 mute_reg = wm8940_read_reg_cache(codec, WM8940_DAC) & 0xffbf; 433 u16 mute_reg = snd_soc_read(codec, WM8940_DAC) & 0xffbf;
478 434
479 if (mute) 435 if (mute)
480 mute_reg |= 0x40; 436 mute_reg |= 0x40;
481 437
482 return wm8940_write(codec, WM8940_DAC, mute_reg); 438 return snd_soc_write(codec, WM8940_DAC, mute_reg);
483} 439}
484 440
485static int wm8940_set_bias_level(struct snd_soc_codec *codec, 441static int wm8940_set_bias_level(struct snd_soc_codec *codec,
486 enum snd_soc_bias_level level) 442 enum snd_soc_bias_level level)
487{ 443{
488 u16 val; 444 u16 val;
489 u16 pwr_reg = wm8940_read_reg_cache(codec, WM8940_POWER1) & 0x1F0; 445 u16 pwr_reg = snd_soc_read(codec, WM8940_POWER1) & 0x1F0;
490 int ret = 0; 446 int ret = 0;
491 447
492 switch (level) { 448 switch (level) {
@@ -494,26 +450,26 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
494 /* ensure bufioen and biasen */ 450 /* ensure bufioen and biasen */
495 pwr_reg |= (1 << 2) | (1 << 3); 451 pwr_reg |= (1 << 2) | (1 << 3);
496 /* Enable thermal shutdown */ 452 /* Enable thermal shutdown */
497 val = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL); 453 val = snd_soc_read(codec, WM8940_OUTPUTCTL);
498 ret = wm8940_write(codec, WM8940_OUTPUTCTL, val | 0x2); 454 ret = snd_soc_write(codec, WM8940_OUTPUTCTL, val | 0x2);
499 if (ret) 455 if (ret)
500 break; 456 break;
501 /* set vmid to 75k */ 457 /* set vmid to 75k */
502 ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1); 458 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
503 break; 459 break;
504 case SND_SOC_BIAS_PREPARE: 460 case SND_SOC_BIAS_PREPARE:
505 /* ensure bufioen and biasen */ 461 /* ensure bufioen and biasen */
506 pwr_reg |= (1 << 2) | (1 << 3); 462 pwr_reg |= (1 << 2) | (1 << 3);
507 ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1); 463 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
508 break; 464 break;
509 case SND_SOC_BIAS_STANDBY: 465 case SND_SOC_BIAS_STANDBY:
510 /* ensure bufioen and biasen */ 466 /* ensure bufioen and biasen */
511 pwr_reg |= (1 << 2) | (1 << 3); 467 pwr_reg |= (1 << 2) | (1 << 3);
512 /* set vmid to 300k for standby */ 468 /* set vmid to 300k for standby */
513 ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x2); 469 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x2);
514 break; 470 break;
515 case SND_SOC_BIAS_OFF: 471 case SND_SOC_BIAS_OFF:
516 ret = wm8940_write(codec, WM8940_POWER1, pwr_reg); 472 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg);
517 break; 473 break;
518 } 474 }
519 475
@@ -587,36 +543,36 @@ static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai,
587 u16 reg; 543 u16 reg;
588 544
589 /* Turn off PLL */ 545 /* Turn off PLL */
590 reg = wm8940_read_reg_cache(codec, WM8940_POWER1); 546 reg = snd_soc_read(codec, WM8940_POWER1);
591 wm8940_write(codec, WM8940_POWER1, reg & 0x1df); 547 snd_soc_write(codec, WM8940_POWER1, reg & 0x1df);
592 548
593 if (freq_in == 0 || freq_out == 0) { 549 if (freq_in == 0 || freq_out == 0) {
594 /* Clock CODEC directly from MCLK */ 550 /* Clock CODEC directly from MCLK */
595 reg = wm8940_read_reg_cache(codec, WM8940_CLOCK); 551 reg = snd_soc_read(codec, WM8940_CLOCK);
596 wm8940_write(codec, WM8940_CLOCK, reg & 0x0ff); 552 snd_soc_write(codec, WM8940_CLOCK, reg & 0x0ff);
597 /* Pll power down */ 553 /* Pll power down */
598 wm8940_write(codec, WM8940_PLLN, (1 << 7)); 554 snd_soc_write(codec, WM8940_PLLN, (1 << 7));
599 return 0; 555 return 0;
600 } 556 }
601 557
602 /* Pll is followed by a frequency divide by 4 */ 558 /* Pll is followed by a frequency divide by 4 */
603 pll_factors(freq_out*4, freq_in); 559 pll_factors(freq_out*4, freq_in);
604 if (pll_div.k) 560 if (pll_div.k)
605 wm8940_write(codec, WM8940_PLLN, 561 snd_soc_write(codec, WM8940_PLLN,
606 (pll_div.pre_scale << 4) | pll_div.n | (1 << 6)); 562 (pll_div.pre_scale << 4) | pll_div.n | (1 << 6));
607 else /* No factional component */ 563 else /* No factional component */
608 wm8940_write(codec, WM8940_PLLN, 564 snd_soc_write(codec, WM8940_PLLN,
609 (pll_div.pre_scale << 4) | pll_div.n); 565 (pll_div.pre_scale << 4) | pll_div.n);
610 wm8940_write(codec, WM8940_PLLK1, pll_div.k >> 18); 566 snd_soc_write(codec, WM8940_PLLK1, pll_div.k >> 18);
611 wm8940_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff); 567 snd_soc_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
612 wm8940_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff); 568 snd_soc_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff);
613 /* Enable the PLL */ 569 /* Enable the PLL */
614 reg = wm8940_read_reg_cache(codec, WM8940_POWER1); 570 reg = snd_soc_read(codec, WM8940_POWER1);
615 wm8940_write(codec, WM8940_POWER1, reg | 0x020); 571 snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
616 572
617 /* Run CODEC from PLL instead of MCLK */ 573 /* Run CODEC from PLL instead of MCLK */
618 reg = wm8940_read_reg_cache(codec, WM8940_CLOCK); 574 reg = snd_soc_read(codec, WM8940_CLOCK);
619 wm8940_write(codec, WM8940_CLOCK, reg | 0x100); 575 snd_soc_write(codec, WM8940_CLOCK, reg | 0x100);
620 576
621 return 0; 577 return 0;
622} 578}
@@ -648,16 +604,16 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
648 604
649 switch (div_id) { 605 switch (div_id) {
650 case WM8940_BCLKDIV: 606 case WM8940_BCLKDIV:
651 reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFFEF3; 607 reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFEF3;
652 ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 2)); 608 ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2));
653 break; 609 break;
654 case WM8940_MCLKDIV: 610 case WM8940_MCLKDIV:
655 reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFF1F; 611 reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFF1F;
656 ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 5)); 612 ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
657 break; 613 break;
658 case WM8940_OPCLKDIV: 614 case WM8940_OPCLKDIV:
659 reg = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFCF; 615 reg = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFCF;
660 ret = wm8940_write(codec, WM8940_ADDCNTRL, reg | (div << 4)); 616 ret = snd_soc_write(codec, WM8940_ADDCNTRL, reg | (div << 4));
661 break; 617 break;
662 } 618 }
663 return ret; 619 return ret;
@@ -808,7 +764,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8940 = {
808}; 764};
809EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940); 765EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940);
810 766
811static int wm8940_register(struct wm8940_priv *wm8940) 767static int wm8940_register(struct wm8940_priv *wm8940,
768 enum snd_soc_control_type control)
812{ 769{
813 struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data; 770 struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data;
814 struct snd_soc_codec *codec = &wm8940->codec; 771 struct snd_soc_codec *codec = &wm8940->codec;
@@ -825,8 +782,6 @@ static int wm8940_register(struct wm8940_priv *wm8940)
825 codec->private_data = wm8940; 782 codec->private_data = wm8940;
826 codec->name = "WM8940"; 783 codec->name = "WM8940";
827 codec->owner = THIS_MODULE; 784 codec->owner = THIS_MODULE;
828 codec->read = wm8940_read_reg_cache;
829 codec->write = wm8940_write;
830 codec->bias_level = SND_SOC_BIAS_OFF; 785 codec->bias_level = SND_SOC_BIAS_OFF;
831 codec->set_bias_level = wm8940_set_bias_level; 786 codec->set_bias_level = wm8940_set_bias_level;
832 codec->dai = &wm8940_dai; 787 codec->dai = &wm8940_dai;
@@ -834,6 +789,12 @@ static int wm8940_register(struct wm8940_priv *wm8940)
834 codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults); 789 codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults);
835 codec->reg_cache = &wm8940->reg_cache; 790 codec->reg_cache = &wm8940->reg_cache;
836 791
792 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
793 if (ret == 0) {
794 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
795 return ret;
796 }
797
837 memcpy(codec->reg_cache, wm8940_reg_defaults, 798 memcpy(codec->reg_cache, wm8940_reg_defaults,
838 sizeof(wm8940_reg_defaults)); 799 sizeof(wm8940_reg_defaults));
839 800
@@ -847,15 +808,15 @@ static int wm8940_register(struct wm8940_priv *wm8940)
847 808
848 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 809 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
849 810
850 ret = wm8940_write(codec, WM8940_POWER1, 0x180); 811 ret = snd_soc_write(codec, WM8940_POWER1, 0x180);
851 if (ret < 0) 812 if (ret < 0)
852 return ret; 813 return ret;
853 814
854 if (!pdata) 815 if (!pdata)
855 dev_warn(codec->dev, "No platform data supplied\n"); 816 dev_warn(codec->dev, "No platform data supplied\n");
856 else { 817 else {
857 reg = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL); 818 reg = snd_soc_read(codec, WM8940_OUTPUTCTL);
858 ret = wm8940_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi); 819 ret = snd_soc_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi);
859 if (ret < 0) 820 if (ret < 0)
860 return ret; 821 return ret;
861 } 822 }
@@ -904,7 +865,7 @@ static int wm8940_i2c_probe(struct i2c_client *i2c,
904 codec->control_data = i2c; 865 codec->control_data = i2c;
905 codec->dev = &i2c->dev; 866 codec->dev = &i2c->dev;
906 867
907 return wm8940_register(wm8940); 868 return wm8940_register(wm8940, SND_SOC_I2C);
908} 869}
909 870
910static int __devexit wm8940_i2c_remove(struct i2c_client *client) 871static int __devexit wm8940_i2c_remove(struct i2c_client *client)
@@ -916,6 +877,21 @@ static int __devexit wm8940_i2c_remove(struct i2c_client *client)
916 return 0; 877 return 0;
917} 878}
918 879
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
919static const struct i2c_device_id wm8940_i2c_id[] = { 895static const struct i2c_device_id wm8940_i2c_id[] = {
920 { "wm8940", 0 }, 896 { "wm8940", 0 },
921 { } 897 { }
@@ -929,6 +905,8 @@ static struct i2c_driver wm8940_i2c_driver = {
929 }, 905 },
930 .probe = wm8940_i2c_probe, 906 .probe = wm8940_i2c_probe,
931 .remove = __devexit_p(wm8940_i2c_remove), 907 .remove = __devexit_p(wm8940_i2c_remove),
908 .suspend = wm8940_i2c_suspend,
909 .resume = wm8940_i2c_resume,
932 .id_table = wm8940_i2c_id, 910 .id_table = wm8940_i2c_id,
933}; 911};
934 912
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index e224d8add170..f59703be61c8 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -69,61 +69,7 @@ struct wm8960_priv {
69 struct snd_soc_codec codec; 69 struct snd_soc_codec codec;
70}; 70};
71 71
72/* 72#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
73 * read wm8960 register cache
74 */
75static inline unsigned int wm8960_read_reg_cache(struct snd_soc_codec *codec,
76 unsigned int reg)
77{
78 u16 *cache = codec->reg_cache;
79 if (reg == WM8960_RESET)
80 return 0;
81 if (reg >= WM8960_CACHEREGNUM)
82 return -1;
83 return cache[reg];
84}
85
86/*
87 * write wm8960 register cache
88 */
89static inline void wm8960_write_reg_cache(struct snd_soc_codec *codec,
90 u16 reg, unsigned int value)
91{
92 u16 *cache = codec->reg_cache;
93 if (reg >= WM8960_CACHEREGNUM)
94 return;
95 cache[reg] = value;
96}
97
98static inline unsigned int wm8960_read(struct snd_soc_codec *codec,
99 unsigned int reg)
100{
101 return wm8960_read_reg_cache(codec, reg);
102}
103
104/*
105 * write to the WM8960 register space
106 */
107static int wm8960_write(struct snd_soc_codec *codec, unsigned int reg,
108 unsigned int value)
109{
110 u8 data[2];
111
112 /* data is
113 * D15..D9 WM8960 register offset
114 * D8...D0 register data
115 */
116 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
117 data[1] = value & 0x00ff;
118
119 wm8960_write_reg_cache(codec, reg, value);
120 if (codec->hw_write(codec->control_data, data, 2) == 2)
121 return 0;
122 else
123 return -EIO;
124}
125
126#define wm8960_reset(c) wm8960_write(c, WM8960_RESET, 0)
127 73
128/* enumerated controls */ 74/* enumerated controls */
129static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 75static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
@@ -420,7 +366,7 @@ static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
420 } 366 }
421 367
422 /* set iface */ 368 /* set iface */
423 wm8960_write(codec, WM8960_IFACE1, iface); 369 snd_soc_write(codec, WM8960_IFACE1, iface);
424 return 0; 370 return 0;
425} 371}
426 372
@@ -431,7 +377,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
431 struct snd_soc_pcm_runtime *rtd = substream->private_data; 377 struct snd_soc_pcm_runtime *rtd = substream->private_data;
432 struct snd_soc_device *socdev = rtd->socdev; 378 struct snd_soc_device *socdev = rtd->socdev;
433 struct snd_soc_codec *codec = socdev->card->codec; 379 struct snd_soc_codec *codec = socdev->card->codec;
434 u16 iface = wm8960_read(codec, WM8960_IFACE1) & 0xfff3; 380 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
435 381
436 /* bit size */ 382 /* bit size */
437 switch (params_format(params)) { 383 switch (params_format(params)) {
@@ -446,19 +392,19 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
446 } 392 }
447 393
448 /* set iface */ 394 /* set iface */
449 wm8960_write(codec, WM8960_IFACE1, iface); 395 snd_soc_write(codec, WM8960_IFACE1, iface);
450 return 0; 396 return 0;
451} 397}
452 398
453static int wm8960_mute(struct snd_soc_dai *dai, int mute) 399static int wm8960_mute(struct snd_soc_dai *dai, int mute)
454{ 400{
455 struct snd_soc_codec *codec = dai->codec; 401 struct snd_soc_codec *codec = dai->codec;
456 u16 mute_reg = wm8960_read(codec, WM8960_DACCTL1) & 0xfff7; 402 u16 mute_reg = snd_soc_read(codec, WM8960_DACCTL1) & 0xfff7;
457 403
458 if (mute) 404 if (mute)
459 wm8960_write(codec, WM8960_DACCTL1, mute_reg | 0x8); 405 snd_soc_write(codec, WM8960_DACCTL1, mute_reg | 0x8);
460 else 406 else
461 wm8960_write(codec, WM8960_DACCTL1, mute_reg); 407 snd_soc_write(codec, WM8960_DACCTL1, mute_reg);
462 return 0; 408 return 0;
463} 409}
464 410
@@ -474,16 +420,16 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
474 420
475 case SND_SOC_BIAS_PREPARE: 421 case SND_SOC_BIAS_PREPARE:
476 /* Set VMID to 2x50k */ 422 /* Set VMID to 2x50k */
477 reg = wm8960_read(codec, WM8960_POWER1); 423 reg = snd_soc_read(codec, WM8960_POWER1);
478 reg &= ~0x180; 424 reg &= ~0x180;
479 reg |= 0x80; 425 reg |= 0x80;
480 wm8960_write(codec, WM8960_POWER1, reg); 426 snd_soc_write(codec, WM8960_POWER1, reg);
481 break; 427 break;
482 428
483 case SND_SOC_BIAS_STANDBY: 429 case SND_SOC_BIAS_STANDBY:
484 if (codec->bias_level == SND_SOC_BIAS_OFF) { 430 if (codec->bias_level == SND_SOC_BIAS_OFF) {
485 /* Enable anti-pop features */ 431 /* Enable anti-pop features */
486 wm8960_write(codec, WM8960_APOP1, 432 snd_soc_write(codec, WM8960_APOP1,
487 WM8960_POBCTRL | WM8960_SOFT_ST | 433 WM8960_POBCTRL | WM8960_SOFT_ST |
488 WM8960_BUFDCOPEN | WM8960_BUFIOEN); 434 WM8960_BUFDCOPEN | WM8960_BUFIOEN);
489 435
@@ -491,43 +437,43 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
491 reg = WM8960_DISOP; 437 reg = WM8960_DISOP;
492 if (pdata) 438 if (pdata)
493 reg |= pdata->dres << 4; 439 reg |= pdata->dres << 4;
494 wm8960_write(codec, WM8960_APOP2, reg); 440 snd_soc_write(codec, WM8960_APOP2, reg);
495 441
496 msleep(400); 442 msleep(400);
497 443
498 wm8960_write(codec, WM8960_APOP2, 0); 444 snd_soc_write(codec, WM8960_APOP2, 0);
499 445
500 /* Enable & ramp VMID at 2x50k */ 446 /* Enable & ramp VMID at 2x50k */
501 reg = wm8960_read(codec, WM8960_POWER1); 447 reg = snd_soc_read(codec, WM8960_POWER1);
502 reg |= 0x80; 448 reg |= 0x80;
503 wm8960_write(codec, WM8960_POWER1, reg); 449 snd_soc_write(codec, WM8960_POWER1, reg);
504 msleep(100); 450 msleep(100);
505 451
506 /* Enable VREF */ 452 /* Enable VREF */
507 wm8960_write(codec, WM8960_POWER1, reg | WM8960_VREF); 453 snd_soc_write(codec, WM8960_POWER1, reg | WM8960_VREF);
508 454
509 /* Disable anti-pop features */ 455 /* Disable anti-pop features */
510 wm8960_write(codec, WM8960_APOP1, WM8960_BUFIOEN); 456 snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
511 } 457 }
512 458
513 /* Set VMID to 2x250k */ 459 /* Set VMID to 2x250k */
514 reg = wm8960_read(codec, WM8960_POWER1); 460 reg = snd_soc_read(codec, WM8960_POWER1);
515 reg &= ~0x180; 461 reg &= ~0x180;
516 reg |= 0x100; 462 reg |= 0x100;
517 wm8960_write(codec, WM8960_POWER1, reg); 463 snd_soc_write(codec, WM8960_POWER1, reg);
518 break; 464 break;
519 465
520 case SND_SOC_BIAS_OFF: 466 case SND_SOC_BIAS_OFF:
521 /* Enable anti-pop features */ 467 /* Enable anti-pop features */
522 wm8960_write(codec, WM8960_APOP1, 468 snd_soc_write(codec, WM8960_APOP1,
523 WM8960_POBCTRL | WM8960_SOFT_ST | 469 WM8960_POBCTRL | WM8960_SOFT_ST |
524 WM8960_BUFDCOPEN | WM8960_BUFIOEN); 470 WM8960_BUFDCOPEN | WM8960_BUFIOEN);
525 471
526 /* Disable VMID and VREF, let them discharge */ 472 /* Disable VMID and VREF, let them discharge */
527 wm8960_write(codec, WM8960_POWER1, 0); 473 snd_soc_write(codec, WM8960_POWER1, 0);
528 msleep(600); 474 msleep(600);
529 475
530 wm8960_write(codec, WM8960_APOP1, 0); 476 snd_soc_write(codec, WM8960_APOP1, 0);
531 break; 477 break;
532 } 478 }
533 479
@@ -610,33 +556,33 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai,
610 556
611 /* Disable the PLL: even if we are changing the frequency the 557 /* Disable the PLL: even if we are changing the frequency the
612 * PLL needs to be disabled while we do so. */ 558 * PLL needs to be disabled while we do so. */
613 wm8960_write(codec, WM8960_CLOCK1, 559 snd_soc_write(codec, WM8960_CLOCK1,
614 wm8960_read(codec, WM8960_CLOCK1) & ~1); 560 snd_soc_read(codec, WM8960_CLOCK1) & ~1);
615 wm8960_write(codec, WM8960_POWER2, 561 snd_soc_write(codec, WM8960_POWER2,
616 wm8960_read(codec, WM8960_POWER2) & ~1); 562 snd_soc_read(codec, WM8960_POWER2) & ~1);
617 563
618 if (!freq_in || !freq_out) 564 if (!freq_in || !freq_out)
619 return 0; 565 return 0;
620 566
621 reg = wm8960_read(codec, WM8960_PLL1) & ~0x3f; 567 reg = snd_soc_read(codec, WM8960_PLL1) & ~0x3f;
622 reg |= pll_div.pre_div << 4; 568 reg |= pll_div.pre_div << 4;
623 reg |= pll_div.n; 569 reg |= pll_div.n;
624 570
625 if (pll_div.k) { 571 if (pll_div.k) {
626 reg |= 0x20; 572 reg |= 0x20;
627 573
628 wm8960_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); 574 snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f);
629 wm8960_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); 575 snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff);
630 wm8960_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); 576 snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff);
631 } 577 }
632 wm8960_write(codec, WM8960_PLL1, reg); 578 snd_soc_write(codec, WM8960_PLL1, reg);
633 579
634 /* Turn it on */ 580 /* Turn it on */
635 wm8960_write(codec, WM8960_POWER2, 581 snd_soc_write(codec, WM8960_POWER2,
636 wm8960_read(codec, WM8960_POWER2) | 1); 582 snd_soc_read(codec, WM8960_POWER2) | 1);
637 msleep(250); 583 msleep(250);
638 wm8960_write(codec, WM8960_CLOCK1, 584 snd_soc_write(codec, WM8960_CLOCK1,
639 wm8960_read(codec, WM8960_CLOCK1) | 1); 585 snd_soc_read(codec, WM8960_CLOCK1) | 1);
640 586
641 return 0; 587 return 0;
642} 588}
@@ -649,28 +595,28 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
649 595
650 switch (div_id) { 596 switch (div_id) {
651 case WM8960_SYSCLKSEL: 597 case WM8960_SYSCLKSEL:
652 reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1fe; 598 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1fe;
653 wm8960_write(codec, WM8960_CLOCK1, reg | div); 599 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
654 break; 600 break;
655 case WM8960_SYSCLKDIV: 601 case WM8960_SYSCLKDIV:
656 reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1f9; 602 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9;
657 wm8960_write(codec, WM8960_CLOCK1, reg | div); 603 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
658 break; 604 break;
659 case WM8960_DACDIV: 605 case WM8960_DACDIV:
660 reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1c7; 606 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1c7;
661 wm8960_write(codec, WM8960_CLOCK1, reg | div); 607 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
662 break; 608 break;
663 case WM8960_OPCLKDIV: 609 case WM8960_OPCLKDIV:
664 reg = wm8960_read(codec, WM8960_PLL1) & 0x03f; 610 reg = snd_soc_read(codec, WM8960_PLL1) & 0x03f;
665 wm8960_write(codec, WM8960_PLL1, reg | div); 611 snd_soc_write(codec, WM8960_PLL1, reg | div);
666 break; 612 break;
667 case WM8960_DCLKDIV: 613 case WM8960_DCLKDIV:
668 reg = wm8960_read(codec, WM8960_CLOCK2) & 0x03f; 614 reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
669 wm8960_write(codec, WM8960_CLOCK2, reg | div); 615 snd_soc_write(codec, WM8960_CLOCK2, reg | div);
670 break; 616 break;
671 case WM8960_TOCLKSEL: 617 case WM8960_TOCLKSEL:
672 reg = wm8960_read(codec, WM8960_ADDCTL1) & 0x1fd; 618 reg = snd_soc_read(codec, WM8960_ADDCTL1) & 0x1fd;
673 wm8960_write(codec, WM8960_ADDCTL1, reg | div); 619 snd_soc_write(codec, WM8960_ADDCTL1, reg | div);
674 break; 620 break;
675 default: 621 default:
676 return -EINVAL; 622 return -EINVAL;
@@ -801,7 +747,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8960 = {
801}; 747};
802EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960); 748EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960);
803 749
804static int wm8960_register(struct wm8960_priv *wm8960) 750static int wm8960_register(struct wm8960_priv *wm8960,
751 enum snd_soc_control_type control)
805{ 752{
806 struct wm8960_data *pdata = wm8960->codec.dev->platform_data; 753 struct wm8960_data *pdata = wm8960->codec.dev->platform_data;
807 struct snd_soc_codec *codec = &wm8960->codec; 754 struct snd_soc_codec *codec = &wm8960->codec;
@@ -810,7 +757,8 @@ static int wm8960_register(struct wm8960_priv *wm8960)
810 757
811 if (wm8960_codec) { 758 if (wm8960_codec) {
812 dev_err(codec->dev, "Another WM8960 is registered\n"); 759 dev_err(codec->dev, "Another WM8960 is registered\n");
813 return -EINVAL; 760 ret = -EINVAL;
761 goto err;
814 } 762 }
815 763
816 if (!pdata) { 764 if (!pdata) {
@@ -829,8 +777,6 @@ static int wm8960_register(struct wm8960_priv *wm8960)
829 codec->private_data = wm8960; 777 codec->private_data = wm8960;
830 codec->name = "WM8960"; 778 codec->name = "WM8960";
831 codec->owner = THIS_MODULE; 779 codec->owner = THIS_MODULE;
832 codec->read = wm8960_read_reg_cache;
833 codec->write = wm8960_write;
834 codec->bias_level = SND_SOC_BIAS_OFF; 780 codec->bias_level = SND_SOC_BIAS_OFF;
835 codec->set_bias_level = wm8960_set_bias_level; 781 codec->set_bias_level = wm8960_set_bias_level;
836 codec->dai = &wm8960_dai; 782 codec->dai = &wm8960_dai;
@@ -840,10 +786,16 @@ static int wm8960_register(struct wm8960_priv *wm8960)
840 786
841 memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg)); 787 memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg));
842 788
789 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
790 if (ret < 0) {
791 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
792 goto err;
793 }
794
843 ret = wm8960_reset(codec); 795 ret = wm8960_reset(codec);
844 if (ret < 0) { 796 if (ret < 0) {
845 dev_err(codec->dev, "Failed to issue reset\n"); 797 dev_err(codec->dev, "Failed to issue reset\n");
846 return ret; 798 goto err;
847 } 799 }
848 800
849 wm8960_dai.dev = codec->dev; 801 wm8960_dai.dev = codec->dev;
@@ -851,43 +803,48 @@ static int wm8960_register(struct wm8960_priv *wm8960)
851 wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 803 wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
852 804
853 /* Latch the update bits */ 805 /* Latch the update bits */
854 reg = wm8960_read(codec, WM8960_LINVOL); 806 reg = snd_soc_read(codec, WM8960_LINVOL);
855 wm8960_write(codec, WM8960_LINVOL, reg | 0x100); 807 snd_soc_write(codec, WM8960_LINVOL, reg | 0x100);
856 reg = wm8960_read(codec, WM8960_RINVOL); 808 reg = snd_soc_read(codec, WM8960_RINVOL);
857 wm8960_write(codec, WM8960_RINVOL, reg | 0x100); 809 snd_soc_write(codec, WM8960_RINVOL, reg | 0x100);
858 reg = wm8960_read(codec, WM8960_LADC); 810 reg = snd_soc_read(codec, WM8960_LADC);
859 wm8960_write(codec, WM8960_LADC, reg | 0x100); 811 snd_soc_write(codec, WM8960_LADC, reg | 0x100);
860 reg = wm8960_read(codec, WM8960_RADC); 812 reg = snd_soc_read(codec, WM8960_RADC);
861 wm8960_write(codec, WM8960_RADC, reg | 0x100); 813 snd_soc_write(codec, WM8960_RADC, reg | 0x100);
862 reg = wm8960_read(codec, WM8960_LDAC); 814 reg = snd_soc_read(codec, WM8960_LDAC);
863 wm8960_write(codec, WM8960_LDAC, reg | 0x100); 815 snd_soc_write(codec, WM8960_LDAC, reg | 0x100);
864 reg = wm8960_read(codec, WM8960_RDAC); 816 reg = snd_soc_read(codec, WM8960_RDAC);
865 wm8960_write(codec, WM8960_RDAC, reg | 0x100); 817 snd_soc_write(codec, WM8960_RDAC, reg | 0x100);
866 reg = wm8960_read(codec, WM8960_LOUT1); 818 reg = snd_soc_read(codec, WM8960_LOUT1);
867 wm8960_write(codec, WM8960_LOUT1, reg | 0x100); 819 snd_soc_write(codec, WM8960_LOUT1, reg | 0x100);
868 reg = wm8960_read(codec, WM8960_ROUT1); 820 reg = snd_soc_read(codec, WM8960_ROUT1);
869 wm8960_write(codec, WM8960_ROUT1, reg | 0x100); 821 snd_soc_write(codec, WM8960_ROUT1, reg | 0x100);
870 reg = wm8960_read(codec, WM8960_LOUT2); 822 reg = snd_soc_read(codec, WM8960_LOUT2);
871 wm8960_write(codec, WM8960_LOUT2, reg | 0x100); 823 snd_soc_write(codec, WM8960_LOUT2, reg | 0x100);
872 reg = wm8960_read(codec, WM8960_ROUT2); 824 reg = snd_soc_read(codec, WM8960_ROUT2);
873 wm8960_write(codec, WM8960_ROUT2, reg | 0x100); 825 snd_soc_write(codec, WM8960_ROUT2, reg | 0x100);
874 826
875 wm8960_codec = codec; 827 wm8960_codec = codec;
876 828
877 ret = snd_soc_register_codec(codec); 829 ret = snd_soc_register_codec(codec);
878 if (ret != 0) { 830 if (ret != 0) {
879 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 831 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
880 return ret; 832 goto err;
881 } 833 }
882 834
883 ret = snd_soc_register_dai(&wm8960_dai); 835 ret = snd_soc_register_dai(&wm8960_dai);
884 if (ret != 0) { 836 if (ret != 0) {
885 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 837 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
886 snd_soc_unregister_codec(codec); 838 goto err_codec;
887 return ret;
888 } 839 }
889 840
890 return 0; 841 return 0;
842
843err_codec:
844 snd_soc_unregister_codec(codec);
845err:
846 kfree(wm8960);
847 return ret;
891} 848}
892 849
893static void wm8960_unregister(struct wm8960_priv *wm8960) 850static void wm8960_unregister(struct wm8960_priv *wm8960)
@@ -910,14 +867,13 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
910 return -ENOMEM; 867 return -ENOMEM;
911 868
912 codec = &wm8960->codec; 869 codec = &wm8960->codec;
913 codec->hw_write = (hw_write_t)i2c_master_send;
914 870
915 i2c_set_clientdata(i2c, wm8960); 871 i2c_set_clientdata(i2c, wm8960);
916 codec->control_data = i2c; 872 codec->control_data = i2c;
917 873
918 codec->dev = &i2c->dev; 874 codec->dev = &i2c->dev;
919 875
920 return wm8960_register(wm8960); 876 return wm8960_register(wm8960, SND_SOC_I2C);
921} 877}
922 878
923static __devexit int wm8960_i2c_remove(struct i2c_client *client) 879static __devexit int wm8960_i2c_remove(struct i2c_client *client)
@@ -927,6 +883,21 @@ static __devexit int wm8960_i2c_remove(struct i2c_client *client)
927 return 0; 883 return 0;
928} 884}
929 885
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
930static const struct i2c_device_id wm8960_i2c_id[] = { 901static const struct i2c_device_id wm8960_i2c_id[] = {
931 { "wm8960", 0 }, 902 { "wm8960", 0 },
932 { } 903 { }
@@ -940,6 +911,8 @@ static struct i2c_driver wm8960_i2c_driver = {
940 }, 911 },
941 .probe = wm8960_i2c_probe, 912 .probe = wm8960_i2c_probe,
942 .remove = __devexit_p(wm8960_i2c_remove), 913 .remove = __devexit_p(wm8960_i2c_remove),
914 .suspend = wm8960_i2c_suspend,
915 .resume = wm8960_i2c_resume,
943 .id_table = wm8960_i2c_id, 916 .id_table = wm8960_i2c_id,
944}; 917};
945 918
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
new file mode 100644
index 000000000000..503032085899
--- /dev/null
+++ b/sound/soc/codecs/wm8961.c
@@ -0,0 +1,1265 @@
1/*
2 * wm8961.c -- WM8961 ALSA SoC Audio driver
3 *
4 * Author: Mark Brown
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 * Currently unimplemented features:
11 * - ALC
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 <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include "wm8961.h"
30
31#define WM8961_MAX_REGISTER 0xFC
32
33static u16 wm8961_reg_defaults[] = {
34 0x009F, /* R0 - Left Input volume */
35 0x009F, /* R1 - Right Input volume */
36 0x0000, /* R2 - LOUT1 volume */
37 0x0000, /* R3 - ROUT1 volume */
38 0x0020, /* R4 - Clocking1 */
39 0x0008, /* R5 - ADC & DAC Control 1 */
40 0x0000, /* R6 - ADC & DAC Control 2 */
41 0x000A, /* R7 - Audio Interface 0 */
42 0x01F4, /* R8 - Clocking2 */
43 0x0000, /* R9 - Audio Interface 1 */
44 0x00FF, /* R10 - Left DAC volume */
45 0x00FF, /* R11 - Right DAC volume */
46 0x0000, /* R12 */
47 0x0000, /* R13 */
48 0x0040, /* R14 - Audio Interface 2 */
49 0x0000, /* R15 - Software Reset */
50 0x0000, /* R16 */
51 0x007B, /* R17 - ALC1 */
52 0x0000, /* R18 - ALC2 */
53 0x0032, /* R19 - ALC3 */
54 0x0000, /* R20 - Noise Gate */
55 0x00C0, /* R21 - Left ADC volume */
56 0x00C0, /* R22 - Right ADC volume */
57 0x0120, /* R23 - Additional control(1) */
58 0x0000, /* R24 - Additional control(2) */
59 0x0000, /* R25 - Pwr Mgmt (1) */
60 0x0000, /* R26 - Pwr Mgmt (2) */
61 0x0000, /* R27 - Additional Control (3) */
62 0x0000, /* R28 - Anti-pop */
63 0x0000, /* R29 */
64 0x005F, /* R30 - Clocking 3 */
65 0x0000, /* R31 */
66 0x0000, /* R32 - ADCL signal path */
67 0x0000, /* R33 - ADCR signal path */
68 0x0000, /* R34 */
69 0x0000, /* R35 */
70 0x0000, /* R36 */
71 0x0000, /* R37 */
72 0x0000, /* R38 */
73 0x0000, /* R39 */
74 0x0000, /* R40 - LOUT2 volume */
75 0x0000, /* R41 - ROUT2 volume */
76 0x0000, /* R42 */
77 0x0000, /* R43 */
78 0x0000, /* R44 */
79 0x0000, /* R45 */
80 0x0000, /* R46 */
81 0x0000, /* R47 - Pwr Mgmt (3) */
82 0x0023, /* R48 - Additional Control (4) */
83 0x0000, /* R49 - Class D Control 1 */
84 0x0000, /* R50 */
85 0x0003, /* R51 - Class D Control 2 */
86 0x0000, /* R52 */
87 0x0000, /* R53 */
88 0x0000, /* R54 */
89 0x0000, /* R55 */
90 0x0106, /* R56 - Clocking 4 */
91 0x0000, /* R57 - DSP Sidetone 0 */
92 0x0000, /* R58 - DSP Sidetone 1 */
93 0x0000, /* R59 */
94 0x0000, /* R60 - DC Servo 0 */
95 0x0000, /* R61 - DC Servo 1 */
96 0x0000, /* R62 */
97 0x015E, /* R63 - DC Servo 3 */
98 0x0010, /* R64 */
99 0x0010, /* R65 - DC Servo 5 */
100 0x0000, /* R66 */
101 0x0001, /* R67 */
102 0x0003, /* R68 - Analogue PGA Bias */
103 0x0000, /* R69 - Analogue HP 0 */
104 0x0060, /* R70 */
105 0x01FB, /* R71 - Analogue HP 2 */
106 0x0000, /* R72 - Charge Pump 1 */
107 0x0065, /* R73 */
108 0x005F, /* R74 */
109 0x0059, /* R75 */
110 0x006B, /* R76 */
111 0x0038, /* R77 */
112 0x000C, /* R78 */
113 0x000A, /* R79 */
114 0x006B, /* R80 */
115 0x0000, /* R81 */
116 0x0000, /* R82 - Charge Pump B */
117 0x0087, /* R83 */
118 0x0000, /* R84 */
119 0x005C, /* R85 */
120 0x0000, /* R86 */
121 0x0000, /* R87 - Write Sequencer 1 */
122 0x0000, /* R88 - Write Sequencer 2 */
123 0x0000, /* R89 - Write Sequencer 3 */
124 0x0000, /* R90 - Write Sequencer 4 */
125 0x0000, /* R91 - Write Sequencer 5 */
126 0x0000, /* R92 - Write Sequencer 6 */
127 0x0000, /* R93 - Write Sequencer 7 */
128 0x0000, /* R94 */
129 0x0000, /* R95 */
130 0x0000, /* R96 */
131 0x0000, /* R97 */
132 0x0000, /* R98 */
133 0x0000, /* R99 */
134 0x0000, /* R100 */
135 0x0000, /* R101 */
136 0x0000, /* R102 */
137 0x0000, /* R103 */
138 0x0000, /* R104 */
139 0x0000, /* R105 */
140 0x0000, /* R106 */
141 0x0000, /* R107 */
142 0x0000, /* R108 */
143 0x0000, /* R109 */
144 0x0000, /* R110 */
145 0x0000, /* R111 */
146 0x0000, /* R112 */
147 0x0000, /* R113 */
148 0x0000, /* R114 */
149 0x0000, /* R115 */
150 0x0000, /* R116 */
151 0x0000, /* R117 */
152 0x0000, /* R118 */
153 0x0000, /* R119 */
154 0x0000, /* R120 */
155 0x0000, /* R121 */
156 0x0000, /* R122 */
157 0x0000, /* R123 */
158 0x0000, /* R124 */
159 0x0000, /* R125 */
160 0x0000, /* R126 */
161 0x0000, /* R127 */
162 0x0000, /* R128 */
163 0x0000, /* R129 */
164 0x0000, /* R130 */
165 0x0000, /* R131 */
166 0x0000, /* R132 */
167 0x0000, /* R133 */
168 0x0000, /* R134 */
169 0x0000, /* R135 */
170 0x0000, /* R136 */
171 0x0000, /* R137 */
172 0x0000, /* R138 */
173 0x0000, /* R139 */
174 0x0000, /* R140 */
175 0x0000, /* R141 */
176 0x0000, /* R142 */
177 0x0000, /* R143 */
178 0x0000, /* R144 */
179 0x0000, /* R145 */
180 0x0000, /* R146 */
181 0x0000, /* R147 */
182 0x0000, /* R148 */
183 0x0000, /* R149 */
184 0x0000, /* R150 */
185 0x0000, /* R151 */
186 0x0000, /* R152 */
187 0x0000, /* R153 */
188 0x0000, /* R154 */
189 0x0000, /* R155 */
190 0x0000, /* R156 */
191 0x0000, /* R157 */
192 0x0000, /* R158 */
193 0x0000, /* R159 */
194 0x0000, /* R160 */
195 0x0000, /* R161 */
196 0x0000, /* R162 */
197 0x0000, /* R163 */
198 0x0000, /* R164 */
199 0x0000, /* R165 */
200 0x0000, /* R166 */
201 0x0000, /* R167 */
202 0x0000, /* R168 */
203 0x0000, /* R169 */
204 0x0000, /* R170 */
205 0x0000, /* R171 */
206 0x0000, /* R172 */
207 0x0000, /* R173 */
208 0x0000, /* R174 */
209 0x0000, /* R175 */
210 0x0000, /* R176 */
211 0x0000, /* R177 */
212 0x0000, /* R178 */
213 0x0000, /* R179 */
214 0x0000, /* R180 */
215 0x0000, /* R181 */
216 0x0000, /* R182 */
217 0x0000, /* R183 */
218 0x0000, /* R184 */
219 0x0000, /* R185 */
220 0x0000, /* R186 */
221 0x0000, /* R187 */
222 0x0000, /* R188 */
223 0x0000, /* R189 */
224 0x0000, /* R190 */
225 0x0000, /* R191 */
226 0x0000, /* R192 */
227 0x0000, /* R193 */
228 0x0000, /* R194 */
229 0x0000, /* R195 */
230 0x0030, /* R196 */
231 0x0006, /* R197 */
232 0x0000, /* R198 */
233 0x0060, /* R199 */
234 0x0000, /* R200 */
235 0x003F, /* R201 */
236 0x0000, /* R202 */
237 0x0000, /* R203 */
238 0x0000, /* R204 */
239 0x0001, /* R205 */
240 0x0000, /* R206 */
241 0x0181, /* R207 */
242 0x0005, /* R208 */
243 0x0008, /* R209 */
244 0x0008, /* R210 */
245 0x0000, /* R211 */
246 0x013B, /* R212 */
247 0x0000, /* R213 */
248 0x0000, /* R214 */
249 0x0000, /* R215 */
250 0x0000, /* R216 */
251 0x0070, /* R217 */
252 0x0000, /* R218 */
253 0x0000, /* R219 */
254 0x0000, /* R220 */
255 0x0000, /* R221 */
256 0x0000, /* R222 */
257 0x0003, /* R223 */
258 0x0000, /* R224 */
259 0x0000, /* R225 */
260 0x0001, /* R226 */
261 0x0008, /* R227 */
262 0x0000, /* R228 */
263 0x0000, /* R229 */
264 0x0000, /* R230 */
265 0x0000, /* R231 */
266 0x0004, /* R232 */
267 0x0000, /* R233 */
268 0x0000, /* R234 */
269 0x0000, /* R235 */
270 0x0000, /* R236 */
271 0x0000, /* R237 */
272 0x0080, /* R238 */
273 0x0000, /* R239 */
274 0x0000, /* R240 */
275 0x0000, /* R241 */
276 0x0000, /* R242 */
277 0x0000, /* R243 */
278 0x0000, /* R244 */
279 0x0052, /* R245 */
280 0x0110, /* R246 */
281 0x0040, /* R247 */
282 0x0000, /* R248 */
283 0x0030, /* R249 */
284 0x0000, /* R250 */
285 0x0000, /* R251 */
286 0x0001, /* R252 - General test 1 */
287};
288
289struct wm8961_priv {
290 struct snd_soc_codec codec;
291 int sysclk;
292 u16 reg_cache[WM8961_MAX_REGISTER];
293};
294
295static int wm8961_volatile_register(unsigned int reg)
296{
297 switch (reg) {
298 case WM8961_SOFTWARE_RESET:
299 case WM8961_WRITE_SEQUENCER_7:
300 case WM8961_DC_SERVO_1:
301 return 1;
302
303 default:
304 return 0;
305 }
306}
307
308static int wm8961_reset(struct snd_soc_codec *codec)
309{
310 return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0);
311}
312
313/*
314 * The headphone output supports special anti-pop sequences giving
315 * silent power up and power down.
316 */
317static int wm8961_hp_event(struct snd_soc_dapm_widget *w,
318 struct snd_kcontrol *kcontrol, int event)
319{
320 struct snd_soc_codec *codec = w->codec;
321 u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0);
322 u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1);
323 u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
324 u16 dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
325 int timeout = 500;
326
327 if (event & SND_SOC_DAPM_POST_PMU) {
328 /* Make sure the output is shorted */
329 hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
330 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
331
332 /* Enable the charge pump */
333 cp_reg |= WM8961_CP_ENA;
334 snd_soc_write(codec, WM8961_CHARGE_PUMP_1, cp_reg);
335 mdelay(5);
336
337 /* Enable the PGA */
338 pwr_reg |= WM8961_LOUT1_PGA | WM8961_ROUT1_PGA;
339 snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
340
341 /* Enable the amplifier */
342 hp_reg |= WM8961_HPR_ENA | WM8961_HPL_ENA;
343 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
344
345 /* Second stage enable */
346 hp_reg |= WM8961_HPR_ENA_DLY | WM8961_HPL_ENA_DLY;
347 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
348
349 /* Enable the DC servo & trigger startup */
350 dcs_reg |=
351 WM8961_DCS_ENA_CHAN_HPR | WM8961_DCS_TRIG_STARTUP_HPR |
352 WM8961_DCS_ENA_CHAN_HPL | WM8961_DCS_TRIG_STARTUP_HPL;
353 dev_dbg(codec->dev, "Enabling DC servo\n");
354
355 snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
356 do {
357 msleep(1);
358 dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
359 } while (--timeout &&
360 dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
361 WM8961_DCS_TRIG_STARTUP_HPL));
362 if (dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
363 WM8961_DCS_TRIG_STARTUP_HPL))
364 dev_err(codec->dev, "DC servo timed out\n");
365 else
366 dev_dbg(codec->dev, "DC servo startup complete\n");
367
368 /* Enable the output stage */
369 hp_reg |= WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP;
370 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
371
372 /* Remove the short on the output stage */
373 hp_reg |= WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT;
374 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
375 }
376
377 if (event & SND_SOC_DAPM_PRE_PMD) {
378 /* Short the output */
379 hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
380 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
381
382 /* Disable the output stage */
383 hp_reg &= ~(WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP);
384 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
385
386 /* Disable DC offset cancellation */
387 dcs_reg &= ~(WM8961_DCS_ENA_CHAN_HPR |
388 WM8961_DCS_ENA_CHAN_HPL);
389 snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
390
391 /* Finish up */
392 hp_reg &= ~(WM8961_HPR_ENA_DLY | WM8961_HPR_ENA |
393 WM8961_HPL_ENA_DLY | WM8961_HPL_ENA);
394 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
395
396 /* Disable the PGA */
397 pwr_reg &= ~(WM8961_LOUT1_PGA | WM8961_ROUT1_PGA);
398 snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
399
400 /* Disable the charge pump */
401 dev_dbg(codec->dev, "Disabling charge pump\n");
402 snd_soc_write(codec, WM8961_CHARGE_PUMP_1,
403 cp_reg & ~WM8961_CP_ENA);
404 }
405
406 return 0;
407}
408
409static int wm8961_spk_event(struct snd_soc_dapm_widget *w,
410 struct snd_kcontrol *kcontrol, int event)
411{
412 struct snd_soc_codec *codec = w->codec;
413 u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
414 u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1);
415
416 if (event & SND_SOC_DAPM_POST_PMU) {
417 /* Enable the PGA */
418 pwr_reg |= WM8961_SPKL_PGA | WM8961_SPKR_PGA;
419 snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
420
421 /* Enable the amplifier */
422 spk_reg |= WM8961_SPKL_ENA | WM8961_SPKR_ENA;
423 snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
424 }
425
426 if (event & SND_SOC_DAPM_PRE_PMD) {
427 /* Enable the amplifier */
428 spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA);
429 snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
430
431 /* Enable the PGA */
432 pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA);
433 snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
434 }
435
436 return 0;
437}
438
439static const char *adc_hpf_text[] = {
440 "Hi-fi", "Voice 1", "Voice 2", "Voice 3",
441};
442
443static const struct soc_enum adc_hpf =
444 SOC_ENUM_SINGLE(WM8961_ADC_DAC_CONTROL_2, 7, 4, adc_hpf_text);
445
446static const char *dac_deemph_text[] = {
447 "None", "32kHz", "44.1kHz", "48kHz",
448};
449
450static const struct soc_enum dac_deemph =
451 SOC_ENUM_SINGLE(WM8961_ADC_DAC_CONTROL_1, 1, 4, dac_deemph_text);
452
453static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
454static const DECLARE_TLV_DB_SCALE(hp_sec_tlv, -700, 100, 0);
455static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
456static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
457static unsigned int boost_tlv[] = {
458 TLV_DB_RANGE_HEAD(4),
459 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
460 1, 1, TLV_DB_SCALE_ITEM(13, 0, 0),
461 2, 2, TLV_DB_SCALE_ITEM(20, 0, 0),
462 3, 3, TLV_DB_SCALE_ITEM(29, 0, 0),
463};
464static const DECLARE_TLV_DB_SCALE(pga_tlv, -2325, 75, 0);
465
466static const struct snd_kcontrol_new wm8961_snd_controls[] = {
467SOC_DOUBLE_R_TLV("Headphone Volume", WM8961_LOUT1_VOLUME, WM8961_ROUT1_VOLUME,
468 0, 127, 0, out_tlv),
469SOC_DOUBLE_TLV("Headphone Secondary Volume", WM8961_ANALOGUE_HP_2,
470 6, 3, 7, 0, hp_sec_tlv),
471SOC_DOUBLE_R("Headphone ZC Switch", WM8961_LOUT1_VOLUME, WM8961_ROUT1_VOLUME,
472 7, 1, 0),
473
474SOC_DOUBLE_R_TLV("Speaker Volume", WM8961_LOUT2_VOLUME, WM8961_ROUT2_VOLUME,
475 0, 127, 0, out_tlv),
476SOC_DOUBLE_R("Speaker ZC Switch", WM8961_LOUT2_VOLUME, WM8961_ROUT2_VOLUME,
477 7, 1, 0),
478SOC_SINGLE("Speaker AC Gain", WM8961_CLASS_D_CONTROL_2, 0, 7, 0),
479
480SOC_SINGLE("DAC x128 OSR Switch", WM8961_ADC_DAC_CONTROL_2, 0, 1, 0),
481SOC_ENUM("DAC Deemphasis", dac_deemph),
482SOC_SINGLE("DAC Soft Mute Switch", WM8961_ADC_DAC_CONTROL_2, 3, 1, 0),
483
484SOC_DOUBLE_R_TLV("Sidetone Volume", WM8961_DSP_SIDETONE_0,
485 WM8961_DSP_SIDETONE_1, 4, 12, 0, sidetone_tlv),
486
487SOC_SINGLE("ADC High Pass Filter Switch", WM8961_ADC_DAC_CONTROL_1, 0, 1, 0),
488SOC_ENUM("ADC High Pass Filter Mode", adc_hpf),
489
490SOC_DOUBLE_R_TLV("Capture Volume",
491 WM8961_LEFT_ADC_VOLUME, WM8961_RIGHT_ADC_VOLUME,
492 1, 119, 0, adc_tlv),
493SOC_DOUBLE_R_TLV("Capture Boost Volume",
494 WM8961_ADCL_SIGNAL_PATH, WM8961_ADCR_SIGNAL_PATH,
495 4, 3, 0, boost_tlv),
496SOC_DOUBLE_R_TLV("Capture PGA Volume",
497 WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
498 0, 62, 0, pga_tlv),
499SOC_DOUBLE_R("Capture PGA ZC Switch",
500 WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
501 6, 1, 1),
502SOC_DOUBLE_R("Capture PGA Switch",
503 WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
504 7, 1, 1),
505};
506
507static const char *sidetone_text[] = {
508 "None", "Left", "Right"
509};
510
511static const struct soc_enum dacl_sidetone =
512 SOC_ENUM_SINGLE(WM8961_DSP_SIDETONE_0, 2, 3, sidetone_text);
513
514static const struct soc_enum dacr_sidetone =
515 SOC_ENUM_SINGLE(WM8961_DSP_SIDETONE_1, 2, 3, sidetone_text);
516
517static const struct snd_kcontrol_new dacl_mux =
518 SOC_DAPM_ENUM("DACL Sidetone", dacl_sidetone);
519
520static const struct snd_kcontrol_new dacr_mux =
521 SOC_DAPM_ENUM("DACR Sidetone", dacr_sidetone);
522
523static const struct snd_soc_dapm_widget wm8961_dapm_widgets[] = {
524SND_SOC_DAPM_INPUT("LINPUT"),
525SND_SOC_DAPM_INPUT("RINPUT"),
526
527SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8961_CLOCKING2, 4, 0, NULL, 0),
528
529SND_SOC_DAPM_PGA("Left Input", WM8961_PWR_MGMT_1, 5, 0, NULL, 0),
530SND_SOC_DAPM_PGA("Right Input", WM8961_PWR_MGMT_1, 4, 0, NULL, 0),
531
532SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", WM8961_PWR_MGMT_1, 3, 0),
533SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", WM8961_PWR_MGMT_1, 2, 0),
534
535SND_SOC_DAPM_MICBIAS("MICBIAS", WM8961_PWR_MGMT_1, 1, 0),
536
537SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &dacl_mux),
538SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &dacr_mux),
539
540SND_SOC_DAPM_DAC("DACL", "HiFi Playback", WM8961_PWR_MGMT_2, 8, 0),
541SND_SOC_DAPM_DAC("DACR", "HiFi Playback", WM8961_PWR_MGMT_2, 7, 0),
542
543/* Handle as a mono path for DCS */
544SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM,
545 4, 0, NULL, 0, wm8961_hp_event,
546 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
547SND_SOC_DAPM_PGA_E("Speaker Output", SND_SOC_NOPM,
548 4, 0, NULL, 0, wm8961_spk_event,
549 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
550
551SND_SOC_DAPM_OUTPUT("HP_L"),
552SND_SOC_DAPM_OUTPUT("HP_R"),
553SND_SOC_DAPM_OUTPUT("SPK_LN"),
554SND_SOC_DAPM_OUTPUT("SPK_LP"),
555SND_SOC_DAPM_OUTPUT("SPK_RN"),
556SND_SOC_DAPM_OUTPUT("SPK_RP"),
557};
558
559
560static const struct snd_soc_dapm_route audio_paths[] = {
561 { "DACL", NULL, "CLK_DSP" },
562 { "DACL", NULL, "DACL Sidetone" },
563 { "DACR", NULL, "CLK_DSP" },
564 { "DACR", NULL, "DACR Sidetone" },
565
566 { "DACL Sidetone", "Left", "ADCL" },
567 { "DACL Sidetone", "Right", "ADCR" },
568
569 { "DACR Sidetone", "Left", "ADCL" },
570 { "DACR Sidetone", "Right", "ADCR" },
571
572 { "HP_L", NULL, "Headphone Output" },
573 { "HP_R", NULL, "Headphone Output" },
574 { "Headphone Output", NULL, "DACL" },
575 { "Headphone Output", NULL, "DACR" },
576
577 { "SPK_LN", NULL, "Speaker Output" },
578 { "SPK_LP", NULL, "Speaker Output" },
579 { "SPK_RN", NULL, "Speaker Output" },
580 { "SPK_RP", NULL, "Speaker Output" },
581
582 { "Speaker Output", NULL, "DACL" },
583 { "Speaker Output", NULL, "DACR" },
584
585 { "ADCL", NULL, "Left Input" },
586 { "ADCL", NULL, "CLK_DSP" },
587 { "ADCR", NULL, "Right Input" },
588 { "ADCR", NULL, "CLK_DSP" },
589
590 { "Left Input", NULL, "LINPUT" },
591 { "Right Input", NULL, "RINPUT" },
592
593};
594
595/* Values for CLK_SYS_RATE */
596static struct {
597 int ratio;
598 u16 val;
599} wm8961_clk_sys_ratio[] = {
600 { 64, 0 },
601 { 128, 1 },
602 { 192, 2 },
603 { 256, 3 },
604 { 384, 4 },
605 { 512, 5 },
606 { 768, 6 },
607 { 1024, 7 },
608 { 1408, 8 },
609 { 1536, 9 },
610};
611
612/* Values for SAMPLE_RATE */
613static struct {
614 int rate;
615 u16 val;
616} wm8961_srate[] = {
617 { 48000, 0 },
618 { 44100, 0 },
619 { 32000, 1 },
620 { 22050, 2 },
621 { 24000, 2 },
622 { 16000, 3 },
623 { 11250, 4 },
624 { 12000, 4 },
625 { 8000, 5 },
626};
627
628static int wm8961_hw_params(struct snd_pcm_substream *substream,
629 struct snd_pcm_hw_params *params,
630 struct snd_soc_dai *dai)
631{
632 struct snd_soc_codec *codec = dai->codec;
633 struct wm8961_priv *wm8961 = codec->private_data;
634 int i, best, target, fs;
635 u16 reg;
636
637 fs = params_rate(params);
638
639 if (!wm8961->sysclk) {
640 dev_err(codec->dev, "MCLK has not been specified\n");
641 return -EINVAL;
642 }
643
644 /* Find the closest sample rate for the filters */
645 best = 0;
646 for (i = 0; i < ARRAY_SIZE(wm8961_srate); i++) {
647 if (abs(wm8961_srate[i].rate - fs) <
648 abs(wm8961_srate[best].rate - fs))
649 best = i;
650 }
651 reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_3);
652 reg &= ~WM8961_SAMPLE_RATE_MASK;
653 reg |= wm8961_srate[best].val;
654 snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_3, reg);
655 dev_dbg(codec->dev, "Selected SRATE %dHz for %dHz\n",
656 wm8961_srate[best].rate, fs);
657
658 /* Select a CLK_SYS/fs ratio equal to or higher than required */
659 target = wm8961->sysclk / fs;
660
661 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && target < 64) {
662 dev_err(codec->dev,
663 "SYSCLK must be at least 64*fs for DAC\n");
664 return -EINVAL;
665 }
666 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && target < 256) {
667 dev_err(codec->dev,
668 "SYSCLK must be at least 256*fs for ADC\n");
669 return -EINVAL;
670 }
671
672 for (i = 0; i < ARRAY_SIZE(wm8961_clk_sys_ratio); i++) {
673 if (wm8961_clk_sys_ratio[i].ratio >= target)
674 break;
675 }
676 if (i == ARRAY_SIZE(wm8961_clk_sys_ratio)) {
677 dev_err(codec->dev, "Unable to generate CLK_SYS_RATE\n");
678 return -EINVAL;
679 }
680 dev_dbg(codec->dev, "Selected CLK_SYS_RATE of %d for %d/%d=%d\n",
681 wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs,
682 wm8961->sysclk / fs);
683
684 reg = snd_soc_read(codec, WM8961_CLOCKING_4);
685 reg &= ~WM8961_CLK_SYS_RATE_MASK;
686 reg |= wm8961_clk_sys_ratio[i].val << WM8961_CLK_SYS_RATE_SHIFT;
687 snd_soc_write(codec, WM8961_CLOCKING_4, reg);
688
689 reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
690 reg &= ~WM8961_WL_MASK;
691 switch (params_format(params)) {
692 case SNDRV_PCM_FORMAT_S16_LE:
693 break;
694 case SNDRV_PCM_FORMAT_S20_3LE:
695 reg |= 1 << WM8961_WL_SHIFT;
696 break;
697 case SNDRV_PCM_FORMAT_S24_LE:
698 reg |= 2 << WM8961_WL_SHIFT;
699 break;
700 case SNDRV_PCM_FORMAT_S32_LE:
701 reg |= 3 << WM8961_WL_SHIFT;
702 break;
703 default:
704 return -EINVAL;
705 }
706 snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, reg);
707
708 /* Sloping stop-band filter is recommended for <= 24kHz */
709 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
710 if (fs <= 24000)
711 reg |= WM8961_DACSLOPE;
712 else
713 reg &= WM8961_DACSLOPE;
714 snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
715
716 return 0;
717}
718
719static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
720 unsigned int freq,
721 int dir)
722{
723 struct snd_soc_codec *codec = dai->codec;
724 struct wm8961_priv *wm8961 = codec->private_data;
725 u16 reg = snd_soc_read(codec, WM8961_CLOCKING1);
726
727 if (freq > 33000000) {
728 dev_err(codec->dev, "MCLK must be <33MHz\n");
729 return -EINVAL;
730 }
731
732 if (freq > 16500000) {
733 dev_dbg(codec->dev, "Using MCLK/2 for %dHz MCLK\n", freq);
734 reg |= WM8961_MCLKDIV;
735 freq /= 2;
736 } else {
737 dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
738 reg &= WM8961_MCLKDIV;
739 }
740
741 snd_soc_write(codec, WM8961_CLOCKING1, reg);
742
743 wm8961->sysclk = freq;
744
745 return 0;
746}
747
748static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
749{
750 struct snd_soc_codec *codec = dai->codec;
751 u16 aif = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
752
753 aif &= ~(WM8961_BCLKINV | WM8961_LRP |
754 WM8961_MS | WM8961_FORMAT_MASK);
755
756 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
757 case SND_SOC_DAIFMT_CBM_CFM:
758 aif |= WM8961_MS;
759 break;
760 case SND_SOC_DAIFMT_CBS_CFS:
761 break;
762 default:
763 return -EINVAL;
764 }
765
766 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
767 case SND_SOC_DAIFMT_RIGHT_J:
768 break;
769
770 case SND_SOC_DAIFMT_LEFT_J:
771 aif |= 1;
772 break;
773
774 case SND_SOC_DAIFMT_I2S:
775 aif |= 2;
776 break;
777
778 case SND_SOC_DAIFMT_DSP_B:
779 aif |= WM8961_LRP;
780 case SND_SOC_DAIFMT_DSP_A:
781 aif |= 3;
782 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
783 case SND_SOC_DAIFMT_NB_NF:
784 case SND_SOC_DAIFMT_IB_NF:
785 break;
786 default:
787 return -EINVAL;
788 }
789 break;
790
791 default:
792 return -EINVAL;
793 }
794
795 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
796 case SND_SOC_DAIFMT_NB_NF:
797 break;
798 case SND_SOC_DAIFMT_NB_IF:
799 aif |= WM8961_LRP;
800 break;
801 case SND_SOC_DAIFMT_IB_NF:
802 aif |= WM8961_BCLKINV;
803 break;
804 case SND_SOC_DAIFMT_IB_IF:
805 aif |= WM8961_BCLKINV | WM8961_LRP;
806 break;
807 default:
808 return -EINVAL;
809 }
810
811 return snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, aif);
812}
813
814static int wm8961_set_tristate(struct snd_soc_dai *dai, int tristate)
815{
816 struct snd_soc_codec *codec = dai->codec;
817 u16 reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_2);
818
819 if (tristate)
820 reg |= WM8961_TRIS;
821 else
822 reg &= ~WM8961_TRIS;
823
824 return snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_2, reg);
825}
826
827static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute)
828{
829 struct snd_soc_codec *codec = dai->codec;
830 u16 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_1);
831
832 if (mute)
833 reg |= WM8961_DACMU;
834 else
835 reg &= ~WM8961_DACMU;
836
837 msleep(17);
838
839 return snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_1, reg);
840}
841
842static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
843{
844 struct snd_soc_codec *codec = dai->codec;
845 u16 reg;
846
847 switch (div_id) {
848 case WM8961_BCLK:
849 reg = snd_soc_read(codec, WM8961_CLOCKING2);
850 reg &= ~WM8961_BCLKDIV_MASK;
851 reg |= div;
852 snd_soc_write(codec, WM8961_CLOCKING2, reg);
853 break;
854
855 case WM8961_LRCLK:
856 reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_2);
857 reg &= ~WM8961_LRCLK_RATE_MASK;
858 reg |= div;
859 snd_soc_write(codec, WM8961_AUDIO_INTERFACE_2, reg);
860 break;
861
862 default:
863 return -EINVAL;
864 }
865
866 return 0;
867}
868
869static int wm8961_set_bias_level(struct snd_soc_codec *codec,
870 enum snd_soc_bias_level level)
871{
872 u16 reg;
873
874 /* This is all slightly unusual since we have no bypass paths
875 * and the output amplifier structure means we can just slam
876 * the biases straight up rather than having to ramp them
877 * slowly.
878 */
879 switch (level) {
880 case SND_SOC_BIAS_ON:
881 break;
882
883 case SND_SOC_BIAS_PREPARE:
884 if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
885 /* Enable bias generation */
886 reg = snd_soc_read(codec, WM8961_ANTI_POP);
887 reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN;
888 snd_soc_write(codec, WM8961_ANTI_POP, reg);
889
890 /* VMID=2*50k, VREF */
891 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
892 reg &= ~WM8961_VMIDSEL_MASK;
893 reg |= (1 << WM8961_VMIDSEL_SHIFT) | WM8961_VREF;
894 snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
895 }
896 break;
897
898 case SND_SOC_BIAS_STANDBY:
899 if (codec->bias_level == SND_SOC_BIAS_PREPARE) {
900 /* VREF off */
901 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
902 reg &= ~WM8961_VREF;
903 snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
904
905 /* Bias generation off */
906 reg = snd_soc_read(codec, WM8961_ANTI_POP);
907 reg &= ~(WM8961_BUFIOEN | WM8961_BUFDCOPEN);
908 snd_soc_write(codec, WM8961_ANTI_POP, reg);
909
910 /* VMID off */
911 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
912 reg &= ~WM8961_VMIDSEL_MASK;
913 snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
914 }
915 break;
916
917 case SND_SOC_BIAS_OFF:
918 break;
919 }
920
921 codec->bias_level = level;
922
923 return 0;
924}
925
926
927#define WM8961_RATES SNDRV_PCM_RATE_8000_48000
928
929#define WM8961_FORMATS \
930 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
931 SNDRV_PCM_FMTBIT_S24_LE)
932
933static struct snd_soc_dai_ops wm8961_dai_ops = {
934 .hw_params = wm8961_hw_params,
935 .set_sysclk = wm8961_set_sysclk,
936 .set_fmt = wm8961_set_fmt,
937 .digital_mute = wm8961_digital_mute,
938 .set_tristate = wm8961_set_tristate,
939 .set_clkdiv = wm8961_set_clkdiv,
940};
941
942struct snd_soc_dai wm8961_dai = {
943 .name = "WM8961",
944 .playback = {
945 .stream_name = "HiFi Playback",
946 .channels_min = 1,
947 .channels_max = 2,
948 .rates = WM8961_RATES,
949 .formats = WM8961_FORMATS,},
950 .capture = {
951 .stream_name = "HiFi Capture",
952 .channels_min = 1,
953 .channels_max = 2,
954 .rates = WM8961_RATES,
955 .formats = WM8961_FORMATS,},
956 .ops = &wm8961_dai_ops,
957};
958EXPORT_SYMBOL_GPL(wm8961_dai);
959
960
961static struct snd_soc_codec *wm8961_codec;
962
963static int wm8961_probe(struct platform_device *pdev)
964{
965 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
966 struct snd_soc_codec *codec;
967 int ret = 0;
968
969 if (wm8961_codec == NULL) {
970 dev_err(&pdev->dev, "Codec device not registered\n");
971 return -ENODEV;
972 }
973
974 socdev->card->codec = wm8961_codec;
975 codec = wm8961_codec;
976
977 /* register pcms */
978 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
979 if (ret < 0) {
980 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
981 goto pcm_err;
982 }
983
984 snd_soc_add_controls(codec, wm8961_snd_controls,
985 ARRAY_SIZE(wm8961_snd_controls));
986 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
987 ARRAY_SIZE(wm8961_dapm_widgets));
988 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
997 return ret;
998
999card_err:
1000 snd_soc_free_pcms(socdev);
1001 snd_soc_dapm_free(socdev);
1002pcm_err:
1003 return ret;
1004}
1005
1006static int wm8961_remove(struct platform_device *pdev)
1007{
1008 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1009
1010 snd_soc_free_pcms(socdev);
1011 snd_soc_dapm_free(socdev);
1012
1013 return 0;
1014}
1015
1016#ifdef CONFIG_PM
1017static int wm8961_suspend(struct platform_device *pdev, pm_message_t state)
1018{
1019 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1020 struct snd_soc_codec *codec = socdev->card->codec;
1021
1022 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
1023
1024 return 0;
1025}
1026
1027static int wm8961_resume(struct platform_device *pdev)
1028{
1029 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1030 struct snd_soc_codec *codec = socdev->card->codec;
1031 u16 *reg_cache = codec->reg_cache;
1032 int i;
1033
1034 for (i = 0; i < codec->reg_cache_size; i++) {
1035 if (i == WM8961_SOFTWARE_RESET)
1036 continue;
1037
1038 snd_soc_write(codec, i, reg_cache[i]);
1039 }
1040
1041 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1042
1043 return 0;
1044}
1045#else
1046#define wm8961_suspend NULL
1047#define wm8961_resume NULL
1048#endif
1049
1050struct snd_soc_codec_device soc_codec_dev_wm8961 = {
1051 .probe = wm8961_probe,
1052 .remove = wm8961_remove,
1053 .suspend = wm8961_suspend,
1054 .resume = wm8961_resume,
1055};
1056EXPORT_SYMBOL_GPL(soc_codec_dev_wm8961);
1057
1058static int wm8961_register(struct wm8961_priv *wm8961)
1059{
1060 struct snd_soc_codec *codec = &wm8961->codec;
1061 int ret;
1062 u16 reg;
1063
1064 if (wm8961_codec) {
1065 dev_err(codec->dev, "Another WM8961 is registered\n");
1066 ret = -EINVAL;
1067 goto err;
1068 }
1069
1070 mutex_init(&codec->mutex);
1071 INIT_LIST_HEAD(&codec->dapm_widgets);
1072 INIT_LIST_HEAD(&codec->dapm_paths);
1073
1074 codec->private_data = wm8961;
1075 codec->name = "WM8961";
1076 codec->owner = THIS_MODULE;
1077 codec->dai = &wm8961_dai;
1078 codec->num_dai = 1;
1079 codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache);
1080 codec->reg_cache = &wm8961->reg_cache;
1081 codec->bias_level = SND_SOC_BIAS_OFF;
1082 codec->set_bias_level = wm8961_set_bias_level;
1083 codec->volatile_register = wm8961_volatile_register;
1084
1085 memcpy(codec->reg_cache, wm8961_reg_defaults,
1086 sizeof(wm8961_reg_defaults));
1087
1088 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1089 if (ret != 0) {
1090 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1091 goto err;
1092 }
1093
1094 reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
1095 if (reg != 0x1801) {
1096 dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
1097 ret = -EINVAL;
1098 goto err;
1099 }
1100
1101 /* This isn't volatile - readback doesn't correspond to write */
1102 reg = codec->hw_read(codec, WM8961_RIGHT_INPUT_VOLUME);
1103 dev_info(codec->dev, "WM8961 family %d revision %c\n",
1104 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
1105 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
1106 + 'A');
1107
1108 ret = wm8961_reset(codec);
1109 if (ret < 0) {
1110 dev_err(codec->dev, "Failed to issue reset\n");
1111 return ret;
1112 }
1113
1114 /* Enable class W */
1115 reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
1116 reg |= WM8961_CP_DYN_PWR_MASK;
1117 snd_soc_write(codec, WM8961_CHARGE_PUMP_B, reg);
1118
1119 /* Latch volume update bits (right channel only, we always
1120 * write both out) and default ZC on. */
1121 reg = snd_soc_read(codec, WM8961_ROUT1_VOLUME);
1122 snd_soc_write(codec, WM8961_ROUT1_VOLUME,
1123 reg | WM8961_LO1ZC | WM8961_OUT1VU);
1124 snd_soc_write(codec, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC);
1125 reg = snd_soc_read(codec, WM8961_ROUT2_VOLUME);
1126 snd_soc_write(codec, WM8961_ROUT2_VOLUME,
1127 reg | WM8961_SPKRZC | WM8961_SPKVU);
1128 snd_soc_write(codec, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC);
1129
1130 reg = snd_soc_read(codec, WM8961_RIGHT_ADC_VOLUME);
1131 snd_soc_write(codec, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU);
1132 reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
1133 snd_soc_write(codec, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU);
1134
1135 /* Use soft mute by default */
1136 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
1137 reg |= WM8961_DACSMM;
1138 snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
1139
1140 /* Use automatic clocking mode by default; for now this is all
1141 * we support.
1142 */
1143 reg = snd_soc_read(codec, WM8961_CLOCKING_3);
1144 reg &= ~WM8961_MANUAL_MODE;
1145 snd_soc_write(codec, WM8961_CLOCKING_3, reg);
1146
1147 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1148
1149 wm8961_dai.dev = codec->dev;
1150
1151 wm8961_codec = codec;
1152
1153 ret = snd_soc_register_codec(codec);
1154 if (ret != 0) {
1155 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1156 return ret;
1157 }
1158
1159 ret = snd_soc_register_dai(&wm8961_dai);
1160 if (ret != 0) {
1161 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1162 snd_soc_unregister_codec(codec);
1163 return ret;
1164 }
1165
1166 return 0;
1167
1168err:
1169 kfree(wm8961);
1170 return ret;
1171}
1172
1173static void wm8961_unregister(struct wm8961_priv *wm8961)
1174{
1175 wm8961_set_bias_level(&wm8961->codec, SND_SOC_BIAS_OFF);
1176 snd_soc_unregister_dai(&wm8961_dai);
1177 snd_soc_unregister_codec(&wm8961->codec);
1178 kfree(wm8961);
1179 wm8961_codec = NULL;
1180}
1181
1182static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
1183 const struct i2c_device_id *id)
1184{
1185 struct wm8961_priv *wm8961;
1186 struct snd_soc_codec *codec;
1187
1188 wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL);
1189 if (wm8961 == NULL)
1190 return -ENOMEM;
1191
1192 codec = &wm8961->codec;
1193
1194 i2c_set_clientdata(i2c, wm8961);
1195 codec->control_data = i2c;
1196
1197 codec->dev = &i2c->dev;
1198
1199 return wm8961_register(wm8961);
1200}
1201
1202static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1203{
1204 struct wm8961_priv *wm8961 = i2c_get_clientdata(client);
1205 wm8961_unregister(wm8961);
1206 return 0;
1207}
1208
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[] = {
1225 { "wm8961", 0 },
1226 { }
1227};
1228MODULE_DEVICE_TABLE(i2c, wm8961_i2c_id);
1229
1230static struct i2c_driver wm8961_i2c_driver = {
1231 .driver = {
1232 .name = "wm8961",
1233 .owner = THIS_MODULE,
1234 },
1235 .probe = wm8961_i2c_probe,
1236 .remove = __devexit_p(wm8961_i2c_remove),
1237 .suspend = wm8961_i2c_suspend,
1238 .resume = wm8961_i2c_resume,
1239 .id_table = wm8961_i2c_id,
1240};
1241
1242static int __init wm8961_modinit(void)
1243{
1244 int ret;
1245
1246 ret = i2c_add_driver(&wm8961_i2c_driver);
1247 if (ret != 0) {
1248 printk(KERN_ERR "Failed to register WM8961 I2C driver: %d\n",
1249 ret);
1250 }
1251
1252 return ret;
1253}
1254module_init(wm8961_modinit);
1255
1256static void __exit wm8961_exit(void)
1257{
1258 i2c_del_driver(&wm8961_i2c_driver);
1259}
1260module_exit(wm8961_exit);
1261
1262
1263MODULE_DESCRIPTION("ASoC WM8961 driver");
1264MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1265MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8961.h b/sound/soc/codecs/wm8961.h
new file mode 100644
index 000000000000..5513bfd720d6
--- /dev/null
+++ b/sound/soc/codecs/wm8961.h
@@ -0,0 +1,866 @@
1/*
2 * wm8961.h -- WM8961 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 _WM8961_H
10#define _WM8961_H
11
12#include <sound/soc.h>
13
14extern struct snd_soc_codec_device soc_codec_dev_wm8961;
15extern struct snd_soc_dai wm8961_dai;
16
17#define WM8961_BCLK 1
18#define WM8961_LRCLK 2
19
20#define WM8961_BCLK_DIV_1 0
21#define WM8961_BCLK_DIV_1_5 1
22#define WM8961_BCLK_DIV_2 2
23#define WM8961_BCLK_DIV_3 3
24#define WM8961_BCLK_DIV_4 4
25#define WM8961_BCLK_DIV_5_5 5
26#define WM8961_BCLK_DIV_6 6
27#define WM8961_BCLK_DIV_8 7
28#define WM8961_BCLK_DIV_11 8
29#define WM8961_BCLK_DIV_12 9
30#define WM8961_BCLK_DIV_16 10
31#define WM8961_BCLK_DIV_24 11
32#define WM8961_BCLK_DIV_32 13
33
34
35/*
36 * Register values.
37 */
38#define WM8961_LEFT_INPUT_VOLUME 0x00
39#define WM8961_RIGHT_INPUT_VOLUME 0x01
40#define WM8961_LOUT1_VOLUME 0x02
41#define WM8961_ROUT1_VOLUME 0x03
42#define WM8961_CLOCKING1 0x04
43#define WM8961_ADC_DAC_CONTROL_1 0x05
44#define WM8961_ADC_DAC_CONTROL_2 0x06
45#define WM8961_AUDIO_INTERFACE_0 0x07
46#define WM8961_CLOCKING2 0x08
47#define WM8961_AUDIO_INTERFACE_1 0x09
48#define WM8961_LEFT_DAC_VOLUME 0x0A
49#define WM8961_RIGHT_DAC_VOLUME 0x0B
50#define WM8961_AUDIO_INTERFACE_2 0x0E
51#define WM8961_SOFTWARE_RESET 0x0F
52#define WM8961_ALC1 0x11
53#define WM8961_ALC2 0x12
54#define WM8961_ALC3 0x13
55#define WM8961_NOISE_GATE 0x14
56#define WM8961_LEFT_ADC_VOLUME 0x15
57#define WM8961_RIGHT_ADC_VOLUME 0x16
58#define WM8961_ADDITIONAL_CONTROL_1 0x17
59#define WM8961_ADDITIONAL_CONTROL_2 0x18
60#define WM8961_PWR_MGMT_1 0x19
61#define WM8961_PWR_MGMT_2 0x1A
62#define WM8961_ADDITIONAL_CONTROL_3 0x1B
63#define WM8961_ANTI_POP 0x1C
64#define WM8961_CLOCKING_3 0x1E
65#define WM8961_ADCL_SIGNAL_PATH 0x20
66#define WM8961_ADCR_SIGNAL_PATH 0x21
67#define WM8961_LOUT2_VOLUME 0x28
68#define WM8961_ROUT2_VOLUME 0x29
69#define WM8961_PWR_MGMT_3 0x2F
70#define WM8961_ADDITIONAL_CONTROL_4 0x30
71#define WM8961_CLASS_D_CONTROL_1 0x31
72#define WM8961_CLASS_D_CONTROL_2 0x33
73#define WM8961_CLOCKING_4 0x38
74#define WM8961_DSP_SIDETONE_0 0x39
75#define WM8961_DSP_SIDETONE_1 0x3A
76#define WM8961_DC_SERVO_0 0x3C
77#define WM8961_DC_SERVO_1 0x3D
78#define WM8961_DC_SERVO_3 0x3F
79#define WM8961_DC_SERVO_5 0x41
80#define WM8961_ANALOGUE_PGA_BIAS 0x44
81#define WM8961_ANALOGUE_HP_0 0x45
82#define WM8961_ANALOGUE_HP_2 0x47
83#define WM8961_CHARGE_PUMP_1 0x48
84#define WM8961_CHARGE_PUMP_B 0x52
85#define WM8961_WRITE_SEQUENCER_1 0x57
86#define WM8961_WRITE_SEQUENCER_2 0x58
87#define WM8961_WRITE_SEQUENCER_3 0x59
88#define WM8961_WRITE_SEQUENCER_4 0x5A
89#define WM8961_WRITE_SEQUENCER_5 0x5B
90#define WM8961_WRITE_SEQUENCER_6 0x5C
91#define WM8961_WRITE_SEQUENCER_7 0x5D
92#define WM8961_GENERAL_TEST_1 0xFC
93
94
95/*
96 * Field Definitions.
97 */
98
99/*
100 * R0 (0x00) - Left Input volume
101 */
102#define WM8961_IPVU 0x0100 /* IPVU */
103#define WM8961_IPVU_MASK 0x0100 /* IPVU */
104#define WM8961_IPVU_SHIFT 8 /* IPVU */
105#define WM8961_IPVU_WIDTH 1 /* IPVU */
106#define WM8961_LINMUTE 0x0080 /* LINMUTE */
107#define WM8961_LINMUTE_MASK 0x0080 /* LINMUTE */
108#define WM8961_LINMUTE_SHIFT 7 /* LINMUTE */
109#define WM8961_LINMUTE_WIDTH 1 /* LINMUTE */
110#define WM8961_LIZC 0x0040 /* LIZC */
111#define WM8961_LIZC_MASK 0x0040 /* LIZC */
112#define WM8961_LIZC_SHIFT 6 /* LIZC */
113#define WM8961_LIZC_WIDTH 1 /* LIZC */
114#define WM8961_LINVOL_MASK 0x003F /* LINVOL - [5:0] */
115#define WM8961_LINVOL_SHIFT 0 /* LINVOL - [5:0] */
116#define WM8961_LINVOL_WIDTH 6 /* LINVOL - [5:0] */
117
118/*
119 * R1 (0x01) - Right Input volume
120 */
121#define WM8961_DEVICE_ID_MASK 0xF000 /* DEVICE_ID - [15:12] */
122#define WM8961_DEVICE_ID_SHIFT 12 /* DEVICE_ID - [15:12] */
123#define WM8961_DEVICE_ID_WIDTH 4 /* DEVICE_ID - [15:12] */
124#define WM8961_CHIP_REV_MASK 0x0E00 /* CHIP_REV - [11:9] */
125#define WM8961_CHIP_REV_SHIFT 9 /* CHIP_REV - [11:9] */
126#define WM8961_CHIP_REV_WIDTH 3 /* CHIP_REV - [11:9] */
127#define WM8961_IPVU 0x0100 /* IPVU */
128#define WM8961_IPVU_MASK 0x0100 /* IPVU */
129#define WM8961_IPVU_SHIFT 8 /* IPVU */
130#define WM8961_IPVU_WIDTH 1 /* IPVU */
131#define WM8961_RINMUTE 0x0080 /* RINMUTE */
132#define WM8961_RINMUTE_MASK 0x0080 /* RINMUTE */
133#define WM8961_RINMUTE_SHIFT 7 /* RINMUTE */
134#define WM8961_RINMUTE_WIDTH 1 /* RINMUTE */
135#define WM8961_RIZC 0x0040 /* RIZC */
136#define WM8961_RIZC_MASK 0x0040 /* RIZC */
137#define WM8961_RIZC_SHIFT 6 /* RIZC */
138#define WM8961_RIZC_WIDTH 1 /* RIZC */
139#define WM8961_RINVOL_MASK 0x003F /* RINVOL - [5:0] */
140#define WM8961_RINVOL_SHIFT 0 /* RINVOL - [5:0] */
141#define WM8961_RINVOL_WIDTH 6 /* RINVOL - [5:0] */
142
143/*
144 * R2 (0x02) - LOUT1 volume
145 */
146#define WM8961_OUT1VU 0x0100 /* OUT1VU */
147#define WM8961_OUT1VU_MASK 0x0100 /* OUT1VU */
148#define WM8961_OUT1VU_SHIFT 8 /* OUT1VU */
149#define WM8961_OUT1VU_WIDTH 1 /* OUT1VU */
150#define WM8961_LO1ZC 0x0080 /* LO1ZC */
151#define WM8961_LO1ZC_MASK 0x0080 /* LO1ZC */
152#define WM8961_LO1ZC_SHIFT 7 /* LO1ZC */
153#define WM8961_LO1ZC_WIDTH 1 /* LO1ZC */
154#define WM8961_LOUT1VOL_MASK 0x007F /* LOUT1VOL - [6:0] */
155#define WM8961_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [6:0] */
156#define WM8961_LOUT1VOL_WIDTH 7 /* LOUT1VOL - [6:0] */
157
158/*
159 * R3 (0x03) - ROUT1 volume
160 */
161#define WM8961_OUT1VU 0x0100 /* OUT1VU */
162#define WM8961_OUT1VU_MASK 0x0100 /* OUT1VU */
163#define WM8961_OUT1VU_SHIFT 8 /* OUT1VU */
164#define WM8961_OUT1VU_WIDTH 1 /* OUT1VU */
165#define WM8961_RO1ZC 0x0080 /* RO1ZC */
166#define WM8961_RO1ZC_MASK 0x0080 /* RO1ZC */
167#define WM8961_RO1ZC_SHIFT 7 /* RO1ZC */
168#define WM8961_RO1ZC_WIDTH 1 /* RO1ZC */
169#define WM8961_ROUT1VOL_MASK 0x007F /* ROUT1VOL - [6:0] */
170#define WM8961_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [6:0] */
171#define WM8961_ROUT1VOL_WIDTH 7 /* ROUT1VOL - [6:0] */
172
173/*
174 * R4 (0x04) - Clocking1
175 */
176#define WM8961_ADCDIV_MASK 0x01C0 /* ADCDIV - [8:6] */
177#define WM8961_ADCDIV_SHIFT 6 /* ADCDIV - [8:6] */
178#define WM8961_ADCDIV_WIDTH 3 /* ADCDIV - [8:6] */
179#define WM8961_DACDIV_MASK 0x0038 /* DACDIV - [5:3] */
180#define WM8961_DACDIV_SHIFT 3 /* DACDIV - [5:3] */
181#define WM8961_DACDIV_WIDTH 3 /* DACDIV - [5:3] */
182#define WM8961_MCLKDIV 0x0004 /* MCLKDIV */
183#define WM8961_MCLKDIV_MASK 0x0004 /* MCLKDIV */
184#define WM8961_MCLKDIV_SHIFT 2 /* MCLKDIV */
185#define WM8961_MCLKDIV_WIDTH 1 /* MCLKDIV */
186
187/*
188 * R5 (0x05) - ADC & DAC Control 1
189 */
190#define WM8961_ADCPOL_MASK 0x0060 /* ADCPOL - [6:5] */
191#define WM8961_ADCPOL_SHIFT 5 /* ADCPOL - [6:5] */
192#define WM8961_ADCPOL_WIDTH 2 /* ADCPOL - [6:5] */
193#define WM8961_DACMU 0x0008 /* DACMU */
194#define WM8961_DACMU_MASK 0x0008 /* DACMU */
195#define WM8961_DACMU_SHIFT 3 /* DACMU */
196#define WM8961_DACMU_WIDTH 1 /* DACMU */
197#define WM8961_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
198#define WM8961_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
199#define WM8961_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
200#define WM8961_ADCHPD 0x0001 /* ADCHPD */
201#define WM8961_ADCHPD_MASK 0x0001 /* ADCHPD */
202#define WM8961_ADCHPD_SHIFT 0 /* ADCHPD */
203#define WM8961_ADCHPD_WIDTH 1 /* ADCHPD */
204
205/*
206 * R6 (0x06) - ADC & DAC Control 2
207 */
208#define WM8961_ADC_HPF_CUT_MASK 0x0180 /* ADC_HPF_CUT - [8:7] */
209#define WM8961_ADC_HPF_CUT_SHIFT 7 /* ADC_HPF_CUT - [8:7] */
210#define WM8961_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [8:7] */
211#define WM8961_DACPOL_MASK 0x0060 /* DACPOL - [6:5] */
212#define WM8961_DACPOL_SHIFT 5 /* DACPOL - [6:5] */
213#define WM8961_DACPOL_WIDTH 2 /* DACPOL - [6:5] */
214#define WM8961_DACSMM 0x0008 /* DACSMM */
215#define WM8961_DACSMM_MASK 0x0008 /* DACSMM */
216#define WM8961_DACSMM_SHIFT 3 /* DACSMM */
217#define WM8961_DACSMM_WIDTH 1 /* DACSMM */
218#define WM8961_DACMR 0x0004 /* DACMR */
219#define WM8961_DACMR_MASK 0x0004 /* DACMR */
220#define WM8961_DACMR_SHIFT 2 /* DACMR */
221#define WM8961_DACMR_WIDTH 1 /* DACMR */
222#define WM8961_DACSLOPE 0x0002 /* DACSLOPE */
223#define WM8961_DACSLOPE_MASK 0x0002 /* DACSLOPE */
224#define WM8961_DACSLOPE_SHIFT 1 /* DACSLOPE */
225#define WM8961_DACSLOPE_WIDTH 1 /* DACSLOPE */
226#define WM8961_DAC_OSR128 0x0001 /* DAC_OSR128 */
227#define WM8961_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
228#define WM8961_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
229#define WM8961_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
230
231/*
232 * R7 (0x07) - Audio Interface 0
233 */
234#define WM8961_ALRSWAP 0x0100 /* ALRSWAP */
235#define WM8961_ALRSWAP_MASK 0x0100 /* ALRSWAP */
236#define WM8961_ALRSWAP_SHIFT 8 /* ALRSWAP */
237#define WM8961_ALRSWAP_WIDTH 1 /* ALRSWAP */
238#define WM8961_BCLKINV 0x0080 /* BCLKINV */
239#define WM8961_BCLKINV_MASK 0x0080 /* BCLKINV */
240#define WM8961_BCLKINV_SHIFT 7 /* BCLKINV */
241#define WM8961_BCLKINV_WIDTH 1 /* BCLKINV */
242#define WM8961_MS 0x0040 /* MS */
243#define WM8961_MS_MASK 0x0040 /* MS */
244#define WM8961_MS_SHIFT 6 /* MS */
245#define WM8961_MS_WIDTH 1 /* MS */
246#define WM8961_DLRSWAP 0x0020 /* DLRSWAP */
247#define WM8961_DLRSWAP_MASK 0x0020 /* DLRSWAP */
248#define WM8961_DLRSWAP_SHIFT 5 /* DLRSWAP */
249#define WM8961_DLRSWAP_WIDTH 1 /* DLRSWAP */
250#define WM8961_LRP 0x0010 /* LRP */
251#define WM8961_LRP_MASK 0x0010 /* LRP */
252#define WM8961_LRP_SHIFT 4 /* LRP */
253#define WM8961_LRP_WIDTH 1 /* LRP */
254#define WM8961_WL_MASK 0x000C /* WL - [3:2] */
255#define WM8961_WL_SHIFT 2 /* WL - [3:2] */
256#define WM8961_WL_WIDTH 2 /* WL - [3:2] */
257#define WM8961_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
258#define WM8961_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
259#define WM8961_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
260
261/*
262 * R8 (0x08) - Clocking2
263 */
264#define WM8961_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
265#define WM8961_DCLKDIV_SHIFT 6 /* DCLKDIV - [8:6] */
266#define WM8961_DCLKDIV_WIDTH 3 /* DCLKDIV - [8:6] */
267#define WM8961_CLK_SYS_ENA 0x0020 /* CLK_SYS_ENA */
268#define WM8961_CLK_SYS_ENA_MASK 0x0020 /* CLK_SYS_ENA */
269#define WM8961_CLK_SYS_ENA_SHIFT 5 /* CLK_SYS_ENA */
270#define WM8961_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
271#define WM8961_CLK_DSP_ENA 0x0010 /* CLK_DSP_ENA */
272#define WM8961_CLK_DSP_ENA_MASK 0x0010 /* CLK_DSP_ENA */
273#define WM8961_CLK_DSP_ENA_SHIFT 4 /* CLK_DSP_ENA */
274#define WM8961_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
275#define WM8961_BCLKDIV_MASK 0x000F /* BCLKDIV - [3:0] */
276#define WM8961_BCLKDIV_SHIFT 0 /* BCLKDIV - [3:0] */
277#define WM8961_BCLKDIV_WIDTH 4 /* BCLKDIV - [3:0] */
278
279/*
280 * R9 (0x09) - Audio Interface 1
281 */
282#define WM8961_DACCOMP_MASK 0x0018 /* DACCOMP - [4:3] */
283#define WM8961_DACCOMP_SHIFT 3 /* DACCOMP - [4:3] */
284#define WM8961_DACCOMP_WIDTH 2 /* DACCOMP - [4:3] */
285#define WM8961_ADCCOMP_MASK 0x0006 /* ADCCOMP - [2:1] */
286#define WM8961_ADCCOMP_SHIFT 1 /* ADCCOMP - [2:1] */
287#define WM8961_ADCCOMP_WIDTH 2 /* ADCCOMP - [2:1] */
288#define WM8961_LOOPBACK 0x0001 /* LOOPBACK */
289#define WM8961_LOOPBACK_MASK 0x0001 /* LOOPBACK */
290#define WM8961_LOOPBACK_SHIFT 0 /* LOOPBACK */
291#define WM8961_LOOPBACK_WIDTH 1 /* LOOPBACK */
292
293/*
294 * R10 (0x0A) - Left DAC volume
295 */
296#define WM8961_DACVU 0x0100 /* DACVU */
297#define WM8961_DACVU_MASK 0x0100 /* DACVU */
298#define WM8961_DACVU_SHIFT 8 /* DACVU */
299#define WM8961_DACVU_WIDTH 1 /* DACVU */
300#define WM8961_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */
301#define WM8961_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */
302#define WM8961_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */
303
304/*
305 * R11 (0x0B) - Right DAC volume
306 */
307#define WM8961_DACVU 0x0100 /* DACVU */
308#define WM8961_DACVU_MASK 0x0100 /* DACVU */
309#define WM8961_DACVU_SHIFT 8 /* DACVU */
310#define WM8961_DACVU_WIDTH 1 /* DACVU */
311#define WM8961_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */
312#define WM8961_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */
313#define WM8961_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */
314
315/*
316 * R14 (0x0E) - Audio Interface 2
317 */
318#define WM8961_LRCLK_RATE_MASK 0x01FF /* LRCLK_RATE - [8:0] */
319#define WM8961_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [8:0] */
320#define WM8961_LRCLK_RATE_WIDTH 9 /* LRCLK_RATE - [8:0] */
321
322/*
323 * R15 (0x0F) - Software Reset
324 */
325#define WM8961_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
326#define WM8961_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
327#define WM8961_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
328
329/*
330 * R17 (0x11) - ALC1
331 */
332#define WM8961_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
333#define WM8961_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
334#define WM8961_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
335#define WM8961_MAXGAIN_MASK 0x0070 /* MAXGAIN - [6:4] */
336#define WM8961_MAXGAIN_SHIFT 4 /* MAXGAIN - [6:4] */
337#define WM8961_MAXGAIN_WIDTH 3 /* MAXGAIN - [6:4] */
338#define WM8961_ALCL_MASK 0x000F /* ALCL - [3:0] */
339#define WM8961_ALCL_SHIFT 0 /* ALCL - [3:0] */
340#define WM8961_ALCL_WIDTH 4 /* ALCL - [3:0] */
341
342/*
343 * R18 (0x12) - ALC2
344 */
345#define WM8961_ALCZC 0x0080 /* ALCZC */
346#define WM8961_ALCZC_MASK 0x0080 /* ALCZC */
347#define WM8961_ALCZC_SHIFT 7 /* ALCZC */
348#define WM8961_ALCZC_WIDTH 1 /* ALCZC */
349#define WM8961_MINGAIN_MASK 0x0070 /* MINGAIN - [6:4] */
350#define WM8961_MINGAIN_SHIFT 4 /* MINGAIN - [6:4] */
351#define WM8961_MINGAIN_WIDTH 3 /* MINGAIN - [6:4] */
352#define WM8961_HLD_MASK 0x000F /* HLD - [3:0] */
353#define WM8961_HLD_SHIFT 0 /* HLD - [3:0] */
354#define WM8961_HLD_WIDTH 4 /* HLD - [3:0] */
355
356/*
357 * R19 (0x13) - ALC3
358 */
359#define WM8961_ALCMODE 0x0100 /* ALCMODE */
360#define WM8961_ALCMODE_MASK 0x0100 /* ALCMODE */
361#define WM8961_ALCMODE_SHIFT 8 /* ALCMODE */
362#define WM8961_ALCMODE_WIDTH 1 /* ALCMODE */
363#define WM8961_DCY_MASK 0x00F0 /* DCY - [7:4] */
364#define WM8961_DCY_SHIFT 4 /* DCY - [7:4] */
365#define WM8961_DCY_WIDTH 4 /* DCY - [7:4] */
366#define WM8961_ATK_MASK 0x000F /* ATK - [3:0] */
367#define WM8961_ATK_SHIFT 0 /* ATK - [3:0] */
368#define WM8961_ATK_WIDTH 4 /* ATK - [3:0] */
369
370/*
371 * R20 (0x14) - Noise Gate
372 */
373#define WM8961_NGTH_MASK 0x00F8 /* NGTH - [7:3] */
374#define WM8961_NGTH_SHIFT 3 /* NGTH - [7:3] */
375#define WM8961_NGTH_WIDTH 5 /* NGTH - [7:3] */
376#define WM8961_NGG 0x0002 /* NGG */
377#define WM8961_NGG_MASK 0x0002 /* NGG */
378#define WM8961_NGG_SHIFT 1 /* NGG */
379#define WM8961_NGG_WIDTH 1 /* NGG */
380#define WM8961_NGAT 0x0001 /* NGAT */
381#define WM8961_NGAT_MASK 0x0001 /* NGAT */
382#define WM8961_NGAT_SHIFT 0 /* NGAT */
383#define WM8961_NGAT_WIDTH 1 /* NGAT */
384
385/*
386 * R21 (0x15) - Left ADC volume
387 */
388#define WM8961_ADCVU 0x0100 /* ADCVU */
389#define WM8961_ADCVU_MASK 0x0100 /* ADCVU */
390#define WM8961_ADCVU_SHIFT 8 /* ADCVU */
391#define WM8961_ADCVU_WIDTH 1 /* ADCVU */
392#define WM8961_LADCVOL_MASK 0x00FF /* LADCVOL - [7:0] */
393#define WM8961_LADCVOL_SHIFT 0 /* LADCVOL - [7:0] */
394#define WM8961_LADCVOL_WIDTH 8 /* LADCVOL - [7:0] */
395
396/*
397 * R22 (0x16) - Right ADC volume
398 */
399#define WM8961_ADCVU 0x0100 /* ADCVU */
400#define WM8961_ADCVU_MASK 0x0100 /* ADCVU */
401#define WM8961_ADCVU_SHIFT 8 /* ADCVU */
402#define WM8961_ADCVU_WIDTH 1 /* ADCVU */
403#define WM8961_RADCVOL_MASK 0x00FF /* RADCVOL - [7:0] */
404#define WM8961_RADCVOL_SHIFT 0 /* RADCVOL - [7:0] */
405#define WM8961_RADCVOL_WIDTH 8 /* RADCVOL - [7:0] */
406
407/*
408 * R23 (0x17) - Additional control(1)
409 */
410#define WM8961_TSDEN 0x0100 /* TSDEN */
411#define WM8961_TSDEN_MASK 0x0100 /* TSDEN */
412#define WM8961_TSDEN_SHIFT 8 /* TSDEN */
413#define WM8961_TSDEN_WIDTH 1 /* TSDEN */
414#define WM8961_DMONOMIX 0x0010 /* DMONOMIX */
415#define WM8961_DMONOMIX_MASK 0x0010 /* DMONOMIX */
416#define WM8961_DMONOMIX_SHIFT 4 /* DMONOMIX */
417#define WM8961_DMONOMIX_WIDTH 1 /* DMONOMIX */
418#define WM8961_TOEN 0x0001 /* TOEN */
419#define WM8961_TOEN_MASK 0x0001 /* TOEN */
420#define WM8961_TOEN_SHIFT 0 /* TOEN */
421#define WM8961_TOEN_WIDTH 1 /* TOEN */
422
423/*
424 * R24 (0x18) - Additional control(2)
425 */
426#define WM8961_TRIS 0x0008 /* TRIS */
427#define WM8961_TRIS_MASK 0x0008 /* TRIS */
428#define WM8961_TRIS_SHIFT 3 /* TRIS */
429#define WM8961_TRIS_WIDTH 1 /* TRIS */
430
431/*
432 * R25 (0x19) - Pwr Mgmt (1)
433 */
434#define WM8961_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */
435#define WM8961_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */
436#define WM8961_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */
437#define WM8961_VREF 0x0040 /* VREF */
438#define WM8961_VREF_MASK 0x0040 /* VREF */
439#define WM8961_VREF_SHIFT 6 /* VREF */
440#define WM8961_VREF_WIDTH 1 /* VREF */
441#define WM8961_AINL 0x0020 /* AINL */
442#define WM8961_AINL_MASK 0x0020 /* AINL */
443#define WM8961_AINL_SHIFT 5 /* AINL */
444#define WM8961_AINL_WIDTH 1 /* AINL */
445#define WM8961_AINR 0x0010 /* AINR */
446#define WM8961_AINR_MASK 0x0010 /* AINR */
447#define WM8961_AINR_SHIFT 4 /* AINR */
448#define WM8961_AINR_WIDTH 1 /* AINR */
449#define WM8961_ADCL 0x0008 /* ADCL */
450#define WM8961_ADCL_MASK 0x0008 /* ADCL */
451#define WM8961_ADCL_SHIFT 3 /* ADCL */
452#define WM8961_ADCL_WIDTH 1 /* ADCL */
453#define WM8961_ADCR 0x0004 /* ADCR */
454#define WM8961_ADCR_MASK 0x0004 /* ADCR */
455#define WM8961_ADCR_SHIFT 2 /* ADCR */
456#define WM8961_ADCR_WIDTH 1 /* ADCR */
457#define WM8961_MICB 0x0002 /* MICB */
458#define WM8961_MICB_MASK 0x0002 /* MICB */
459#define WM8961_MICB_SHIFT 1 /* MICB */
460#define WM8961_MICB_WIDTH 1 /* MICB */
461
462/*
463 * R26 (0x1A) - Pwr Mgmt (2)
464 */
465#define WM8961_DACL 0x0100 /* DACL */
466#define WM8961_DACL_MASK 0x0100 /* DACL */
467#define WM8961_DACL_SHIFT 8 /* DACL */
468#define WM8961_DACL_WIDTH 1 /* DACL */
469#define WM8961_DACR 0x0080 /* DACR */
470#define WM8961_DACR_MASK 0x0080 /* DACR */
471#define WM8961_DACR_SHIFT 7 /* DACR */
472#define WM8961_DACR_WIDTH 1 /* DACR */
473#define WM8961_LOUT1_PGA 0x0040 /* LOUT1_PGA */
474#define WM8961_LOUT1_PGA_MASK 0x0040 /* LOUT1_PGA */
475#define WM8961_LOUT1_PGA_SHIFT 6 /* LOUT1_PGA */
476#define WM8961_LOUT1_PGA_WIDTH 1 /* LOUT1_PGA */
477#define WM8961_ROUT1_PGA 0x0020 /* ROUT1_PGA */
478#define WM8961_ROUT1_PGA_MASK 0x0020 /* ROUT1_PGA */
479#define WM8961_ROUT1_PGA_SHIFT 5 /* ROUT1_PGA */
480#define WM8961_ROUT1_PGA_WIDTH 1 /* ROUT1_PGA */
481#define WM8961_SPKL_PGA 0x0010 /* SPKL_PGA */
482#define WM8961_SPKL_PGA_MASK 0x0010 /* SPKL_PGA */
483#define WM8961_SPKL_PGA_SHIFT 4 /* SPKL_PGA */
484#define WM8961_SPKL_PGA_WIDTH 1 /* SPKL_PGA */
485#define WM8961_SPKR_PGA 0x0008 /* SPKR_PGA */
486#define WM8961_SPKR_PGA_MASK 0x0008 /* SPKR_PGA */
487#define WM8961_SPKR_PGA_SHIFT 3 /* SPKR_PGA */
488#define WM8961_SPKR_PGA_WIDTH 1 /* SPKR_PGA */
489
490/*
491 * R27 (0x1B) - Additional Control (3)
492 */
493#define WM8961_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
494#define WM8961_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
495#define WM8961_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
496
497/*
498 * R28 (0x1C) - Anti-pop
499 */
500#define WM8961_BUFDCOPEN 0x0010 /* BUFDCOPEN */
501#define WM8961_BUFDCOPEN_MASK 0x0010 /* BUFDCOPEN */
502#define WM8961_BUFDCOPEN_SHIFT 4 /* BUFDCOPEN */
503#define WM8961_BUFDCOPEN_WIDTH 1 /* BUFDCOPEN */
504#define WM8961_BUFIOEN 0x0008 /* BUFIOEN */
505#define WM8961_BUFIOEN_MASK 0x0008 /* BUFIOEN */
506#define WM8961_BUFIOEN_SHIFT 3 /* BUFIOEN */
507#define WM8961_BUFIOEN_WIDTH 1 /* BUFIOEN */
508#define WM8961_SOFT_ST 0x0004 /* SOFT_ST */
509#define WM8961_SOFT_ST_MASK 0x0004 /* SOFT_ST */
510#define WM8961_SOFT_ST_SHIFT 2 /* SOFT_ST */
511#define WM8961_SOFT_ST_WIDTH 1 /* SOFT_ST */
512
513/*
514 * R30 (0x1E) - Clocking 3
515 */
516#define WM8961_CLK_TO_DIV_MASK 0x0180 /* CLK_TO_DIV - [8:7] */
517#define WM8961_CLK_TO_DIV_SHIFT 7 /* CLK_TO_DIV - [8:7] */
518#define WM8961_CLK_TO_DIV_WIDTH 2 /* CLK_TO_DIV - [8:7] */
519#define WM8961_CLK_256K_DIV_MASK 0x007E /* CLK_256K_DIV - [6:1] */
520#define WM8961_CLK_256K_DIV_SHIFT 1 /* CLK_256K_DIV - [6:1] */
521#define WM8961_CLK_256K_DIV_WIDTH 6 /* CLK_256K_DIV - [6:1] */
522#define WM8961_MANUAL_MODE 0x0001 /* MANUAL_MODE */
523#define WM8961_MANUAL_MODE_MASK 0x0001 /* MANUAL_MODE */
524#define WM8961_MANUAL_MODE_SHIFT 0 /* MANUAL_MODE */
525#define WM8961_MANUAL_MODE_WIDTH 1 /* MANUAL_MODE */
526
527/*
528 * R32 (0x20) - ADCL signal path
529 */
530#define WM8961_LMICBOOST_MASK 0x0030 /* LMICBOOST - [5:4] */
531#define WM8961_LMICBOOST_SHIFT 4 /* LMICBOOST - [5:4] */
532#define WM8961_LMICBOOST_WIDTH 2 /* LMICBOOST - [5:4] */
533
534/*
535 * R33 (0x21) - ADCR signal path
536 */
537#define WM8961_RMICBOOST_MASK 0x0030 /* RMICBOOST - [5:4] */
538#define WM8961_RMICBOOST_SHIFT 4 /* RMICBOOST - [5:4] */
539#define WM8961_RMICBOOST_WIDTH 2 /* RMICBOOST - [5:4] */
540
541/*
542 * R40 (0x28) - LOUT2 volume
543 */
544#define WM8961_SPKVU 0x0100 /* SPKVU */
545#define WM8961_SPKVU_MASK 0x0100 /* SPKVU */
546#define WM8961_SPKVU_SHIFT 8 /* SPKVU */
547#define WM8961_SPKVU_WIDTH 1 /* SPKVU */
548#define WM8961_SPKLZC 0x0080 /* SPKLZC */
549#define WM8961_SPKLZC_MASK 0x0080 /* SPKLZC */
550#define WM8961_SPKLZC_SHIFT 7 /* SPKLZC */
551#define WM8961_SPKLZC_WIDTH 1 /* SPKLZC */
552#define WM8961_SPKLVOL_MASK 0x007F /* SPKLVOL - [6:0] */
553#define WM8961_SPKLVOL_SHIFT 0 /* SPKLVOL - [6:0] */
554#define WM8961_SPKLVOL_WIDTH 7 /* SPKLVOL - [6:0] */
555
556/*
557 * R41 (0x29) - ROUT2 volume
558 */
559#define WM8961_SPKVU 0x0100 /* SPKVU */
560#define WM8961_SPKVU_MASK 0x0100 /* SPKVU */
561#define WM8961_SPKVU_SHIFT 8 /* SPKVU */
562#define WM8961_SPKVU_WIDTH 1 /* SPKVU */
563#define WM8961_SPKRZC 0x0080 /* SPKRZC */
564#define WM8961_SPKRZC_MASK 0x0080 /* SPKRZC */
565#define WM8961_SPKRZC_SHIFT 7 /* SPKRZC */
566#define WM8961_SPKRZC_WIDTH 1 /* SPKRZC */
567#define WM8961_SPKRVOL_MASK 0x007F /* SPKRVOL - [6:0] */
568#define WM8961_SPKRVOL_SHIFT 0 /* SPKRVOL - [6:0] */
569#define WM8961_SPKRVOL_WIDTH 7 /* SPKRVOL - [6:0] */
570
571/*
572 * R47 (0x2F) - Pwr Mgmt (3)
573 */
574#define WM8961_TEMP_SHUT 0x0002 /* TEMP_SHUT */
575#define WM8961_TEMP_SHUT_MASK 0x0002 /* TEMP_SHUT */
576#define WM8961_TEMP_SHUT_SHIFT 1 /* TEMP_SHUT */
577#define WM8961_TEMP_SHUT_WIDTH 1 /* TEMP_SHUT */
578#define WM8961_TEMP_WARN 0x0001 /* TEMP_WARN */
579#define WM8961_TEMP_WARN_MASK 0x0001 /* TEMP_WARN */
580#define WM8961_TEMP_WARN_SHIFT 0 /* TEMP_WARN */
581#define WM8961_TEMP_WARN_WIDTH 1 /* TEMP_WARN */
582
583/*
584 * R48 (0x30) - Additional Control (4)
585 */
586#define WM8961_TSENSEN 0x0002 /* TSENSEN */
587#define WM8961_TSENSEN_MASK 0x0002 /* TSENSEN */
588#define WM8961_TSENSEN_SHIFT 1 /* TSENSEN */
589#define WM8961_TSENSEN_WIDTH 1 /* TSENSEN */
590#define WM8961_MBSEL 0x0001 /* MBSEL */
591#define WM8961_MBSEL_MASK 0x0001 /* MBSEL */
592#define WM8961_MBSEL_SHIFT 0 /* MBSEL */
593#define WM8961_MBSEL_WIDTH 1 /* MBSEL */
594
595/*
596 * R49 (0x31) - Class D Control 1
597 */
598#define WM8961_SPKR_ENA 0x0080 /* SPKR_ENA */
599#define WM8961_SPKR_ENA_MASK 0x0080 /* SPKR_ENA */
600#define WM8961_SPKR_ENA_SHIFT 7 /* SPKR_ENA */
601#define WM8961_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
602#define WM8961_SPKL_ENA 0x0040 /* SPKL_ENA */
603#define WM8961_SPKL_ENA_MASK 0x0040 /* SPKL_ENA */
604#define WM8961_SPKL_ENA_SHIFT 6 /* SPKL_ENA */
605#define WM8961_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
606
607/*
608 * R51 (0x33) - Class D Control 2
609 */
610#define WM8961_CLASSD_ACGAIN_MASK 0x0007 /* CLASSD_ACGAIN - [2:0] */
611#define WM8961_CLASSD_ACGAIN_SHIFT 0 /* CLASSD_ACGAIN - [2:0] */
612#define WM8961_CLASSD_ACGAIN_WIDTH 3 /* CLASSD_ACGAIN - [2:0] */
613
614/*
615 * R56 (0x38) - Clocking 4
616 */
617#define WM8961_CLK_DCS_DIV_MASK 0x01E0 /* CLK_DCS_DIV - [8:5] */
618#define WM8961_CLK_DCS_DIV_SHIFT 5 /* CLK_DCS_DIV - [8:5] */
619#define WM8961_CLK_DCS_DIV_WIDTH 4 /* CLK_DCS_DIV - [8:5] */
620#define WM8961_CLK_SYS_RATE_MASK 0x001E /* CLK_SYS_RATE - [4:1] */
621#define WM8961_CLK_SYS_RATE_SHIFT 1 /* CLK_SYS_RATE - [4:1] */
622#define WM8961_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [4:1] */
623
624/*
625 * R57 (0x39) - DSP Sidetone 0
626 */
627#define WM8961_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
628#define WM8961_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
629#define WM8961_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
630#define WM8961_ADC_TO_DACR_MASK 0x000C /* ADC_TO_DACR - [3:2] */
631#define WM8961_ADC_TO_DACR_SHIFT 2 /* ADC_TO_DACR - [3:2] */
632#define WM8961_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [3:2] */
633
634/*
635 * R58 (0x3A) - DSP Sidetone 1
636 */
637#define WM8961_ADCL_DAC_SVOL_MASK 0x00F0 /* ADCL_DAC_SVOL - [7:4] */
638#define WM8961_ADCL_DAC_SVOL_SHIFT 4 /* ADCL_DAC_SVOL - [7:4] */
639#define WM8961_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [7:4] */
640#define WM8961_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
641#define WM8961_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
642#define WM8961_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
643
644/*
645 * R60 (0x3C) - DC Servo 0
646 */
647#define WM8961_DCS_ENA_CHAN_INL 0x0080 /* DCS_ENA_CHAN_INL */
648#define WM8961_DCS_ENA_CHAN_INL_MASK 0x0080 /* DCS_ENA_CHAN_INL */
649#define WM8961_DCS_ENA_CHAN_INL_SHIFT 7 /* DCS_ENA_CHAN_INL */
650#define WM8961_DCS_ENA_CHAN_INL_WIDTH 1 /* DCS_ENA_CHAN_INL */
651#define WM8961_DCS_TRIG_STARTUP_INL 0x0040 /* DCS_TRIG_STARTUP_INL */
652#define WM8961_DCS_TRIG_STARTUP_INL_MASK 0x0040 /* DCS_TRIG_STARTUP_INL */
653#define WM8961_DCS_TRIG_STARTUP_INL_SHIFT 6 /* DCS_TRIG_STARTUP_INL */
654#define WM8961_DCS_TRIG_STARTUP_INL_WIDTH 1 /* DCS_TRIG_STARTUP_INL */
655#define WM8961_DCS_TRIG_SERIES_INL 0x0010 /* DCS_TRIG_SERIES_INL */
656#define WM8961_DCS_TRIG_SERIES_INL_MASK 0x0010 /* DCS_TRIG_SERIES_INL */
657#define WM8961_DCS_TRIG_SERIES_INL_SHIFT 4 /* DCS_TRIG_SERIES_INL */
658#define WM8961_DCS_TRIG_SERIES_INL_WIDTH 1 /* DCS_TRIG_SERIES_INL */
659#define WM8961_DCS_ENA_CHAN_INR 0x0008 /* DCS_ENA_CHAN_INR */
660#define WM8961_DCS_ENA_CHAN_INR_MASK 0x0008 /* DCS_ENA_CHAN_INR */
661#define WM8961_DCS_ENA_CHAN_INR_SHIFT 3 /* DCS_ENA_CHAN_INR */
662#define WM8961_DCS_ENA_CHAN_INR_WIDTH 1 /* DCS_ENA_CHAN_INR */
663#define WM8961_DCS_TRIG_STARTUP_INR 0x0004 /* DCS_TRIG_STARTUP_INR */
664#define WM8961_DCS_TRIG_STARTUP_INR_MASK 0x0004 /* DCS_TRIG_STARTUP_INR */
665#define WM8961_DCS_TRIG_STARTUP_INR_SHIFT 2 /* DCS_TRIG_STARTUP_INR */
666#define WM8961_DCS_TRIG_STARTUP_INR_WIDTH 1 /* DCS_TRIG_STARTUP_INR */
667#define WM8961_DCS_TRIG_SERIES_INR 0x0001 /* DCS_TRIG_SERIES_INR */
668#define WM8961_DCS_TRIG_SERIES_INR_MASK 0x0001 /* DCS_TRIG_SERIES_INR */
669#define WM8961_DCS_TRIG_SERIES_INR_SHIFT 0 /* DCS_TRIG_SERIES_INR */
670#define WM8961_DCS_TRIG_SERIES_INR_WIDTH 1 /* DCS_TRIG_SERIES_INR */
671
672/*
673 * R61 (0x3D) - DC Servo 1
674 */
675#define WM8961_DCS_ENA_CHAN_HPL 0x0080 /* DCS_ENA_CHAN_HPL */
676#define WM8961_DCS_ENA_CHAN_HPL_MASK 0x0080 /* DCS_ENA_CHAN_HPL */
677#define WM8961_DCS_ENA_CHAN_HPL_SHIFT 7 /* DCS_ENA_CHAN_HPL */
678#define WM8961_DCS_ENA_CHAN_HPL_WIDTH 1 /* DCS_ENA_CHAN_HPL */
679#define WM8961_DCS_TRIG_STARTUP_HPL 0x0040 /* DCS_TRIG_STARTUP_HPL */
680#define WM8961_DCS_TRIG_STARTUP_HPL_MASK 0x0040 /* DCS_TRIG_STARTUP_HPL */
681#define WM8961_DCS_TRIG_STARTUP_HPL_SHIFT 6 /* DCS_TRIG_STARTUP_HPL */
682#define WM8961_DCS_TRIG_STARTUP_HPL_WIDTH 1 /* DCS_TRIG_STARTUP_HPL */
683#define WM8961_DCS_TRIG_SERIES_HPL 0x0010 /* DCS_TRIG_SERIES_HPL */
684#define WM8961_DCS_TRIG_SERIES_HPL_MASK 0x0010 /* DCS_TRIG_SERIES_HPL */
685#define WM8961_DCS_TRIG_SERIES_HPL_SHIFT 4 /* DCS_TRIG_SERIES_HPL */
686#define WM8961_DCS_TRIG_SERIES_HPL_WIDTH 1 /* DCS_TRIG_SERIES_HPL */
687#define WM8961_DCS_ENA_CHAN_HPR 0x0008 /* DCS_ENA_CHAN_HPR */
688#define WM8961_DCS_ENA_CHAN_HPR_MASK 0x0008 /* DCS_ENA_CHAN_HPR */
689#define WM8961_DCS_ENA_CHAN_HPR_SHIFT 3 /* DCS_ENA_CHAN_HPR */
690#define WM8961_DCS_ENA_CHAN_HPR_WIDTH 1 /* DCS_ENA_CHAN_HPR */
691#define WM8961_DCS_TRIG_STARTUP_HPR 0x0004 /* DCS_TRIG_STARTUP_HPR */
692#define WM8961_DCS_TRIG_STARTUP_HPR_MASK 0x0004 /* DCS_TRIG_STARTUP_HPR */
693#define WM8961_DCS_TRIG_STARTUP_HPR_SHIFT 2 /* DCS_TRIG_STARTUP_HPR */
694#define WM8961_DCS_TRIG_STARTUP_HPR_WIDTH 1 /* DCS_TRIG_STARTUP_HPR */
695#define WM8961_DCS_TRIG_SERIES_HPR 0x0001 /* DCS_TRIG_SERIES_HPR */
696#define WM8961_DCS_TRIG_SERIES_HPR_MASK 0x0001 /* DCS_TRIG_SERIES_HPR */
697#define WM8961_DCS_TRIG_SERIES_HPR_SHIFT 0 /* DCS_TRIG_SERIES_HPR */
698#define WM8961_DCS_TRIG_SERIES_HPR_WIDTH 1 /* DCS_TRIG_SERIES_HPR */
699
700/*
701 * R63 (0x3F) - DC Servo 3
702 */
703#define WM8961_DCS_FILT_BW_SERIES_MASK 0x0030 /* DCS_FILT_BW_SERIES - [5:4] */
704#define WM8961_DCS_FILT_BW_SERIES_SHIFT 4 /* DCS_FILT_BW_SERIES - [5:4] */
705#define WM8961_DCS_FILT_BW_SERIES_WIDTH 2 /* DCS_FILT_BW_SERIES - [5:4] */
706
707/*
708 * R65 (0x41) - DC Servo 5
709 */
710#define WM8961_DCS_SERIES_NO_HP_MASK 0x007F /* DCS_SERIES_NO_HP - [6:0] */
711#define WM8961_DCS_SERIES_NO_HP_SHIFT 0 /* DCS_SERIES_NO_HP - [6:0] */
712#define WM8961_DCS_SERIES_NO_HP_WIDTH 7 /* DCS_SERIES_NO_HP - [6:0] */
713
714/*
715 * R68 (0x44) - Analogue PGA Bias
716 */
717#define WM8961_HP_PGAS_BIAS_MASK 0x0007 /* HP_PGAS_BIAS - [2:0] */
718#define WM8961_HP_PGAS_BIAS_SHIFT 0 /* HP_PGAS_BIAS - [2:0] */
719#define WM8961_HP_PGAS_BIAS_WIDTH 3 /* HP_PGAS_BIAS - [2:0] */
720
721/*
722 * R69 (0x45) - Analogue HP 0
723 */
724#define WM8961_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
725#define WM8961_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
726#define WM8961_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
727#define WM8961_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
728#define WM8961_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
729#define WM8961_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
730#define WM8961_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
731#define WM8961_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
732#define WM8961_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
733#define WM8961_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
734#define WM8961_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
735#define WM8961_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
736#define WM8961_HPL_ENA 0x0010 /* HPL_ENA */
737#define WM8961_HPL_ENA_MASK 0x0010 /* HPL_ENA */
738#define WM8961_HPL_ENA_SHIFT 4 /* HPL_ENA */
739#define WM8961_HPL_ENA_WIDTH 1 /* HPL_ENA */
740#define WM8961_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
741#define WM8961_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
742#define WM8961_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
743#define WM8961_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
744#define WM8961_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
745#define WM8961_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
746#define WM8961_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
747#define WM8961_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
748#define WM8961_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
749#define WM8961_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
750#define WM8961_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
751#define WM8961_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
752#define WM8961_HPR_ENA 0x0001 /* HPR_ENA */
753#define WM8961_HPR_ENA_MASK 0x0001 /* HPR_ENA */
754#define WM8961_HPR_ENA_SHIFT 0 /* HPR_ENA */
755#define WM8961_HPR_ENA_WIDTH 1 /* HPR_ENA */
756
757/*
758 * R71 (0x47) - Analogue HP 2
759 */
760#define WM8961_HPL_VOL_MASK 0x01C0 /* HPL_VOL - [8:6] */
761#define WM8961_HPL_VOL_SHIFT 6 /* HPL_VOL - [8:6] */
762#define WM8961_HPL_VOL_WIDTH 3 /* HPL_VOL - [8:6] */
763#define WM8961_HPR_VOL_MASK 0x0038 /* HPR_VOL - [5:3] */
764#define WM8961_HPR_VOL_SHIFT 3 /* HPR_VOL - [5:3] */
765#define WM8961_HPR_VOL_WIDTH 3 /* HPR_VOL - [5:3] */
766#define WM8961_HP_BIAS_BOOST_MASK 0x0007 /* HP_BIAS_BOOST - [2:0] */
767#define WM8961_HP_BIAS_BOOST_SHIFT 0 /* HP_BIAS_BOOST - [2:0] */
768#define WM8961_HP_BIAS_BOOST_WIDTH 3 /* HP_BIAS_BOOST - [2:0] */
769
770/*
771 * R72 (0x48) - Charge Pump 1
772 */
773#define WM8961_CP_ENA 0x0001 /* CP_ENA */
774#define WM8961_CP_ENA_MASK 0x0001 /* CP_ENA */
775#define WM8961_CP_ENA_SHIFT 0 /* CP_ENA */
776#define WM8961_CP_ENA_WIDTH 1 /* CP_ENA */
777
778/*
779 * R82 (0x52) - Charge Pump B
780 */
781#define WM8961_CP_DYN_PWR_MASK 0x0003 /* CP_DYN_PWR - [1:0] */
782#define WM8961_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR - [1:0] */
783#define WM8961_CP_DYN_PWR_WIDTH 2 /* CP_DYN_PWR - [1:0] */
784
785/*
786 * R87 (0x57) - Write Sequencer 1
787 */
788#define WM8961_WSEQ_ENA 0x0020 /* WSEQ_ENA */
789#define WM8961_WSEQ_ENA_MASK 0x0020 /* WSEQ_ENA */
790#define WM8961_WSEQ_ENA_SHIFT 5 /* WSEQ_ENA */
791#define WM8961_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
792#define WM8961_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
793#define WM8961_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
794#define WM8961_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
795
796/*
797 * R88 (0x58) - Write Sequencer 2
798 */
799#define WM8961_WSEQ_EOS 0x0100 /* WSEQ_EOS */
800#define WM8961_WSEQ_EOS_MASK 0x0100 /* WSEQ_EOS */
801#define WM8961_WSEQ_EOS_SHIFT 8 /* WSEQ_EOS */
802#define WM8961_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
803#define WM8961_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
804#define WM8961_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
805#define WM8961_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
806
807/*
808 * R89 (0x59) - Write Sequencer 3
809 */
810#define WM8961_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
811#define WM8961_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
812#define WM8961_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
813
814/*
815 * R90 (0x5A) - Write Sequencer 4
816 */
817#define WM8961_WSEQ_ABORT 0x0100 /* WSEQ_ABORT */
818#define WM8961_WSEQ_ABORT_MASK 0x0100 /* WSEQ_ABORT */
819#define WM8961_WSEQ_ABORT_SHIFT 8 /* WSEQ_ABORT */
820#define WM8961_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
821#define WM8961_WSEQ_START 0x0080 /* WSEQ_START */
822#define WM8961_WSEQ_START_MASK 0x0080 /* WSEQ_START */
823#define WM8961_WSEQ_START_SHIFT 7 /* WSEQ_START */
824#define WM8961_WSEQ_START_WIDTH 1 /* WSEQ_START */
825#define WM8961_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
826#define WM8961_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
827#define WM8961_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
828
829/*
830 * R91 (0x5B) - Write Sequencer 5
831 */
832#define WM8961_WSEQ_DATA_WIDTH_MASK 0x0070 /* WSEQ_DATA_WIDTH - [6:4] */
833#define WM8961_WSEQ_DATA_WIDTH_SHIFT 4 /* WSEQ_DATA_WIDTH - [6:4] */
834#define WM8961_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [6:4] */
835#define WM8961_WSEQ_DATA_START_MASK 0x000F /* WSEQ_DATA_START - [3:0] */
836#define WM8961_WSEQ_DATA_START_SHIFT 0 /* WSEQ_DATA_START - [3:0] */
837#define WM8961_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [3:0] */
838
839/*
840 * R92 (0x5C) - Write Sequencer 6
841 */
842#define WM8961_WSEQ_DELAY_MASK 0x000F /* WSEQ_DELAY - [3:0] */
843#define WM8961_WSEQ_DELAY_SHIFT 0 /* WSEQ_DELAY - [3:0] */
844#define WM8961_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [3:0] */
845
846/*
847 * R93 (0x5D) - Write Sequencer 7
848 */
849#define WM8961_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
850#define WM8961_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
851#define WM8961_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
852#define WM8961_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
853
854/*
855 * R252 (0xFC) - General test 1
856 */
857#define WM8961_ARA_ENA 0x0002 /* ARA_ENA */
858#define WM8961_ARA_ENA_MASK 0x0002 /* ARA_ENA */
859#define WM8961_ARA_ENA_SHIFT 1 /* ARA_ENA */
860#define WM8961_ARA_ENA_WIDTH 1 /* ARA_ENA */
861#define WM8961_AUTO_INC 0x0001 /* AUTO_INC */
862#define WM8961_AUTO_INC_MASK 0x0001 /* AUTO_INC */
863#define WM8961_AUTO_INC_SHIFT 0 /* AUTO_INC */
864#define WM8961_AUTO_INC_WIDTH 1 /* AUTO_INC */
865
866#endif
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 032dca22dbd3..d66efb0546ea 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -59,44 +59,7 @@ static const u16 wm8971_reg[] = {
59 0x0079, 0x0079, 0x0079, /* 40 */ 59 0x0079, 0x0079, 0x0079, /* 40 */
60}; 60};
61 61
62static inline unsigned int wm8971_read_reg_cache(struct snd_soc_codec *codec, 62#define wm8971_reset(c) snd_soc_write(c, WM8971_RESET, 0)
63 unsigned int reg)
64{
65 u16 *cache = codec->reg_cache;
66 if (reg < WM8971_REG_COUNT)
67 return cache[reg];
68
69 return -1;
70}
71
72static inline void wm8971_write_reg_cache(struct snd_soc_codec *codec,
73 unsigned int reg, unsigned int value)
74{
75 u16 *cache = codec->reg_cache;
76 if (reg < WM8971_REG_COUNT)
77 cache[reg] = value;
78}
79
80static int wm8971_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value)
82{
83 u8 data[2];
84
85 /* data is
86 * D15..D9 WM8753 register offset
87 * D8...D0 register data
88 */
89 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
90 data[1] = value & 0x00ff;
91
92 wm8971_write_reg_cache (codec, reg, value);
93 if (codec->hw_write(codec->control_data, data, 2) == 2)
94 return 0;
95 else
96 return -EIO;
97}
98
99#define wm8971_reset(c) wm8971_write(c, WM8971_RESET, 0)
100 63
101/* WM8971 Controls */ 64/* WM8971 Controls */
102static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" }; 65static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
@@ -521,7 +484,7 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
521 return -EINVAL; 484 return -EINVAL;
522 } 485 }
523 486
524 wm8971_write(codec, WM8971_IFACE, iface); 487 snd_soc_write(codec, WM8971_IFACE, iface);
525 return 0; 488 return 0;
526} 489}
527 490
@@ -533,8 +496,8 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
533 struct snd_soc_device *socdev = rtd->socdev; 496 struct snd_soc_device *socdev = rtd->socdev;
534 struct snd_soc_codec *codec = socdev->card->codec; 497 struct snd_soc_codec *codec = socdev->card->codec;
535 struct wm8971_priv *wm8971 = codec->private_data; 498 struct wm8971_priv *wm8971 = codec->private_data;
536 u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3; 499 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
537 u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0; 500 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
538 int coeff = get_coeff(wm8971->sysclk, params_rate(params)); 501 int coeff = get_coeff(wm8971->sysclk, params_rate(params));
539 502
540 /* bit size */ 503 /* bit size */
@@ -553,9 +516,9 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
553 } 516 }
554 517
555 /* set iface & srate */ 518 /* set iface & srate */
556 wm8971_write(codec, WM8971_IFACE, iface); 519 snd_soc_write(codec, WM8971_IFACE, iface);
557 if (coeff >= 0) 520 if (coeff >= 0)
558 wm8971_write(codec, WM8971_SRATE, srate | 521 snd_soc_write(codec, WM8971_SRATE, srate |
559 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); 522 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
560 523
561 return 0; 524 return 0;
@@ -564,33 +527,33 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
564static int wm8971_mute(struct snd_soc_dai *dai, int mute) 527static int wm8971_mute(struct snd_soc_dai *dai, int mute)
565{ 528{
566 struct snd_soc_codec *codec = dai->codec; 529 struct snd_soc_codec *codec = dai->codec;
567 u16 mute_reg = wm8971_read_reg_cache(codec, WM8971_ADCDAC) & 0xfff7; 530 u16 mute_reg = snd_soc_read(codec, WM8971_ADCDAC) & 0xfff7;
568 531
569 if (mute) 532 if (mute)
570 wm8971_write(codec, WM8971_ADCDAC, mute_reg | 0x8); 533 snd_soc_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
571 else 534 else
572 wm8971_write(codec, WM8971_ADCDAC, mute_reg); 535 snd_soc_write(codec, WM8971_ADCDAC, mute_reg);
573 return 0; 536 return 0;
574} 537}
575 538
576static int wm8971_set_bias_level(struct snd_soc_codec *codec, 539static int wm8971_set_bias_level(struct snd_soc_codec *codec,
577 enum snd_soc_bias_level level) 540 enum snd_soc_bias_level level)
578{ 541{
579 u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e; 542 u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
580 543
581 switch (level) { 544 switch (level) {
582 case SND_SOC_BIAS_ON: 545 case SND_SOC_BIAS_ON:
583 /* set vmid to 50k and unmute dac */ 546 /* set vmid to 50k and unmute dac */
584 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c1); 547 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
585 break; 548 break;
586 case SND_SOC_BIAS_PREPARE: 549 case SND_SOC_BIAS_PREPARE:
587 break; 550 break;
588 case SND_SOC_BIAS_STANDBY: 551 case SND_SOC_BIAS_STANDBY:
589 /* mute dac and set vmid to 500k, enable VREF */ 552 /* mute dac and set vmid to 500k, enable VREF */
590 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x0140); 553 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
591 break; 554 break;
592 case SND_SOC_BIAS_OFF: 555 case SND_SOC_BIAS_OFF:
593 wm8971_write(codec, WM8971_PWR1, 0x0001); 556 snd_soc_write(codec, WM8971_PWR1, 0x0001);
594 break; 557 break;
595 } 558 }
596 codec->bias_level = level; 559 codec->bias_level = level;
@@ -667,8 +630,8 @@ static int wm8971_resume(struct platform_device *pdev)
667 630
668 /* charge wm8971 caps */ 631 /* charge wm8971 caps */
669 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 632 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
670 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e; 633 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
671 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0); 634 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
672 codec->bias_level = SND_SOC_BIAS_ON; 635 codec->bias_level = SND_SOC_BIAS_ON;
673 queue_delayed_work(wm8971_workq, &codec->delayed_work, 636 queue_delayed_work(wm8971_workq, &codec->delayed_work,
674 msecs_to_jiffies(1000)); 637 msecs_to_jiffies(1000));
@@ -677,15 +640,14 @@ static int wm8971_resume(struct platform_device *pdev)
677 return 0; 640 return 0;
678} 641}
679 642
680static int wm8971_init(struct snd_soc_device *socdev) 643static int wm8971_init(struct snd_soc_device *socdev,
644 enum snd_soc_control_type control)
681{ 645{
682 struct snd_soc_codec *codec = socdev->card->codec; 646 struct snd_soc_codec *codec = socdev->card->codec;
683 int reg, ret = 0; 647 int reg, ret = 0;
684 648
685 codec->name = "WM8971"; 649 codec->name = "WM8971";
686 codec->owner = THIS_MODULE; 650 codec->owner = THIS_MODULE;
687 codec->read = wm8971_read_reg_cache;
688 codec->write = wm8971_write;
689 codec->set_bias_level = wm8971_set_bias_level; 651 codec->set_bias_level = wm8971_set_bias_level;
690 codec->dai = &wm8971_dai; 652 codec->dai = &wm8971_dai;
691 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg); 653 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
@@ -695,42 +657,48 @@ static int wm8971_init(struct snd_soc_device *socdev)
695 if (codec->reg_cache == NULL) 657 if (codec->reg_cache == NULL)
696 return -ENOMEM; 658 return -ENOMEM;
697 659
660 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
661 if (ret < 0) {
662 printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
663 goto err;
664 }
665
698 wm8971_reset(codec); 666 wm8971_reset(codec);
699 667
700 /* register pcms */ 668 /* register pcms */
701 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 669 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
702 if (ret < 0) { 670 if (ret < 0) {
703 printk(KERN_ERR "wm8971: failed to create pcms\n"); 671 printk(KERN_ERR "wm8971: failed to create pcms\n");
704 goto pcm_err; 672 goto err;
705 } 673 }
706 674
707 /* charge output caps - set vmid to 5k for quick power up */ 675 /* charge output caps - set vmid to 5k for quick power up */
708 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e; 676 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
709 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0); 677 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
710 codec->bias_level = SND_SOC_BIAS_STANDBY; 678 codec->bias_level = SND_SOC_BIAS_STANDBY;
711 queue_delayed_work(wm8971_workq, &codec->delayed_work, 679 queue_delayed_work(wm8971_workq, &codec->delayed_work,
712 msecs_to_jiffies(1000)); 680 msecs_to_jiffies(1000));
713 681
714 /* set the update bits */ 682 /* set the update bits */
715 reg = wm8971_read_reg_cache(codec, WM8971_LDAC); 683 reg = snd_soc_read(codec, WM8971_LDAC);
716 wm8971_write(codec, WM8971_LDAC, reg | 0x0100); 684 snd_soc_write(codec, WM8971_LDAC, reg | 0x0100);
717 reg = wm8971_read_reg_cache(codec, WM8971_RDAC); 685 reg = snd_soc_read(codec, WM8971_RDAC);
718 wm8971_write(codec, WM8971_RDAC, reg | 0x0100); 686 snd_soc_write(codec, WM8971_RDAC, reg | 0x0100);
719 687
720 reg = wm8971_read_reg_cache(codec, WM8971_LOUT1V); 688 reg = snd_soc_read(codec, WM8971_LOUT1V);
721 wm8971_write(codec, WM8971_LOUT1V, reg | 0x0100); 689 snd_soc_write(codec, WM8971_LOUT1V, reg | 0x0100);
722 reg = wm8971_read_reg_cache(codec, WM8971_ROUT1V); 690 reg = snd_soc_read(codec, WM8971_ROUT1V);
723 wm8971_write(codec, WM8971_ROUT1V, reg | 0x0100); 691 snd_soc_write(codec, WM8971_ROUT1V, reg | 0x0100);
724 692
725 reg = wm8971_read_reg_cache(codec, WM8971_LOUT2V); 693 reg = snd_soc_read(codec, WM8971_LOUT2V);
726 wm8971_write(codec, WM8971_LOUT2V, reg | 0x0100); 694 snd_soc_write(codec, WM8971_LOUT2V, reg | 0x0100);
727 reg = wm8971_read_reg_cache(codec, WM8971_ROUT2V); 695 reg = snd_soc_read(codec, WM8971_ROUT2V);
728 wm8971_write(codec, WM8971_ROUT2V, reg | 0x0100); 696 snd_soc_write(codec, WM8971_ROUT2V, reg | 0x0100);
729 697
730 reg = wm8971_read_reg_cache(codec, WM8971_LINVOL); 698 reg = snd_soc_read(codec, WM8971_LINVOL);
731 wm8971_write(codec, WM8971_LINVOL, reg | 0x0100); 699 snd_soc_write(codec, WM8971_LINVOL, reg | 0x0100);
732 reg = wm8971_read_reg_cache(codec, WM8971_RINVOL); 700 reg = snd_soc_read(codec, WM8971_RINVOL);
733 wm8971_write(codec, WM8971_RINVOL, reg | 0x0100); 701 snd_soc_write(codec, WM8971_RINVOL, reg | 0x0100);
734 702
735 snd_soc_add_controls(codec, wm8971_snd_controls, 703 snd_soc_add_controls(codec, wm8971_snd_controls,
736 ARRAY_SIZE(wm8971_snd_controls)); 704 ARRAY_SIZE(wm8971_snd_controls));
@@ -745,7 +713,7 @@ static int wm8971_init(struct snd_soc_device *socdev)
745card_err: 713card_err:
746 snd_soc_free_pcms(socdev); 714 snd_soc_free_pcms(socdev);
747 snd_soc_dapm_free(socdev); 715 snd_soc_dapm_free(socdev);
748pcm_err: 716err:
749 kfree(codec->reg_cache); 717 kfree(codec->reg_cache);
750 return ret; 718 return ret;
751} 719}
@@ -767,7 +735,7 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
767 735
768 codec->control_data = i2c; 736 codec->control_data = i2c;
769 737
770 ret = wm8971_init(socdev); 738 ret = wm8971_init(socdev, SND_SOC_I2C);
771 if (ret < 0) 739 if (ret < 0)
772 pr_err("failed to initialise WM8971\n"); 740 pr_err("failed to initialise WM8971\n");
773 741
@@ -877,7 +845,6 @@ static int wm8971_probe(struct platform_device *pdev)
877 845
878#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 846#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
879 if (setup->i2c_address) { 847 if (setup->i2c_address) {
880 codec->hw_write = (hw_write_t)i2c_master_send;
881 ret = wm8971_add_i2c_device(pdev, setup); 848 ret = wm8971_add_i2c_device(pdev, setup);
882 } 849 }
883#endif 850#endif
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index c05f71803aa8..1c8653523c8c 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -57,50 +57,7 @@ struct wm8988_priv {
57}; 57};
58 58
59 59
60/* 60#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0)
61 * read wm8988 register cache
62 */
63static inline unsigned int wm8988_read_reg_cache(struct snd_soc_codec *codec,
64 unsigned int reg)
65{
66 u16 *cache = codec->reg_cache;
67 if (reg > WM8988_NUM_REG)
68 return -1;
69 return cache[reg];
70}
71
72/*
73 * write wm8988 register cache
74 */
75static inline void wm8988_write_reg_cache(struct snd_soc_codec *codec,
76 unsigned int reg, unsigned int value)
77{
78 u16 *cache = codec->reg_cache;
79 if (reg > WM8988_NUM_REG)
80 return;
81 cache[reg] = value;
82}
83
84static int wm8988_write(struct snd_soc_codec *codec, unsigned int reg,
85 unsigned int value)
86{
87 u8 data[2];
88
89 /* data is
90 * D15..D9 WM8753 register offset
91 * D8...D0 register data
92 */
93 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
94 data[1] = value & 0x00ff;
95
96 wm8988_write_reg_cache(codec, reg, value);
97 if (codec->hw_write(codec->control_data, data, 2) == 2)
98 return 0;
99 else
100 return -EIO;
101}
102
103#define wm8988_reset(c) wm8988_write(c, WM8988_RESET, 0)
104 61
105/* 62/*
106 * WM8988 Controls 63 * WM8988 Controls
@@ -226,15 +183,15 @@ static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
226 struct snd_kcontrol *kcontrol, int event) 183 struct snd_kcontrol *kcontrol, int event)
227{ 184{
228 struct snd_soc_codec *codec = w->codec; 185 struct snd_soc_codec *codec = w->codec;
229 u16 adctl2 = wm8988_read_reg_cache(codec, WM8988_ADCTL2); 186 u16 adctl2 = snd_soc_read(codec, WM8988_ADCTL2);
230 187
231 /* Use the DAC to gate LRC if active, otherwise use ADC */ 188 /* Use the DAC to gate LRC if active, otherwise use ADC */
232 if (wm8988_read_reg_cache(codec, WM8988_PWR2) & 0x180) 189 if (snd_soc_read(codec, WM8988_PWR2) & 0x180)
233 adctl2 &= ~0x4; 190 adctl2 &= ~0x4;
234 else 191 else
235 adctl2 |= 0x4; 192 adctl2 |= 0x4;
236 193
237 return wm8988_write(codec, WM8988_ADCTL2, adctl2); 194 return snd_soc_write(codec, WM8988_ADCTL2, adctl2);
238} 195}
239 196
240static const char *wm8988_line_texts[] = { 197static const char *wm8988_line_texts[] = {
@@ -619,7 +576,7 @@ static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
619 return -EINVAL; 576 return -EINVAL;
620 } 577 }
621 578
622 wm8988_write(codec, WM8988_IFACE, iface); 579 snd_soc_write(codec, WM8988_IFACE, iface);
623 return 0; 580 return 0;
624} 581}
625 582
@@ -653,8 +610,8 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
653 struct snd_soc_device *socdev = rtd->socdev; 610 struct snd_soc_device *socdev = rtd->socdev;
654 struct snd_soc_codec *codec = socdev->card->codec; 611 struct snd_soc_codec *codec = socdev->card->codec;
655 struct wm8988_priv *wm8988 = codec->private_data; 612 struct wm8988_priv *wm8988 = codec->private_data;
656 u16 iface = wm8988_read_reg_cache(codec, WM8988_IFACE) & 0x1f3; 613 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
657 u16 srate = wm8988_read_reg_cache(codec, WM8988_SRATE) & 0x180; 614 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
658 int coeff; 615 int coeff;
659 616
660 coeff = get_coeff(wm8988->sysclk, params_rate(params)); 617 coeff = get_coeff(wm8988->sysclk, params_rate(params));
@@ -685,9 +642,9 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
685 } 642 }
686 643
687 /* set iface & srate */ 644 /* set iface & srate */
688 wm8988_write(codec, WM8988_IFACE, iface); 645 snd_soc_write(codec, WM8988_IFACE, iface);
689 if (coeff >= 0) 646 if (coeff >= 0)
690 wm8988_write(codec, WM8988_SRATE, srate | 647 snd_soc_write(codec, WM8988_SRATE, srate |
691 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); 648 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
692 649
693 return 0; 650 return 0;
@@ -696,19 +653,19 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
696static int wm8988_mute(struct snd_soc_dai *dai, int mute) 653static int wm8988_mute(struct snd_soc_dai *dai, int mute)
697{ 654{
698 struct snd_soc_codec *codec = dai->codec; 655 struct snd_soc_codec *codec = dai->codec;
699 u16 mute_reg = wm8988_read_reg_cache(codec, WM8988_ADCDAC) & 0xfff7; 656 u16 mute_reg = snd_soc_read(codec, WM8988_ADCDAC) & 0xfff7;
700 657
701 if (mute) 658 if (mute)
702 wm8988_write(codec, WM8988_ADCDAC, mute_reg | 0x8); 659 snd_soc_write(codec, WM8988_ADCDAC, mute_reg | 0x8);
703 else 660 else
704 wm8988_write(codec, WM8988_ADCDAC, mute_reg); 661 snd_soc_write(codec, WM8988_ADCDAC, mute_reg);
705 return 0; 662 return 0;
706} 663}
707 664
708static int wm8988_set_bias_level(struct snd_soc_codec *codec, 665static int wm8988_set_bias_level(struct snd_soc_codec *codec,
709 enum snd_soc_bias_level level) 666 enum snd_soc_bias_level level)
710{ 667{
711 u16 pwr_reg = wm8988_read_reg_cache(codec, WM8988_PWR1) & ~0x1c1; 668 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
712 669
713 switch (level) { 670 switch (level) {
714 case SND_SOC_BIAS_ON: 671 case SND_SOC_BIAS_ON:
@@ -716,24 +673,24 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
716 673
717 case SND_SOC_BIAS_PREPARE: 674 case SND_SOC_BIAS_PREPARE:
718 /* VREF, VMID=2x50k, digital enabled */ 675 /* VREF, VMID=2x50k, digital enabled */
719 wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x00c0); 676 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x00c0);
720 break; 677 break;
721 678
722 case SND_SOC_BIAS_STANDBY: 679 case SND_SOC_BIAS_STANDBY:
723 if (codec->bias_level == SND_SOC_BIAS_OFF) { 680 if (codec->bias_level == SND_SOC_BIAS_OFF) {
724 /* VREF, VMID=2x5k */ 681 /* VREF, VMID=2x5k */
725 wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 682 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
726 683
727 /* Charge caps */ 684 /* Charge caps */
728 msleep(100); 685 msleep(100);
729 } 686 }
730 687
731 /* VREF, VMID=2*500k, digital stopped */ 688 /* VREF, VMID=2*500k, digital stopped */
732 wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x0141); 689 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x0141);
733 break; 690 break;
734 691
735 case SND_SOC_BIAS_OFF: 692 case SND_SOC_BIAS_OFF:
736 wm8988_write(codec, WM8988_PWR1, 0x0000); 693 snd_soc_write(codec, WM8988_PWR1, 0x0000);
737 break; 694 break;
738 } 695 }
739 codec->bias_level = level; 696 codec->bias_level = level;
@@ -868,7 +825,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8988 = {
868}; 825};
869EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988); 826EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988);
870 827
871static int wm8988_register(struct wm8988_priv *wm8988) 828static int wm8988_register(struct wm8988_priv *wm8988,
829 enum snd_soc_control_type control)
872{ 830{
873 struct snd_soc_codec *codec = &wm8988->codec; 831 struct snd_soc_codec *codec = &wm8988->codec;
874 int ret; 832 int ret;
@@ -887,8 +845,6 @@ static int wm8988_register(struct wm8988_priv *wm8988)
887 codec->private_data = wm8988; 845 codec->private_data = wm8988;
888 codec->name = "WM8988"; 846 codec->name = "WM8988";
889 codec->owner = THIS_MODULE; 847 codec->owner = THIS_MODULE;
890 codec->read = wm8988_read_reg_cache;
891 codec->write = wm8988_write;
892 codec->dai = &wm8988_dai; 848 codec->dai = &wm8988_dai;
893 codec->num_dai = 1; 849 codec->num_dai = 1;
894 codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache); 850 codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache);
@@ -899,23 +855,29 @@ static int wm8988_register(struct wm8988_priv *wm8988)
899 memcpy(codec->reg_cache, wm8988_reg, 855 memcpy(codec->reg_cache, wm8988_reg,
900 sizeof(wm8988_reg)); 856 sizeof(wm8988_reg));
901 857
858 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
859 if (ret < 0) {
860 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
861 goto err;
862 }
863
902 ret = wm8988_reset(codec); 864 ret = wm8988_reset(codec);
903 if (ret < 0) { 865 if (ret < 0) {
904 dev_err(codec->dev, "Failed to issue reset\n"); 866 dev_err(codec->dev, "Failed to issue reset\n");
905 return ret; 867 goto err;
906 } 868 }
907 869
908 /* set the update bits (we always update left then right) */ 870 /* set the update bits (we always update left then right) */
909 reg = wm8988_read_reg_cache(codec, WM8988_RADC); 871 reg = snd_soc_read(codec, WM8988_RADC);
910 wm8988_write(codec, WM8988_RADC, reg | 0x100); 872 snd_soc_write(codec, WM8988_RADC, reg | 0x100);
911 reg = wm8988_read_reg_cache(codec, WM8988_RDAC); 873 reg = snd_soc_read(codec, WM8988_RDAC);
912 wm8988_write(codec, WM8988_RDAC, reg | 0x0100); 874 snd_soc_write(codec, WM8988_RDAC, reg | 0x0100);
913 reg = wm8988_read_reg_cache(codec, WM8988_ROUT1V); 875 reg = snd_soc_read(codec, WM8988_ROUT1V);
914 wm8988_write(codec, WM8988_ROUT1V, reg | 0x0100); 876 snd_soc_write(codec, WM8988_ROUT1V, reg | 0x0100);
915 reg = wm8988_read_reg_cache(codec, WM8988_ROUT2V); 877 reg = snd_soc_read(codec, WM8988_ROUT2V);
916 wm8988_write(codec, WM8988_ROUT2V, reg | 0x0100); 878 snd_soc_write(codec, WM8988_ROUT2V, reg | 0x0100);
917 reg = wm8988_read_reg_cache(codec, WM8988_RINVOL); 879 reg = snd_soc_read(codec, WM8988_RINVOL);
918 wm8988_write(codec, WM8988_RINVOL, reg | 0x0100); 880 snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
919 881
920 wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY); 882 wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY);
921 883
@@ -926,18 +888,20 @@ static int wm8988_register(struct wm8988_priv *wm8988)
926 ret = snd_soc_register_codec(codec); 888 ret = snd_soc_register_codec(codec);
927 if (ret != 0) { 889 if (ret != 0) {
928 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 890 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
929 return ret; 891 goto err;
930 } 892 }
931 893
932 ret = snd_soc_register_dai(&wm8988_dai); 894 ret = snd_soc_register_dai(&wm8988_dai);
933 if (ret != 0) { 895 if (ret != 0) {
934 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 896 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
935 snd_soc_unregister_codec(codec); 897 snd_soc_unregister_codec(codec);
936 return ret; 898 goto err_codec;
937 } 899 }
938 900
939 return 0; 901 return 0;
940 902
903err_codec:
904 snd_soc_unregister_codec(codec);
941err: 905err:
942 kfree(wm8988); 906 kfree(wm8988);
943 return ret; 907 return ret;
@@ -964,14 +928,13 @@ static int wm8988_i2c_probe(struct i2c_client *i2c,
964 return -ENOMEM; 928 return -ENOMEM;
965 929
966 codec = &wm8988->codec; 930 codec = &wm8988->codec;
967 codec->hw_write = (hw_write_t)i2c_master_send;
968 931
969 i2c_set_clientdata(i2c, wm8988); 932 i2c_set_clientdata(i2c, wm8988);
970 codec->control_data = i2c; 933 codec->control_data = i2c;
971 934
972 codec->dev = &i2c->dev; 935 codec->dev = &i2c->dev;
973 936
974 return wm8988_register(wm8988); 937 return wm8988_register(wm8988, SND_SOC_I2C);
975} 938}
976 939
977static int wm8988_i2c_remove(struct i2c_client *client) 940static int wm8988_i2c_remove(struct i2c_client *client)
@@ -981,6 +944,21 @@ static int wm8988_i2c_remove(struct i2c_client *client)
981 return 0; 944 return 0;
982} 945}
983 946
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
984static const struct i2c_device_id wm8988_i2c_id[] = { 962static const struct i2c_device_id wm8988_i2c_id[] = {
985 { "wm8988", 0 }, 963 { "wm8988", 0 },
986 { } 964 { }
@@ -994,35 +972,13 @@ static struct i2c_driver wm8988_i2c_driver = {
994 }, 972 },
995 .probe = wm8988_i2c_probe, 973 .probe = wm8988_i2c_probe,
996 .remove = wm8988_i2c_remove, 974 .remove = wm8988_i2c_remove,
975 .suspend = wm8988_i2c_suspend,
976 .resume = wm8988_i2c_resume,
997 .id_table = wm8988_i2c_id, 977 .id_table = wm8988_i2c_id,
998}; 978};
999#endif 979#endif
1000 980
1001#if defined(CONFIG_SPI_MASTER) 981#if defined(CONFIG_SPI_MASTER)
1002static int wm8988_spi_write(struct spi_device *spi, const char *data, int len)
1003{
1004 struct spi_transfer t;
1005 struct spi_message m;
1006 u8 msg[2];
1007
1008 if (len <= 0)
1009 return 0;
1010
1011 msg[0] = data[0];
1012 msg[1] = data[1];
1013
1014 spi_message_init(&m);
1015 memset(&t, 0, (sizeof t));
1016
1017 t.tx_buf = &msg[0];
1018 t.len = len;
1019
1020 spi_message_add_tail(&t, &m);
1021 spi_sync(spi, &m);
1022
1023 return len;
1024}
1025
1026static int __devinit wm8988_spi_probe(struct spi_device *spi) 982static int __devinit wm8988_spi_probe(struct spi_device *spi)
1027{ 983{
1028 struct wm8988_priv *wm8988; 984 struct wm8988_priv *wm8988;
@@ -1033,13 +989,12 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi)
1033 return -ENOMEM; 989 return -ENOMEM;
1034 990
1035 codec = &wm8988->codec; 991 codec = &wm8988->codec;
1036 codec->hw_write = (hw_write_t)wm8988_spi_write;
1037 codec->control_data = spi; 992 codec->control_data = spi;
1038 codec->dev = &spi->dev; 993 codec->dev = &spi->dev;
1039 994
1040 spi->dev.driver_data = wm8988; 995 spi->dev.driver_data = wm8988;
1041 996
1042 return wm8988_register(wm8988); 997 return wm8988_register(wm8988, SND_SOC_SPI);
1043} 998}
1044 999
1045static int __devexit wm8988_spi_remove(struct spi_device *spi) 1000static int __devexit wm8988_spi_remove(struct spi_device *spi)
@@ -1051,6 +1006,21 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi)
1051 return 0; 1006 return 0;
1052} 1007}
1053 1008
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
1054static struct spi_driver wm8988_spi_driver = { 1024static struct spi_driver wm8988_spi_driver = {
1055 .driver = { 1025 .driver = {
1056 .name = "wm8988", 1026 .name = "wm8988",
@@ -1059,6 +1029,8 @@ static struct spi_driver wm8988_spi_driver = {
1059 }, 1029 },
1060 .probe = wm8988_spi_probe, 1030 .probe = wm8988_spi_probe,
1061 .remove = __devexit_p(wm8988_spi_remove), 1031 .remove = __devexit_p(wm8988_spi_remove),
1032 .suspend = wm8988_spi_suspend,
1033 .resume = wm8988_spi_resume,
1062}; 1034};
1063#endif 1035#endif
1064 1036
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 40cd274eb1ef..2d702db4131d 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -108,53 +108,7 @@ static const u16 wm8990_reg[] = {
108 0x0000, /* R63 - Driver internal */ 108 0x0000, /* R63 - Driver internal */
109}; 109};
110 110
111/* 111#define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0)
112 * read wm8990 register cache
113 */
114static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec,
115 unsigned int reg)
116{
117 u16 *cache = codec->reg_cache;
118 BUG_ON(reg >= ARRAY_SIZE(wm8990_reg));
119 return cache[reg];
120}
121
122/*
123 * write wm8990 register cache
124 */
125static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
126 unsigned int reg, unsigned int value)
127{
128 u16 *cache = codec->reg_cache;
129
130 /* Reset register and reserved registers are uncached */
131 if (reg == 0 || reg >= ARRAY_SIZE(wm8990_reg))
132 return;
133
134 cache[reg] = value;
135}
136
137/*
138 * write to the wm8990 register space
139 */
140static int wm8990_write(struct snd_soc_codec *codec, unsigned int reg,
141 unsigned int value)
142{
143 u8 data[3];
144
145 data[0] = reg & 0xFF;
146 data[1] = (value >> 8) & 0xFF;
147 data[2] = value & 0xFF;
148
149 wm8990_write_reg_cache(codec, reg, value);
150
151 if (codec->hw_write(codec->control_data, data, 3) == 2)
152 return 0;
153 else
154 return -EIO;
155}
156
157#define wm8990_reset(c) wm8990_write(c, WM8990_RESET, 0)
158 112
159static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); 113static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600);
160 114
@@ -187,8 +141,8 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
187 return ret; 141 return ret;
188 142
189 /* now hit the volume update bits (always bit 8) */ 143 /* now hit the volume update bits (always bit 8) */
190 val = wm8990_read_reg_cache(codec, reg); 144 val = snd_soc_read(codec, reg);
191 return wm8990_write(codec, reg, val | 0x0100); 145 return snd_soc_write(codec, reg, val | 0x0100);
192} 146}
193 147
194#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\ 148#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
@@ -427,8 +381,8 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
427{ 381{
428 u16 reg, fakepower; 382 u16 reg, fakepower;
429 383
430 reg = wm8990_read_reg_cache(w->codec, WM8990_POWER_MANAGEMENT_2); 384 reg = snd_soc_read(w->codec, WM8990_POWER_MANAGEMENT_2);
431 fakepower = wm8990_read_reg_cache(w->codec, WM8990_INTDRIVBITS); 385 fakepower = snd_soc_read(w->codec, WM8990_INTDRIVBITS);
432 386
433 if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) | 387 if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) |
434 (1 << WM8990_AINLMUX_PWR_BIT))) { 388 (1 << WM8990_AINLMUX_PWR_BIT))) {
@@ -443,7 +397,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
443 } else { 397 } else {
444 reg &= ~WM8990_AINL_ENA; 398 reg &= ~WM8990_AINL_ENA;
445 } 399 }
446 wm8990_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg); 400 snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
447 401
448 return 0; 402 return 0;
449} 403}
@@ -457,7 +411,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
457 411
458 switch (reg_shift) { 412 switch (reg_shift) {
459 case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) : 413 case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) :
460 reg = wm8990_read_reg_cache(w->codec, WM8990_OUTPUT_MIXER1); 414 reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER1);
461 if (reg & WM8990_LDLO) { 415 if (reg & WM8990_LDLO) {
462 printk(KERN_WARNING 416 printk(KERN_WARNING
463 "Cannot set as Output Mixer 1 LDLO Set\n"); 417 "Cannot set as Output Mixer 1 LDLO Set\n");
@@ -465,7 +419,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
465 } 419 }
466 break; 420 break;
467 case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8): 421 case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8):
468 reg = wm8990_read_reg_cache(w->codec, WM8990_OUTPUT_MIXER2); 422 reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER2);
469 if (reg & WM8990_RDRO) { 423 if (reg & WM8990_RDRO) {
470 printk(KERN_WARNING 424 printk(KERN_WARNING
471 "Cannot set as Output Mixer 2 RDRO Set\n"); 425 "Cannot set as Output Mixer 2 RDRO Set\n");
@@ -473,7 +427,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
473 } 427 }
474 break; 428 break;
475 case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8): 429 case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8):
476 reg = wm8990_read_reg_cache(w->codec, WM8990_SPEAKER_MIXER); 430 reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
477 if (reg & WM8990_LDSPK) { 431 if (reg & WM8990_LDSPK) {
478 printk(KERN_WARNING 432 printk(KERN_WARNING
479 "Cannot set as Speaker Mixer LDSPK Set\n"); 433 "Cannot set as Speaker Mixer LDSPK Set\n");
@@ -481,7 +435,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
481 } 435 }
482 break; 436 break;
483 case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8): 437 case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8):
484 reg = wm8990_read_reg_cache(w->codec, WM8990_SPEAKER_MIXER); 438 reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
485 if (reg & WM8990_RDSPK) { 439 if (reg & WM8990_RDSPK) {
486 printk(KERN_WARNING 440 printk(KERN_WARNING
487 "Cannot set as Speaker Mixer RDSPK Set\n"); 441 "Cannot set as Speaker Mixer RDSPK Set\n");
@@ -998,7 +952,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
998 952
999 if ((Ndiv < 6) || (Ndiv > 12)) 953 if ((Ndiv < 6) || (Ndiv > 12))
1000 printk(KERN_WARNING 954 printk(KERN_WARNING
1001 "WM8990 N value outwith recommended range! N = %d\n", Ndiv); 955 "WM8990 N value outwith recommended range! N = %u\n", Ndiv);
1002 956
1003 pll_div->n = Ndiv; 957 pll_div->n = Ndiv;
1004 Nmod = target % source; 958 Nmod = target % source;
@@ -1029,24 +983,24 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai,
1029 pll_factors(&pll_div, freq_out * 4, freq_in); 983 pll_factors(&pll_div, freq_out * 4, freq_in);
1030 984
1031 /* Turn on PLL */ 985 /* Turn on PLL */
1032 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2); 986 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
1033 reg |= WM8990_PLL_ENA; 987 reg |= WM8990_PLL_ENA;
1034 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg); 988 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
1035 989
1036 /* sysclk comes from PLL */ 990 /* sysclk comes from PLL */
1037 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2); 991 reg = snd_soc_read(codec, WM8990_CLOCKING_2);
1038 wm8990_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); 992 snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC);
1039 993
1040 /* set up N , fractional mode and pre-divisor if neccessary */ 994 /* set up N , fractional mode and pre-divisor if neccessary */
1041 wm8990_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | 995 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
1042 (pll_div.div2?WM8990_PRESCALE:0)); 996 (pll_div.div2?WM8990_PRESCALE:0));
1043 wm8990_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); 997 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
1044 wm8990_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF)); 998 snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
1045 } else { 999 } else {
1046 /* Turn on PLL */ 1000 /* Turn on PLL */
1047 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2); 1001 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
1048 reg &= ~WM8990_PLL_ENA; 1002 reg &= ~WM8990_PLL_ENA;
1049 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg); 1003 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
1050 } 1004 }
1051 return 0; 1005 return 0;
1052} 1006}
@@ -1073,8 +1027,8 @@ static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
1073 struct snd_soc_codec *codec = codec_dai->codec; 1027 struct snd_soc_codec *codec = codec_dai->codec;
1074 u16 audio1, audio3; 1028 u16 audio1, audio3;
1075 1029
1076 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1); 1030 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
1077 audio3 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_3); 1031 audio3 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_3);
1078 1032
1079 /* set master/slave audio interface */ 1033 /* set master/slave audio interface */
1080 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1034 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1115,8 +1069,8 @@ static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
1115 return -EINVAL; 1069 return -EINVAL;
1116 } 1070 }
1117 1071
1118 wm8990_write(codec, WM8990_AUDIO_INTERFACE_1, audio1); 1072 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
1119 wm8990_write(codec, WM8990_AUDIO_INTERFACE_3, audio3); 1073 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_3, audio3);
1120 return 0; 1074 return 0;
1121} 1075}
1122 1076
@@ -1128,24 +1082,24 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1128 1082
1129 switch (div_id) { 1083 switch (div_id) {
1130 case WM8990_MCLK_DIV: 1084 case WM8990_MCLK_DIV:
1131 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) & 1085 reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
1132 ~WM8990_MCLK_DIV_MASK; 1086 ~WM8990_MCLK_DIV_MASK;
1133 wm8990_write(codec, WM8990_CLOCKING_2, reg | div); 1087 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1134 break; 1088 break;
1135 case WM8990_DACCLK_DIV: 1089 case WM8990_DACCLK_DIV:
1136 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) & 1090 reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
1137 ~WM8990_DAC_CLKDIV_MASK; 1091 ~WM8990_DAC_CLKDIV_MASK;
1138 wm8990_write(codec, WM8990_CLOCKING_2, reg | div); 1092 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1139 break; 1093 break;
1140 case WM8990_ADCCLK_DIV: 1094 case WM8990_ADCCLK_DIV:
1141 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) & 1095 reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
1142 ~WM8990_ADC_CLKDIV_MASK; 1096 ~WM8990_ADC_CLKDIV_MASK;
1143 wm8990_write(codec, WM8990_CLOCKING_2, reg | div); 1097 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1144 break; 1098 break;
1145 case WM8990_BCLK_DIV: 1099 case WM8990_BCLK_DIV:
1146 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_1) & 1100 reg = snd_soc_read(codec, WM8990_CLOCKING_1) &
1147 ~WM8990_BCLK_DIV_MASK; 1101 ~WM8990_BCLK_DIV_MASK;
1148 wm8990_write(codec, WM8990_CLOCKING_1, reg | div); 1102 snd_soc_write(codec, WM8990_CLOCKING_1, reg | div);
1149 break; 1103 break;
1150 default: 1104 default:
1151 return -EINVAL; 1105 return -EINVAL;
@@ -1164,7 +1118,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1118 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1165 struct snd_soc_device *socdev = rtd->socdev; 1119 struct snd_soc_device *socdev = rtd->socdev;
1166 struct snd_soc_codec *codec = socdev->card->codec; 1120 struct snd_soc_codec *codec = socdev->card->codec;
1167 u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1); 1121 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
1168 1122
1169 audio1 &= ~WM8990_AIF_WL_MASK; 1123 audio1 &= ~WM8990_AIF_WL_MASK;
1170 /* bit size */ 1124 /* bit size */
@@ -1182,7 +1136,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1182 break; 1136 break;
1183 } 1137 }
1184 1138
1185 wm8990_write(codec, WM8990_AUDIO_INTERFACE_1, audio1); 1139 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
1186 return 0; 1140 return 0;
1187} 1141}
1188 1142
@@ -1191,12 +1145,12 @@ static int wm8990_mute(struct snd_soc_dai *dai, int mute)
1191 struct snd_soc_codec *codec = dai->codec; 1145 struct snd_soc_codec *codec = dai->codec;
1192 u16 val; 1146 u16 val;
1193 1147
1194 val = wm8990_read_reg_cache(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE; 1148 val = snd_soc_read(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE;
1195 1149
1196 if (mute) 1150 if (mute)
1197 wm8990_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); 1151 snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
1198 else 1152 else
1199 wm8990_write(codec, WM8990_DAC_CTRL, val); 1153 snd_soc_write(codec, WM8990_DAC_CTRL, val);
1200 1154
1201 return 0; 1155 return 0;
1202} 1156}
@@ -1212,21 +1166,21 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1212 1166
1213 case SND_SOC_BIAS_PREPARE: 1167 case SND_SOC_BIAS_PREPARE:
1214 /* VMID=2*50k */ 1168 /* VMID=2*50k */
1215 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) & 1169 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) &
1216 ~WM8990_VMID_MODE_MASK; 1170 ~WM8990_VMID_MODE_MASK;
1217 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2); 1171 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
1218 break; 1172 break;
1219 1173
1220 case SND_SOC_BIAS_STANDBY: 1174 case SND_SOC_BIAS_STANDBY:
1221 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1175 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1222 /* Enable all output discharge bits */ 1176 /* Enable all output discharge bits */
1223 wm8990_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1177 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1224 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | 1178 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
1225 WM8990_DIS_OUT4 | WM8990_DIS_LOUT | 1179 WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
1226 WM8990_DIS_ROUT); 1180 WM8990_DIS_ROUT);
1227 1181
1228 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */ 1182 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1229 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1183 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1230 WM8990_BUFDCOPEN | WM8990_POBCTRL | 1184 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1231 WM8990_VMIDTOG); 1185 WM8990_VMIDTOG);
1232 1186
@@ -1234,83 +1188,83 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1234 msleep(msecs_to_jiffies(300)); 1188 msleep(msecs_to_jiffies(300));
1235 1189
1236 /* Disable VMIDTOG */ 1190 /* Disable VMIDTOG */
1237 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1191 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1238 WM8990_BUFDCOPEN | WM8990_POBCTRL); 1192 WM8990_BUFDCOPEN | WM8990_POBCTRL);
1239 1193
1240 /* disable all output discharge bits */ 1194 /* disable all output discharge bits */
1241 wm8990_write(codec, WM8990_ANTIPOP1, 0); 1195 snd_soc_write(codec, WM8990_ANTIPOP1, 0);
1242 1196
1243 /* Enable outputs */ 1197 /* Enable outputs */
1244 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00); 1198 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00);
1245 1199
1246 msleep(msecs_to_jiffies(50)); 1200 msleep(msecs_to_jiffies(50));
1247 1201
1248 /* Enable VMID at 2x50k */ 1202 /* Enable VMID at 2x50k */
1249 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02); 1203 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02);
1250 1204
1251 msleep(msecs_to_jiffies(100)); 1205 msleep(msecs_to_jiffies(100));
1252 1206
1253 /* Enable VREF */ 1207 /* Enable VREF */
1254 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); 1208 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
1255 1209
1256 msleep(msecs_to_jiffies(600)); 1210 msleep(msecs_to_jiffies(600));
1257 1211
1258 /* Enable BUFIOEN */ 1212 /* Enable BUFIOEN */
1259 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1213 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1260 WM8990_BUFDCOPEN | WM8990_POBCTRL | 1214 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1261 WM8990_BUFIOEN); 1215 WM8990_BUFIOEN);
1262 1216
1263 /* Disable outputs */ 1217 /* Disable outputs */
1264 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3); 1218 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3);
1265 1219
1266 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1220 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1267 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN); 1221 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
1268 1222
1269 /* Enable workaround for ADC clocking issue. */ 1223 /* Enable workaround for ADC clocking issue. */
1270 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0x2); 1224 snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
1271 wm8990_write(codec, WM8990_EXT_CTL1, 0xa003); 1225 snd_soc_write(codec, WM8990_EXT_CTL1, 0xa003);
1272 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0); 1226 snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0);
1273 } 1227 }
1274 1228
1275 /* VMID=2*250k */ 1229 /* VMID=2*250k */
1276 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) & 1230 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) &
1277 ~WM8990_VMID_MODE_MASK; 1231 ~WM8990_VMID_MODE_MASK;
1278 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4); 1232 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
1279 break; 1233 break;
1280 1234
1281 case SND_SOC_BIAS_OFF: 1235 case SND_SOC_BIAS_OFF:
1282 /* Enable POBCTRL and SOFT_ST */ 1236 /* Enable POBCTRL and SOFT_ST */
1283 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1237 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1284 WM8990_POBCTRL | WM8990_BUFIOEN); 1238 WM8990_POBCTRL | WM8990_BUFIOEN);
1285 1239
1286 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */ 1240 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1287 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1241 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1288 WM8990_BUFDCOPEN | WM8990_POBCTRL | 1242 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1289 WM8990_BUFIOEN); 1243 WM8990_BUFIOEN);
1290 1244
1291 /* mute DAC */ 1245 /* mute DAC */
1292 val = wm8990_read_reg_cache(codec, WM8990_DAC_CTRL); 1246 val = snd_soc_read(codec, WM8990_DAC_CTRL);
1293 wm8990_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); 1247 snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
1294 1248
1295 /* Enable any disabled outputs */ 1249 /* Enable any disabled outputs */
1296 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); 1250 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
1297 1251
1298 /* Disable VMID */ 1252 /* Disable VMID */
1299 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01); 1253 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01);
1300 1254
1301 msleep(msecs_to_jiffies(300)); 1255 msleep(msecs_to_jiffies(300));
1302 1256
1303 /* Enable all output discharge bits */ 1257 /* Enable all output discharge bits */
1304 wm8990_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1258 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1305 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | 1259 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
1306 WM8990_DIS_OUT4 | WM8990_DIS_LOUT | 1260 WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
1307 WM8990_DIS_ROUT); 1261 WM8990_DIS_ROUT);
1308 1262
1309 /* Disable VREF */ 1263 /* Disable VREF */
1310 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0); 1264 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0);
1311 1265
1312 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1266 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1313 wm8990_write(codec, WM8990_ANTIPOP2, 0x0); 1267 snd_soc_write(codec, WM8990_ANTIPOP2, 0x0);
1314 break; 1268 break;
1315 } 1269 }
1316 1270
@@ -1411,8 +1365,6 @@ static int wm8990_init(struct snd_soc_device *socdev)
1411 1365
1412 codec->name = "WM8990"; 1366 codec->name = "WM8990";
1413 codec->owner = THIS_MODULE; 1367 codec->owner = THIS_MODULE;
1414 codec->read = wm8990_read_reg_cache;
1415 codec->write = wm8990_write;
1416 codec->set_bias_level = wm8990_set_bias_level; 1368 codec->set_bias_level = wm8990_set_bias_level;
1417 codec->dai = &wm8990_dai; 1369 codec->dai = &wm8990_dai;
1418 codec->num_dai = 2; 1370 codec->num_dai = 2;
@@ -1422,6 +1374,12 @@ static int wm8990_init(struct snd_soc_device *socdev)
1422 if (codec->reg_cache == NULL) 1374 if (codec->reg_cache == NULL)
1423 return -ENOMEM; 1375 return -ENOMEM;
1424 1376
1377 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1378 if (ret < 0) {
1379 printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
1380 goto pcm_err;
1381 }
1382
1425 wm8990_reset(codec); 1383 wm8990_reset(codec);
1426 1384
1427 /* register pcms */ 1385 /* register pcms */
@@ -1435,18 +1393,18 @@ static int wm8990_init(struct snd_soc_device *socdev)
1435 codec->bias_level = SND_SOC_BIAS_OFF; 1393 codec->bias_level = SND_SOC_BIAS_OFF;
1436 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1394 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1437 1395
1438 reg = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_4); 1396 reg = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_4);
1439 wm8990_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1); 1397 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1);
1440 1398
1441 reg = wm8990_read_reg_cache(codec, WM8990_GPIO1_GPIO2) & 1399 reg = snd_soc_read(codec, WM8990_GPIO1_GPIO2) &
1442 ~WM8990_GPIO1_SEL_MASK; 1400 ~WM8990_GPIO1_SEL_MASK;
1443 wm8990_write(codec, WM8990_GPIO1_GPIO2, reg | 1); 1401 snd_soc_write(codec, WM8990_GPIO1_GPIO2, reg | 1);
1444 1402
1445 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2); 1403 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
1446 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA); 1404 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA);
1447 1405
1448 wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1406 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1449 wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1407 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1450 1408
1451 snd_soc_add_controls(codec, wm8990_snd_controls, 1409 snd_soc_add_controls(codec, wm8990_snd_controls,
1452 ARRAY_SIZE(wm8990_snd_controls)); 1410 ARRAY_SIZE(wm8990_snd_controls));
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
new file mode 100644
index 000000000000..cd1566931135
--- /dev/null
+++ b/sound/soc/codecs/wm8993.c
@@ -0,0 +1,1534 @@
1/*
2 * wm8993.c -- WM8993 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/spi/spi.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/tlv.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/wm8993.h>
28
29#include "wm8993.h"
30#include "wm_hubs.h"
31
32static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = {
33 0x8993, /* R0 - Software Reset */
34 0x0000, /* R1 - Power Management (1) */
35 0x6000, /* R2 - Power Management (2) */
36 0x0000, /* R3 - Power Management (3) */
37 0x4050, /* R4 - Audio Interface (1) */
38 0x4000, /* R5 - Audio Interface (2) */
39 0x01C8, /* R6 - Clocking 1 */
40 0x0000, /* R7 - Clocking 2 */
41 0x0000, /* R8 - Audio Interface (3) */
42 0x0040, /* R9 - Audio Interface (4) */
43 0x0004, /* R10 - DAC CTRL */
44 0x00C0, /* R11 - Left DAC Digital Volume */
45 0x00C0, /* R12 - Right DAC Digital Volume */
46 0x0000, /* R13 - Digital Side Tone */
47 0x0300, /* R14 - ADC CTRL */
48 0x00C0, /* R15 - Left ADC Digital Volume */
49 0x00C0, /* R16 - Right ADC Digital Volume */
50 0x0000, /* R17 */
51 0x0000, /* R18 - GPIO CTRL 1 */
52 0x0010, /* R19 - GPIO1 */
53 0x0000, /* R20 - IRQ_DEBOUNCE */
54 0x0000, /* R21 */
55 0x8000, /* R22 - GPIOCTRL 2 */
56 0x0800, /* R23 - GPIO_POL */
57 0x008B, /* R24 - Left Line Input 1&2 Volume */
58 0x008B, /* R25 - Left Line Input 3&4 Volume */
59 0x008B, /* R26 - Right Line Input 1&2 Volume */
60 0x008B, /* R27 - Right Line Input 3&4 Volume */
61 0x006D, /* R28 - Left Output Volume */
62 0x006D, /* R29 - Right Output Volume */
63 0x0066, /* R30 - Line Outputs Volume */
64 0x0020, /* R31 - HPOUT2 Volume */
65 0x0079, /* R32 - Left OPGA Volume */
66 0x0079, /* R33 - Right OPGA Volume */
67 0x0003, /* R34 - SPKMIXL Attenuation */
68 0x0003, /* R35 - SPKMIXR Attenuation */
69 0x0011, /* R36 - SPKOUT Mixers */
70 0x0100, /* R37 - SPKOUT Boost */
71 0x0079, /* R38 - Speaker Volume Left */
72 0x0079, /* R39 - Speaker Volume Right */
73 0x0000, /* R40 - Input Mixer2 */
74 0x0000, /* R41 - Input Mixer3 */
75 0x0000, /* R42 - Input Mixer4 */
76 0x0000, /* R43 - Input Mixer5 */
77 0x0000, /* R44 - Input Mixer6 */
78 0x0000, /* R45 - Output Mixer1 */
79 0x0000, /* R46 - Output Mixer2 */
80 0x0000, /* R47 - Output Mixer3 */
81 0x0000, /* R48 - Output Mixer4 */
82 0x0000, /* R49 - Output Mixer5 */
83 0x0000, /* R50 - Output Mixer6 */
84 0x0000, /* R51 - HPOUT2 Mixer */
85 0x0000, /* R52 - Line Mixer1 */
86 0x0000, /* R53 - Line Mixer2 */
87 0x0000, /* R54 - Speaker Mixer */
88 0x0000, /* R55 - Additional Control */
89 0x0000, /* R56 - AntiPOP1 */
90 0x0000, /* R57 - AntiPOP2 */
91 0x0000, /* R58 - MICBIAS */
92 0x0000, /* R59 */
93 0x0000, /* R60 - FLL Control 1 */
94 0x0000, /* R61 - FLL Control 2 */
95 0x0000, /* R62 - FLL Control 3 */
96 0x2EE0, /* R63 - FLL Control 4 */
97 0x0002, /* R64 - FLL Control 5 */
98 0x2287, /* R65 - Clocking 3 */
99 0x025F, /* R66 - Clocking 4 */
100 0x0000, /* R67 - MW Slave Control */
101 0x0000, /* R68 */
102 0x0002, /* R69 - Bus Control 1 */
103 0x0000, /* R70 - Write Sequencer 0 */
104 0x0000, /* R71 - Write Sequencer 1 */
105 0x0000, /* R72 - Write Sequencer 2 */
106 0x0000, /* R73 - Write Sequencer 3 */
107 0x0000, /* R74 - Write Sequencer 4 */
108 0x0000, /* R75 - Write Sequencer 5 */
109 0x1F25, /* R76 - Charge Pump 1 */
110 0x0000, /* R77 */
111 0x0000, /* R78 */
112 0x0000, /* R79 */
113 0x0000, /* R80 */
114 0x0000, /* R81 - Class W 0 */
115 0x0000, /* R82 */
116 0x0000, /* R83 */
117 0x0000, /* R84 - DC Servo 0 */
118 0x054A, /* R85 - DC Servo 1 */
119 0x0000, /* R86 */
120 0x0000, /* R87 - DC Servo 3 */
121 0x0000, /* R88 - DC Servo Readback 0 */
122 0x0000, /* R89 - DC Servo Readback 1 */
123 0x0000, /* R90 - DC Servo Readback 2 */
124 0x0000, /* R91 */
125 0x0000, /* R92 */
126 0x0000, /* R93 */
127 0x0000, /* R94 */
128 0x0000, /* R95 */
129 0x0100, /* R96 - Analogue HP 0 */
130 0x0000, /* R97 */
131 0x0000, /* R98 - EQ1 */
132 0x000C, /* R99 - EQ2 */
133 0x000C, /* R100 - EQ3 */
134 0x000C, /* R101 - EQ4 */
135 0x000C, /* R102 - EQ5 */
136 0x000C, /* R103 - EQ6 */
137 0x0FCA, /* R104 - EQ7 */
138 0x0400, /* R105 - EQ8 */
139 0x00D8, /* R106 - EQ9 */
140 0x1EB5, /* R107 - EQ10 */
141 0xF145, /* R108 - EQ11 */
142 0x0B75, /* R109 - EQ12 */
143 0x01C5, /* R110 - EQ13 */
144 0x1C58, /* R111 - EQ14 */
145 0xF373, /* R112 - EQ15 */
146 0x0A54, /* R113 - EQ16 */
147 0x0558, /* R114 - EQ17 */
148 0x168E, /* R115 - EQ18 */
149 0xF829, /* R116 - EQ19 */
150 0x07AD, /* R117 - EQ20 */
151 0x1103, /* R118 - EQ21 */
152 0x0564, /* R119 - EQ22 */
153 0x0559, /* R120 - EQ23 */
154 0x4000, /* R121 - EQ24 */
155 0x0000, /* R122 - Digital Pulls */
156 0x0F08, /* R123 - DRC Control 1 */
157 0x0000, /* R124 - DRC Control 2 */
158 0x0080, /* R125 - DRC Control 3 */
159 0x0000, /* R126 - DRC Control 4 */
160};
161
162static struct {
163 int ratio;
164 int clk_sys_rate;
165} clk_sys_rates[] = {
166 { 64, 0 },
167 { 128, 1 },
168 { 192, 2 },
169 { 256, 3 },
170 { 384, 4 },
171 { 512, 5 },
172 { 768, 6 },
173 { 1024, 7 },
174 { 1408, 8 },
175 { 1536, 9 },
176};
177
178static struct {
179 int rate;
180 int sample_rate;
181} sample_rates[] = {
182 { 8000, 0 },
183 { 11025, 1 },
184 { 12000, 1 },
185 { 16000, 2 },
186 { 22050, 3 },
187 { 24000, 3 },
188 { 32000, 4 },
189 { 44100, 5 },
190 { 48000, 5 },
191};
192
193static struct {
194 int div; /* *10 due to .5s */
195 int bclk_div;
196} bclk_divs[] = {
197 { 10, 0 },
198 { 15, 1 },
199 { 20, 2 },
200 { 30, 3 },
201 { 40, 4 },
202 { 55, 5 },
203 { 60, 6 },
204 { 80, 7 },
205 { 110, 8 },
206 { 120, 9 },
207 { 160, 10 },
208 { 220, 11 },
209 { 240, 12 },
210 { 320, 13 },
211 { 440, 14 },
212 { 480, 15 },
213};
214
215struct wm8993_priv {
216 u16 reg_cache[WM8993_REGISTER_COUNT];
217 struct wm8993_platform_data pdata;
218 struct snd_soc_codec codec;
219 int master;
220 int sysclk_source;
221 unsigned int mclk_rate;
222 unsigned int sysclk_rate;
223 unsigned int fs;
224 unsigned int bclk;
225 int class_w_users;
226 unsigned int fll_fref;
227 unsigned int fll_fout;
228};
229
230static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg)
231{
232 struct i2c_msg xfer[2];
233 u16 data;
234 int ret;
235 struct i2c_client *i2c = codec->control_data;
236
237 /* Write register */
238 xfer[0].addr = i2c->addr;
239 xfer[0].flags = 0;
240 xfer[0].len = 1;
241 xfer[0].buf = &reg;
242
243 /* Read data */
244 xfer[1].addr = i2c->addr;
245 xfer[1].flags = I2C_M_RD;
246 xfer[1].len = 2;
247 xfer[1].buf = (u8 *)&data;
248
249 ret = i2c_transfer(i2c->adapter, xfer, 2);
250 if (ret != 2) {
251 dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret);
252 return 0;
253 }
254
255 return (data >> 8) | ((data & 0xff) << 8);
256}
257
258static int wm8993_volatile(unsigned int reg)
259{
260 switch (reg) {
261 case WM8993_SOFTWARE_RESET:
262 case WM8993_DC_SERVO_0:
263 case WM8993_DC_SERVO_READBACK_0:
264 case WM8993_DC_SERVO_READBACK_1:
265 case WM8993_DC_SERVO_READBACK_2:
266 return 1;
267 default:
268 return 0;
269 }
270}
271
272static unsigned int wm8993_read(struct snd_soc_codec *codec,
273 unsigned int reg)
274{
275 u16 *reg_cache = codec->reg_cache;
276
277 BUG_ON(reg > WM8993_MAX_REGISTER);
278
279 if (wm8993_volatile(reg))
280 return wm8993_read_hw(codec, reg);
281 else
282 return reg_cache[reg];
283}
284
285static int wm8993_write(struct snd_soc_codec *codec, unsigned int reg,
286 unsigned int value)
287{
288 u16 *reg_cache = codec->reg_cache;
289 u8 data[3];
290 int ret;
291
292 BUG_ON(reg > WM8993_MAX_REGISTER);
293
294 /* data is
295 * D15..D9 WM8993 register offset
296 * D8...D0 register data
297 */
298 data[0] = reg;
299 data[1] = value >> 8;
300 data[2] = value & 0x00ff;
301
302 if (!wm8993_volatile(reg))
303 reg_cache[reg] = value;
304
305 ret = codec->hw_write(codec->control_data, data, 3);
306
307 if (ret == 3)
308 return 0;
309 if (ret < 0)
310 return ret;
311 return -EIO;
312}
313
314struct _fll_div {
315 u16 fll_fratio;
316 u16 fll_outdiv;
317 u16 fll_clk_ref_div;
318 u16 n;
319 u16 k;
320};
321
322/* The size in bits of the FLL divide multiplied by 10
323 * to allow rounding later */
324#define FIXED_FLL_SIZE ((1 << 16) * 10)
325
326static struct {
327 unsigned int min;
328 unsigned int max;
329 u16 fll_fratio;
330 int ratio;
331} fll_fratios[] = {
332 { 0, 64000, 4, 16 },
333 { 64000, 128000, 3, 8 },
334 { 128000, 256000, 2, 4 },
335 { 256000, 1000000, 1, 2 },
336 { 1000000, 13500000, 0, 1 },
337};
338
339static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
340 unsigned int Fout)
341{
342 u64 Kpart;
343 unsigned int K, Ndiv, Nmod, target;
344 unsigned int div;
345 int i;
346
347 /* Fref must be <=13.5MHz */
348 div = 1;
349 fll_div->fll_clk_ref_div = 0;
350 while ((Fref / div) > 13500000) {
351 div *= 2;
352 fll_div->fll_clk_ref_div++;
353
354 if (div > 8) {
355 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
356 Fref);
357 return -EINVAL;
358 }
359 }
360
361 pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
362
363 /* Apply the division for our remaining calculations */
364 Fref /= div;
365
366 /* Fvco should be 90-100MHz; don't check the upper bound */
367 div = 0;
368 target = Fout * 2;
369 while (target < 90000000) {
370 div++;
371 target *= 2;
372 if (div > 7) {
373 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
374 Fout);
375 return -EINVAL;
376 }
377 }
378 fll_div->fll_outdiv = div;
379
380 pr_debug("Fvco=%dHz\n", target);
381
382 /* Find an appropraite FLL_FRATIO and factor it out of the target */
383 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
384 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
385 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
386 target /= fll_fratios[i].ratio;
387 break;
388 }
389 }
390 if (i == ARRAY_SIZE(fll_fratios)) {
391 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
392 return -EINVAL;
393 }
394
395 /* Now, calculate N.K */
396 Ndiv = target / Fref;
397
398 fll_div->n = Ndiv;
399 Nmod = target % Fref;
400 pr_debug("Nmod=%d\n", Nmod);
401
402 /* Calculate fractional part - scale up so we can round. */
403 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
404
405 do_div(Kpart, Fref);
406
407 K = Kpart & 0xFFFFFFFF;
408
409 if ((K % 10) >= 5)
410 K += 5;
411
412 /* Move down to proper range now rounding is done */
413 fll_div->k = K / 10;
414
415 pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
416 fll_div->n, fll_div->k,
417 fll_div->fll_fratio, fll_div->fll_outdiv,
418 fll_div->fll_clk_ref_div);
419
420 return 0;
421}
422
423static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id,
424 unsigned int Fref, unsigned int Fout)
425{
426 struct snd_soc_codec *codec = dai->codec;
427 struct wm8993_priv *wm8993 = codec->private_data;
428 u16 reg1, reg4, reg5;
429 struct _fll_div fll_div;
430 int ret;
431
432 /* Any change? */
433 if (Fref == wm8993->fll_fref && Fout == wm8993->fll_fout)
434 return 0;
435
436 /* Disable the FLL */
437 if (Fout == 0) {
438 dev_dbg(codec->dev, "FLL disabled\n");
439 wm8993->fll_fref = 0;
440 wm8993->fll_fout = 0;
441
442 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1);
443 reg1 &= ~WM8993_FLL_ENA;
444 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1);
445
446 return 0;
447 }
448
449 ret = fll_factors(&fll_div, Fref, Fout);
450 if (ret != 0)
451 return ret;
452
453 reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5);
454 reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
455
456 switch (fll_id) {
457 case WM8993_FLL_MCLK:
458 break;
459
460 case WM8993_FLL_LRCLK:
461 reg5 |= 1;
462 break;
463
464 case WM8993_FLL_BCLK:
465 reg5 |= 2;
466 break;
467
468 default:
469 dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
470 return -EINVAL;
471 }
472
473 /* Any FLL configuration change requires that the FLL be
474 * disabled first. */
475 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1);
476 reg1 &= ~WM8993_FLL_ENA;
477 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1);
478
479 /* Apply the configuration */
480 if (fll_div.k)
481 reg1 |= WM8993_FLL_FRAC_MASK;
482 else
483 reg1 &= ~WM8993_FLL_FRAC_MASK;
484 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1);
485
486 wm8993_write(codec, WM8993_FLL_CONTROL_2,
487 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
488 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
489 wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
490
491 reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4);
492 reg4 &= ~WM8993_FLL_N_MASK;
493 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
494 wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4);
495
496 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
497 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
498 wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5);
499
500 /* Enable the FLL */
501 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
502
503 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
504
505 wm8993->fll_fref = Fref;
506 wm8993->fll_fout = Fout;
507
508 return 0;
509}
510
511static int configure_clock(struct snd_soc_codec *codec)
512{
513 struct wm8993_priv *wm8993 = codec->private_data;
514 unsigned int reg;
515
516 /* This should be done on init() for bypass paths */
517 switch (wm8993->sysclk_source) {
518 case WM8993_SYSCLK_MCLK:
519 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
520
521 reg = wm8993_read(codec, WM8993_CLOCKING_2);
522 reg &= ~WM8993_SYSCLK_SRC;
523 if (wm8993->mclk_rate > 13500000) {
524 reg |= WM8993_MCLK_DIV;
525 wm8993->sysclk_rate = wm8993->mclk_rate / 2;
526 } else {
527 reg &= ~WM8993_MCLK_DIV;
528 wm8993->sysclk_rate = wm8993->mclk_rate;
529 }
530 reg &= ~WM8993_MCLK_DIV;
531 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
532 wm8993_write(codec, WM8993_CLOCKING_2, reg);
533 break;
534
535 case WM8993_SYSCLK_FLL:
536 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
537 wm8993->fll_fout);
538
539 reg = wm8993_read(codec, WM8993_CLOCKING_2);
540 reg |= WM8993_SYSCLK_SRC;
541 if (wm8993->fll_fout > 13500000) {
542 reg |= WM8993_MCLK_DIV;
543 wm8993->sysclk_rate = wm8993->fll_fout / 2;
544 } else {
545 reg &= ~WM8993_MCLK_DIV;
546 wm8993->sysclk_rate = wm8993->fll_fout;
547 }
548 wm8993_write(codec, WM8993_CLOCKING_2, reg);
549 break;
550
551 default:
552 dev_err(codec->dev, "System clock not configured\n");
553 return -EINVAL;
554 }
555
556 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8993->sysclk_rate);
557
558 return 0;
559}
560
561static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
562static const DECLARE_TLV_DB_SCALE(drc_comp_threash, -4500, 75, 0);
563static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0);
564static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0);
565static const unsigned int drc_max_tlv[] = {
566 TLV_DB_RANGE_HEAD(4),
567 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
568 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0),
569};
570static const DECLARE_TLV_DB_SCALE(drc_qr_tlv, 1200, 600, 0);
571static const DECLARE_TLV_DB_SCALE(drc_startup_tlv, -1800, 300, 0);
572static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
573static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
574static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
575
576static const char *dac_deemph_text[] = {
577 "None",
578 "32kHz",
579 "44.1kHz",
580 "48kHz",
581};
582
583static const struct soc_enum dac_deemph =
584 SOC_ENUM_SINGLE(WM8993_DAC_CTRL, 4, 4, dac_deemph_text);
585
586static const char *adc_hpf_text[] = {
587 "Hi-Fi",
588 "Voice 1",
589 "Voice 2",
590 "Voice 3",
591};
592
593static const struct soc_enum adc_hpf =
594 SOC_ENUM_SINGLE(WM8993_ADC_CTRL, 5, 4, adc_hpf_text);
595
596static const char *drc_path_text[] = {
597 "ADC",
598 "DAC"
599};
600
601static const struct soc_enum drc_path =
602 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 14, 2, drc_path_text);
603
604static const char *drc_r0_text[] = {
605 "1",
606 "1/2",
607 "1/4",
608 "1/8",
609 "1/16",
610 "0",
611};
612
613static const struct soc_enum drc_r0 =
614 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 8, 6, drc_r0_text);
615
616static const char *drc_r1_text[] = {
617 "1",
618 "1/2",
619 "1/4",
620 "1/8",
621 "0",
622};
623
624static const struct soc_enum drc_r1 =
625 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_4, 13, 5, drc_r1_text);
626
627static const char *drc_attack_text[] = {
628 "Reserved",
629 "181us",
630 "363us",
631 "726us",
632 "1.45ms",
633 "2.9ms",
634 "5.8ms",
635 "11.6ms",
636 "23.2ms",
637 "46.4ms",
638 "92.8ms",
639 "185.6ms",
640};
641
642static const struct soc_enum drc_attack =
643 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_2, 12, 12, drc_attack_text);
644
645static const char *drc_decay_text[] = {
646 "186ms",
647 "372ms",
648 "743ms",
649 "1.49s",
650 "2.97ms",
651 "5.94ms",
652 "11.89ms",
653 "23.78ms",
654 "47.56ms",
655};
656
657static const struct soc_enum drc_decay =
658 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_2, 8, 9, drc_decay_text);
659
660static const char *drc_ff_text[] = {
661 "5 samples",
662 "9 samples",
663};
664
665static const struct soc_enum drc_ff =
666 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 7, 2, drc_ff_text);
667
668static const char *drc_qr_rate_text[] = {
669 "0.725ms",
670 "1.45ms",
671 "5.8ms",
672};
673
674static const struct soc_enum drc_qr_rate =
675 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 0, 3, drc_qr_rate_text);
676
677static const char *drc_smooth_text[] = {
678 "Low",
679 "Medium",
680 "High",
681};
682
683static const struct soc_enum drc_smooth =
684 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 4, 3, drc_smooth_text);
685
686static const struct snd_kcontrol_new wm8993_snd_controls[] = {
687SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE,
688 5, 9, 12, 0, sidetone_tlv),
689
690SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0),
691SOC_ENUM("DRC Path", drc_path),
692SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8993_DRC_CONTROL_2,
693 2, 60, 1, drc_comp_threash),
694SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3,
695 11, 30, 1, drc_comp_amp),
696SOC_ENUM("DRC R0", drc_r0),
697SOC_ENUM("DRC R1", drc_r1),
698SOC_SINGLE_TLV("DRC Minimum Volume", WM8993_DRC_CONTROL_1, 2, 3, 1,
699 drc_min_tlv),
700SOC_SINGLE_TLV("DRC Maximum Volume", WM8993_DRC_CONTROL_1, 0, 3, 0,
701 drc_max_tlv),
702SOC_ENUM("DRC Attack Rate", drc_attack),
703SOC_ENUM("DRC Decay Rate", drc_decay),
704SOC_ENUM("DRC FF Delay", drc_ff),
705SOC_SINGLE("DRC Anti-clip Switch", WM8993_DRC_CONTROL_1, 9, 1, 0),
706SOC_SINGLE("DRC Quick Release Switch", WM8993_DRC_CONTROL_1, 10, 1, 0),
707SOC_SINGLE_TLV("DRC Quick Release Volume", WM8993_DRC_CONTROL_3, 2, 3, 0,
708 drc_qr_tlv),
709SOC_ENUM("DRC Quick Release Rate", drc_qr_rate),
710SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0),
711SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0),
712SOC_ENUM("DRC Smoothing Hysteresis Threashold", drc_smooth),
713SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0,
714 drc_startup_tlv),
715
716SOC_SINGLE("EQ Switch", WM8993_EQ1, 0, 1, 0),
717
718SOC_DOUBLE_R_TLV("Capture Volume", WM8993_LEFT_ADC_DIGITAL_VOLUME,
719 WM8993_RIGHT_ADC_DIGITAL_VOLUME, 1, 96, 0, digital_tlv),
720SOC_SINGLE("ADC High Pass Filter Switch", WM8993_ADC_CTRL, 8, 1, 0),
721SOC_ENUM("ADC High Pass Filter Mode", adc_hpf),
722
723SOC_DOUBLE_R_TLV("Playback Volume", WM8993_LEFT_DAC_DIGITAL_VOLUME,
724 WM8993_RIGHT_DAC_DIGITAL_VOLUME, 1, 96, 0, digital_tlv),
725SOC_SINGLE_TLV("Playback Boost Volume", WM8993_AUDIO_INTERFACE_2, 10, 3, 0,
726 dac_boost_tlv),
727SOC_ENUM("DAC Deemphasis", dac_deemph),
728
729SOC_SINGLE_TLV("SPKL DAC Volume", WM8993_SPKMIXL_ATTENUATION,
730 2, 1, 1, wm_hubs_spkmix_tlv),
731
732SOC_SINGLE_TLV("SPKR DAC Volume", WM8993_SPKMIXR_ATTENUATION,
733 2, 1, 1, wm_hubs_spkmix_tlv),
734};
735
736static const struct snd_kcontrol_new wm8993_eq_controls[] = {
737SOC_SINGLE_TLV("EQ1 Volume", WM8993_EQ2, 0, 24, 0, eq_tlv),
738SOC_SINGLE_TLV("EQ2 Volume", WM8993_EQ3, 0, 24, 0, eq_tlv),
739SOC_SINGLE_TLV("EQ3 Volume", WM8993_EQ4, 0, 24, 0, eq_tlv),
740SOC_SINGLE_TLV("EQ4 Volume", WM8993_EQ5, 0, 24, 0, eq_tlv),
741SOC_SINGLE_TLV("EQ5 Volume", WM8993_EQ6, 0, 24, 0, eq_tlv),
742};
743
744static int clk_sys_event(struct snd_soc_dapm_widget *w,
745 struct snd_kcontrol *kcontrol, int event)
746{
747 struct snd_soc_codec *codec = w->codec;
748
749 switch (event) {
750 case SND_SOC_DAPM_PRE_PMU:
751 return configure_clock(codec);
752
753 case SND_SOC_DAPM_POST_PMD:
754 break;
755 }
756
757 return 0;
758}
759
760/*
761 * When used with DAC outputs only the WM8993 charge pump supports
762 * operation in class W mode, providing very low power consumption
763 * when used with digital sources. Enable and disable this mode
764 * automatically depending on the mixer configuration.
765 *
766 * Currently the only supported paths are the direct DAC->headphone
767 * paths (which provide minimum power consumption anyway).
768 */
769static int class_w_put(struct snd_kcontrol *kcontrol,
770 struct snd_ctl_elem_value *ucontrol)
771{
772 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
773 struct snd_soc_codec *codec = widget->codec;
774 struct wm8993_priv *wm8993 = codec->private_data;
775 int ret;
776
777 /* Turn it off if we're using the main output mixer */
778 if (ucontrol->value.integer.value[0] == 0) {
779 if (wm8993->class_w_users == 0) {
780 dev_dbg(codec->dev, "Disabling Class W\n");
781 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
782 WM8993_CP_DYN_FREQ |
783 WM8993_CP_DYN_V,
784 0);
785 }
786 wm8993->class_w_users++;
787 }
788
789 /* Implement the change */
790 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
791
792 /* Enable it if we're using the direct DAC path */
793 if (ucontrol->value.integer.value[0] == 1) {
794 if (wm8993->class_w_users == 1) {
795 dev_dbg(codec->dev, "Enabling Class W\n");
796 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
797 WM8993_CP_DYN_FREQ |
798 WM8993_CP_DYN_V,
799 WM8993_CP_DYN_FREQ |
800 WM8993_CP_DYN_V);
801 }
802 wm8993->class_w_users--;
803 }
804
805 dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
806 wm8993->class_w_users);
807
808 return ret;
809}
810
811#define SOC_DAPM_ENUM_W(xname, xenum) \
812{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
813 .info = snd_soc_info_enum_double, \
814 .get = snd_soc_dapm_get_enum_double, \
815 .put = class_w_put, \
816 .private_value = (unsigned long)&xenum }
817
818static const char *hp_mux_text[] = {
819 "Mixer",
820 "DAC",
821};
822
823static const struct soc_enum hpl_enum =
824 SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER1, 8, 2, hp_mux_text);
825
826static const struct snd_kcontrol_new hpl_mux =
827 SOC_DAPM_ENUM_W("Left Headphone Mux", hpl_enum);
828
829static const struct soc_enum hpr_enum =
830 SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER2, 8, 2, hp_mux_text);
831
832static const struct snd_kcontrol_new hpr_mux =
833 SOC_DAPM_ENUM_W("Right Headphone Mux", hpr_enum);
834
835static const struct snd_kcontrol_new left_speaker_mixer[] = {
836SOC_DAPM_SINGLE("Input Switch", WM8993_SPEAKER_MIXER, 7, 1, 0),
837SOC_DAPM_SINGLE("IN1LP Switch", WM8993_SPEAKER_MIXER, 5, 1, 0),
838SOC_DAPM_SINGLE("Output Switch", WM8993_SPEAKER_MIXER, 3, 1, 0),
839SOC_DAPM_SINGLE("DAC Switch", WM8993_SPEAKER_MIXER, 6, 1, 0),
840};
841
842static const struct snd_kcontrol_new right_speaker_mixer[] = {
843SOC_DAPM_SINGLE("Input Switch", WM8993_SPEAKER_MIXER, 6, 1, 0),
844SOC_DAPM_SINGLE("IN1RP Switch", WM8993_SPEAKER_MIXER, 4, 1, 0),
845SOC_DAPM_SINGLE("Output Switch", WM8993_SPEAKER_MIXER, 2, 1, 0),
846SOC_DAPM_SINGLE("DAC Switch", WM8993_SPEAKER_MIXER, 0, 1, 0),
847};
848
849static const struct snd_soc_dapm_widget wm8993_dapm_widgets[] = {
850SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8993_BUS_CONTROL_1, 1, 0, clk_sys_event,
851 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
852SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0),
853SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0),
854
855
856SND_SOC_DAPM_ADC("ADCL", "Capture", WM8993_POWER_MANAGEMENT_2, 1, 0),
857SND_SOC_DAPM_ADC("ADCR", "Capture", WM8993_POWER_MANAGEMENT_2, 0, 0),
858
859SND_SOC_DAPM_DAC("DACL", "Playback", WM8993_POWER_MANAGEMENT_3, 1, 0),
860SND_SOC_DAPM_DAC("DACR", "Playback", WM8993_POWER_MANAGEMENT_3, 0, 0),
861
862SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
863SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
864
865SND_SOC_DAPM_MIXER("SPKL", WM8993_POWER_MANAGEMENT_3, 8, 0,
866 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
867SND_SOC_DAPM_MIXER("SPKR", WM8993_POWER_MANAGEMENT_3, 9, 0,
868 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
869
870};
871
872static const struct snd_soc_dapm_route routes[] = {
873 { "ADCL", NULL, "CLK_SYS" },
874 { "ADCL", NULL, "CLK_DSP" },
875 { "ADCR", NULL, "CLK_SYS" },
876 { "ADCR", NULL, "CLK_DSP" },
877
878 { "DACL", NULL, "CLK_SYS" },
879 { "DACL", NULL, "CLK_DSP" },
880 { "DACR", NULL, "CLK_SYS" },
881 { "DACR", NULL, "CLK_DSP" },
882
883 { "Left Output Mixer", "DAC Switch", "DACL" },
884
885 { "Right Output Mixer", "DAC Switch", "DACR" },
886
887 { "Left Output PGA", NULL, "CLK_SYS" },
888
889 { "Right Output PGA", NULL, "CLK_SYS" },
890
891 { "SPKL", "DAC Switch", "DACL" },
892 { "SPKL", NULL, "CLK_SYS" },
893
894 { "SPKR", "DAC Switch", "DACR" },
895 { "SPKR", NULL, "CLK_SYS" },
896
897 { "Left Headphone Mux", "DAC", "DACL" },
898 { "Right Headphone Mux", "DAC", "DACR" },
899};
900
901static int wm8993_set_bias_level(struct snd_soc_codec *codec,
902 enum snd_soc_bias_level level)
903{
904 struct wm8993_priv *wm8993 = codec->private_data;
905
906 switch (level) {
907 case SND_SOC_BIAS_ON:
908 case SND_SOC_BIAS_PREPARE:
909 /* VMID=2*40k */
910 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
911 WM8993_VMID_SEL_MASK, 0x2);
912 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
913 WM8993_TSHUT_ENA, WM8993_TSHUT_ENA);
914 break;
915
916 case SND_SOC_BIAS_STANDBY:
917 if (codec->bias_level == SND_SOC_BIAS_OFF) {
918 /* Bring up VMID with fast soft start */
919 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
920 WM8993_STARTUP_BIAS_ENA |
921 WM8993_VMID_BUF_ENA |
922 WM8993_VMID_RAMP_MASK |
923 WM8993_BIAS_SRC,
924 WM8993_STARTUP_BIAS_ENA |
925 WM8993_VMID_BUF_ENA |
926 WM8993_VMID_RAMP_MASK |
927 WM8993_BIAS_SRC);
928
929 /* If either line output is single ended we
930 * need the VMID buffer */
931 if (!wm8993->pdata.lineout1_diff ||
932 !wm8993->pdata.lineout2_diff)
933 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
934 WM8993_LINEOUT_VMID_BUF_ENA,
935 WM8993_LINEOUT_VMID_BUF_ENA);
936
937 /* VMID=2*40k */
938 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
939 WM8993_VMID_SEL_MASK |
940 WM8993_BIAS_ENA,
941 WM8993_BIAS_ENA | 0x2);
942 msleep(32);
943
944 /* Switch to normal bias */
945 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
946 WM8993_BIAS_SRC |
947 WM8993_STARTUP_BIAS_ENA, 0);
948 }
949
950 /* VMID=2*240k */
951 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
952 WM8993_VMID_SEL_MASK, 0x4);
953
954 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
955 WM8993_TSHUT_ENA, 0);
956 break;
957
958 case SND_SOC_BIAS_OFF:
959 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
960 WM8993_LINEOUT_VMID_BUF_ENA, 0);
961
962 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
963 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
964 0);
965 break;
966 }
967
968 codec->bias_level = level;
969
970 return 0;
971}
972
973static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
974 int clk_id, unsigned int freq, int dir)
975{
976 struct snd_soc_codec *codec = codec_dai->codec;
977 struct wm8993_priv *wm8993 = codec->private_data;
978
979 switch (clk_id) {
980 case WM8993_SYSCLK_MCLK:
981 wm8993->mclk_rate = freq;
982 case WM8993_SYSCLK_FLL:
983 wm8993->sysclk_source = clk_id;
984 break;
985
986 default:
987 return -EINVAL;
988 }
989
990 return 0;
991}
992
993static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
994 unsigned int fmt)
995{
996 struct snd_soc_codec *codec = dai->codec;
997 struct wm8993_priv *wm8993 = codec->private_data;
998 unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1);
999 unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4);
1000
1001 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1002 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
1003 aif4 &= ~WM8993_LRCLK_DIR;
1004
1005 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1006 case SND_SOC_DAIFMT_CBS_CFS:
1007 wm8993->master = 0;
1008 break;
1009 case SND_SOC_DAIFMT_CBS_CFM:
1010 aif4 |= WM8993_LRCLK_DIR;
1011 wm8993->master = 1;
1012 break;
1013 case SND_SOC_DAIFMT_CBM_CFS:
1014 aif1 |= WM8993_BCLK_DIR;
1015 wm8993->master = 1;
1016 break;
1017 case SND_SOC_DAIFMT_CBM_CFM:
1018 aif1 |= WM8993_BCLK_DIR;
1019 aif4 |= WM8993_LRCLK_DIR;
1020 wm8993->master = 1;
1021 break;
1022 default:
1023 return -EINVAL;
1024 }
1025
1026 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1027 case SND_SOC_DAIFMT_DSP_B:
1028 aif1 |= WM8993_AIF_LRCLK_INV;
1029 case SND_SOC_DAIFMT_DSP_A:
1030 aif1 |= 0x18;
1031 break;
1032 case SND_SOC_DAIFMT_I2S:
1033 aif1 |= 0x10;
1034 break;
1035 case SND_SOC_DAIFMT_RIGHT_J:
1036 break;
1037 case SND_SOC_DAIFMT_LEFT_J:
1038 aif1 |= 0x8;
1039 break;
1040 default:
1041 return -EINVAL;
1042 }
1043
1044 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1045 case SND_SOC_DAIFMT_DSP_A:
1046 case SND_SOC_DAIFMT_DSP_B:
1047 /* frame inversion not valid for DSP modes */
1048 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1049 case SND_SOC_DAIFMT_NB_NF:
1050 break;
1051 case SND_SOC_DAIFMT_IB_NF:
1052 aif1 |= WM8993_AIF_BCLK_INV;
1053 break;
1054 default:
1055 return -EINVAL;
1056 }
1057 break;
1058
1059 case SND_SOC_DAIFMT_I2S:
1060 case SND_SOC_DAIFMT_RIGHT_J:
1061 case SND_SOC_DAIFMT_LEFT_J:
1062 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1063 case SND_SOC_DAIFMT_NB_NF:
1064 break;
1065 case SND_SOC_DAIFMT_IB_IF:
1066 aif1 |= WM8993_AIF_BCLK_INV | WM8993_AIF_LRCLK_INV;
1067 break;
1068 case SND_SOC_DAIFMT_IB_NF:
1069 aif1 |= WM8993_AIF_BCLK_INV;
1070 break;
1071 case SND_SOC_DAIFMT_NB_IF:
1072 aif1 |= WM8993_AIF_LRCLK_INV;
1073 break;
1074 default:
1075 return -EINVAL;
1076 }
1077 break;
1078 default:
1079 return -EINVAL;
1080 }
1081
1082 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1083 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1084
1085 return 0;
1086}
1087
1088static int wm8993_hw_params(struct snd_pcm_substream *substream,
1089 struct snd_pcm_hw_params *params,
1090 struct snd_soc_dai *dai)
1091{
1092 struct snd_soc_codec *codec = dai->codec;
1093 struct wm8993_priv *wm8993 = codec->private_data;
1094 int ret, i, best, best_val, cur_val;
1095 unsigned int clocking1, clocking3, aif1, aif4;
1096
1097 clocking1 = wm8993_read(codec, WM8993_CLOCKING_1);
1098 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1099
1100 clocking3 = wm8993_read(codec, WM8993_CLOCKING_3);
1101 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
1102
1103 aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1);
1104 aif1 &= ~WM8993_AIF_WL_MASK;
1105
1106 aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4);
1107 aif4 &= ~WM8993_LRCLK_RATE_MASK;
1108
1109 /* What BCLK do we need? */
1110 wm8993->fs = params_rate(params);
1111 wm8993->bclk = 2 * wm8993->fs;
1112 switch (params_format(params)) {
1113 case SNDRV_PCM_FORMAT_S16_LE:
1114 wm8993->bclk *= 16;
1115 break;
1116 case SNDRV_PCM_FORMAT_S20_3LE:
1117 wm8993->bclk *= 20;
1118 aif1 |= 0x8;
1119 break;
1120 case SNDRV_PCM_FORMAT_S24_LE:
1121 wm8993->bclk *= 24;
1122 aif1 |= 0x10;
1123 break;
1124 case SNDRV_PCM_FORMAT_S32_LE:
1125 wm8993->bclk *= 32;
1126 aif1 |= 0x18;
1127 break;
1128 default:
1129 return -EINVAL;
1130 }
1131
1132 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8993->bclk);
1133
1134 ret = configure_clock(codec);
1135 if (ret != 0)
1136 return ret;
1137
1138 /* Select nearest CLK_SYS_RATE */
1139 best = 0;
1140 best_val = abs((wm8993->sysclk_rate / clk_sys_rates[0].ratio)
1141 - wm8993->fs);
1142 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1143 cur_val = abs((wm8993->sysclk_rate /
1144 clk_sys_rates[i].ratio) - wm8993->fs);;
1145 if (cur_val < best_val) {
1146 best = i;
1147 best_val = cur_val;
1148 }
1149 }
1150 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1151 clk_sys_rates[best].ratio);
1152 clocking3 |= (clk_sys_rates[best].clk_sys_rate
1153 << WM8993_CLK_SYS_RATE_SHIFT);
1154
1155 /* SAMPLE_RATE */
1156 best = 0;
1157 best_val = abs(wm8993->fs - sample_rates[0].rate);
1158 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1159 /* Closest match */
1160 cur_val = abs(wm8993->fs - sample_rates[i].rate);
1161 if (cur_val < best_val) {
1162 best = i;
1163 best_val = cur_val;
1164 }
1165 }
1166 dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
1167 sample_rates[best].rate);
1168 clocking3 |= (sample_rates[best].sample_rate
1169 << WM8993_SAMPLE_RATE_SHIFT);
1170
1171 /* BCLK_DIV */
1172 best = 0;
1173 best_val = INT_MAX;
1174 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1175 cur_val = ((wm8993->sysclk_rate * 10) / bclk_divs[i].div)
1176 - wm8993->bclk;
1177 if (cur_val < 0) /* Table is sorted */
1178 break;
1179 if (cur_val < best_val) {
1180 best = i;
1181 best_val = cur_val;
1182 }
1183 }
1184 wm8993->bclk = (wm8993->sysclk_rate * 10) / bclk_divs[best].div;
1185 dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
1186 bclk_divs[best].div, wm8993->bclk);
1187 clocking1 |= bclk_divs[best].bclk_div << WM8993_BCLK_DIV_SHIFT;
1188
1189 /* LRCLK is a simple fraction of BCLK */
1190 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
1191 aif4 |= wm8993->bclk / wm8993->fs;
1192
1193 wm8993_write(codec, WM8993_CLOCKING_1, clocking1);
1194 wm8993_write(codec, WM8993_CLOCKING_3, clocking3);
1195 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1196 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1197
1198 /* ReTune Mobile? */
1199 if (wm8993->pdata.num_retune_configs) {
1200 u16 eq1 = wm8993_read(codec, WM8993_EQ1);
1201 struct wm8993_retune_mobile_setting *s;
1202
1203 best = 0;
1204 best_val = abs(wm8993->pdata.retune_configs[0].rate
1205 - wm8993->fs);
1206 for (i = 0; i < wm8993->pdata.num_retune_configs; i++) {
1207 cur_val = abs(wm8993->pdata.retune_configs[i].rate
1208 - wm8993->fs);
1209 if (cur_val < best_val) {
1210 best_val = cur_val;
1211 best = i;
1212 }
1213 }
1214 s = &wm8993->pdata.retune_configs[best];
1215
1216 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
1217 s->name, s->rate);
1218
1219 /* Disable EQ while we reconfigure */
1220 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
1221
1222 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1223 wm8993_write(codec, WM8993_EQ1 + i, s->config[i]);
1224
1225 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
1226 }
1227
1228 return 0;
1229}
1230
1231static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1232{
1233 struct snd_soc_codec *codec = codec_dai->codec;
1234 unsigned int reg;
1235
1236 reg = wm8993_read(codec, WM8993_DAC_CTRL);
1237
1238 if (mute)
1239 reg |= WM8993_DAC_MUTE;
1240 else
1241 reg &= ~WM8993_DAC_MUTE;
1242
1243 wm8993_write(codec, WM8993_DAC_CTRL, reg);
1244
1245 return 0;
1246}
1247
1248static struct snd_soc_dai_ops wm8993_ops = {
1249 .set_sysclk = wm8993_set_sysclk,
1250 .set_fmt = wm8993_set_dai_fmt,
1251 .hw_params = wm8993_hw_params,
1252 .digital_mute = wm8993_digital_mute,
1253 .set_pll = wm8993_set_fll,
1254};
1255
1256#define WM8993_RATES SNDRV_PCM_RATE_8000_48000
1257
1258#define WM8993_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1259 SNDRV_PCM_FMTBIT_S20_3LE |\
1260 SNDRV_PCM_FMTBIT_S24_LE |\
1261 SNDRV_PCM_FMTBIT_S32_LE)
1262
1263struct snd_soc_dai wm8993_dai = {
1264 .name = "WM8993",
1265 .playback = {
1266 .stream_name = "Playback",
1267 .channels_min = 1,
1268 .channels_max = 2,
1269 .rates = WM8993_RATES,
1270 .formats = WM8993_FORMATS,
1271 },
1272 .capture = {
1273 .stream_name = "Capture",
1274 .channels_min = 1,
1275 .channels_max = 2,
1276 .rates = WM8993_RATES,
1277 .formats = WM8993_FORMATS,
1278 },
1279 .ops = &wm8993_ops,
1280 .symmetric_rates = 1,
1281};
1282EXPORT_SYMBOL_GPL(wm8993_dai);
1283
1284static struct snd_soc_codec *wm8993_codec;
1285
1286static int wm8993_probe(struct platform_device *pdev)
1287{
1288 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1289 struct snd_soc_codec *codec;
1290 struct wm8993_priv *wm8993;
1291 int ret = 0;
1292
1293 if (!wm8993_codec) {
1294 dev_err(&pdev->dev, "I2C device not yet probed\n");
1295 goto err;
1296 }
1297
1298 socdev->card->codec = wm8993_codec;
1299 codec = wm8993_codec;
1300 wm8993 = codec->private_data;
1301
1302 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1303 if (ret < 0) {
1304 dev_err(codec->dev, "failed to create pcms\n");
1305 goto err;
1306 }
1307
1308 snd_soc_add_controls(codec, wm8993_snd_controls,
1309 ARRAY_SIZE(wm8993_snd_controls));
1310 if (wm8993->pdata.num_retune_configs != 0) {
1311 dev_dbg(codec->dev, "Using ReTune Mobile\n");
1312 } else {
1313 dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n");
1314 snd_soc_add_controls(codec, wm8993_eq_controls,
1315 ARRAY_SIZE(wm8993_eq_controls));
1316 }
1317
1318 snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets,
1319 ARRAY_SIZE(wm8993_dapm_widgets));
1320 wm_hubs_add_analogue_controls(codec);
1321
1322 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
1323 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1324 wm8993->pdata.lineout2_diff);
1325
1326 snd_soc_dapm_new_widgets(codec);
1327
1328 ret = snd_soc_init_card(socdev);
1329 if (ret < 0) {
1330 dev_err(codec->dev, "failed to register card\n");
1331 goto card_err;
1332 }
1333
1334 return ret;
1335
1336card_err:
1337 snd_soc_free_pcms(socdev);
1338 snd_soc_dapm_free(socdev);
1339err:
1340 return ret;
1341}
1342
1343static int wm8993_remove(struct platform_device *pdev)
1344{
1345 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1346
1347 snd_soc_free_pcms(socdev);
1348 snd_soc_dapm_free(socdev);
1349
1350 return 0;
1351}
1352
1353struct snd_soc_codec_device soc_codec_dev_wm8993 = {
1354 .probe = wm8993_probe,
1355 .remove = wm8993_remove,
1356};
1357EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1358
1359static int wm8993_i2c_probe(struct i2c_client *i2c,
1360 const struct i2c_device_id *id)
1361{
1362 struct wm8993_priv *wm8993;
1363 struct snd_soc_codec *codec;
1364 unsigned int val;
1365 int ret;
1366
1367 if (wm8993_codec) {
1368 dev_err(&i2c->dev, "A WM8993 is already registered\n");
1369 return -EINVAL;
1370 }
1371
1372 wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL);
1373 if (wm8993 == NULL)
1374 return -ENOMEM;
1375
1376 codec = &wm8993->codec;
1377 if (i2c->dev.platform_data)
1378 memcpy(&wm8993->pdata, i2c->dev.platform_data,
1379 sizeof(wm8993->pdata));
1380
1381 mutex_init(&codec->mutex);
1382 INIT_LIST_HEAD(&codec->dapm_widgets);
1383 INIT_LIST_HEAD(&codec->dapm_paths);
1384
1385 codec->name = "WM8993";
1386 codec->read = wm8993_read;
1387 codec->write = wm8993_write;
1388 codec->hw_write = (hw_write_t)i2c_master_send;
1389 codec->reg_cache = wm8993->reg_cache;
1390 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1391 codec->bias_level = SND_SOC_BIAS_OFF;
1392 codec->set_bias_level = wm8993_set_bias_level;
1393 codec->dai = &wm8993_dai;
1394 codec->num_dai = 1;
1395 codec->private_data = wm8993;
1396
1397 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1398 sizeof(wm8993->reg_cache));
1399
1400 i2c_set_clientdata(i2c, wm8993);
1401 codec->control_data = i2c;
1402 wm8993_codec = codec;
1403
1404 codec->dev = &i2c->dev;
1405
1406 val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET);
1407 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1408 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1409 ret = -EINVAL;
1410 goto err;
1411 }
1412
1413 ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1414 if (ret != 0)
1415 goto err;
1416
1417 /* By default we're using the output mixers */
1418 wm8993->class_w_users = 2;
1419
1420 /* Latch volume update bits and default ZC on */
1421 snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
1422 WM8993_DAC_VU, WM8993_DAC_VU);
1423 snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
1424 WM8993_ADC_VU, WM8993_ADC_VU);
1425
1426 /* Manualy manage the HPOUT sequencing for independent stereo
1427 * control. */
1428 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
1429 WM8993_HPOUT1_AUTO_PU, 0);
1430
1431 /* Use automatic clock configuration */
1432 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1433
1434 if (!wm8993->pdata.lineout1_diff)
1435 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
1436 WM8993_LINEOUT1_MODE,
1437 WM8993_LINEOUT1_MODE);
1438 if (!wm8993->pdata.lineout2_diff)
1439 snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
1440 WM8993_LINEOUT2_MODE,
1441 WM8993_LINEOUT2_MODE);
1442
1443 if (wm8993->pdata.lineout1fb)
1444 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1445 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
1446
1447 if (wm8993->pdata.lineout2fb)
1448 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1449 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
1450
1451 /* Apply the microphone bias/detection configuration - the
1452 * platform data is directly applicable to the register. */
1453 snd_soc_update_bits(codec, WM8993_MICBIAS,
1454 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
1455 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
1456 wm8993->pdata.jd_scthr << WM8993_JD_SCTHR_SHIFT |
1457 wm8993->pdata.jd_thr << WM8993_JD_THR_SHIFT |
1458 wm8993->pdata.micbias1_lvl |
1459 wm8993->pdata.micbias1_lvl << 1);
1460
1461 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1462 if (ret != 0)
1463 goto err;
1464
1465 wm8993_dai.dev = codec->dev;
1466
1467 ret = snd_soc_register_dai(&wm8993_dai);
1468 if (ret != 0)
1469 goto err_bias;
1470
1471 ret = snd_soc_register_codec(codec);
1472
1473 return 0;
1474
1475err_bias:
1476 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1477err:
1478 wm8993_codec = NULL;
1479 kfree(wm8993);
1480 return ret;
1481}
1482
1483static int wm8993_i2c_remove(struct i2c_client *client)
1484{
1485 struct wm8993_priv *wm8993 = i2c_get_clientdata(client);
1486
1487 snd_soc_unregister_codec(&wm8993->codec);
1488 snd_soc_unregister_dai(&wm8993_dai);
1489
1490 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1491 kfree(wm8993);
1492
1493 return 0;
1494}
1495
1496static const struct i2c_device_id wm8993_i2c_id[] = {
1497 { "wm8993", 0 },
1498 { }
1499};
1500MODULE_DEVICE_TABLE(i2c, wm8993_i2c_id);
1501
1502static struct i2c_driver wm8993_i2c_driver = {
1503 .driver = {
1504 .name = "WM8993",
1505 .owner = THIS_MODULE,
1506 },
1507 .probe = wm8993_i2c_probe,
1508 .remove = wm8993_i2c_remove,
1509 .id_table = wm8993_i2c_id,
1510};
1511
1512
1513static int __init wm8993_modinit(void)
1514{
1515 int ret;
1516
1517 ret = i2c_add_driver(&wm8993_i2c_driver);
1518 if (ret != 0)
1519 pr_err("WM8993: Unable to register I2C driver: %d\n", ret);
1520
1521 return ret;
1522}
1523module_init(wm8993_modinit);
1524
1525static void __exit wm8993_exit(void)
1526{
1527 i2c_del_driver(&wm8993_i2c_driver);
1528}
1529module_exit(wm8993_exit);
1530
1531
1532MODULE_DESCRIPTION("ASoC WM8993 driver");
1533MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1534MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
new file mode 100644
index 000000000000..30e71ca88dad
--- /dev/null
+++ b/sound/soc/codecs/wm8993.h
@@ -0,0 +1,2132 @@
1#ifndef WM8993_H
2#define WM8993_H
3
4extern struct snd_soc_dai wm8993_dai;
5extern struct snd_soc_codec_device soc_codec_dev_wm8993;
6
7#define WM8993_SYSCLK_MCLK 1
8#define WM8993_SYSCLK_FLL 2
9
10#define WM8993_FLL_MCLK 1
11#define WM8993_FLL_BCLK 2
12#define WM8993_FLL_LRCLK 3
13
14/*
15 * Register values.
16 */
17#define WM8993_SOFTWARE_RESET 0x00
18#define WM8993_POWER_MANAGEMENT_1 0x01
19#define WM8993_POWER_MANAGEMENT_2 0x02
20#define WM8993_POWER_MANAGEMENT_3 0x03
21#define WM8993_AUDIO_INTERFACE_1 0x04
22#define WM8993_AUDIO_INTERFACE_2 0x05
23#define WM8993_CLOCKING_1 0x06
24#define WM8993_CLOCKING_2 0x07
25#define WM8993_AUDIO_INTERFACE_3 0x08
26#define WM8993_AUDIO_INTERFACE_4 0x09
27#define WM8993_DAC_CTRL 0x0A
28#define WM8993_LEFT_DAC_DIGITAL_VOLUME 0x0B
29#define WM8993_RIGHT_DAC_DIGITAL_VOLUME 0x0C
30#define WM8993_DIGITAL_SIDE_TONE 0x0D
31#define WM8993_ADC_CTRL 0x0E
32#define WM8993_LEFT_ADC_DIGITAL_VOLUME 0x0F
33#define WM8993_RIGHT_ADC_DIGITAL_VOLUME 0x10
34#define WM8993_GPIO_CTRL_1 0x12
35#define WM8993_GPIO1 0x13
36#define WM8993_IRQ_DEBOUNCE 0x14
37#define WM8993_GPIOCTRL_2 0x16
38#define WM8993_GPIO_POL 0x17
39#define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18
40#define WM8993_LEFT_LINE_INPUT_3_4_VOLUME 0x19
41#define WM8993_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
42#define WM8993_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
43#define WM8993_LEFT_OUTPUT_VOLUME 0x1C
44#define WM8993_RIGHT_OUTPUT_VOLUME 0x1D
45#define WM8993_LINE_OUTPUTS_VOLUME 0x1E
46#define WM8993_HPOUT2_VOLUME 0x1F
47#define WM8993_LEFT_OPGA_VOLUME 0x20
48#define WM8993_RIGHT_OPGA_VOLUME 0x21
49#define WM8993_SPKMIXL_ATTENUATION 0x22
50#define WM8993_SPKMIXR_ATTENUATION 0x23
51#define WM8993_SPKOUT_MIXERS 0x24
52#define WM8993_SPKOUT_BOOST 0x25
53#define WM8993_SPEAKER_VOLUME_LEFT 0x26
54#define WM8993_SPEAKER_VOLUME_RIGHT 0x27
55#define WM8993_INPUT_MIXER2 0x28
56#define WM8993_INPUT_MIXER3 0x29
57#define WM8993_INPUT_MIXER4 0x2A
58#define WM8993_INPUT_MIXER5 0x2B
59#define WM8993_INPUT_MIXER6 0x2C
60#define WM8993_OUTPUT_MIXER1 0x2D
61#define WM8993_OUTPUT_MIXER2 0x2E
62#define WM8993_OUTPUT_MIXER3 0x2F
63#define WM8993_OUTPUT_MIXER4 0x30
64#define WM8993_OUTPUT_MIXER5 0x31
65#define WM8993_OUTPUT_MIXER6 0x32
66#define WM8993_HPOUT2_MIXER 0x33
67#define WM8993_LINE_MIXER1 0x34
68#define WM8993_LINE_MIXER2 0x35
69#define WM8993_SPEAKER_MIXER 0x36
70#define WM8993_ADDITIONAL_CONTROL 0x37
71#define WM8993_ANTIPOP1 0x38
72#define WM8993_ANTIPOP2 0x39
73#define WM8993_MICBIAS 0x3A
74#define WM8993_FLL_CONTROL_1 0x3C
75#define WM8993_FLL_CONTROL_2 0x3D
76#define WM8993_FLL_CONTROL_3 0x3E
77#define WM8993_FLL_CONTROL_4 0x3F
78#define WM8993_FLL_CONTROL_5 0x40
79#define WM8993_CLOCKING_3 0x41
80#define WM8993_CLOCKING_4 0x42
81#define WM8993_MW_SLAVE_CONTROL 0x43
82#define WM8993_BUS_CONTROL_1 0x45
83#define WM8993_WRITE_SEQUENCER_0 0x46
84#define WM8993_WRITE_SEQUENCER_1 0x47
85#define WM8993_WRITE_SEQUENCER_2 0x48
86#define WM8993_WRITE_SEQUENCER_3 0x49
87#define WM8993_WRITE_SEQUENCER_4 0x4A
88#define WM8993_WRITE_SEQUENCER_5 0x4B
89#define WM8993_CHARGE_PUMP_1 0x4C
90#define WM8993_CLASS_W_0 0x51
91#define WM8993_DC_SERVO_0 0x54
92#define WM8993_DC_SERVO_1 0x55
93#define WM8993_DC_SERVO_3 0x57
94#define WM8993_DC_SERVO_READBACK_0 0x58
95#define WM8993_DC_SERVO_READBACK_1 0x59
96#define WM8993_DC_SERVO_READBACK_2 0x5A
97#define WM8993_ANALOGUE_HP_0 0x60
98#define WM8993_EQ1 0x62
99#define WM8993_EQ2 0x63
100#define WM8993_EQ3 0x64
101#define WM8993_EQ4 0x65
102#define WM8993_EQ5 0x66
103#define WM8993_EQ6 0x67
104#define WM8993_EQ7 0x68
105#define WM8993_EQ8 0x69
106#define WM8993_EQ9 0x6A
107#define WM8993_EQ10 0x6B
108#define WM8993_EQ11 0x6C
109#define WM8993_EQ12 0x6D
110#define WM8993_EQ13 0x6E
111#define WM8993_EQ14 0x6F
112#define WM8993_EQ15 0x70
113#define WM8993_EQ16 0x71
114#define WM8993_EQ17 0x72
115#define WM8993_EQ18 0x73
116#define WM8993_EQ19 0x74
117#define WM8993_EQ20 0x75
118#define WM8993_EQ21 0x76
119#define WM8993_EQ22 0x77
120#define WM8993_EQ23 0x78
121#define WM8993_EQ24 0x79
122#define WM8993_DIGITAL_PULLS 0x7A
123#define WM8993_DRC_CONTROL_1 0x7B
124#define WM8993_DRC_CONTROL_2 0x7C
125#define WM8993_DRC_CONTROL_3 0x7D
126#define WM8993_DRC_CONTROL_4 0x7E
127
128#define WM8993_REGISTER_COUNT 0x7F
129#define WM8993_MAX_REGISTER 0x7E
130
131/*
132 * Field Definitions.
133 */
134
135/*
136 * R0 (0x00) - Software Reset
137 */
138#define WM8993_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
139#define WM8993_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
140#define WM8993_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
141
142/*
143 * R1 (0x01) - Power Management (1)
144 */
145#define WM8993_SPKOUTR_ENA 0x2000 /* SPKOUTR_ENA */
146#define WM8993_SPKOUTR_ENA_MASK 0x2000 /* SPKOUTR_ENA */
147#define WM8993_SPKOUTR_ENA_SHIFT 13 /* SPKOUTR_ENA */
148#define WM8993_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */
149#define WM8993_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
150#define WM8993_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
151#define WM8993_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
152#define WM8993_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
153#define WM8993_HPOUT2_ENA 0x0800 /* HPOUT2_ENA */
154#define WM8993_HPOUT2_ENA_MASK 0x0800 /* HPOUT2_ENA */
155#define WM8993_HPOUT2_ENA_SHIFT 11 /* HPOUT2_ENA */
156#define WM8993_HPOUT2_ENA_WIDTH 1 /* HPOUT2_ENA */
157#define WM8993_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
158#define WM8993_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
159#define WM8993_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
160#define WM8993_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
161#define WM8993_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
162#define WM8993_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
163#define WM8993_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
164#define WM8993_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
165#define WM8993_MICB2_ENA 0x0020 /* MICB2_ENA */
166#define WM8993_MICB2_ENA_MASK 0x0020 /* MICB2_ENA */
167#define WM8993_MICB2_ENA_SHIFT 5 /* MICB2_ENA */
168#define WM8993_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
169#define WM8993_MICB1_ENA 0x0010 /* MICB1_ENA */
170#define WM8993_MICB1_ENA_MASK 0x0010 /* MICB1_ENA */
171#define WM8993_MICB1_ENA_SHIFT 4 /* MICB1_ENA */
172#define WM8993_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
173#define WM8993_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */
174#define WM8993_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */
175#define WM8993_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */
176#define WM8993_BIAS_ENA 0x0001 /* BIAS_ENA */
177#define WM8993_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
178#define WM8993_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
179#define WM8993_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
180
181/*
182 * R2 (0x02) - Power Management (2)
183 */
184#define WM8993_TSHUT_ENA 0x4000 /* TSHUT_ENA */
185#define WM8993_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
186#define WM8993_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
187#define WM8993_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
188#define WM8993_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
189#define WM8993_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
190#define WM8993_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
191#define WM8993_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
192#define WM8993_OPCLK_ENA 0x0800 /* OPCLK_ENA */
193#define WM8993_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
194#define WM8993_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
195#define WM8993_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
196#define WM8993_MIXINL_ENA 0x0200 /* MIXINL_ENA */
197#define WM8993_MIXINL_ENA_MASK 0x0200 /* MIXINL_ENA */
198#define WM8993_MIXINL_ENA_SHIFT 9 /* MIXINL_ENA */
199#define WM8993_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */
200#define WM8993_MIXINR_ENA 0x0100 /* MIXINR_ENA */
201#define WM8993_MIXINR_ENA_MASK 0x0100 /* MIXINR_ENA */
202#define WM8993_MIXINR_ENA_SHIFT 8 /* MIXINR_ENA */
203#define WM8993_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */
204#define WM8993_IN2L_ENA 0x0080 /* IN2L_ENA */
205#define WM8993_IN2L_ENA_MASK 0x0080 /* IN2L_ENA */
206#define WM8993_IN2L_ENA_SHIFT 7 /* IN2L_ENA */
207#define WM8993_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
208#define WM8993_IN1L_ENA 0x0040 /* IN1L_ENA */
209#define WM8993_IN1L_ENA_MASK 0x0040 /* IN1L_ENA */
210#define WM8993_IN1L_ENA_SHIFT 6 /* IN1L_ENA */
211#define WM8993_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
212#define WM8993_IN2R_ENA 0x0020 /* IN2R_ENA */
213#define WM8993_IN2R_ENA_MASK 0x0020 /* IN2R_ENA */
214#define WM8993_IN2R_ENA_SHIFT 5 /* IN2R_ENA */
215#define WM8993_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
216#define WM8993_IN1R_ENA 0x0010 /* IN1R_ENA */
217#define WM8993_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
218#define WM8993_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
219#define WM8993_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
220#define WM8993_ADCL_ENA 0x0002 /* ADCL_ENA */
221#define WM8993_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
222#define WM8993_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
223#define WM8993_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
224#define WM8993_ADCR_ENA 0x0001 /* ADCR_ENA */
225#define WM8993_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
226#define WM8993_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
227#define WM8993_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
228
229/*
230 * R3 (0x03) - Power Management (3)
231 */
232#define WM8993_LINEOUT1N_ENA 0x2000 /* LINEOUT1N_ENA */
233#define WM8993_LINEOUT1N_ENA_MASK 0x2000 /* LINEOUT1N_ENA */
234#define WM8993_LINEOUT1N_ENA_SHIFT 13 /* LINEOUT1N_ENA */
235#define WM8993_LINEOUT1N_ENA_WIDTH 1 /* LINEOUT1N_ENA */
236#define WM8993_LINEOUT1P_ENA 0x1000 /* LINEOUT1P_ENA */
237#define WM8993_LINEOUT1P_ENA_MASK 0x1000 /* LINEOUT1P_ENA */
238#define WM8993_LINEOUT1P_ENA_SHIFT 12 /* LINEOUT1P_ENA */
239#define WM8993_LINEOUT1P_ENA_WIDTH 1 /* LINEOUT1P_ENA */
240#define WM8993_LINEOUT2N_ENA 0x0800 /* LINEOUT2N_ENA */
241#define WM8993_LINEOUT2N_ENA_MASK 0x0800 /* LINEOUT2N_ENA */
242#define WM8993_LINEOUT2N_ENA_SHIFT 11 /* LINEOUT2N_ENA */
243#define WM8993_LINEOUT2N_ENA_WIDTH 1 /* LINEOUT2N_ENA */
244#define WM8993_LINEOUT2P_ENA 0x0400 /* LINEOUT2P_ENA */
245#define WM8993_LINEOUT2P_ENA_MASK 0x0400 /* LINEOUT2P_ENA */
246#define WM8993_LINEOUT2P_ENA_SHIFT 10 /* LINEOUT2P_ENA */
247#define WM8993_LINEOUT2P_ENA_WIDTH 1 /* LINEOUT2P_ENA */
248#define WM8993_SPKRVOL_ENA 0x0200 /* SPKRVOL_ENA */
249#define WM8993_SPKRVOL_ENA_MASK 0x0200 /* SPKRVOL_ENA */
250#define WM8993_SPKRVOL_ENA_SHIFT 9 /* SPKRVOL_ENA */
251#define WM8993_SPKRVOL_ENA_WIDTH 1 /* SPKRVOL_ENA */
252#define WM8993_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
253#define WM8993_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
254#define WM8993_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
255#define WM8993_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
256#define WM8993_MIXOUTLVOL_ENA 0x0080 /* MIXOUTLVOL_ENA */
257#define WM8993_MIXOUTLVOL_ENA_MASK 0x0080 /* MIXOUTLVOL_ENA */
258#define WM8993_MIXOUTLVOL_ENA_SHIFT 7 /* MIXOUTLVOL_ENA */
259#define WM8993_MIXOUTLVOL_ENA_WIDTH 1 /* MIXOUTLVOL_ENA */
260#define WM8993_MIXOUTRVOL_ENA 0x0040 /* MIXOUTRVOL_ENA */
261#define WM8993_MIXOUTRVOL_ENA_MASK 0x0040 /* MIXOUTRVOL_ENA */
262#define WM8993_MIXOUTRVOL_ENA_SHIFT 6 /* MIXOUTRVOL_ENA */
263#define WM8993_MIXOUTRVOL_ENA_WIDTH 1 /* MIXOUTRVOL_ENA */
264#define WM8993_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
265#define WM8993_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
266#define WM8993_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
267#define WM8993_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
268#define WM8993_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
269#define WM8993_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
270#define WM8993_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
271#define WM8993_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
272#define WM8993_DACL_ENA 0x0002 /* DACL_ENA */
273#define WM8993_DACL_ENA_MASK 0x0002 /* DACL_ENA */
274#define WM8993_DACL_ENA_SHIFT 1 /* DACL_ENA */
275#define WM8993_DACL_ENA_WIDTH 1 /* DACL_ENA */
276#define WM8993_DACR_ENA 0x0001 /* DACR_ENA */
277#define WM8993_DACR_ENA_MASK 0x0001 /* DACR_ENA */
278#define WM8993_DACR_ENA_SHIFT 0 /* DACR_ENA */
279#define WM8993_DACR_ENA_WIDTH 1 /* DACR_ENA */
280
281/*
282 * R4 (0x04) - Audio Interface (1)
283 */
284#define WM8993_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
285#define WM8993_AIFADCL_SRC_MASK 0x8000 /* AIFADCL_SRC */
286#define WM8993_AIFADCL_SRC_SHIFT 15 /* AIFADCL_SRC */
287#define WM8993_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
288#define WM8993_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
289#define WM8993_AIFADCR_SRC_MASK 0x4000 /* AIFADCR_SRC */
290#define WM8993_AIFADCR_SRC_SHIFT 14 /* AIFADCR_SRC */
291#define WM8993_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
292#define WM8993_AIFADC_TDM 0x2000 /* AIFADC_TDM */
293#define WM8993_AIFADC_TDM_MASK 0x2000 /* AIFADC_TDM */
294#define WM8993_AIFADC_TDM_SHIFT 13 /* AIFADC_TDM */
295#define WM8993_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
296#define WM8993_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
297#define WM8993_AIFADC_TDM_CHAN_MASK 0x1000 /* AIFADC_TDM_CHAN */
298#define WM8993_AIFADC_TDM_CHAN_SHIFT 12 /* AIFADC_TDM_CHAN */
299#define WM8993_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
300#define WM8993_BCLK_DIR 0x0200 /* BCLK_DIR */
301#define WM8993_BCLK_DIR_MASK 0x0200 /* BCLK_DIR */
302#define WM8993_BCLK_DIR_SHIFT 9 /* BCLK_DIR */
303#define WM8993_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
304#define WM8993_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
305#define WM8993_AIF_BCLK_INV_MASK 0x0100 /* AIF_BCLK_INV */
306#define WM8993_AIF_BCLK_INV_SHIFT 8 /* AIF_BCLK_INV */
307#define WM8993_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
308#define WM8993_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
309#define WM8993_AIF_LRCLK_INV_MASK 0x0080 /* AIF_LRCLK_INV */
310#define WM8993_AIF_LRCLK_INV_SHIFT 7 /* AIF_LRCLK_INV */
311#define WM8993_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
312#define WM8993_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
313#define WM8993_AIF_WL_SHIFT 5 /* AIF_WL - [6:5] */
314#define WM8993_AIF_WL_WIDTH 2 /* AIF_WL - [6:5] */
315#define WM8993_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
316#define WM8993_AIF_FMT_SHIFT 3 /* AIF_FMT - [4:3] */
317#define WM8993_AIF_FMT_WIDTH 2 /* AIF_FMT - [4:3] */
318
319/*
320 * R5 (0x05) - Audio Interface (2)
321 */
322#define WM8993_AIFDACL_SRC 0x8000 /* AIFDACL_SRC */
323#define WM8993_AIFDACL_SRC_MASK 0x8000 /* AIFDACL_SRC */
324#define WM8993_AIFDACL_SRC_SHIFT 15 /* AIFDACL_SRC */
325#define WM8993_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
326#define WM8993_AIFDACR_SRC 0x4000 /* AIFDACR_SRC */
327#define WM8993_AIFDACR_SRC_MASK 0x4000 /* AIFDACR_SRC */
328#define WM8993_AIFDACR_SRC_SHIFT 14 /* AIFDACR_SRC */
329#define WM8993_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
330#define WM8993_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
331#define WM8993_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
332#define WM8993_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
333#define WM8993_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
334#define WM8993_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
335#define WM8993_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
336#define WM8993_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
337#define WM8993_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
338#define WM8993_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */
339#define WM8993_DAC_BOOST_SHIFT 10 /* DAC_BOOST - [11:10] */
340#define WM8993_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [11:10] */
341#define WM8993_DAC_COMP 0x0010 /* DAC_COMP */
342#define WM8993_DAC_COMP_MASK 0x0010 /* DAC_COMP */
343#define WM8993_DAC_COMP_SHIFT 4 /* DAC_COMP */
344#define WM8993_DAC_COMP_WIDTH 1 /* DAC_COMP */
345#define WM8993_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
346#define WM8993_DAC_COMPMODE_MASK 0x0008 /* DAC_COMPMODE */
347#define WM8993_DAC_COMPMODE_SHIFT 3 /* DAC_COMPMODE */
348#define WM8993_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
349#define WM8993_ADC_COMP 0x0004 /* ADC_COMP */
350#define WM8993_ADC_COMP_MASK 0x0004 /* ADC_COMP */
351#define WM8993_ADC_COMP_SHIFT 2 /* ADC_COMP */
352#define WM8993_ADC_COMP_WIDTH 1 /* ADC_COMP */
353#define WM8993_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
354#define WM8993_ADC_COMPMODE_MASK 0x0002 /* ADC_COMPMODE */
355#define WM8993_ADC_COMPMODE_SHIFT 1 /* ADC_COMPMODE */
356#define WM8993_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
357#define WM8993_LOOPBACK 0x0001 /* LOOPBACK */
358#define WM8993_LOOPBACK_MASK 0x0001 /* LOOPBACK */
359#define WM8993_LOOPBACK_SHIFT 0 /* LOOPBACK */
360#define WM8993_LOOPBACK_WIDTH 1 /* LOOPBACK */
361
362/*
363 * R6 (0x06) - Clocking 1
364 */
365#define WM8993_TOCLK_RATE 0x8000 /* TOCLK_RATE */
366#define WM8993_TOCLK_RATE_MASK 0x8000 /* TOCLK_RATE */
367#define WM8993_TOCLK_RATE_SHIFT 15 /* TOCLK_RATE */
368#define WM8993_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
369#define WM8993_TOCLK_ENA 0x4000 /* TOCLK_ENA */
370#define WM8993_TOCLK_ENA_MASK 0x4000 /* TOCLK_ENA */
371#define WM8993_TOCLK_ENA_SHIFT 14 /* TOCLK_ENA */
372#define WM8993_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
373#define WM8993_OPCLK_DIV_MASK 0x1E00 /* OPCLK_DIV - [12:9] */
374#define WM8993_OPCLK_DIV_SHIFT 9 /* OPCLK_DIV - [12:9] */
375#define WM8993_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [12:9] */
376#define WM8993_DCLK_DIV_MASK 0x01C0 /* DCLK_DIV - [8:6] */
377#define WM8993_DCLK_DIV_SHIFT 6 /* DCLK_DIV - [8:6] */
378#define WM8993_DCLK_DIV_WIDTH 3 /* DCLK_DIV - [8:6] */
379#define WM8993_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
380#define WM8993_BCLK_DIV_SHIFT 1 /* BCLK_DIV - [4:1] */
381#define WM8993_BCLK_DIV_WIDTH 4 /* BCLK_DIV - [4:1] */
382
383/*
384 * R7 (0x07) - Clocking 2
385 */
386#define WM8993_MCLK_SRC 0x8000 /* MCLK_SRC */
387#define WM8993_MCLK_SRC_MASK 0x8000 /* MCLK_SRC */
388#define WM8993_MCLK_SRC_SHIFT 15 /* MCLK_SRC */
389#define WM8993_MCLK_SRC_WIDTH 1 /* MCLK_SRC */
390#define WM8993_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
391#define WM8993_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
392#define WM8993_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
393#define WM8993_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
394#define WM8993_MCLK_DIV 0x1000 /* MCLK_DIV */
395#define WM8993_MCLK_DIV_MASK 0x1000 /* MCLK_DIV */
396#define WM8993_MCLK_DIV_SHIFT 12 /* MCLK_DIV */
397#define WM8993_MCLK_DIV_WIDTH 1 /* MCLK_DIV */
398#define WM8993_MCLK_INV 0x0400 /* MCLK_INV */
399#define WM8993_MCLK_INV_MASK 0x0400 /* MCLK_INV */
400#define WM8993_MCLK_INV_SHIFT 10 /* MCLK_INV */
401#define WM8993_MCLK_INV_WIDTH 1 /* MCLK_INV */
402#define WM8993_ADC_DIV_MASK 0x00E0 /* ADC_DIV - [7:5] */
403#define WM8993_ADC_DIV_SHIFT 5 /* ADC_DIV - [7:5] */
404#define WM8993_ADC_DIV_WIDTH 3 /* ADC_DIV - [7:5] */
405#define WM8993_DAC_DIV_MASK 0x001C /* DAC_DIV - [4:2] */
406#define WM8993_DAC_DIV_SHIFT 2 /* DAC_DIV - [4:2] */
407#define WM8993_DAC_DIV_WIDTH 3 /* DAC_DIV - [4:2] */
408
409/*
410 * R8 (0x08) - Audio Interface (3)
411 */
412#define WM8993_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
413#define WM8993_AIF_MSTR1_MASK 0x8000 /* AIF_MSTR1 */
414#define WM8993_AIF_MSTR1_SHIFT 15 /* AIF_MSTR1 */
415#define WM8993_AIF_MSTR1_WIDTH 1 /* AIF_MSTR1 */
416
417/*
418 * R9 (0x09) - Audio Interface (4)
419 */
420#define WM8993_AIF_TRIS 0x2000 /* AIF_TRIS */
421#define WM8993_AIF_TRIS_MASK 0x2000 /* AIF_TRIS */
422#define WM8993_AIF_TRIS_SHIFT 13 /* AIF_TRIS */
423#define WM8993_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
424#define WM8993_LRCLK_DIR 0x0800 /* LRCLK_DIR */
425#define WM8993_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */
426#define WM8993_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */
427#define WM8993_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
428#define WM8993_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
429#define WM8993_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
430#define WM8993_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
431
432/*
433 * R10 (0x0A) - DAC CTRL
434 */
435#define WM8993_DAC_OSR128 0x2000 /* DAC_OSR128 */
436#define WM8993_DAC_OSR128_MASK 0x2000 /* DAC_OSR128 */
437#define WM8993_DAC_OSR128_SHIFT 13 /* DAC_OSR128 */
438#define WM8993_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
439#define WM8993_DAC_MONO 0x0200 /* DAC_MONO */
440#define WM8993_DAC_MONO_MASK 0x0200 /* DAC_MONO */
441#define WM8993_DAC_MONO_SHIFT 9 /* DAC_MONO */
442#define WM8993_DAC_MONO_WIDTH 1 /* DAC_MONO */
443#define WM8993_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
444#define WM8993_DAC_SB_FILT_MASK 0x0100 /* DAC_SB_FILT */
445#define WM8993_DAC_SB_FILT_SHIFT 8 /* DAC_SB_FILT */
446#define WM8993_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
447#define WM8993_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
448#define WM8993_DAC_MUTERATE_MASK 0x0080 /* DAC_MUTERATE */
449#define WM8993_DAC_MUTERATE_SHIFT 7 /* DAC_MUTERATE */
450#define WM8993_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
451#define WM8993_DAC_UNMUTE_RAMP 0x0040 /* DAC_UNMUTE_RAMP */
452#define WM8993_DAC_UNMUTE_RAMP_MASK 0x0040 /* DAC_UNMUTE_RAMP */
453#define WM8993_DAC_UNMUTE_RAMP_SHIFT 6 /* DAC_UNMUTE_RAMP */
454#define WM8993_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
455#define WM8993_DEEMPH_MASK 0x0030 /* DEEMPH - [5:4] */
456#define WM8993_DEEMPH_SHIFT 4 /* DEEMPH - [5:4] */
457#define WM8993_DEEMPH_WIDTH 2 /* DEEMPH - [5:4] */
458#define WM8993_DAC_MUTE 0x0004 /* DAC_MUTE */
459#define WM8993_DAC_MUTE_MASK 0x0004 /* DAC_MUTE */
460#define WM8993_DAC_MUTE_SHIFT 2 /* DAC_MUTE */
461#define WM8993_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
462#define WM8993_DACL_DATINV 0x0002 /* DACL_DATINV */
463#define WM8993_DACL_DATINV_MASK 0x0002 /* DACL_DATINV */
464#define WM8993_DACL_DATINV_SHIFT 1 /* DACL_DATINV */
465#define WM8993_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
466#define WM8993_DACR_DATINV 0x0001 /* DACR_DATINV */
467#define WM8993_DACR_DATINV_MASK 0x0001 /* DACR_DATINV */
468#define WM8993_DACR_DATINV_SHIFT 0 /* DACR_DATINV */
469#define WM8993_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
470
471/*
472 * R11 (0x0B) - Left DAC Digital Volume
473 */
474#define WM8993_DAC_VU 0x0100 /* DAC_VU */
475#define WM8993_DAC_VU_MASK 0x0100 /* DAC_VU */
476#define WM8993_DAC_VU_SHIFT 8 /* DAC_VU */
477#define WM8993_DAC_VU_WIDTH 1 /* DAC_VU */
478#define WM8993_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
479#define WM8993_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
480#define WM8993_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
481
482/*
483 * R12 (0x0C) - Right DAC Digital Volume
484 */
485#define WM8993_DAC_VU 0x0100 /* DAC_VU */
486#define WM8993_DAC_VU_MASK 0x0100 /* DAC_VU */
487#define WM8993_DAC_VU_SHIFT 8 /* DAC_VU */
488#define WM8993_DAC_VU_WIDTH 1 /* DAC_VU */
489#define WM8993_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
490#define WM8993_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
491#define WM8993_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
492
493/*
494 * R13 (0x0D) - Digital Side Tone
495 */
496#define WM8993_ADCL_DAC_SVOL_MASK 0x1E00 /* ADCL_DAC_SVOL - [12:9] */
497#define WM8993_ADCL_DAC_SVOL_SHIFT 9 /* ADCL_DAC_SVOL - [12:9] */
498#define WM8993_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [12:9] */
499#define WM8993_ADCR_DAC_SVOL_MASK 0x01E0 /* ADCR_DAC_SVOL - [8:5] */
500#define WM8993_ADCR_DAC_SVOL_SHIFT 5 /* ADCR_DAC_SVOL - [8:5] */
501#define WM8993_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [8:5] */
502#define WM8993_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
503#define WM8993_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
504#define WM8993_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
505#define WM8993_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
506#define WM8993_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
507#define WM8993_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
508
509/*
510 * R14 (0x0E) - ADC CTRL
511 */
512#define WM8993_ADC_OSR128 0x0200 /* ADC_OSR128 */
513#define WM8993_ADC_OSR128_MASK 0x0200 /* ADC_OSR128 */
514#define WM8993_ADC_OSR128_SHIFT 9 /* ADC_OSR128 */
515#define WM8993_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
516#define WM8993_ADC_HPF 0x0100 /* ADC_HPF */
517#define WM8993_ADC_HPF_MASK 0x0100 /* ADC_HPF */
518#define WM8993_ADC_HPF_SHIFT 8 /* ADC_HPF */
519#define WM8993_ADC_HPF_WIDTH 1 /* ADC_HPF */
520#define WM8993_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
521#define WM8993_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
522#define WM8993_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
523#define WM8993_ADCL_DATINV 0x0002 /* ADCL_DATINV */
524#define WM8993_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
525#define WM8993_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
526#define WM8993_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
527#define WM8993_ADCR_DATINV 0x0001 /* ADCR_DATINV */
528#define WM8993_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
529#define WM8993_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
530#define WM8993_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
531
532/*
533 * R15 (0x0F) - Left ADC Digital Volume
534 */
535#define WM8993_ADC_VU 0x0100 /* ADC_VU */
536#define WM8993_ADC_VU_MASK 0x0100 /* ADC_VU */
537#define WM8993_ADC_VU_SHIFT 8 /* ADC_VU */
538#define WM8993_ADC_VU_WIDTH 1 /* ADC_VU */
539#define WM8993_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
540#define WM8993_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
541#define WM8993_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
542
543/*
544 * R16 (0x10) - Right ADC Digital Volume
545 */
546#define WM8993_ADC_VU 0x0100 /* ADC_VU */
547#define WM8993_ADC_VU_MASK 0x0100 /* ADC_VU */
548#define WM8993_ADC_VU_SHIFT 8 /* ADC_VU */
549#define WM8993_ADC_VU_WIDTH 1 /* ADC_VU */
550#define WM8993_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
551#define WM8993_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
552#define WM8993_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
553
554/*
555 * R18 (0x12) - GPIO CTRL 1
556 */
557#define WM8993_JD2_SC_EINT 0x8000 /* JD2_SC_EINT */
558#define WM8993_JD2_SC_EINT_MASK 0x8000 /* JD2_SC_EINT */
559#define WM8993_JD2_SC_EINT_SHIFT 15 /* JD2_SC_EINT */
560#define WM8993_JD2_SC_EINT_WIDTH 1 /* JD2_SC_EINT */
561#define WM8993_JD2_EINT 0x4000 /* JD2_EINT */
562#define WM8993_JD2_EINT_MASK 0x4000 /* JD2_EINT */
563#define WM8993_JD2_EINT_SHIFT 14 /* JD2_EINT */
564#define WM8993_JD2_EINT_WIDTH 1 /* JD2_EINT */
565#define WM8993_WSEQ_EINT 0x2000 /* WSEQ_EINT */
566#define WM8993_WSEQ_EINT_MASK 0x2000 /* WSEQ_EINT */
567#define WM8993_WSEQ_EINT_SHIFT 13 /* WSEQ_EINT */
568#define WM8993_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */
569#define WM8993_IRQ 0x1000 /* IRQ */
570#define WM8993_IRQ_MASK 0x1000 /* IRQ */
571#define WM8993_IRQ_SHIFT 12 /* IRQ */
572#define WM8993_IRQ_WIDTH 1 /* IRQ */
573#define WM8993_TEMPOK_EINT 0x0800 /* TEMPOK_EINT */
574#define WM8993_TEMPOK_EINT_MASK 0x0800 /* TEMPOK_EINT */
575#define WM8993_TEMPOK_EINT_SHIFT 11 /* TEMPOK_EINT */
576#define WM8993_TEMPOK_EINT_WIDTH 1 /* TEMPOK_EINT */
577#define WM8993_JD1_SC_EINT 0x0400 /* JD1_SC_EINT */
578#define WM8993_JD1_SC_EINT_MASK 0x0400 /* JD1_SC_EINT */
579#define WM8993_JD1_SC_EINT_SHIFT 10 /* JD1_SC_EINT */
580#define WM8993_JD1_SC_EINT_WIDTH 1 /* JD1_SC_EINT */
581#define WM8993_JD1_EINT 0x0200 /* JD1_EINT */
582#define WM8993_JD1_EINT_MASK 0x0200 /* JD1_EINT */
583#define WM8993_JD1_EINT_SHIFT 9 /* JD1_EINT */
584#define WM8993_JD1_EINT_WIDTH 1 /* JD1_EINT */
585#define WM8993_FLL_LOCK_EINT 0x0100 /* FLL_LOCK_EINT */
586#define WM8993_FLL_LOCK_EINT_MASK 0x0100 /* FLL_LOCK_EINT */
587#define WM8993_FLL_LOCK_EINT_SHIFT 8 /* FLL_LOCK_EINT */
588#define WM8993_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
589#define WM8993_GPI8_EINT 0x0080 /* GPI8_EINT */
590#define WM8993_GPI8_EINT_MASK 0x0080 /* GPI8_EINT */
591#define WM8993_GPI8_EINT_SHIFT 7 /* GPI8_EINT */
592#define WM8993_GPI8_EINT_WIDTH 1 /* GPI8_EINT */
593#define WM8993_GPI7_EINT 0x0040 /* GPI7_EINT */
594#define WM8993_GPI7_EINT_MASK 0x0040 /* GPI7_EINT */
595#define WM8993_GPI7_EINT_SHIFT 6 /* GPI7_EINT */
596#define WM8993_GPI7_EINT_WIDTH 1 /* GPI7_EINT */
597#define WM8993_GPIO1_EINT 0x0001 /* GPIO1_EINT */
598#define WM8993_GPIO1_EINT_MASK 0x0001 /* GPIO1_EINT */
599#define WM8993_GPIO1_EINT_SHIFT 0 /* GPIO1_EINT */
600#define WM8993_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */
601
602/*
603 * R19 (0x13) - GPIO1
604 */
605#define WM8993_GPIO1_PU 0x0020 /* GPIO1_PU */
606#define WM8993_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
607#define WM8993_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
608#define WM8993_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
609#define WM8993_GPIO1_PD 0x0010 /* GPIO1_PD */
610#define WM8993_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
611#define WM8993_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
612#define WM8993_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
613#define WM8993_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
614#define WM8993_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
615#define WM8993_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
616
617/*
618 * R20 (0x14) - IRQ_DEBOUNCE
619 */
620#define WM8993_JD2_SC_DB 0x8000 /* JD2_SC_DB */
621#define WM8993_JD2_SC_DB_MASK 0x8000 /* JD2_SC_DB */
622#define WM8993_JD2_SC_DB_SHIFT 15 /* JD2_SC_DB */
623#define WM8993_JD2_SC_DB_WIDTH 1 /* JD2_SC_DB */
624#define WM8993_JD2_DB 0x4000 /* JD2_DB */
625#define WM8993_JD2_DB_MASK 0x4000 /* JD2_DB */
626#define WM8993_JD2_DB_SHIFT 14 /* JD2_DB */
627#define WM8993_JD2_DB_WIDTH 1 /* JD2_DB */
628#define WM8993_WSEQ_DB 0x2000 /* WSEQ_DB */
629#define WM8993_WSEQ_DB_MASK 0x2000 /* WSEQ_DB */
630#define WM8993_WSEQ_DB_SHIFT 13 /* WSEQ_DB */
631#define WM8993_WSEQ_DB_WIDTH 1 /* WSEQ_DB */
632#define WM8993_TEMPOK_DB 0x0800 /* TEMPOK_DB */
633#define WM8993_TEMPOK_DB_MASK 0x0800 /* TEMPOK_DB */
634#define WM8993_TEMPOK_DB_SHIFT 11 /* TEMPOK_DB */
635#define WM8993_TEMPOK_DB_WIDTH 1 /* TEMPOK_DB */
636#define WM8993_JD1_SC_DB 0x0400 /* JD1_SC_DB */
637#define WM8993_JD1_SC_DB_MASK 0x0400 /* JD1_SC_DB */
638#define WM8993_JD1_SC_DB_SHIFT 10 /* JD1_SC_DB */
639#define WM8993_JD1_SC_DB_WIDTH 1 /* JD1_SC_DB */
640#define WM8993_JD1_DB 0x0200 /* JD1_DB */
641#define WM8993_JD1_DB_MASK 0x0200 /* JD1_DB */
642#define WM8993_JD1_DB_SHIFT 9 /* JD1_DB */
643#define WM8993_JD1_DB_WIDTH 1 /* JD1_DB */
644#define WM8993_FLL_LOCK_DB 0x0100 /* FLL_LOCK_DB */
645#define WM8993_FLL_LOCK_DB_MASK 0x0100 /* FLL_LOCK_DB */
646#define WM8993_FLL_LOCK_DB_SHIFT 8 /* FLL_LOCK_DB */
647#define WM8993_FLL_LOCK_DB_WIDTH 1 /* FLL_LOCK_DB */
648#define WM8993_GPI8_DB 0x0080 /* GPI8_DB */
649#define WM8993_GPI8_DB_MASK 0x0080 /* GPI8_DB */
650#define WM8993_GPI8_DB_SHIFT 7 /* GPI8_DB */
651#define WM8993_GPI8_DB_WIDTH 1 /* GPI8_DB */
652#define WM8993_GPI7_DB 0x0008 /* GPI7_DB */
653#define WM8993_GPI7_DB_MASK 0x0008 /* GPI7_DB */
654#define WM8993_GPI7_DB_SHIFT 3 /* GPI7_DB */
655#define WM8993_GPI7_DB_WIDTH 1 /* GPI7_DB */
656#define WM8993_GPIO1_DB 0x0001 /* GPIO1_DB */
657#define WM8993_GPIO1_DB_MASK 0x0001 /* GPIO1_DB */
658#define WM8993_GPIO1_DB_SHIFT 0 /* GPIO1_DB */
659#define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */
660
661/*
662 * R22 (0x16) - GPIOCTRL 2
663 */
664#define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */
665#define WM8993_IM_JD2_EINT_MASK 0x2000 /* IM_JD2_EINT */
666#define WM8993_IM_JD2_EINT_SHIFT 13 /* IM_JD2_EINT */
667#define WM8993_IM_JD2_EINT_WIDTH 1 /* IM_JD2_EINT */
668#define WM8993_IM_JD2_SC_EINT 0x1000 /* IM_JD2_SC_EINT */
669#define WM8993_IM_JD2_SC_EINT_MASK 0x1000 /* IM_JD2_SC_EINT */
670#define WM8993_IM_JD2_SC_EINT_SHIFT 12 /* IM_JD2_SC_EINT */
671#define WM8993_IM_JD2_SC_EINT_WIDTH 1 /* IM_JD2_SC_EINT */
672#define WM8993_IM_TEMPOK_EINT 0x0800 /* IM_TEMPOK_EINT */
673#define WM8993_IM_TEMPOK_EINT_MASK 0x0800 /* IM_TEMPOK_EINT */
674#define WM8993_IM_TEMPOK_EINT_SHIFT 11 /* IM_TEMPOK_EINT */
675#define WM8993_IM_TEMPOK_EINT_WIDTH 1 /* IM_TEMPOK_EINT */
676#define WM8993_IM_JD1_SC_EINT 0x0400 /* IM_JD1_SC_EINT */
677#define WM8993_IM_JD1_SC_EINT_MASK 0x0400 /* IM_JD1_SC_EINT */
678#define WM8993_IM_JD1_SC_EINT_SHIFT 10 /* IM_JD1_SC_EINT */
679#define WM8993_IM_JD1_SC_EINT_WIDTH 1 /* IM_JD1_SC_EINT */
680#define WM8993_IM_JD1_EINT 0x0200 /* IM_JD1_EINT */
681#define WM8993_IM_JD1_EINT_MASK 0x0200 /* IM_JD1_EINT */
682#define WM8993_IM_JD1_EINT_SHIFT 9 /* IM_JD1_EINT */
683#define WM8993_IM_JD1_EINT_WIDTH 1 /* IM_JD1_EINT */
684#define WM8993_IM_FLL_LOCK_EINT 0x0100 /* IM_FLL_LOCK_EINT */
685#define WM8993_IM_FLL_LOCK_EINT_MASK 0x0100 /* IM_FLL_LOCK_EINT */
686#define WM8993_IM_FLL_LOCK_EINT_SHIFT 8 /* IM_FLL_LOCK_EINT */
687#define WM8993_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
688#define WM8993_IM_GPI8_EINT 0x0040 /* IM_GPI8_EINT */
689#define WM8993_IM_GPI8_EINT_MASK 0x0040 /* IM_GPI8_EINT */
690#define WM8993_IM_GPI8_EINT_SHIFT 6 /* IM_GPI8_EINT */
691#define WM8993_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */
692#define WM8993_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */
693#define WM8993_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */
694#define WM8993_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */
695#define WM8993_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */
696#define WM8993_GPI8_ENA 0x0010 /* GPI8_ENA */
697#define WM8993_GPI8_ENA_MASK 0x0010 /* GPI8_ENA */
698#define WM8993_GPI8_ENA_SHIFT 4 /* GPI8_ENA */
699#define WM8993_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
700#define WM8993_IM_GPI7_EINT 0x0004 /* IM_GPI7_EINT */
701#define WM8993_IM_GPI7_EINT_MASK 0x0004 /* IM_GPI7_EINT */
702#define WM8993_IM_GPI7_EINT_SHIFT 2 /* IM_GPI7_EINT */
703#define WM8993_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */
704#define WM8993_IM_WSEQ_EINT 0x0002 /* IM_WSEQ_EINT */
705#define WM8993_IM_WSEQ_EINT_MASK 0x0002 /* IM_WSEQ_EINT */
706#define WM8993_IM_WSEQ_EINT_SHIFT 1 /* IM_WSEQ_EINT */
707#define WM8993_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */
708#define WM8993_GPI7_ENA 0x0001 /* GPI7_ENA */
709#define WM8993_GPI7_ENA_MASK 0x0001 /* GPI7_ENA */
710#define WM8993_GPI7_ENA_SHIFT 0 /* GPI7_ENA */
711#define WM8993_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
712
713/*
714 * R23 (0x17) - GPIO_POL
715 */
716#define WM8993_JD2_SC_POL 0x8000 /* JD2_SC_POL */
717#define WM8993_JD2_SC_POL_MASK 0x8000 /* JD2_SC_POL */
718#define WM8993_JD2_SC_POL_SHIFT 15 /* JD2_SC_POL */
719#define WM8993_JD2_SC_POL_WIDTH 1 /* JD2_SC_POL */
720#define WM8993_JD2_POL 0x4000 /* JD2_POL */
721#define WM8993_JD2_POL_MASK 0x4000 /* JD2_POL */
722#define WM8993_JD2_POL_SHIFT 14 /* JD2_POL */
723#define WM8993_JD2_POL_WIDTH 1 /* JD2_POL */
724#define WM8993_WSEQ_POL 0x2000 /* WSEQ_POL */
725#define WM8993_WSEQ_POL_MASK 0x2000 /* WSEQ_POL */
726#define WM8993_WSEQ_POL_SHIFT 13 /* WSEQ_POL */
727#define WM8993_WSEQ_POL_WIDTH 1 /* WSEQ_POL */
728#define WM8993_IRQ_POL 0x1000 /* IRQ_POL */
729#define WM8993_IRQ_POL_MASK 0x1000 /* IRQ_POL */
730#define WM8993_IRQ_POL_SHIFT 12 /* IRQ_POL */
731#define WM8993_IRQ_POL_WIDTH 1 /* IRQ_POL */
732#define WM8993_TEMPOK_POL 0x0800 /* TEMPOK_POL */
733#define WM8993_TEMPOK_POL_MASK 0x0800 /* TEMPOK_POL */
734#define WM8993_TEMPOK_POL_SHIFT 11 /* TEMPOK_POL */
735#define WM8993_TEMPOK_POL_WIDTH 1 /* TEMPOK_POL */
736#define WM8993_JD1_SC_POL 0x0400 /* JD1_SC_POL */
737#define WM8993_JD1_SC_POL_MASK 0x0400 /* JD1_SC_POL */
738#define WM8993_JD1_SC_POL_SHIFT 10 /* JD1_SC_POL */
739#define WM8993_JD1_SC_POL_WIDTH 1 /* JD1_SC_POL */
740#define WM8993_JD1_POL 0x0200 /* JD1_POL */
741#define WM8993_JD1_POL_MASK 0x0200 /* JD1_POL */
742#define WM8993_JD1_POL_SHIFT 9 /* JD1_POL */
743#define WM8993_JD1_POL_WIDTH 1 /* JD1_POL */
744#define WM8993_FLL_LOCK_POL 0x0100 /* FLL_LOCK_POL */
745#define WM8993_FLL_LOCK_POL_MASK 0x0100 /* FLL_LOCK_POL */
746#define WM8993_FLL_LOCK_POL_SHIFT 8 /* FLL_LOCK_POL */
747#define WM8993_FLL_LOCK_POL_WIDTH 1 /* FLL_LOCK_POL */
748#define WM8993_GPI8_POL 0x0080 /* GPI8_POL */
749#define WM8993_GPI8_POL_MASK 0x0080 /* GPI8_POL */
750#define WM8993_GPI8_POL_SHIFT 7 /* GPI8_POL */
751#define WM8993_GPI8_POL_WIDTH 1 /* GPI8_POL */
752#define WM8993_GPI7_POL 0x0040 /* GPI7_POL */
753#define WM8993_GPI7_POL_MASK 0x0040 /* GPI7_POL */
754#define WM8993_GPI7_POL_SHIFT 6 /* GPI7_POL */
755#define WM8993_GPI7_POL_WIDTH 1 /* GPI7_POL */
756#define WM8993_GPIO1_POL 0x0001 /* GPIO1_POL */
757#define WM8993_GPIO1_POL_MASK 0x0001 /* GPIO1_POL */
758#define WM8993_GPIO1_POL_SHIFT 0 /* GPIO1_POL */
759#define WM8993_GPIO1_POL_WIDTH 1 /* GPIO1_POL */
760
761/*
762 * R24 (0x18) - Left Line Input 1&2 Volume
763 */
764#define WM8993_IN1_VU 0x0100 /* IN1_VU */
765#define WM8993_IN1_VU_MASK 0x0100 /* IN1_VU */
766#define WM8993_IN1_VU_SHIFT 8 /* IN1_VU */
767#define WM8993_IN1_VU_WIDTH 1 /* IN1_VU */
768#define WM8993_IN1L_MUTE 0x0080 /* IN1L_MUTE */
769#define WM8993_IN1L_MUTE_MASK 0x0080 /* IN1L_MUTE */
770#define WM8993_IN1L_MUTE_SHIFT 7 /* IN1L_MUTE */
771#define WM8993_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
772#define WM8993_IN1L_ZC 0x0040 /* IN1L_ZC */
773#define WM8993_IN1L_ZC_MASK 0x0040 /* IN1L_ZC */
774#define WM8993_IN1L_ZC_SHIFT 6 /* IN1L_ZC */
775#define WM8993_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
776#define WM8993_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
777#define WM8993_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
778#define WM8993_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
779
780/*
781 * R25 (0x19) - Left Line Input 3&4 Volume
782 */
783#define WM8993_IN2_VU 0x0100 /* IN2_VU */
784#define WM8993_IN2_VU_MASK 0x0100 /* IN2_VU */
785#define WM8993_IN2_VU_SHIFT 8 /* IN2_VU */
786#define WM8993_IN2_VU_WIDTH 1 /* IN2_VU */
787#define WM8993_IN2L_MUTE 0x0080 /* IN2L_MUTE */
788#define WM8993_IN2L_MUTE_MASK 0x0080 /* IN2L_MUTE */
789#define WM8993_IN2L_MUTE_SHIFT 7 /* IN2L_MUTE */
790#define WM8993_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
791#define WM8993_IN2L_ZC 0x0040 /* IN2L_ZC */
792#define WM8993_IN2L_ZC_MASK 0x0040 /* IN2L_ZC */
793#define WM8993_IN2L_ZC_SHIFT 6 /* IN2L_ZC */
794#define WM8993_IN2L_ZC_WIDTH 1 /* IN2L_ZC */
795#define WM8993_IN2L_VOL_MASK 0x001F /* IN2L_VOL - [4:0] */
796#define WM8993_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [4:0] */
797#define WM8993_IN2L_VOL_WIDTH 5 /* IN2L_VOL - [4:0] */
798
799/*
800 * R26 (0x1A) - Right Line Input 1&2 Volume
801 */
802#define WM8993_IN1_VU 0x0100 /* IN1_VU */
803#define WM8993_IN1_VU_MASK 0x0100 /* IN1_VU */
804#define WM8993_IN1_VU_SHIFT 8 /* IN1_VU */
805#define WM8993_IN1_VU_WIDTH 1 /* IN1_VU */
806#define WM8993_IN1R_MUTE 0x0080 /* IN1R_MUTE */
807#define WM8993_IN1R_MUTE_MASK 0x0080 /* IN1R_MUTE */
808#define WM8993_IN1R_MUTE_SHIFT 7 /* IN1R_MUTE */
809#define WM8993_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
810#define WM8993_IN1R_ZC 0x0040 /* IN1R_ZC */
811#define WM8993_IN1R_ZC_MASK 0x0040 /* IN1R_ZC */
812#define WM8993_IN1R_ZC_SHIFT 6 /* IN1R_ZC */
813#define WM8993_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
814#define WM8993_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
815#define WM8993_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
816#define WM8993_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
817
818/*
819 * R27 (0x1B) - Right Line Input 3&4 Volume
820 */
821#define WM8993_IN2_VU 0x0100 /* IN2_VU */
822#define WM8993_IN2_VU_MASK 0x0100 /* IN2_VU */
823#define WM8993_IN2_VU_SHIFT 8 /* IN2_VU */
824#define WM8993_IN2_VU_WIDTH 1 /* IN2_VU */
825#define WM8993_IN2R_MUTE 0x0080 /* IN2R_MUTE */
826#define WM8993_IN2R_MUTE_MASK 0x0080 /* IN2R_MUTE */
827#define WM8993_IN2R_MUTE_SHIFT 7 /* IN2R_MUTE */
828#define WM8993_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
829#define WM8993_IN2R_ZC 0x0040 /* IN2R_ZC */
830#define WM8993_IN2R_ZC_MASK 0x0040 /* IN2R_ZC */
831#define WM8993_IN2R_ZC_SHIFT 6 /* IN2R_ZC */
832#define WM8993_IN2R_ZC_WIDTH 1 /* IN2R_ZC */
833#define WM8993_IN2R_VOL_MASK 0x001F /* IN2R_VOL - [4:0] */
834#define WM8993_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [4:0] */
835#define WM8993_IN2R_VOL_WIDTH 5 /* IN2R_VOL - [4:0] */
836
837/*
838 * R28 (0x1C) - Left Output Volume
839 */
840#define WM8993_HPOUT1_VU 0x0100 /* HPOUT1_VU */
841#define WM8993_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
842#define WM8993_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
843#define WM8993_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
844#define WM8993_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
845#define WM8993_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
846#define WM8993_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
847#define WM8993_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
848#define WM8993_HPOUT1L_MUTE_N 0x0040 /* HPOUT1L_MUTE_N */
849#define WM8993_HPOUT1L_MUTE_N_MASK 0x0040 /* HPOUT1L_MUTE_N */
850#define WM8993_HPOUT1L_MUTE_N_SHIFT 6 /* HPOUT1L_MUTE_N */
851#define WM8993_HPOUT1L_MUTE_N_WIDTH 1 /* HPOUT1L_MUTE_N */
852#define WM8993_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
853#define WM8993_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
854#define WM8993_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
855
856/*
857 * R29 (0x1D) - Right Output Volume
858 */
859#define WM8993_HPOUT1_VU 0x0100 /* HPOUT1_VU */
860#define WM8993_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
861#define WM8993_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
862#define WM8993_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
863#define WM8993_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
864#define WM8993_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
865#define WM8993_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
866#define WM8993_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
867#define WM8993_HPOUT1R_MUTE_N 0x0040 /* HPOUT1R_MUTE_N */
868#define WM8993_HPOUT1R_MUTE_N_MASK 0x0040 /* HPOUT1R_MUTE_N */
869#define WM8993_HPOUT1R_MUTE_N_SHIFT 6 /* HPOUT1R_MUTE_N */
870#define WM8993_HPOUT1R_MUTE_N_WIDTH 1 /* HPOUT1R_MUTE_N */
871#define WM8993_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
872#define WM8993_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
873#define WM8993_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
874
875/*
876 * R30 (0x1E) - Line Outputs Volume
877 */
878#define WM8993_LINEOUT1N_MUTE 0x0040 /* LINEOUT1N_MUTE */
879#define WM8993_LINEOUT1N_MUTE_MASK 0x0040 /* LINEOUT1N_MUTE */
880#define WM8993_LINEOUT1N_MUTE_SHIFT 6 /* LINEOUT1N_MUTE */
881#define WM8993_LINEOUT1N_MUTE_WIDTH 1 /* LINEOUT1N_MUTE */
882#define WM8993_LINEOUT1P_MUTE 0x0020 /* LINEOUT1P_MUTE */
883#define WM8993_LINEOUT1P_MUTE_MASK 0x0020 /* LINEOUT1P_MUTE */
884#define WM8993_LINEOUT1P_MUTE_SHIFT 5 /* LINEOUT1P_MUTE */
885#define WM8993_LINEOUT1P_MUTE_WIDTH 1 /* LINEOUT1P_MUTE */
886#define WM8993_LINEOUT1_VOL 0x0010 /* LINEOUT1_VOL */
887#define WM8993_LINEOUT1_VOL_MASK 0x0010 /* LINEOUT1_VOL */
888#define WM8993_LINEOUT1_VOL_SHIFT 4 /* LINEOUT1_VOL */
889#define WM8993_LINEOUT1_VOL_WIDTH 1 /* LINEOUT1_VOL */
890#define WM8993_LINEOUT2N_MUTE 0x0004 /* LINEOUT2N_MUTE */
891#define WM8993_LINEOUT2N_MUTE_MASK 0x0004 /* LINEOUT2N_MUTE */
892#define WM8993_LINEOUT2N_MUTE_SHIFT 2 /* LINEOUT2N_MUTE */
893#define WM8993_LINEOUT2N_MUTE_WIDTH 1 /* LINEOUT2N_MUTE */
894#define WM8993_LINEOUT2P_MUTE 0x0002 /* LINEOUT2P_MUTE */
895#define WM8993_LINEOUT2P_MUTE_MASK 0x0002 /* LINEOUT2P_MUTE */
896#define WM8993_LINEOUT2P_MUTE_SHIFT 1 /* LINEOUT2P_MUTE */
897#define WM8993_LINEOUT2P_MUTE_WIDTH 1 /* LINEOUT2P_MUTE */
898#define WM8993_LINEOUT2_VOL 0x0001 /* LINEOUT2_VOL */
899#define WM8993_LINEOUT2_VOL_MASK 0x0001 /* LINEOUT2_VOL */
900#define WM8993_LINEOUT2_VOL_SHIFT 0 /* LINEOUT2_VOL */
901#define WM8993_LINEOUT2_VOL_WIDTH 1 /* LINEOUT2_VOL */
902
903/*
904 * R31 (0x1F) - HPOUT2 Volume
905 */
906#define WM8993_HPOUT2_MUTE 0x0020 /* HPOUT2_MUTE */
907#define WM8993_HPOUT2_MUTE_MASK 0x0020 /* HPOUT2_MUTE */
908#define WM8993_HPOUT2_MUTE_SHIFT 5 /* HPOUT2_MUTE */
909#define WM8993_HPOUT2_MUTE_WIDTH 1 /* HPOUT2_MUTE */
910#define WM8993_HPOUT2_VOL 0x0010 /* HPOUT2_VOL */
911#define WM8993_HPOUT2_VOL_MASK 0x0010 /* HPOUT2_VOL */
912#define WM8993_HPOUT2_VOL_SHIFT 4 /* HPOUT2_VOL */
913#define WM8993_HPOUT2_VOL_WIDTH 1 /* HPOUT2_VOL */
914
915/*
916 * R32 (0x20) - Left OPGA Volume
917 */
918#define WM8993_MIXOUT_VU 0x0100 /* MIXOUT_VU */
919#define WM8993_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
920#define WM8993_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
921#define WM8993_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
922#define WM8993_MIXOUTL_ZC 0x0080 /* MIXOUTL_ZC */
923#define WM8993_MIXOUTL_ZC_MASK 0x0080 /* MIXOUTL_ZC */
924#define WM8993_MIXOUTL_ZC_SHIFT 7 /* MIXOUTL_ZC */
925#define WM8993_MIXOUTL_ZC_WIDTH 1 /* MIXOUTL_ZC */
926#define WM8993_MIXOUTL_MUTE_N 0x0040 /* MIXOUTL_MUTE_N */
927#define WM8993_MIXOUTL_MUTE_N_MASK 0x0040 /* MIXOUTL_MUTE_N */
928#define WM8993_MIXOUTL_MUTE_N_SHIFT 6 /* MIXOUTL_MUTE_N */
929#define WM8993_MIXOUTL_MUTE_N_WIDTH 1 /* MIXOUTL_MUTE_N */
930#define WM8993_MIXOUTL_VOL_MASK 0x003F /* MIXOUTL_VOL - [5:0] */
931#define WM8993_MIXOUTL_VOL_SHIFT 0 /* MIXOUTL_VOL - [5:0] */
932#define WM8993_MIXOUTL_VOL_WIDTH 6 /* MIXOUTL_VOL - [5:0] */
933
934/*
935 * R33 (0x21) - Right OPGA Volume
936 */
937#define WM8993_MIXOUT_VU 0x0100 /* MIXOUT_VU */
938#define WM8993_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
939#define WM8993_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
940#define WM8993_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
941#define WM8993_MIXOUTR_ZC 0x0080 /* MIXOUTR_ZC */
942#define WM8993_MIXOUTR_ZC_MASK 0x0080 /* MIXOUTR_ZC */
943#define WM8993_MIXOUTR_ZC_SHIFT 7 /* MIXOUTR_ZC */
944#define WM8993_MIXOUTR_ZC_WIDTH 1 /* MIXOUTR_ZC */
945#define WM8993_MIXOUTR_MUTE_N 0x0040 /* MIXOUTR_MUTE_N */
946#define WM8993_MIXOUTR_MUTE_N_MASK 0x0040 /* MIXOUTR_MUTE_N */
947#define WM8993_MIXOUTR_MUTE_N_SHIFT 6 /* MIXOUTR_MUTE_N */
948#define WM8993_MIXOUTR_MUTE_N_WIDTH 1 /* MIXOUTR_MUTE_N */
949#define WM8993_MIXOUTR_VOL_MASK 0x003F /* MIXOUTR_VOL - [5:0] */
950#define WM8993_MIXOUTR_VOL_SHIFT 0 /* MIXOUTR_VOL - [5:0] */
951#define WM8993_MIXOUTR_VOL_WIDTH 6 /* MIXOUTR_VOL - [5:0] */
952
953/*
954 * R34 (0x22) - SPKMIXL Attenuation
955 */
956#define WM8993_MIXINL_SPKMIXL_VOL 0x0020 /* MIXINL_SPKMIXL_VOL */
957#define WM8993_MIXINL_SPKMIXL_VOL_MASK 0x0020 /* MIXINL_SPKMIXL_VOL */
958#define WM8993_MIXINL_SPKMIXL_VOL_SHIFT 5 /* MIXINL_SPKMIXL_VOL */
959#define WM8993_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */
960#define WM8993_IN1LP_SPKMIXL_VOL 0x0010 /* IN1LP_SPKMIXL_VOL */
961#define WM8993_IN1LP_SPKMIXL_VOL_MASK 0x0010 /* IN1LP_SPKMIXL_VOL */
962#define WM8993_IN1LP_SPKMIXL_VOL_SHIFT 4 /* IN1LP_SPKMIXL_VOL */
963#define WM8993_IN1LP_SPKMIXL_VOL_WIDTH 1 /* IN1LP_SPKMIXL_VOL */
964#define WM8993_MIXOUTL_SPKMIXL_VOL 0x0008 /* MIXOUTL_SPKMIXL_VOL */
965#define WM8993_MIXOUTL_SPKMIXL_VOL_MASK 0x0008 /* MIXOUTL_SPKMIXL_VOL */
966#define WM8993_MIXOUTL_SPKMIXL_VOL_SHIFT 3 /* MIXOUTL_SPKMIXL_VOL */
967#define WM8993_MIXOUTL_SPKMIXL_VOL_WIDTH 1 /* MIXOUTL_SPKMIXL_VOL */
968#define WM8993_DACL_SPKMIXL_VOL 0x0004 /* DACL_SPKMIXL_VOL */
969#define WM8993_DACL_SPKMIXL_VOL_MASK 0x0004 /* DACL_SPKMIXL_VOL */
970#define WM8993_DACL_SPKMIXL_VOL_SHIFT 2 /* DACL_SPKMIXL_VOL */
971#define WM8993_DACL_SPKMIXL_VOL_WIDTH 1 /* DACL_SPKMIXL_VOL */
972#define WM8993_SPKMIXL_VOL_MASK 0x0003 /* SPKMIXL_VOL - [1:0] */
973#define WM8993_SPKMIXL_VOL_SHIFT 0 /* SPKMIXL_VOL - [1:0] */
974#define WM8993_SPKMIXL_VOL_WIDTH 2 /* SPKMIXL_VOL - [1:0] */
975
976/*
977 * R35 (0x23) - SPKMIXR Attenuation
978 */
979#define WM8993_SPKOUT_CLASSAB_MODE 0x0100 /* SPKOUT_CLASSAB_MODE */
980#define WM8993_SPKOUT_CLASSAB_MODE_MASK 0x0100 /* SPKOUT_CLASSAB_MODE */
981#define WM8993_SPKOUT_CLASSAB_MODE_SHIFT 8 /* SPKOUT_CLASSAB_MODE */
982#define WM8993_SPKOUT_CLASSAB_MODE_WIDTH 1 /* SPKOUT_CLASSAB_MODE */
983#define WM8993_MIXINR_SPKMIXR_VOL 0x0020 /* MIXINR_SPKMIXR_VOL */
984#define WM8993_MIXINR_SPKMIXR_VOL_MASK 0x0020 /* MIXINR_SPKMIXR_VOL */
985#define WM8993_MIXINR_SPKMIXR_VOL_SHIFT 5 /* MIXINR_SPKMIXR_VOL */
986#define WM8993_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */
987#define WM8993_IN1RP_SPKMIXR_VOL 0x0010 /* IN1RP_SPKMIXR_VOL */
988#define WM8993_IN1RP_SPKMIXR_VOL_MASK 0x0010 /* IN1RP_SPKMIXR_VOL */
989#define WM8993_IN1RP_SPKMIXR_VOL_SHIFT 4 /* IN1RP_SPKMIXR_VOL */
990#define WM8993_IN1RP_SPKMIXR_VOL_WIDTH 1 /* IN1RP_SPKMIXR_VOL */
991#define WM8993_MIXOUTR_SPKMIXR_VOL 0x0008 /* MIXOUTR_SPKMIXR_VOL */
992#define WM8993_MIXOUTR_SPKMIXR_VOL_MASK 0x0008 /* MIXOUTR_SPKMIXR_VOL */
993#define WM8993_MIXOUTR_SPKMIXR_VOL_SHIFT 3 /* MIXOUTR_SPKMIXR_VOL */
994#define WM8993_MIXOUTR_SPKMIXR_VOL_WIDTH 1 /* MIXOUTR_SPKMIXR_VOL */
995#define WM8993_DACR_SPKMIXR_VOL 0x0004 /* DACR_SPKMIXR_VOL */
996#define WM8993_DACR_SPKMIXR_VOL_MASK 0x0004 /* DACR_SPKMIXR_VOL */
997#define WM8993_DACR_SPKMIXR_VOL_SHIFT 2 /* DACR_SPKMIXR_VOL */
998#define WM8993_DACR_SPKMIXR_VOL_WIDTH 1 /* DACR_SPKMIXR_VOL */
999#define WM8993_SPKMIXR_VOL_MASK 0x0003 /* SPKMIXR_VOL - [1:0] */
1000#define WM8993_SPKMIXR_VOL_SHIFT 0 /* SPKMIXR_VOL - [1:0] */
1001#define WM8993_SPKMIXR_VOL_WIDTH 2 /* SPKMIXR_VOL - [1:0] */
1002
1003/*
1004 * R36 (0x24) - SPKOUT Mixers
1005 */
1006#define WM8993_VRX_TO_SPKOUTL 0x0020 /* VRX_TO_SPKOUTL */
1007#define WM8993_VRX_TO_SPKOUTL_MASK 0x0020 /* VRX_TO_SPKOUTL */
1008#define WM8993_VRX_TO_SPKOUTL_SHIFT 5 /* VRX_TO_SPKOUTL */
1009#define WM8993_VRX_TO_SPKOUTL_WIDTH 1 /* VRX_TO_SPKOUTL */
1010#define WM8993_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
1011#define WM8993_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
1012#define WM8993_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
1013#define WM8993_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
1014#define WM8993_SPKMIXR_TO_SPKOUTL 0x0008 /* SPKMIXR_TO_SPKOUTL */
1015#define WM8993_SPKMIXR_TO_SPKOUTL_MASK 0x0008 /* SPKMIXR_TO_SPKOUTL */
1016#define WM8993_SPKMIXR_TO_SPKOUTL_SHIFT 3 /* SPKMIXR_TO_SPKOUTL */
1017#define WM8993_SPKMIXR_TO_SPKOUTL_WIDTH 1 /* SPKMIXR_TO_SPKOUTL */
1018#define WM8993_VRX_TO_SPKOUTR 0x0004 /* VRX_TO_SPKOUTR */
1019#define WM8993_VRX_TO_SPKOUTR_MASK 0x0004 /* VRX_TO_SPKOUTR */
1020#define WM8993_VRX_TO_SPKOUTR_SHIFT 2 /* VRX_TO_SPKOUTR */
1021#define WM8993_VRX_TO_SPKOUTR_WIDTH 1 /* VRX_TO_SPKOUTR */
1022#define WM8993_SPKMIXL_TO_SPKOUTR 0x0002 /* SPKMIXL_TO_SPKOUTR */
1023#define WM8993_SPKMIXL_TO_SPKOUTR_MASK 0x0002 /* SPKMIXL_TO_SPKOUTR */
1024#define WM8993_SPKMIXL_TO_SPKOUTR_SHIFT 1 /* SPKMIXL_TO_SPKOUTR */
1025#define WM8993_SPKMIXL_TO_SPKOUTR_WIDTH 1 /* SPKMIXL_TO_SPKOUTR */
1026#define WM8993_SPKMIXR_TO_SPKOUTR 0x0001 /* SPKMIXR_TO_SPKOUTR */
1027#define WM8993_SPKMIXR_TO_SPKOUTR_MASK 0x0001 /* SPKMIXR_TO_SPKOUTR */
1028#define WM8993_SPKMIXR_TO_SPKOUTR_SHIFT 0 /* SPKMIXR_TO_SPKOUTR */
1029#define WM8993_SPKMIXR_TO_SPKOUTR_WIDTH 1 /* SPKMIXR_TO_SPKOUTR */
1030
1031/*
1032 * R37 (0x25) - SPKOUT Boost
1033 */
1034#define WM8993_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
1035#define WM8993_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
1036#define WM8993_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
1037#define WM8993_SPKOUTR_BOOST_MASK 0x0007 /* SPKOUTR_BOOST - [2:0] */
1038#define WM8993_SPKOUTR_BOOST_SHIFT 0 /* SPKOUTR_BOOST - [2:0] */
1039#define WM8993_SPKOUTR_BOOST_WIDTH 3 /* SPKOUTR_BOOST - [2:0] */
1040
1041/*
1042 * R38 (0x26) - Speaker Volume Left
1043 */
1044#define WM8993_SPKOUT_VU 0x0100 /* SPKOUT_VU */
1045#define WM8993_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
1046#define WM8993_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
1047#define WM8993_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
1048#define WM8993_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
1049#define WM8993_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
1050#define WM8993_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
1051#define WM8993_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
1052#define WM8993_SPKOUTL_MUTE_N 0x0040 /* SPKOUTL_MUTE_N */
1053#define WM8993_SPKOUTL_MUTE_N_MASK 0x0040 /* SPKOUTL_MUTE_N */
1054#define WM8993_SPKOUTL_MUTE_N_SHIFT 6 /* SPKOUTL_MUTE_N */
1055#define WM8993_SPKOUTL_MUTE_N_WIDTH 1 /* SPKOUTL_MUTE_N */
1056#define WM8993_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
1057#define WM8993_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
1058#define WM8993_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
1059
1060/*
1061 * R39 (0x27) - Speaker Volume Right
1062 */
1063#define WM8993_SPKOUT_VU 0x0100 /* SPKOUT_VU */
1064#define WM8993_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
1065#define WM8993_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
1066#define WM8993_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
1067#define WM8993_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */
1068#define WM8993_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */
1069#define WM8993_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */
1070#define WM8993_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */
1071#define WM8993_SPKOUTR_MUTE_N 0x0040 /* SPKOUTR_MUTE_N */
1072#define WM8993_SPKOUTR_MUTE_N_MASK 0x0040 /* SPKOUTR_MUTE_N */
1073#define WM8993_SPKOUTR_MUTE_N_SHIFT 6 /* SPKOUTR_MUTE_N */
1074#define WM8993_SPKOUTR_MUTE_N_WIDTH 1 /* SPKOUTR_MUTE_N */
1075#define WM8993_SPKOUTR_VOL_MASK 0x003F /* SPKOUTR_VOL - [5:0] */
1076#define WM8993_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [5:0] */
1077#define WM8993_SPKOUTR_VOL_WIDTH 6 /* SPKOUTR_VOL - [5:0] */
1078
1079/*
1080 * R40 (0x28) - Input Mixer2
1081 */
1082#define WM8993_IN2LP_TO_IN2L 0x0080 /* IN2LP_TO_IN2L */
1083#define WM8993_IN2LP_TO_IN2L_MASK 0x0080 /* IN2LP_TO_IN2L */
1084#define WM8993_IN2LP_TO_IN2L_SHIFT 7 /* IN2LP_TO_IN2L */
1085#define WM8993_IN2LP_TO_IN2L_WIDTH 1 /* IN2LP_TO_IN2L */
1086#define WM8993_IN2LN_TO_IN2L 0x0040 /* IN2LN_TO_IN2L */
1087#define WM8993_IN2LN_TO_IN2L_MASK 0x0040 /* IN2LN_TO_IN2L */
1088#define WM8993_IN2LN_TO_IN2L_SHIFT 6 /* IN2LN_TO_IN2L */
1089#define WM8993_IN2LN_TO_IN2L_WIDTH 1 /* IN2LN_TO_IN2L */
1090#define WM8993_IN1LP_TO_IN1L 0x0020 /* IN1LP_TO_IN1L */
1091#define WM8993_IN1LP_TO_IN1L_MASK 0x0020 /* IN1LP_TO_IN1L */
1092#define WM8993_IN1LP_TO_IN1L_SHIFT 5 /* IN1LP_TO_IN1L */
1093#define WM8993_IN1LP_TO_IN1L_WIDTH 1 /* IN1LP_TO_IN1L */
1094#define WM8993_IN1LN_TO_IN1L 0x0010 /* IN1LN_TO_IN1L */
1095#define WM8993_IN1LN_TO_IN1L_MASK 0x0010 /* IN1LN_TO_IN1L */
1096#define WM8993_IN1LN_TO_IN1L_SHIFT 4 /* IN1LN_TO_IN1L */
1097#define WM8993_IN1LN_TO_IN1L_WIDTH 1 /* IN1LN_TO_IN1L */
1098#define WM8993_IN2RP_TO_IN2R 0x0008 /* IN2RP_TO_IN2R */
1099#define WM8993_IN2RP_TO_IN2R_MASK 0x0008 /* IN2RP_TO_IN2R */
1100#define WM8993_IN2RP_TO_IN2R_SHIFT 3 /* IN2RP_TO_IN2R */
1101#define WM8993_IN2RP_TO_IN2R_WIDTH 1 /* IN2RP_TO_IN2R */
1102#define WM8993_IN2RN_TO_IN2R 0x0004 /* IN2RN_TO_IN2R */
1103#define WM8993_IN2RN_TO_IN2R_MASK 0x0004 /* IN2RN_TO_IN2R */
1104#define WM8993_IN2RN_TO_IN2R_SHIFT 2 /* IN2RN_TO_IN2R */
1105#define WM8993_IN2RN_TO_IN2R_WIDTH 1 /* IN2RN_TO_IN2R */
1106#define WM8993_IN1RP_TO_IN1R 0x0002 /* IN1RP_TO_IN1R */
1107#define WM8993_IN1RP_TO_IN1R_MASK 0x0002 /* IN1RP_TO_IN1R */
1108#define WM8993_IN1RP_TO_IN1R_SHIFT 1 /* IN1RP_TO_IN1R */
1109#define WM8993_IN1RP_TO_IN1R_WIDTH 1 /* IN1RP_TO_IN1R */
1110#define WM8993_IN1RN_TO_IN1R 0x0001 /* IN1RN_TO_IN1R */
1111#define WM8993_IN1RN_TO_IN1R_MASK 0x0001 /* IN1RN_TO_IN1R */
1112#define WM8993_IN1RN_TO_IN1R_SHIFT 0 /* IN1RN_TO_IN1R */
1113#define WM8993_IN1RN_TO_IN1R_WIDTH 1 /* IN1RN_TO_IN1R */
1114
1115/*
1116 * R41 (0x29) - Input Mixer3
1117 */
1118#define WM8993_IN2L_TO_MIXINL 0x0100 /* IN2L_TO_MIXINL */
1119#define WM8993_IN2L_TO_MIXINL_MASK 0x0100 /* IN2L_TO_MIXINL */
1120#define WM8993_IN2L_TO_MIXINL_SHIFT 8 /* IN2L_TO_MIXINL */
1121#define WM8993_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */
1122#define WM8993_IN2L_MIXINL_VOL 0x0080 /* IN2L_MIXINL_VOL */
1123#define WM8993_IN2L_MIXINL_VOL_MASK 0x0080 /* IN2L_MIXINL_VOL */
1124#define WM8993_IN2L_MIXINL_VOL_SHIFT 7 /* IN2L_MIXINL_VOL */
1125#define WM8993_IN2L_MIXINL_VOL_WIDTH 1 /* IN2L_MIXINL_VOL */
1126#define WM8993_IN1L_TO_MIXINL 0x0020 /* IN1L_TO_MIXINL */
1127#define WM8993_IN1L_TO_MIXINL_MASK 0x0020 /* IN1L_TO_MIXINL */
1128#define WM8993_IN1L_TO_MIXINL_SHIFT 5 /* IN1L_TO_MIXINL */
1129#define WM8993_IN1L_TO_MIXINL_WIDTH 1 /* IN1L_TO_MIXINL */
1130#define WM8993_IN1L_MIXINL_VOL 0x0010 /* IN1L_MIXINL_VOL */
1131#define WM8993_IN1L_MIXINL_VOL_MASK 0x0010 /* IN1L_MIXINL_VOL */
1132#define WM8993_IN1L_MIXINL_VOL_SHIFT 4 /* IN1L_MIXINL_VOL */
1133#define WM8993_IN1L_MIXINL_VOL_WIDTH 1 /* IN1L_MIXINL_VOL */
1134#define WM8993_MIXOUTL_MIXINL_VOL_MASK 0x0007 /* MIXOUTL_MIXINL_VOL - [2:0] */
1135#define WM8993_MIXOUTL_MIXINL_VOL_SHIFT 0 /* MIXOUTL_MIXINL_VOL - [2:0] */
1136#define WM8993_MIXOUTL_MIXINL_VOL_WIDTH 3 /* MIXOUTL_MIXINL_VOL - [2:0] */
1137
1138/*
1139 * R42 (0x2A) - Input Mixer4
1140 */
1141#define WM8993_IN2R_TO_MIXINR 0x0100 /* IN2R_TO_MIXINR */
1142#define WM8993_IN2R_TO_MIXINR_MASK 0x0100 /* IN2R_TO_MIXINR */
1143#define WM8993_IN2R_TO_MIXINR_SHIFT 8 /* IN2R_TO_MIXINR */
1144#define WM8993_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */
1145#define WM8993_IN2R_MIXINR_VOL 0x0080 /* IN2R_MIXINR_VOL */
1146#define WM8993_IN2R_MIXINR_VOL_MASK 0x0080 /* IN2R_MIXINR_VOL */
1147#define WM8993_IN2R_MIXINR_VOL_SHIFT 7 /* IN2R_MIXINR_VOL */
1148#define WM8993_IN2R_MIXINR_VOL_WIDTH 1 /* IN2R_MIXINR_VOL */
1149#define WM8993_IN1R_TO_MIXINR 0x0020 /* IN1R_TO_MIXINR */
1150#define WM8993_IN1R_TO_MIXINR_MASK 0x0020 /* IN1R_TO_MIXINR */
1151#define WM8993_IN1R_TO_MIXINR_SHIFT 5 /* IN1R_TO_MIXINR */
1152#define WM8993_IN1R_TO_MIXINR_WIDTH 1 /* IN1R_TO_MIXINR */
1153#define WM8993_IN1R_MIXINR_VOL 0x0010 /* IN1R_MIXINR_VOL */
1154#define WM8993_IN1R_MIXINR_VOL_MASK 0x0010 /* IN1R_MIXINR_VOL */
1155#define WM8993_IN1R_MIXINR_VOL_SHIFT 4 /* IN1R_MIXINR_VOL */
1156#define WM8993_IN1R_MIXINR_VOL_WIDTH 1 /* IN1R_MIXINR_VOL */
1157#define WM8993_MIXOUTR_MIXINR_VOL_MASK 0x0007 /* MIXOUTR_MIXINR_VOL - [2:0] */
1158#define WM8993_MIXOUTR_MIXINR_VOL_SHIFT 0 /* MIXOUTR_MIXINR_VOL - [2:0] */
1159#define WM8993_MIXOUTR_MIXINR_VOL_WIDTH 3 /* MIXOUTR_MIXINR_VOL - [2:0] */
1160
1161/*
1162 * R43 (0x2B) - Input Mixer5
1163 */
1164#define WM8993_IN1LP_MIXINL_VOL_MASK 0x01C0 /* IN1LP_MIXINL_VOL - [8:6] */
1165#define WM8993_IN1LP_MIXINL_VOL_SHIFT 6 /* IN1LP_MIXINL_VOL - [8:6] */
1166#define WM8993_IN1LP_MIXINL_VOL_WIDTH 3 /* IN1LP_MIXINL_VOL - [8:6] */
1167#define WM8993_VRX_MIXINL_VOL_MASK 0x0007 /* VRX_MIXINL_VOL - [2:0] */
1168#define WM8993_VRX_MIXINL_VOL_SHIFT 0 /* VRX_MIXINL_VOL - [2:0] */
1169#define WM8993_VRX_MIXINL_VOL_WIDTH 3 /* VRX_MIXINL_VOL - [2:0] */
1170
1171/*
1172 * R44 (0x2C) - Input Mixer6
1173 */
1174#define WM8993_IN1RP_MIXINR_VOL_MASK 0x01C0 /* IN1RP_MIXINR_VOL - [8:6] */
1175#define WM8993_IN1RP_MIXINR_VOL_SHIFT 6 /* IN1RP_MIXINR_VOL - [8:6] */
1176#define WM8993_IN1RP_MIXINR_VOL_WIDTH 3 /* IN1RP_MIXINR_VOL - [8:6] */
1177#define WM8993_VRX_MIXINR_VOL_MASK 0x0007 /* VRX_MIXINR_VOL - [2:0] */
1178#define WM8993_VRX_MIXINR_VOL_SHIFT 0 /* VRX_MIXINR_VOL - [2:0] */
1179#define WM8993_VRX_MIXINR_VOL_WIDTH 3 /* VRX_MIXINR_VOL - [2:0] */
1180
1181/*
1182 * R45 (0x2D) - Output Mixer1
1183 */
1184#define WM8993_DACL_TO_HPOUT1L 0x0100 /* DACL_TO_HPOUT1L */
1185#define WM8993_DACL_TO_HPOUT1L_MASK 0x0100 /* DACL_TO_HPOUT1L */
1186#define WM8993_DACL_TO_HPOUT1L_SHIFT 8 /* DACL_TO_HPOUT1L */
1187#define WM8993_DACL_TO_HPOUT1L_WIDTH 1 /* DACL_TO_HPOUT1L */
1188#define WM8993_MIXINR_TO_MIXOUTL 0x0080 /* MIXINR_TO_MIXOUTL */
1189#define WM8993_MIXINR_TO_MIXOUTL_MASK 0x0080 /* MIXINR_TO_MIXOUTL */
1190#define WM8993_MIXINR_TO_MIXOUTL_SHIFT 7 /* MIXINR_TO_MIXOUTL */
1191#define WM8993_MIXINR_TO_MIXOUTL_WIDTH 1 /* MIXINR_TO_MIXOUTL */
1192#define WM8993_MIXINL_TO_MIXOUTL 0x0040 /* MIXINL_TO_MIXOUTL */
1193#define WM8993_MIXINL_TO_MIXOUTL_MASK 0x0040 /* MIXINL_TO_MIXOUTL */
1194#define WM8993_MIXINL_TO_MIXOUTL_SHIFT 6 /* MIXINL_TO_MIXOUTL */
1195#define WM8993_MIXINL_TO_MIXOUTL_WIDTH 1 /* MIXINL_TO_MIXOUTL */
1196#define WM8993_IN2RN_TO_MIXOUTL 0x0020 /* IN2RN_TO_MIXOUTL */
1197#define WM8993_IN2RN_TO_MIXOUTL_MASK 0x0020 /* IN2RN_TO_MIXOUTL */
1198#define WM8993_IN2RN_TO_MIXOUTL_SHIFT 5 /* IN2RN_TO_MIXOUTL */
1199#define WM8993_IN2RN_TO_MIXOUTL_WIDTH 1 /* IN2RN_TO_MIXOUTL */
1200#define WM8993_IN2LN_TO_MIXOUTL 0x0010 /* IN2LN_TO_MIXOUTL */
1201#define WM8993_IN2LN_TO_MIXOUTL_MASK 0x0010 /* IN2LN_TO_MIXOUTL */
1202#define WM8993_IN2LN_TO_MIXOUTL_SHIFT 4 /* IN2LN_TO_MIXOUTL */
1203#define WM8993_IN2LN_TO_MIXOUTL_WIDTH 1 /* IN2LN_TO_MIXOUTL */
1204#define WM8993_IN1R_TO_MIXOUTL 0x0008 /* IN1R_TO_MIXOUTL */
1205#define WM8993_IN1R_TO_MIXOUTL_MASK 0x0008 /* IN1R_TO_MIXOUTL */
1206#define WM8993_IN1R_TO_MIXOUTL_SHIFT 3 /* IN1R_TO_MIXOUTL */
1207#define WM8993_IN1R_TO_MIXOUTL_WIDTH 1 /* IN1R_TO_MIXOUTL */
1208#define WM8993_IN1L_TO_MIXOUTL 0x0004 /* IN1L_TO_MIXOUTL */
1209#define WM8993_IN1L_TO_MIXOUTL_MASK 0x0004 /* IN1L_TO_MIXOUTL */
1210#define WM8993_IN1L_TO_MIXOUTL_SHIFT 2 /* IN1L_TO_MIXOUTL */
1211#define WM8993_IN1L_TO_MIXOUTL_WIDTH 1 /* IN1L_TO_MIXOUTL */
1212#define WM8993_IN2LP_TO_MIXOUTL 0x0002 /* IN2LP_TO_MIXOUTL */
1213#define WM8993_IN2LP_TO_MIXOUTL_MASK 0x0002 /* IN2LP_TO_MIXOUTL */
1214#define WM8993_IN2LP_TO_MIXOUTL_SHIFT 1 /* IN2LP_TO_MIXOUTL */
1215#define WM8993_IN2LP_TO_MIXOUTL_WIDTH 1 /* IN2LP_TO_MIXOUTL */
1216#define WM8993_DACL_TO_MIXOUTL 0x0001 /* DACL_TO_MIXOUTL */
1217#define WM8993_DACL_TO_MIXOUTL_MASK 0x0001 /* DACL_TO_MIXOUTL */
1218#define WM8993_DACL_TO_MIXOUTL_SHIFT 0 /* DACL_TO_MIXOUTL */
1219#define WM8993_DACL_TO_MIXOUTL_WIDTH 1 /* DACL_TO_MIXOUTL */
1220
1221/*
1222 * R46 (0x2E) - Output Mixer2
1223 */
1224#define WM8993_DACR_TO_HPOUT1R 0x0100 /* DACR_TO_HPOUT1R */
1225#define WM8993_DACR_TO_HPOUT1R_MASK 0x0100 /* DACR_TO_HPOUT1R */
1226#define WM8993_DACR_TO_HPOUT1R_SHIFT 8 /* DACR_TO_HPOUT1R */
1227#define WM8993_DACR_TO_HPOUT1R_WIDTH 1 /* DACR_TO_HPOUT1R */
1228#define WM8993_MIXINL_TO_MIXOUTR 0x0080 /* MIXINL_TO_MIXOUTR */
1229#define WM8993_MIXINL_TO_MIXOUTR_MASK 0x0080 /* MIXINL_TO_MIXOUTR */
1230#define WM8993_MIXINL_TO_MIXOUTR_SHIFT 7 /* MIXINL_TO_MIXOUTR */
1231#define WM8993_MIXINL_TO_MIXOUTR_WIDTH 1 /* MIXINL_TO_MIXOUTR */
1232#define WM8993_MIXINR_TO_MIXOUTR 0x0040 /* MIXINR_TO_MIXOUTR */
1233#define WM8993_MIXINR_TO_MIXOUTR_MASK 0x0040 /* MIXINR_TO_MIXOUTR */
1234#define WM8993_MIXINR_TO_MIXOUTR_SHIFT 6 /* MIXINR_TO_MIXOUTR */
1235#define WM8993_MIXINR_TO_MIXOUTR_WIDTH 1 /* MIXINR_TO_MIXOUTR */
1236#define WM8993_IN2LN_TO_MIXOUTR 0x0020 /* IN2LN_TO_MIXOUTR */
1237#define WM8993_IN2LN_TO_MIXOUTR_MASK 0x0020 /* IN2LN_TO_MIXOUTR */
1238#define WM8993_IN2LN_TO_MIXOUTR_SHIFT 5 /* IN2LN_TO_MIXOUTR */
1239#define WM8993_IN2LN_TO_MIXOUTR_WIDTH 1 /* IN2LN_TO_MIXOUTR */
1240#define WM8993_IN2RN_TO_MIXOUTR 0x0010 /* IN2RN_TO_MIXOUTR */
1241#define WM8993_IN2RN_TO_MIXOUTR_MASK 0x0010 /* IN2RN_TO_MIXOUTR */
1242#define WM8993_IN2RN_TO_MIXOUTR_SHIFT 4 /* IN2RN_TO_MIXOUTR */
1243#define WM8993_IN2RN_TO_MIXOUTR_WIDTH 1 /* IN2RN_TO_MIXOUTR */
1244#define WM8993_IN1L_TO_MIXOUTR 0x0008 /* IN1L_TO_MIXOUTR */
1245#define WM8993_IN1L_TO_MIXOUTR_MASK 0x0008 /* IN1L_TO_MIXOUTR */
1246#define WM8993_IN1L_TO_MIXOUTR_SHIFT 3 /* IN1L_TO_MIXOUTR */
1247#define WM8993_IN1L_TO_MIXOUTR_WIDTH 1 /* IN1L_TO_MIXOUTR */
1248#define WM8993_IN1R_TO_MIXOUTR 0x0004 /* IN1R_TO_MIXOUTR */
1249#define WM8993_IN1R_TO_MIXOUTR_MASK 0x0004 /* IN1R_TO_MIXOUTR */
1250#define WM8993_IN1R_TO_MIXOUTR_SHIFT 2 /* IN1R_TO_MIXOUTR */
1251#define WM8993_IN1R_TO_MIXOUTR_WIDTH 1 /* IN1R_TO_MIXOUTR */
1252#define WM8993_IN2RP_TO_MIXOUTR 0x0002 /* IN2RP_TO_MIXOUTR */
1253#define WM8993_IN2RP_TO_MIXOUTR_MASK 0x0002 /* IN2RP_TO_MIXOUTR */
1254#define WM8993_IN2RP_TO_MIXOUTR_SHIFT 1 /* IN2RP_TO_MIXOUTR */
1255#define WM8993_IN2RP_TO_MIXOUTR_WIDTH 1 /* IN2RP_TO_MIXOUTR */
1256#define WM8993_DACR_TO_MIXOUTR 0x0001 /* DACR_TO_MIXOUTR */
1257#define WM8993_DACR_TO_MIXOUTR_MASK 0x0001 /* DACR_TO_MIXOUTR */
1258#define WM8993_DACR_TO_MIXOUTR_SHIFT 0 /* DACR_TO_MIXOUTR */
1259#define WM8993_DACR_TO_MIXOUTR_WIDTH 1 /* DACR_TO_MIXOUTR */
1260
1261/*
1262 * R47 (0x2F) - Output Mixer3
1263 */
1264#define WM8993_IN2LP_MIXOUTL_VOL_MASK 0x0E00 /* IN2LP_MIXOUTL_VOL - [11:9] */
1265#define WM8993_IN2LP_MIXOUTL_VOL_SHIFT 9 /* IN2LP_MIXOUTL_VOL - [11:9] */
1266#define WM8993_IN2LP_MIXOUTL_VOL_WIDTH 3 /* IN2LP_MIXOUTL_VOL - [11:9] */
1267#define WM8993_IN2LN_MIXOUTL_VOL_MASK 0x01C0 /* IN2LN_MIXOUTL_VOL - [8:6] */
1268#define WM8993_IN2LN_MIXOUTL_VOL_SHIFT 6 /* IN2LN_MIXOUTL_VOL - [8:6] */
1269#define WM8993_IN2LN_MIXOUTL_VOL_WIDTH 3 /* IN2LN_MIXOUTL_VOL - [8:6] */
1270#define WM8993_IN1R_MIXOUTL_VOL_MASK 0x0038 /* IN1R_MIXOUTL_VOL - [5:3] */
1271#define WM8993_IN1R_MIXOUTL_VOL_SHIFT 3 /* IN1R_MIXOUTL_VOL - [5:3] */
1272#define WM8993_IN1R_MIXOUTL_VOL_WIDTH 3 /* IN1R_MIXOUTL_VOL - [5:3] */
1273#define WM8993_IN1L_MIXOUTL_VOL_MASK 0x0007 /* IN1L_MIXOUTL_VOL - [2:0] */
1274#define WM8993_IN1L_MIXOUTL_VOL_SHIFT 0 /* IN1L_MIXOUTL_VOL - [2:0] */
1275#define WM8993_IN1L_MIXOUTL_VOL_WIDTH 3 /* IN1L_MIXOUTL_VOL - [2:0] */
1276
1277/*
1278 * R48 (0x30) - Output Mixer4
1279 */
1280#define WM8993_IN2RP_MIXOUTR_VOL_MASK 0x0E00 /* IN2RP_MIXOUTR_VOL - [11:9] */
1281#define WM8993_IN2RP_MIXOUTR_VOL_SHIFT 9 /* IN2RP_MIXOUTR_VOL - [11:9] */
1282#define WM8993_IN2RP_MIXOUTR_VOL_WIDTH 3 /* IN2RP_MIXOUTR_VOL - [11:9] */
1283#define WM8993_IN2RN_MIXOUTR_VOL_MASK 0x01C0 /* IN2RN_MIXOUTR_VOL - [8:6] */
1284#define WM8993_IN2RN_MIXOUTR_VOL_SHIFT 6 /* IN2RN_MIXOUTR_VOL - [8:6] */
1285#define WM8993_IN2RN_MIXOUTR_VOL_WIDTH 3 /* IN2RN_MIXOUTR_VOL - [8:6] */
1286#define WM8993_IN1L_MIXOUTR_VOL_MASK 0x0038 /* IN1L_MIXOUTR_VOL - [5:3] */
1287#define WM8993_IN1L_MIXOUTR_VOL_SHIFT 3 /* IN1L_MIXOUTR_VOL - [5:3] */
1288#define WM8993_IN1L_MIXOUTR_VOL_WIDTH 3 /* IN1L_MIXOUTR_VOL - [5:3] */
1289#define WM8993_IN1R_MIXOUTR_VOL_MASK 0x0007 /* IN1R_MIXOUTR_VOL - [2:0] */
1290#define WM8993_IN1R_MIXOUTR_VOL_SHIFT 0 /* IN1R_MIXOUTR_VOL - [2:0] */
1291#define WM8993_IN1R_MIXOUTR_VOL_WIDTH 3 /* IN1R_MIXOUTR_VOL - [2:0] */
1292
1293/*
1294 * R49 (0x31) - Output Mixer5
1295 */
1296#define WM8993_DACL_MIXOUTL_VOL_MASK 0x0E00 /* DACL_MIXOUTL_VOL - [11:9] */
1297#define WM8993_DACL_MIXOUTL_VOL_SHIFT 9 /* DACL_MIXOUTL_VOL - [11:9] */
1298#define WM8993_DACL_MIXOUTL_VOL_WIDTH 3 /* DACL_MIXOUTL_VOL - [11:9] */
1299#define WM8993_IN2RN_MIXOUTL_VOL_MASK 0x01C0 /* IN2RN_MIXOUTL_VOL - [8:6] */
1300#define WM8993_IN2RN_MIXOUTL_VOL_SHIFT 6 /* IN2RN_MIXOUTL_VOL - [8:6] */
1301#define WM8993_IN2RN_MIXOUTL_VOL_WIDTH 3 /* IN2RN_MIXOUTL_VOL - [8:6] */
1302#define WM8993_MIXINR_MIXOUTL_VOL_MASK 0x0038 /* MIXINR_MIXOUTL_VOL - [5:3] */
1303#define WM8993_MIXINR_MIXOUTL_VOL_SHIFT 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
1304#define WM8993_MIXINR_MIXOUTL_VOL_WIDTH 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
1305#define WM8993_MIXINL_MIXOUTL_VOL_MASK 0x0007 /* MIXINL_MIXOUTL_VOL - [2:0] */
1306#define WM8993_MIXINL_MIXOUTL_VOL_SHIFT 0 /* MIXINL_MIXOUTL_VOL - [2:0] */
1307#define WM8993_MIXINL_MIXOUTL_VOL_WIDTH 3 /* MIXINL_MIXOUTL_VOL - [2:0] */
1308
1309/*
1310 * R50 (0x32) - Output Mixer6
1311 */
1312#define WM8993_DACR_MIXOUTR_VOL_MASK 0x0E00 /* DACR_MIXOUTR_VOL - [11:9] */
1313#define WM8993_DACR_MIXOUTR_VOL_SHIFT 9 /* DACR_MIXOUTR_VOL - [11:9] */
1314#define WM8993_DACR_MIXOUTR_VOL_WIDTH 3 /* DACR_MIXOUTR_VOL - [11:9] */
1315#define WM8993_IN2LN_MIXOUTR_VOL_MASK 0x01C0 /* IN2LN_MIXOUTR_VOL - [8:6] */
1316#define WM8993_IN2LN_MIXOUTR_VOL_SHIFT 6 /* IN2LN_MIXOUTR_VOL - [8:6] */
1317#define WM8993_IN2LN_MIXOUTR_VOL_WIDTH 3 /* IN2LN_MIXOUTR_VOL - [8:6] */
1318#define WM8993_MIXINL_MIXOUTR_VOL_MASK 0x0038 /* MIXINL_MIXOUTR_VOL - [5:3] */
1319#define WM8993_MIXINL_MIXOUTR_VOL_SHIFT 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
1320#define WM8993_MIXINL_MIXOUTR_VOL_WIDTH 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
1321#define WM8993_MIXINR_MIXOUTR_VOL_MASK 0x0007 /* MIXINR_MIXOUTR_VOL - [2:0] */
1322#define WM8993_MIXINR_MIXOUTR_VOL_SHIFT 0 /* MIXINR_MIXOUTR_VOL - [2:0] */
1323#define WM8993_MIXINR_MIXOUTR_VOL_WIDTH 3 /* MIXINR_MIXOUTR_VOL - [2:0] */
1324
1325/*
1326 * R51 (0x33) - HPOUT2 Mixer
1327 */
1328#define WM8993_VRX_TO_HPOUT2 0x0020 /* VRX_TO_HPOUT2 */
1329#define WM8993_VRX_TO_HPOUT2_MASK 0x0020 /* VRX_TO_HPOUT2 */
1330#define WM8993_VRX_TO_HPOUT2_SHIFT 5 /* VRX_TO_HPOUT2 */
1331#define WM8993_VRX_TO_HPOUT2_WIDTH 1 /* VRX_TO_HPOUT2 */
1332#define WM8993_MIXOUTLVOL_TO_HPOUT2 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
1333#define WM8993_MIXOUTLVOL_TO_HPOUT2_MASK 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
1334#define WM8993_MIXOUTLVOL_TO_HPOUT2_SHIFT 4 /* MIXOUTLVOL_TO_HPOUT2 */
1335#define WM8993_MIXOUTLVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTLVOL_TO_HPOUT2 */
1336#define WM8993_MIXOUTRVOL_TO_HPOUT2 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
1337#define WM8993_MIXOUTRVOL_TO_HPOUT2_MASK 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
1338#define WM8993_MIXOUTRVOL_TO_HPOUT2_SHIFT 3 /* MIXOUTRVOL_TO_HPOUT2 */
1339#define WM8993_MIXOUTRVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTRVOL_TO_HPOUT2 */
1340
1341/*
1342 * R52 (0x34) - Line Mixer1
1343 */
1344#define WM8993_MIXOUTL_TO_LINEOUT1N 0x0040 /* MIXOUTL_TO_LINEOUT1N */
1345#define WM8993_MIXOUTL_TO_LINEOUT1N_MASK 0x0040 /* MIXOUTL_TO_LINEOUT1N */
1346#define WM8993_MIXOUTL_TO_LINEOUT1N_SHIFT 6 /* MIXOUTL_TO_LINEOUT1N */
1347#define WM8993_MIXOUTL_TO_LINEOUT1N_WIDTH 1 /* MIXOUTL_TO_LINEOUT1N */
1348#define WM8993_MIXOUTR_TO_LINEOUT1N 0x0020 /* MIXOUTR_TO_LINEOUT1N */
1349#define WM8993_MIXOUTR_TO_LINEOUT1N_MASK 0x0020 /* MIXOUTR_TO_LINEOUT1N */
1350#define WM8993_MIXOUTR_TO_LINEOUT1N_SHIFT 5 /* MIXOUTR_TO_LINEOUT1N */
1351#define WM8993_MIXOUTR_TO_LINEOUT1N_WIDTH 1 /* MIXOUTR_TO_LINEOUT1N */
1352#define WM8993_LINEOUT1_MODE 0x0010 /* LINEOUT1_MODE */
1353#define WM8993_LINEOUT1_MODE_MASK 0x0010 /* LINEOUT1_MODE */
1354#define WM8993_LINEOUT1_MODE_SHIFT 4 /* LINEOUT1_MODE */
1355#define WM8993_LINEOUT1_MODE_WIDTH 1 /* LINEOUT1_MODE */
1356#define WM8993_IN1R_TO_LINEOUT1P 0x0004 /* IN1R_TO_LINEOUT1P */
1357#define WM8993_IN1R_TO_LINEOUT1P_MASK 0x0004 /* IN1R_TO_LINEOUT1P */
1358#define WM8993_IN1R_TO_LINEOUT1P_SHIFT 2 /* IN1R_TO_LINEOUT1P */
1359#define WM8993_IN1R_TO_LINEOUT1P_WIDTH 1 /* IN1R_TO_LINEOUT1P */
1360#define WM8993_IN1L_TO_LINEOUT1P 0x0002 /* IN1L_TO_LINEOUT1P */
1361#define WM8993_IN1L_TO_LINEOUT1P_MASK 0x0002 /* IN1L_TO_LINEOUT1P */
1362#define WM8993_IN1L_TO_LINEOUT1P_SHIFT 1 /* IN1L_TO_LINEOUT1P */
1363#define WM8993_IN1L_TO_LINEOUT1P_WIDTH 1 /* IN1L_TO_LINEOUT1P */
1364#define WM8993_MIXOUTL_TO_LINEOUT1P 0x0001 /* MIXOUTL_TO_LINEOUT1P */
1365#define WM8993_MIXOUTL_TO_LINEOUT1P_MASK 0x0001 /* MIXOUTL_TO_LINEOUT1P */
1366#define WM8993_MIXOUTL_TO_LINEOUT1P_SHIFT 0 /* MIXOUTL_TO_LINEOUT1P */
1367#define WM8993_MIXOUTL_TO_LINEOUT1P_WIDTH 1 /* MIXOUTL_TO_LINEOUT1P */
1368
1369/*
1370 * R53 (0x35) - Line Mixer2
1371 */
1372#define WM8993_MIXOUTR_TO_LINEOUT2N 0x0040 /* MIXOUTR_TO_LINEOUT2N */
1373#define WM8993_MIXOUTR_TO_LINEOUT2N_MASK 0x0040 /* MIXOUTR_TO_LINEOUT2N */
1374#define WM8993_MIXOUTR_TO_LINEOUT2N_SHIFT 6 /* MIXOUTR_TO_LINEOUT2N */
1375#define WM8993_MIXOUTR_TO_LINEOUT2N_WIDTH 1 /* MIXOUTR_TO_LINEOUT2N */
1376#define WM8993_MIXOUTL_TO_LINEOUT2N 0x0020 /* MIXOUTL_TO_LINEOUT2N */
1377#define WM8993_MIXOUTL_TO_LINEOUT2N_MASK 0x0020 /* MIXOUTL_TO_LINEOUT2N */
1378#define WM8993_MIXOUTL_TO_LINEOUT2N_SHIFT 5 /* MIXOUTL_TO_LINEOUT2N */
1379#define WM8993_MIXOUTL_TO_LINEOUT2N_WIDTH 1 /* MIXOUTL_TO_LINEOUT2N */
1380#define WM8993_LINEOUT2_MODE 0x0010 /* LINEOUT2_MODE */
1381#define WM8993_LINEOUT2_MODE_MASK 0x0010 /* LINEOUT2_MODE */
1382#define WM8993_LINEOUT2_MODE_SHIFT 4 /* LINEOUT2_MODE */
1383#define WM8993_LINEOUT2_MODE_WIDTH 1 /* LINEOUT2_MODE */
1384#define WM8993_IN1L_TO_LINEOUT2P 0x0004 /* IN1L_TO_LINEOUT2P */
1385#define WM8993_IN1L_TO_LINEOUT2P_MASK 0x0004 /* IN1L_TO_LINEOUT2P */
1386#define WM8993_IN1L_TO_LINEOUT2P_SHIFT 2 /* IN1L_TO_LINEOUT2P */
1387#define WM8993_IN1L_TO_LINEOUT2P_WIDTH 1 /* IN1L_TO_LINEOUT2P */
1388#define WM8993_IN1R_TO_LINEOUT2P 0x0002 /* IN1R_TO_LINEOUT2P */
1389#define WM8993_IN1R_TO_LINEOUT2P_MASK 0x0002 /* IN1R_TO_LINEOUT2P */
1390#define WM8993_IN1R_TO_LINEOUT2P_SHIFT 1 /* IN1R_TO_LINEOUT2P */
1391#define WM8993_IN1R_TO_LINEOUT2P_WIDTH 1 /* IN1R_TO_LINEOUT2P */
1392#define WM8993_MIXOUTR_TO_LINEOUT2P 0x0001 /* MIXOUTR_TO_LINEOUT2P */
1393#define WM8993_MIXOUTR_TO_LINEOUT2P_MASK 0x0001 /* MIXOUTR_TO_LINEOUT2P */
1394#define WM8993_MIXOUTR_TO_LINEOUT2P_SHIFT 0 /* MIXOUTR_TO_LINEOUT2P */
1395#define WM8993_MIXOUTR_TO_LINEOUT2P_WIDTH 1 /* MIXOUTR_TO_LINEOUT2P */
1396
1397/*
1398 * R54 (0x36) - Speaker Mixer
1399 */
1400#define WM8993_SPKAB_REF_SEL 0x0100 /* SPKAB_REF_SEL */
1401#define WM8993_SPKAB_REF_SEL_MASK 0x0100 /* SPKAB_REF_SEL */
1402#define WM8993_SPKAB_REF_SEL_SHIFT 8 /* SPKAB_REF_SEL */
1403#define WM8993_SPKAB_REF_SEL_WIDTH 1 /* SPKAB_REF_SEL */
1404#define WM8993_MIXINL_TO_SPKMIXL 0x0080 /* MIXINL_TO_SPKMIXL */
1405#define WM8993_MIXINL_TO_SPKMIXL_MASK 0x0080 /* MIXINL_TO_SPKMIXL */
1406#define WM8993_MIXINL_TO_SPKMIXL_SHIFT 7 /* MIXINL_TO_SPKMIXL */
1407#define WM8993_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */
1408#define WM8993_MIXINR_TO_SPKMIXR 0x0040 /* MIXINR_TO_SPKMIXR */
1409#define WM8993_MIXINR_TO_SPKMIXR_MASK 0x0040 /* MIXINR_TO_SPKMIXR */
1410#define WM8993_MIXINR_TO_SPKMIXR_SHIFT 6 /* MIXINR_TO_SPKMIXR */
1411#define WM8993_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */
1412#define WM8993_IN1LP_TO_SPKMIXL 0x0020 /* IN1LP_TO_SPKMIXL */
1413#define WM8993_IN1LP_TO_SPKMIXL_MASK 0x0020 /* IN1LP_TO_SPKMIXL */
1414#define WM8993_IN1LP_TO_SPKMIXL_SHIFT 5 /* IN1LP_TO_SPKMIXL */
1415#define WM8993_IN1LP_TO_SPKMIXL_WIDTH 1 /* IN1LP_TO_SPKMIXL */
1416#define WM8993_IN1RP_TO_SPKMIXR 0x0010 /* IN1RP_TO_SPKMIXR */
1417#define WM8993_IN1RP_TO_SPKMIXR_MASK 0x0010 /* IN1RP_TO_SPKMIXR */
1418#define WM8993_IN1RP_TO_SPKMIXR_SHIFT 4 /* IN1RP_TO_SPKMIXR */
1419#define WM8993_IN1RP_TO_SPKMIXR_WIDTH 1 /* IN1RP_TO_SPKMIXR */
1420#define WM8993_MIXOUTL_TO_SPKMIXL 0x0008 /* MIXOUTL_TO_SPKMIXL */
1421#define WM8993_MIXOUTL_TO_SPKMIXL_MASK 0x0008 /* MIXOUTL_TO_SPKMIXL */
1422#define WM8993_MIXOUTL_TO_SPKMIXL_SHIFT 3 /* MIXOUTL_TO_SPKMIXL */
1423#define WM8993_MIXOUTL_TO_SPKMIXL_WIDTH 1 /* MIXOUTL_TO_SPKMIXL */
1424#define WM8993_MIXOUTR_TO_SPKMIXR 0x0004 /* MIXOUTR_TO_SPKMIXR */
1425#define WM8993_MIXOUTR_TO_SPKMIXR_MASK 0x0004 /* MIXOUTR_TO_SPKMIXR */
1426#define WM8993_MIXOUTR_TO_SPKMIXR_SHIFT 2 /* MIXOUTR_TO_SPKMIXR */
1427#define WM8993_MIXOUTR_TO_SPKMIXR_WIDTH 1 /* MIXOUTR_TO_SPKMIXR */
1428#define WM8993_DACL_TO_SPKMIXL 0x0002 /* DACL_TO_SPKMIXL */
1429#define WM8993_DACL_TO_SPKMIXL_MASK 0x0002 /* DACL_TO_SPKMIXL */
1430#define WM8993_DACL_TO_SPKMIXL_SHIFT 1 /* DACL_TO_SPKMIXL */
1431#define WM8993_DACL_TO_SPKMIXL_WIDTH 1 /* DACL_TO_SPKMIXL */
1432#define WM8993_DACR_TO_SPKMIXR 0x0001 /* DACR_TO_SPKMIXR */
1433#define WM8993_DACR_TO_SPKMIXR_MASK 0x0001 /* DACR_TO_SPKMIXR */
1434#define WM8993_DACR_TO_SPKMIXR_SHIFT 0 /* DACR_TO_SPKMIXR */
1435#define WM8993_DACR_TO_SPKMIXR_WIDTH 1 /* DACR_TO_SPKMIXR */
1436
1437/*
1438 * R55 (0x37) - Additional Control
1439 */
1440#define WM8993_LINEOUT1_FB 0x0080 /* LINEOUT1_FB */
1441#define WM8993_LINEOUT1_FB_MASK 0x0080 /* LINEOUT1_FB */
1442#define WM8993_LINEOUT1_FB_SHIFT 7 /* LINEOUT1_FB */
1443#define WM8993_LINEOUT1_FB_WIDTH 1 /* LINEOUT1_FB */
1444#define WM8993_LINEOUT2_FB 0x0040 /* LINEOUT2_FB */
1445#define WM8993_LINEOUT2_FB_MASK 0x0040 /* LINEOUT2_FB */
1446#define WM8993_LINEOUT2_FB_SHIFT 6 /* LINEOUT2_FB */
1447#define WM8993_LINEOUT2_FB_WIDTH 1 /* LINEOUT2_FB */
1448#define WM8993_VROI 0x0001 /* VROI */
1449#define WM8993_VROI_MASK 0x0001 /* VROI */
1450#define WM8993_VROI_SHIFT 0 /* VROI */
1451#define WM8993_VROI_WIDTH 1 /* VROI */
1452
1453/*
1454 * R56 (0x38) - AntiPOP1
1455 */
1456#define WM8993_LINEOUT_VMID_BUF_ENA 0x0080 /* LINEOUT_VMID_BUF_ENA */
1457#define WM8993_LINEOUT_VMID_BUF_ENA_MASK 0x0080 /* LINEOUT_VMID_BUF_ENA */
1458#define WM8993_LINEOUT_VMID_BUF_ENA_SHIFT 7 /* LINEOUT_VMID_BUF_ENA */
1459#define WM8993_LINEOUT_VMID_BUF_ENA_WIDTH 1 /* LINEOUT_VMID_BUF_ENA */
1460#define WM8993_HPOUT2_IN_ENA 0x0040 /* HPOUT2_IN_ENA */
1461#define WM8993_HPOUT2_IN_ENA_MASK 0x0040 /* HPOUT2_IN_ENA */
1462#define WM8993_HPOUT2_IN_ENA_SHIFT 6 /* HPOUT2_IN_ENA */
1463#define WM8993_HPOUT2_IN_ENA_WIDTH 1 /* HPOUT2_IN_ENA */
1464#define WM8993_LINEOUT1_DISCH 0x0020 /* LINEOUT1_DISCH */
1465#define WM8993_LINEOUT1_DISCH_MASK 0x0020 /* LINEOUT1_DISCH */
1466#define WM8993_LINEOUT1_DISCH_SHIFT 5 /* LINEOUT1_DISCH */
1467#define WM8993_LINEOUT1_DISCH_WIDTH 1 /* LINEOUT1_DISCH */
1468#define WM8993_LINEOUT2_DISCH 0x0010 /* LINEOUT2_DISCH */
1469#define WM8993_LINEOUT2_DISCH_MASK 0x0010 /* LINEOUT2_DISCH */
1470#define WM8993_LINEOUT2_DISCH_SHIFT 4 /* LINEOUT2_DISCH */
1471#define WM8993_LINEOUT2_DISCH_WIDTH 1 /* LINEOUT2_DISCH */
1472
1473/*
1474 * R57 (0x39) - AntiPOP2
1475 */
1476#define WM8993_VMID_RAMP_MASK 0x0060 /* VMID_RAMP - [6:5] */
1477#define WM8993_VMID_RAMP_SHIFT 5 /* VMID_RAMP - [6:5] */
1478#define WM8993_VMID_RAMP_WIDTH 2 /* VMID_RAMP - [6:5] */
1479#define WM8993_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
1480#define WM8993_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
1481#define WM8993_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
1482#define WM8993_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
1483#define WM8993_STARTUP_BIAS_ENA 0x0004 /* STARTUP_BIAS_ENA */
1484#define WM8993_STARTUP_BIAS_ENA_MASK 0x0004 /* STARTUP_BIAS_ENA */
1485#define WM8993_STARTUP_BIAS_ENA_SHIFT 2 /* STARTUP_BIAS_ENA */
1486#define WM8993_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
1487#define WM8993_BIAS_SRC 0x0002 /* BIAS_SRC */
1488#define WM8993_BIAS_SRC_MASK 0x0002 /* BIAS_SRC */
1489#define WM8993_BIAS_SRC_SHIFT 1 /* BIAS_SRC */
1490#define WM8993_BIAS_SRC_WIDTH 1 /* BIAS_SRC */
1491#define WM8993_VMID_DISCH 0x0001 /* VMID_DISCH */
1492#define WM8993_VMID_DISCH_MASK 0x0001 /* VMID_DISCH */
1493#define WM8993_VMID_DISCH_SHIFT 0 /* VMID_DISCH */
1494#define WM8993_VMID_DISCH_WIDTH 1 /* VMID_DISCH */
1495
1496/*
1497 * R58 (0x3A) - MICBIAS
1498 */
1499#define WM8993_JD_SCTHR_MASK 0x00C0 /* JD_SCTHR - [7:6] */
1500#define WM8993_JD_SCTHR_SHIFT 6 /* JD_SCTHR - [7:6] */
1501#define WM8993_JD_SCTHR_WIDTH 2 /* JD_SCTHR - [7:6] */
1502#define WM8993_JD_THR_MASK 0x0030 /* JD_THR - [5:4] */
1503#define WM8993_JD_THR_SHIFT 4 /* JD_THR - [5:4] */
1504#define WM8993_JD_THR_WIDTH 2 /* JD_THR - [5:4] */
1505#define WM8993_JD_ENA 0x0004 /* JD_ENA */
1506#define WM8993_JD_ENA_MASK 0x0004 /* JD_ENA */
1507#define WM8993_JD_ENA_SHIFT 2 /* JD_ENA */
1508#define WM8993_JD_ENA_WIDTH 1 /* JD_ENA */
1509#define WM8993_MICB2_LVL 0x0002 /* MICB2_LVL */
1510#define WM8993_MICB2_LVL_MASK 0x0002 /* MICB2_LVL */
1511#define WM8993_MICB2_LVL_SHIFT 1 /* MICB2_LVL */
1512#define WM8993_MICB2_LVL_WIDTH 1 /* MICB2_LVL */
1513#define WM8993_MICB1_LVL 0x0001 /* MICB1_LVL */
1514#define WM8993_MICB1_LVL_MASK 0x0001 /* MICB1_LVL */
1515#define WM8993_MICB1_LVL_SHIFT 0 /* MICB1_LVL */
1516#define WM8993_MICB1_LVL_WIDTH 1 /* MICB1_LVL */
1517
1518/*
1519 * R60 (0x3C) - FLL Control 1
1520 */
1521#define WM8993_FLL_FRAC 0x0004 /* FLL_FRAC */
1522#define WM8993_FLL_FRAC_MASK 0x0004 /* FLL_FRAC */
1523#define WM8993_FLL_FRAC_SHIFT 2 /* FLL_FRAC */
1524#define WM8993_FLL_FRAC_WIDTH 1 /* FLL_FRAC */
1525#define WM8993_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1526#define WM8993_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1527#define WM8993_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1528#define WM8993_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1529#define WM8993_FLL_ENA 0x0001 /* FLL_ENA */
1530#define WM8993_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1531#define WM8993_FLL_ENA_SHIFT 0 /* FLL_ENA */
1532#define WM8993_FLL_ENA_WIDTH 1 /* FLL_ENA */
1533
1534/*
1535 * R61 (0x3D) - FLL Control 2
1536 */
1537#define WM8993_FLL_OUTDIV_MASK 0x0700 /* FLL_OUTDIV - [10:8] */
1538#define WM8993_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [10:8] */
1539#define WM8993_FLL_OUTDIV_WIDTH 3 /* FLL_OUTDIV - [10:8] */
1540#define WM8993_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
1541#define WM8993_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
1542#define WM8993_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
1543#define WM8993_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1544#define WM8993_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1545#define WM8993_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1546
1547/*
1548 * R62 (0x3E) - FLL Control 3
1549 */
1550#define WM8993_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
1551#define WM8993_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
1552#define WM8993_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
1553
1554/*
1555 * R63 (0x3F) - FLL Control 4
1556 */
1557#define WM8993_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1558#define WM8993_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1559#define WM8993_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1560#define WM8993_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
1561#define WM8993_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
1562#define WM8993_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
1563
1564/*
1565 * R64 (0x40) - FLL Control 5
1566 */
1567#define WM8993_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
1568#define WM8993_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
1569#define WM8993_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
1570#define WM8993_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
1571#define WM8993_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
1572#define WM8993_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
1573#define WM8993_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1574#define WM8993_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
1575#define WM8993_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
1576#define WM8993_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
1577#define WM8993_FLL_CLK_SRC_MASK 0x0003 /* FLL_CLK_SRC - [1:0] */
1578#define WM8993_FLL_CLK_SRC_SHIFT 0 /* FLL_CLK_SRC - [1:0] */
1579#define WM8993_FLL_CLK_SRC_WIDTH 2 /* FLL_CLK_SRC - [1:0] */
1580
1581/*
1582 * R65 (0x41) - Clocking 3
1583 */
1584#define WM8993_CLK_DCS_DIV_MASK 0x3C00 /* CLK_DCS_DIV - [13:10] */
1585#define WM8993_CLK_DCS_DIV_SHIFT 10 /* CLK_DCS_DIV - [13:10] */
1586#define WM8993_CLK_DCS_DIV_WIDTH 4 /* CLK_DCS_DIV - [13:10] */
1587#define WM8993_SAMPLE_RATE_MASK 0x0380 /* SAMPLE_RATE - [9:7] */
1588#define WM8993_SAMPLE_RATE_SHIFT 7 /* SAMPLE_RATE - [9:7] */
1589#define WM8993_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [9:7] */
1590#define WM8993_CLK_SYS_RATE_MASK 0x001E /* CLK_SYS_RATE - [4:1] */
1591#define WM8993_CLK_SYS_RATE_SHIFT 1 /* CLK_SYS_RATE - [4:1] */
1592#define WM8993_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [4:1] */
1593#define WM8993_CLK_DSP_ENA 0x0001 /* CLK_DSP_ENA */
1594#define WM8993_CLK_DSP_ENA_MASK 0x0001 /* CLK_DSP_ENA */
1595#define WM8993_CLK_DSP_ENA_SHIFT 0 /* CLK_DSP_ENA */
1596#define WM8993_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
1597
1598/*
1599 * R66 (0x42) - Clocking 4
1600 */
1601#define WM8993_DAC_DIV4 0x0200 /* DAC_DIV4 */
1602#define WM8993_DAC_DIV4_MASK 0x0200 /* DAC_DIV4 */
1603#define WM8993_DAC_DIV4_SHIFT 9 /* DAC_DIV4 */
1604#define WM8993_DAC_DIV4_WIDTH 1 /* DAC_DIV4 */
1605#define WM8993_CLK_256K_DIV_MASK 0x007E /* CLK_256K_DIV - [6:1] */
1606#define WM8993_CLK_256K_DIV_SHIFT 1 /* CLK_256K_DIV - [6:1] */
1607#define WM8993_CLK_256K_DIV_WIDTH 6 /* CLK_256K_DIV - [6:1] */
1608#define WM8993_SR_MODE 0x0001 /* SR_MODE */
1609#define WM8993_SR_MODE_MASK 0x0001 /* SR_MODE */
1610#define WM8993_SR_MODE_SHIFT 0 /* SR_MODE */
1611#define WM8993_SR_MODE_WIDTH 1 /* SR_MODE */
1612
1613/*
1614 * R67 (0x43) - MW Slave Control
1615 */
1616#define WM8993_MASK_WRITE_ENA 0x0001 /* MASK_WRITE_ENA */
1617#define WM8993_MASK_WRITE_ENA_MASK 0x0001 /* MASK_WRITE_ENA */
1618#define WM8993_MASK_WRITE_ENA_SHIFT 0 /* MASK_WRITE_ENA */
1619#define WM8993_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
1620
1621/*
1622 * R69 (0x45) - Bus Control 1
1623 */
1624#define WM8993_CLK_SYS_ENA 0x0002 /* CLK_SYS_ENA */
1625#define WM8993_CLK_SYS_ENA_MASK 0x0002 /* CLK_SYS_ENA */
1626#define WM8993_CLK_SYS_ENA_SHIFT 1 /* CLK_SYS_ENA */
1627#define WM8993_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
1628
1629/*
1630 * R70 (0x46) - Write Sequencer 0
1631 */
1632#define WM8993_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1633#define WM8993_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1634#define WM8993_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1635#define WM8993_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1636#define WM8993_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1637#define WM8993_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1638#define WM8993_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1639
1640/*
1641 * R71 (0x47) - Write Sequencer 1
1642 */
1643#define WM8993_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1644#define WM8993_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1645#define WM8993_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1646#define WM8993_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1647#define WM8993_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1648#define WM8993_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1649#define WM8993_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1650#define WM8993_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1651#define WM8993_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1652
1653/*
1654 * R72 (0x48) - Write Sequencer 2
1655 */
1656#define WM8993_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1657#define WM8993_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1658#define WM8993_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1659#define WM8993_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1660#define WM8993_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1661#define WM8993_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1662#define WM8993_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1663#define WM8993_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1664#define WM8993_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1665#define WM8993_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1666
1667/*
1668 * R73 (0x49) - Write Sequencer 3
1669 */
1670#define WM8993_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1671#define WM8993_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1672#define WM8993_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1673#define WM8993_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1674#define WM8993_WSEQ_START 0x0100 /* WSEQ_START */
1675#define WM8993_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1676#define WM8993_WSEQ_START_SHIFT 8 /* WSEQ_START */
1677#define WM8993_WSEQ_START_WIDTH 1 /* WSEQ_START */
1678#define WM8993_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1679#define WM8993_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1680#define WM8993_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1681
1682/*
1683 * R74 (0x4A) - Write Sequencer 4
1684 */
1685#define WM8993_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1686#define WM8993_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1687#define WM8993_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1688#define WM8993_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1689
1690/*
1691 * R75 (0x4B) - Write Sequencer 5
1692 */
1693#define WM8993_WSEQ_CURRENT_INDEX_MASK 0x003F /* WSEQ_CURRENT_INDEX - [5:0] */
1694#define WM8993_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [5:0] */
1695#define WM8993_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [5:0] */
1696
1697/*
1698 * R76 (0x4C) - Charge Pump 1
1699 */
1700#define WM8993_CP_ENA 0x8000 /* CP_ENA */
1701#define WM8993_CP_ENA_MASK 0x8000 /* CP_ENA */
1702#define WM8993_CP_ENA_SHIFT 15 /* CP_ENA */
1703#define WM8993_CP_ENA_WIDTH 1 /* CP_ENA */
1704
1705/*
1706 * R81 (0x51) - Class W 0
1707 */
1708#define WM8993_CP_DYN_FREQ 0x0002 /* CP_DYN_FREQ */
1709#define WM8993_CP_DYN_FREQ_MASK 0x0002 /* CP_DYN_FREQ */
1710#define WM8993_CP_DYN_FREQ_SHIFT 1 /* CP_DYN_FREQ */
1711#define WM8993_CP_DYN_FREQ_WIDTH 1 /* CP_DYN_FREQ */
1712#define WM8993_CP_DYN_V 0x0001 /* CP_DYN_V */
1713#define WM8993_CP_DYN_V_MASK 0x0001 /* CP_DYN_V */
1714#define WM8993_CP_DYN_V_SHIFT 0 /* CP_DYN_V */
1715#define WM8993_CP_DYN_V_WIDTH 1 /* CP_DYN_V */
1716
1717/*
1718 * R84 (0x54) - DC Servo 0
1719 */
1720#define WM8993_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1721#define WM8993_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1722#define WM8993_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1723#define WM8993_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1724#define WM8993_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1725#define WM8993_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1726#define WM8993_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1727#define WM8993_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1728#define WM8993_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1729#define WM8993_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1730#define WM8993_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1731#define WM8993_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1732#define WM8993_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1733#define WM8993_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1734#define WM8993_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1735#define WM8993_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1736#define WM8993_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1737#define WM8993_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1738#define WM8993_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1739#define WM8993_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1740#define WM8993_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1741#define WM8993_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1742#define WM8993_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1743#define WM8993_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1744#define WM8993_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
1745#define WM8993_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
1746#define WM8993_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
1747#define WM8993_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1748#define WM8993_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
1749#define WM8993_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
1750#define WM8993_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
1751#define WM8993_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1752#define WM8993_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1753#define WM8993_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1754#define WM8993_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1755#define WM8993_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1756#define WM8993_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1757#define WM8993_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1758#define WM8993_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1759#define WM8993_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1760
1761/*
1762 * R85 (0x55) - DC Servo 1
1763 */
1764#define WM8993_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
1765#define WM8993_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
1766#define WM8993_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
1767#define WM8993_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1768#define WM8993_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1769#define WM8993_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1770
1771/*
1772 * R87 (0x57) - DC Servo 3
1773 */
1774#define WM8993_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1775#define WM8993_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1776#define WM8993_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1777#define WM8993_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1778#define WM8993_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1779#define WM8993_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1780
1781/*
1782 * R88 (0x58) - DC Servo Readback 0
1783 */
1784#define WM8993_DCS_DATAPATH_BUSY 0x4000 /* DCS_DATAPATH_BUSY */
1785#define WM8993_DCS_DATAPATH_BUSY_MASK 0x4000 /* DCS_DATAPATH_BUSY */
1786#define WM8993_DCS_DATAPATH_BUSY_SHIFT 14 /* DCS_DATAPATH_BUSY */
1787#define WM8993_DCS_DATAPATH_BUSY_WIDTH 1 /* DCS_DATAPATH_BUSY */
1788#define WM8993_DCS_CHANNEL_MASK 0x3000 /* DCS_CHANNEL - [13:12] */
1789#define WM8993_DCS_CHANNEL_SHIFT 12 /* DCS_CHANNEL - [13:12] */
1790#define WM8993_DCS_CHANNEL_WIDTH 2 /* DCS_CHANNEL - [13:12] */
1791#define WM8993_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
1792#define WM8993_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
1793#define WM8993_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
1794#define WM8993_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
1795#define WM8993_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
1796#define WM8993_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
1797#define WM8993_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
1798#define WM8993_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
1799#define WM8993_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
1800
1801/*
1802 * R89 (0x59) - DC Servo Readback 1
1803 */
1804#define WM8993_DCS_INTEG_CHAN_1_MASK 0x00FF /* DCS_INTEG_CHAN_1 - [7:0] */
1805#define WM8993_DCS_INTEG_CHAN_1_SHIFT 0 /* DCS_INTEG_CHAN_1 - [7:0] */
1806#define WM8993_DCS_INTEG_CHAN_1_WIDTH 8 /* DCS_INTEG_CHAN_1 - [7:0] */
1807
1808/*
1809 * R90 (0x5A) - DC Servo Readback 2
1810 */
1811#define WM8993_DCS_INTEG_CHAN_0_MASK 0x00FF /* DCS_INTEG_CHAN_0 - [7:0] */
1812#define WM8993_DCS_INTEG_CHAN_0_SHIFT 0 /* DCS_INTEG_CHAN_0 - [7:0] */
1813#define WM8993_DCS_INTEG_CHAN_0_WIDTH 8 /* DCS_INTEG_CHAN_0 - [7:0] */
1814
1815/*
1816 * R96 (0x60) - Analogue HP 0
1817 */
1818#define WM8993_HPOUT1_AUTO_PU 0x0100 /* HPOUT1_AUTO_PU */
1819#define WM8993_HPOUT1_AUTO_PU_MASK 0x0100 /* HPOUT1_AUTO_PU */
1820#define WM8993_HPOUT1_AUTO_PU_SHIFT 8 /* HPOUT1_AUTO_PU */
1821#define WM8993_HPOUT1_AUTO_PU_WIDTH 1 /* HPOUT1_AUTO_PU */
1822#define WM8993_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1823#define WM8993_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1824#define WM8993_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1825#define WM8993_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1826#define WM8993_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1827#define WM8993_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1828#define WM8993_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1829#define WM8993_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1830#define WM8993_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1831#define WM8993_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1832#define WM8993_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1833#define WM8993_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1834#define WM8993_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1835#define WM8993_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1836#define WM8993_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1837#define WM8993_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1838#define WM8993_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1839#define WM8993_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1840#define WM8993_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1841#define WM8993_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1842#define WM8993_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1843#define WM8993_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1844#define WM8993_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1845#define WM8993_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1846
1847/*
1848 * R98 (0x62) - EQ1
1849 */
1850#define WM8993_EQ_ENA 0x0001 /* EQ_ENA */
1851#define WM8993_EQ_ENA_MASK 0x0001 /* EQ_ENA */
1852#define WM8993_EQ_ENA_SHIFT 0 /* EQ_ENA */
1853#define WM8993_EQ_ENA_WIDTH 1 /* EQ_ENA */
1854
1855/*
1856 * R99 (0x63) - EQ2
1857 */
1858#define WM8993_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */
1859#define WM8993_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */
1860#define WM8993_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */
1861
1862/*
1863 * R100 (0x64) - EQ3
1864 */
1865#define WM8993_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */
1866#define WM8993_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */
1867#define WM8993_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */
1868
1869/*
1870 * R101 (0x65) - EQ4
1871 */
1872#define WM8993_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */
1873#define WM8993_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */
1874#define WM8993_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */
1875
1876/*
1877 * R102 (0x66) - EQ5
1878 */
1879#define WM8993_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */
1880#define WM8993_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */
1881#define WM8993_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */
1882
1883/*
1884 * R103 (0x67) - EQ6
1885 */
1886#define WM8993_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */
1887#define WM8993_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */
1888#define WM8993_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */
1889
1890/*
1891 * R104 (0x68) - EQ7
1892 */
1893#define WM8993_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
1894#define WM8993_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
1895#define WM8993_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
1896
1897/*
1898 * R105 (0x69) - EQ8
1899 */
1900#define WM8993_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
1901#define WM8993_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
1902#define WM8993_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
1903
1904/*
1905 * R106 (0x6A) - EQ9
1906 */
1907#define WM8993_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
1908#define WM8993_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
1909#define WM8993_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
1910
1911/*
1912 * R107 (0x6B) - EQ10
1913 */
1914#define WM8993_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
1915#define WM8993_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
1916#define WM8993_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
1917
1918/*
1919 * R108 (0x6C) - EQ11
1920 */
1921#define WM8993_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
1922#define WM8993_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
1923#define WM8993_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
1924
1925/*
1926 * R109 (0x6D) - EQ12
1927 */
1928#define WM8993_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
1929#define WM8993_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
1930#define WM8993_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
1931
1932/*
1933 * R110 (0x6E) - EQ13
1934 */
1935#define WM8993_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
1936#define WM8993_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
1937#define WM8993_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
1938
1939/*
1940 * R111 (0x6F) - EQ14
1941 */
1942#define WM8993_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
1943#define WM8993_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
1944#define WM8993_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
1945
1946/*
1947 * R112 (0x70) - EQ15
1948 */
1949#define WM8993_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
1950#define WM8993_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
1951#define WM8993_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
1952
1953/*
1954 * R113 (0x71) - EQ16
1955 */
1956#define WM8993_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
1957#define WM8993_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
1958#define WM8993_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
1959
1960/*
1961 * R114 (0x72) - EQ17
1962 */
1963#define WM8993_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
1964#define WM8993_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
1965#define WM8993_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
1966
1967/*
1968 * R115 (0x73) - EQ18
1969 */
1970#define WM8993_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
1971#define WM8993_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
1972#define WM8993_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
1973
1974/*
1975 * R116 (0x74) - EQ19
1976 */
1977#define WM8993_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
1978#define WM8993_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
1979#define WM8993_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
1980
1981/*
1982 * R117 (0x75) - EQ20
1983 */
1984#define WM8993_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
1985#define WM8993_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
1986#define WM8993_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
1987
1988/*
1989 * R118 (0x76) - EQ21
1990 */
1991#define WM8993_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
1992#define WM8993_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
1993#define WM8993_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
1994
1995/*
1996 * R119 (0x77) - EQ22
1997 */
1998#define WM8993_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
1999#define WM8993_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
2000#define WM8993_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
2001
2002/*
2003 * R120 (0x78) - EQ23
2004 */
2005#define WM8993_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
2006#define WM8993_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
2007#define WM8993_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
2008
2009/*
2010 * R121 (0x79) - EQ24
2011 */
2012#define WM8993_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
2013#define WM8993_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
2014#define WM8993_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
2015
2016/*
2017 * R122 (0x7A) - Digital Pulls
2018 */
2019#define WM8993_MCLK_PU 0x0080 /* MCLK_PU */
2020#define WM8993_MCLK_PU_MASK 0x0080 /* MCLK_PU */
2021#define WM8993_MCLK_PU_SHIFT 7 /* MCLK_PU */
2022#define WM8993_MCLK_PU_WIDTH 1 /* MCLK_PU */
2023#define WM8993_MCLK_PD 0x0040 /* MCLK_PD */
2024#define WM8993_MCLK_PD_MASK 0x0040 /* MCLK_PD */
2025#define WM8993_MCLK_PD_SHIFT 6 /* MCLK_PD */
2026#define WM8993_MCLK_PD_WIDTH 1 /* MCLK_PD */
2027#define WM8993_DACDAT_PU 0x0020 /* DACDAT_PU */
2028#define WM8993_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */
2029#define WM8993_DACDAT_PU_SHIFT 5 /* DACDAT_PU */
2030#define WM8993_DACDAT_PU_WIDTH 1 /* DACDAT_PU */
2031#define WM8993_DACDAT_PD 0x0010 /* DACDAT_PD */
2032#define WM8993_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */
2033#define WM8993_DACDAT_PD_SHIFT 4 /* DACDAT_PD */
2034#define WM8993_DACDAT_PD_WIDTH 1 /* DACDAT_PD */
2035#define WM8993_LRCLK_PU 0x0008 /* LRCLK_PU */
2036#define WM8993_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */
2037#define WM8993_LRCLK_PU_SHIFT 3 /* LRCLK_PU */
2038#define WM8993_LRCLK_PU_WIDTH 1 /* LRCLK_PU */
2039#define WM8993_LRCLK_PD 0x0004 /* LRCLK_PD */
2040#define WM8993_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */
2041#define WM8993_LRCLK_PD_SHIFT 2 /* LRCLK_PD */
2042#define WM8993_LRCLK_PD_WIDTH 1 /* LRCLK_PD */
2043#define WM8993_BCLK_PU 0x0002 /* BCLK_PU */
2044#define WM8993_BCLK_PU_MASK 0x0002 /* BCLK_PU */
2045#define WM8993_BCLK_PU_SHIFT 1 /* BCLK_PU */
2046#define WM8993_BCLK_PU_WIDTH 1 /* BCLK_PU */
2047#define WM8993_BCLK_PD 0x0001 /* BCLK_PD */
2048#define WM8993_BCLK_PD_MASK 0x0001 /* BCLK_PD */
2049#define WM8993_BCLK_PD_SHIFT 0 /* BCLK_PD */
2050#define WM8993_BCLK_PD_WIDTH 1 /* BCLK_PD */
2051
2052/*
2053 * R123 (0x7B) - DRC Control 1
2054 */
2055#define WM8993_DRC_ENA 0x8000 /* DRC_ENA */
2056#define WM8993_DRC_ENA_MASK 0x8000 /* DRC_ENA */
2057#define WM8993_DRC_ENA_SHIFT 15 /* DRC_ENA */
2058#define WM8993_DRC_ENA_WIDTH 1 /* DRC_ENA */
2059#define WM8993_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */
2060#define WM8993_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */
2061#define WM8993_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */
2062#define WM8993_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */
2063#define WM8993_DRC_SMOOTH_ENA 0x0800 /* DRC_SMOOTH_ENA */
2064#define WM8993_DRC_SMOOTH_ENA_MASK 0x0800 /* DRC_SMOOTH_ENA */
2065#define WM8993_DRC_SMOOTH_ENA_SHIFT 11 /* DRC_SMOOTH_ENA */
2066#define WM8993_DRC_SMOOTH_ENA_WIDTH 1 /* DRC_SMOOTH_ENA */
2067#define WM8993_DRC_QR_ENA 0x0400 /* DRC_QR_ENA */
2068#define WM8993_DRC_QR_ENA_MASK 0x0400 /* DRC_QR_ENA */
2069#define WM8993_DRC_QR_ENA_SHIFT 10 /* DRC_QR_ENA */
2070#define WM8993_DRC_QR_ENA_WIDTH 1 /* DRC_QR_ENA */
2071#define WM8993_DRC_ANTICLIP_ENA 0x0200 /* DRC_ANTICLIP_ENA */
2072#define WM8993_DRC_ANTICLIP_ENA_MASK 0x0200 /* DRC_ANTICLIP_ENA */
2073#define WM8993_DRC_ANTICLIP_ENA_SHIFT 9 /* DRC_ANTICLIP_ENA */
2074#define WM8993_DRC_ANTICLIP_ENA_WIDTH 1 /* DRC_ANTICLIP_ENA */
2075#define WM8993_DRC_HYST_ENA 0x0100 /* DRC_HYST_ENA */
2076#define WM8993_DRC_HYST_ENA_MASK 0x0100 /* DRC_HYST_ENA */
2077#define WM8993_DRC_HYST_ENA_SHIFT 8 /* DRC_HYST_ENA */
2078#define WM8993_DRC_HYST_ENA_WIDTH 1 /* DRC_HYST_ENA */
2079#define WM8993_DRC_THRESH_HYST_MASK 0x0030 /* DRC_THRESH_HYST - [5:4] */
2080#define WM8993_DRC_THRESH_HYST_SHIFT 4 /* DRC_THRESH_HYST - [5:4] */
2081#define WM8993_DRC_THRESH_HYST_WIDTH 2 /* DRC_THRESH_HYST - [5:4] */
2082#define WM8993_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
2083#define WM8993_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
2084#define WM8993_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
2085#define WM8993_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
2086#define WM8993_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
2087#define WM8993_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
2088
2089/*
2090 * R124 (0x7C) - DRC Control 2
2091 */
2092#define WM8993_DRC_ATTACK_RATE_MASK 0xF000 /* DRC_ATTACK_RATE - [15:12] */
2093#define WM8993_DRC_ATTACK_RATE_SHIFT 12 /* DRC_ATTACK_RATE - [15:12] */
2094#define WM8993_DRC_ATTACK_RATE_WIDTH 4 /* DRC_ATTACK_RATE - [15:12] */
2095#define WM8993_DRC_DECAY_RATE_MASK 0x0F00 /* DRC_DECAY_RATE - [11:8] */
2096#define WM8993_DRC_DECAY_RATE_SHIFT 8 /* DRC_DECAY_RATE - [11:8] */
2097#define WM8993_DRC_DECAY_RATE_WIDTH 4 /* DRC_DECAY_RATE - [11:8] */
2098#define WM8993_DRC_THRESH_COMP_MASK 0x00FC /* DRC_THRESH_COMP - [7:2] */
2099#define WM8993_DRC_THRESH_COMP_SHIFT 2 /* DRC_THRESH_COMP - [7:2] */
2100#define WM8993_DRC_THRESH_COMP_WIDTH 6 /* DRC_THRESH_COMP - [7:2] */
2101
2102/*
2103 * R125 (0x7D) - DRC Control 3
2104 */
2105#define WM8993_DRC_AMP_COMP_MASK 0xF800 /* DRC_AMP_COMP - [15:11] */
2106#define WM8993_DRC_AMP_COMP_SHIFT 11 /* DRC_AMP_COMP - [15:11] */
2107#define WM8993_DRC_AMP_COMP_WIDTH 5 /* DRC_AMP_COMP - [15:11] */
2108#define WM8993_DRC_R0_SLOPE_COMP_MASK 0x0700 /* DRC_R0_SLOPE_COMP - [10:8] */
2109#define WM8993_DRC_R0_SLOPE_COMP_SHIFT 8 /* DRC_R0_SLOPE_COMP - [10:8] */
2110#define WM8993_DRC_R0_SLOPE_COMP_WIDTH 3 /* DRC_R0_SLOPE_COMP - [10:8] */
2111#define WM8993_DRC_FF_DELAY 0x0080 /* DRC_FF_DELAY */
2112#define WM8993_DRC_FF_DELAY_MASK 0x0080 /* DRC_FF_DELAY */
2113#define WM8993_DRC_FF_DELAY_SHIFT 7 /* DRC_FF_DELAY */
2114#define WM8993_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
2115#define WM8993_DRC_THRESH_QR_MASK 0x000C /* DRC_THRESH_QR - [3:2] */
2116#define WM8993_DRC_THRESH_QR_SHIFT 2 /* DRC_THRESH_QR - [3:2] */
2117#define WM8993_DRC_THRESH_QR_WIDTH 2 /* DRC_THRESH_QR - [3:2] */
2118#define WM8993_DRC_RATE_QR_MASK 0x0003 /* DRC_RATE_QR - [1:0] */
2119#define WM8993_DRC_RATE_QR_SHIFT 0 /* DRC_RATE_QR - [1:0] */
2120#define WM8993_DRC_RATE_QR_WIDTH 2 /* DRC_RATE_QR - [1:0] */
2121
2122/*
2123 * R126 (0x7E) - DRC Control 4
2124 */
2125#define WM8993_DRC_R1_SLOPE_COMP_MASK 0xE000 /* DRC_R1_SLOPE_COMP - [15:13] */
2126#define WM8993_DRC_R1_SLOPE_COMP_SHIFT 13 /* DRC_R1_SLOPE_COMP - [15:13] */
2127#define WM8993_DRC_R1_SLOPE_COMP_WIDTH 3 /* DRC_R1_SLOPE_COMP - [15:13] */
2128#define WM8993_DRC_STARTUP_GAIN_MASK 0x1F00 /* DRC_STARTUP_GAIN - [12:8] */
2129#define WM8993_DRC_STARTUP_GAIN_SHIFT 8 /* DRC_STARTUP_GAIN - [12:8] */
2130#define WM8993_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [12:8] */
2131
2132#endif
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 86fc57e25f97..c64e55aa63b6 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -165,87 +165,23 @@ struct wm9081_priv {
165 int master; 165 int master;
166 int fll_fref; 166 int fll_fref;
167 int fll_fout; 167 int fll_fout;
168 int tdm_width;
168 struct wm9081_retune_mobile_config *retune; 169 struct wm9081_retune_mobile_config *retune;
169}; 170};
170 171
171static int wm9081_reg_is_volatile(int reg) 172static int wm9081_volatile_register(unsigned int reg)
172{ 173{
173 switch (reg) { 174 switch (reg) {
175 case WM9081_SOFTWARE_RESET:
176 return 1;
174 default: 177 default:
175 return 0; 178 return 0;
176 } 179 }
177} 180}
178 181
179static unsigned int wm9081_read_reg_cache(struct snd_soc_codec *codec,
180 unsigned int reg)
181{
182 u16 *cache = codec->reg_cache;
183 BUG_ON(reg > WM9081_MAX_REGISTER);
184 return cache[reg];
185}
186
187static unsigned int wm9081_read_hw(struct snd_soc_codec *codec, u8 reg)
188{
189 struct i2c_msg xfer[2];
190 u16 data;
191 int ret;
192 struct i2c_client *client = codec->control_data;
193
194 BUG_ON(reg > WM9081_MAX_REGISTER);
195
196 /* Write register */
197 xfer[0].addr = client->addr;
198 xfer[0].flags = 0;
199 xfer[0].len = 1;
200 xfer[0].buf = &reg;
201
202 /* Read data */
203 xfer[1].addr = client->addr;
204 xfer[1].flags = I2C_M_RD;
205 xfer[1].len = 2;
206 xfer[1].buf = (u8 *)&data;
207
208 ret = i2c_transfer(client->adapter, xfer, 2);
209 if (ret != 2) {
210 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
211 return 0;
212 }
213
214 return (data >> 8) | ((data & 0xff) << 8);
215}
216
217static unsigned int wm9081_read(struct snd_soc_codec *codec, unsigned int reg)
218{
219 if (wm9081_reg_is_volatile(reg))
220 return wm9081_read_hw(codec, reg);
221 else
222 return wm9081_read_reg_cache(codec, reg);
223}
224
225static int wm9081_write(struct snd_soc_codec *codec, unsigned int reg,
226 unsigned int value)
227{
228 u16 *cache = codec->reg_cache;
229 u8 data[3];
230
231 BUG_ON(reg > WM9081_MAX_REGISTER);
232
233 if (!wm9081_reg_is_volatile(reg))
234 cache[reg] = value;
235
236 data[0] = reg;
237 data[1] = value >> 8;
238 data[2] = value & 0x00ff;
239
240 if (codec->hw_write(codec->control_data, data, 3) == 3)
241 return 0;
242 else
243 return -EIO;
244}
245
246static int wm9081_reset(struct snd_soc_codec *codec) 182static int wm9081_reset(struct snd_soc_codec *codec)
247{ 183{
248 return wm9081_write(codec, WM9081_SOFTWARE_RESET, 0); 184 return snd_soc_write(codec, WM9081_SOFTWARE_RESET, 0);
249} 185}
250 186
251static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); 187static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0);
@@ -356,7 +292,7 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol,
356 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 292 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
357 unsigned int reg; 293 unsigned int reg;
358 294
359 reg = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_2); 295 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2);
360 if (reg & WM9081_SPK_MODE) 296 if (reg & WM9081_SPK_MODE)
361 ucontrol->value.integer.value[0] = 1; 297 ucontrol->value.integer.value[0] = 1;
362 else 298 else
@@ -375,8 +311,8 @@ static int speaker_mode_put(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol) 311 struct snd_ctl_elem_value *ucontrol)
376{ 312{
377 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 313 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
378 unsigned int reg_pwr = wm9081_read(codec, WM9081_POWER_MANAGEMENT); 314 unsigned int reg_pwr = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
379 unsigned int reg2 = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_2); 315 unsigned int reg2 = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2);
380 316
381 /* Are we changing anything? */ 317 /* Are we changing anything? */
382 if (ucontrol->value.integer.value[0] == 318 if (ucontrol->value.integer.value[0] ==
@@ -397,7 +333,7 @@ static int speaker_mode_put(struct snd_kcontrol *kcontrol,
397 reg2 &= ~WM9081_SPK_MODE; 333 reg2 &= ~WM9081_SPK_MODE;
398 } 334 }
399 335
400 wm9081_write(codec, WM9081_ANALOGUE_SPEAKER_2, reg2); 336 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_2, reg2);
401 337
402 return 0; 338 return 0;
403} 339}
@@ -456,7 +392,7 @@ static int speaker_event(struct snd_soc_dapm_widget *w,
456 struct snd_kcontrol *kcontrol, int event) 392 struct snd_kcontrol *kcontrol, int event)
457{ 393{
458 struct snd_soc_codec *codec = w->codec; 394 struct snd_soc_codec *codec = w->codec;
459 unsigned int reg = wm9081_read(codec, WM9081_POWER_MANAGEMENT); 395 unsigned int reg = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
460 396
461 switch (event) { 397 switch (event) {
462 case SND_SOC_DAPM_POST_PMU: 398 case SND_SOC_DAPM_POST_PMU:
@@ -468,7 +404,7 @@ static int speaker_event(struct snd_soc_dapm_widget *w,
468 break; 404 break;
469 } 405 }
470 406
471 wm9081_write(codec, WM9081_POWER_MANAGEMENT, reg); 407 snd_soc_write(codec, WM9081_POWER_MANAGEMENT, reg);
472 408
473 return 0; 409 return 0;
474} 410}
@@ -607,7 +543,7 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
607 if (ret != 0) 543 if (ret != 0)
608 return ret; 544 return ret;
609 545
610 reg5 = wm9081_read(codec, WM9081_FLL_CONTROL_5); 546 reg5 = snd_soc_read(codec, WM9081_FLL_CONTROL_5);
611 reg5 &= ~WM9081_FLL_CLK_SRC_MASK; 547 reg5 &= ~WM9081_FLL_CLK_SRC_MASK;
612 548
613 switch (fll_id) { 549 switch (fll_id) {
@@ -621,44 +557,44 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
621 } 557 }
622 558
623 /* Disable CLK_SYS while we reconfigure */ 559 /* Disable CLK_SYS while we reconfigure */
624 clk_sys_reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_3); 560 clk_sys_reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
625 if (clk_sys_reg & WM9081_CLK_SYS_ENA) 561 if (clk_sys_reg & WM9081_CLK_SYS_ENA)
626 wm9081_write(codec, WM9081_CLOCK_CONTROL_3, 562 snd_soc_write(codec, WM9081_CLOCK_CONTROL_3,
627 clk_sys_reg & ~WM9081_CLK_SYS_ENA); 563 clk_sys_reg & ~WM9081_CLK_SYS_ENA);
628 564
629 /* Any FLL configuration change requires that the FLL be 565 /* Any FLL configuration change requires that the FLL be
630 * disabled first. */ 566 * disabled first. */
631 reg1 = wm9081_read(codec, WM9081_FLL_CONTROL_1); 567 reg1 = snd_soc_read(codec, WM9081_FLL_CONTROL_1);
632 reg1 &= ~WM9081_FLL_ENA; 568 reg1 &= ~WM9081_FLL_ENA;
633 wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1); 569 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1);
634 570
635 /* Apply the configuration */ 571 /* Apply the configuration */
636 if (fll_div.k) 572 if (fll_div.k)
637 reg1 |= WM9081_FLL_FRAC_MASK; 573 reg1 |= WM9081_FLL_FRAC_MASK;
638 else 574 else
639 reg1 &= ~WM9081_FLL_FRAC_MASK; 575 reg1 &= ~WM9081_FLL_FRAC_MASK;
640 wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1); 576 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1);
641 577
642 wm9081_write(codec, WM9081_FLL_CONTROL_2, 578 snd_soc_write(codec, WM9081_FLL_CONTROL_2,
643 (fll_div.fll_outdiv << WM9081_FLL_OUTDIV_SHIFT) | 579 (fll_div.fll_outdiv << WM9081_FLL_OUTDIV_SHIFT) |
644 (fll_div.fll_fratio << WM9081_FLL_FRATIO_SHIFT)); 580 (fll_div.fll_fratio << WM9081_FLL_FRATIO_SHIFT));
645 wm9081_write(codec, WM9081_FLL_CONTROL_3, fll_div.k); 581 snd_soc_write(codec, WM9081_FLL_CONTROL_3, fll_div.k);
646 582
647 reg4 = wm9081_read(codec, WM9081_FLL_CONTROL_4); 583 reg4 = snd_soc_read(codec, WM9081_FLL_CONTROL_4);
648 reg4 &= ~WM9081_FLL_N_MASK; 584 reg4 &= ~WM9081_FLL_N_MASK;
649 reg4 |= fll_div.n << WM9081_FLL_N_SHIFT; 585 reg4 |= fll_div.n << WM9081_FLL_N_SHIFT;
650 wm9081_write(codec, WM9081_FLL_CONTROL_4, reg4); 586 snd_soc_write(codec, WM9081_FLL_CONTROL_4, reg4);
651 587
652 reg5 &= ~WM9081_FLL_CLK_REF_DIV_MASK; 588 reg5 &= ~WM9081_FLL_CLK_REF_DIV_MASK;
653 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT; 589 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
654 wm9081_write(codec, WM9081_FLL_CONTROL_5, reg5); 590 snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
655 591
656 /* Enable the FLL */ 592 /* Enable the FLL */
657 wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA); 593 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
658 594
659 /* Then bring CLK_SYS up again if it was disabled */ 595 /* Then bring CLK_SYS up again if it was disabled */
660 if (clk_sys_reg & WM9081_CLK_SYS_ENA) 596 if (clk_sys_reg & WM9081_CLK_SYS_ENA)
661 wm9081_write(codec, WM9081_CLOCK_CONTROL_3, clk_sys_reg); 597 snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, clk_sys_reg);
662 598
663 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 599 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
664 600
@@ -707,6 +643,10 @@ static int configure_clock(struct snd_soc_codec *codec)
707 target > 3000000) 643 target > 3000000)
708 break; 644 break;
709 } 645 }
646
647 if (i == ARRAY_SIZE(clk_sys_rates))
648 return -EINVAL;
649
710 } else if (wm9081->fs) { 650 } else if (wm9081->fs) {
711 for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) { 651 for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) {
712 new_sysclk = clk_sys_rates[i].ratio 652 new_sysclk = clk_sys_rates[i].ratio
@@ -714,6 +654,10 @@ static int configure_clock(struct snd_soc_codec *codec)
714 if (new_sysclk > 3000000) 654 if (new_sysclk > 3000000)
715 break; 655 break;
716 } 656 }
657
658 if (i == ARRAY_SIZE(clk_sys_rates))
659 return -EINVAL;
660
717 } else { 661 } else {
718 new_sysclk = 12288000; 662 new_sysclk = 12288000;
719 } 663 }
@@ -734,19 +678,19 @@ static int configure_clock(struct snd_soc_codec *codec)
734 return -EINVAL; 678 return -EINVAL;
735 } 679 }
736 680
737 reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_1); 681 reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_1);
738 if (mclkdiv) 682 if (mclkdiv)
739 reg |= WM9081_MCLKDIV2; 683 reg |= WM9081_MCLKDIV2;
740 else 684 else
741 reg &= ~WM9081_MCLKDIV2; 685 reg &= ~WM9081_MCLKDIV2;
742 wm9081_write(codec, WM9081_CLOCK_CONTROL_1, reg); 686 snd_soc_write(codec, WM9081_CLOCK_CONTROL_1, reg);
743 687
744 reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_3); 688 reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
745 if (fll) 689 if (fll)
746 reg |= WM9081_CLK_SRC_SEL; 690 reg |= WM9081_CLK_SRC_SEL;
747 else 691 else
748 reg &= ~WM9081_CLK_SRC_SEL; 692 reg &= ~WM9081_CLK_SRC_SEL;
749 wm9081_write(codec, WM9081_CLOCK_CONTROL_3, reg); 693 snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, reg);
750 694
751 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate); 695 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate);
752 696
@@ -846,76 +790,76 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
846 790
847 case SND_SOC_BIAS_PREPARE: 791 case SND_SOC_BIAS_PREPARE:
848 /* VMID=2*40k */ 792 /* VMID=2*40k */
849 reg = wm9081_read(codec, WM9081_VMID_CONTROL); 793 reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
850 reg &= ~WM9081_VMID_SEL_MASK; 794 reg &= ~WM9081_VMID_SEL_MASK;
851 reg |= 0x2; 795 reg |= 0x2;
852 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 796 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
853 797
854 /* Normal bias current */ 798 /* Normal bias current */
855 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 799 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
856 reg &= ~WM9081_STBY_BIAS_ENA; 800 reg &= ~WM9081_STBY_BIAS_ENA;
857 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 801 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
858 break; 802 break;
859 803
860 case SND_SOC_BIAS_STANDBY: 804 case SND_SOC_BIAS_STANDBY:
861 /* Initial cold start */ 805 /* Initial cold start */
862 if (codec->bias_level == SND_SOC_BIAS_OFF) { 806 if (codec->bias_level == SND_SOC_BIAS_OFF) {
863 /* Disable LINEOUT discharge */ 807 /* Disable LINEOUT discharge */
864 reg = wm9081_read(codec, WM9081_ANTI_POP_CONTROL); 808 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
865 reg &= ~WM9081_LINEOUT_DISCH; 809 reg &= ~WM9081_LINEOUT_DISCH;
866 wm9081_write(codec, WM9081_ANTI_POP_CONTROL, reg); 810 snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
867 811
868 /* Select startup bias source */ 812 /* Select startup bias source */
869 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 813 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
870 reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA; 814 reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA;
871 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 815 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
872 816
873 /* VMID 2*4k; Soft VMID ramp enable */ 817 /* VMID 2*4k; Soft VMID ramp enable */
874 reg = wm9081_read(codec, WM9081_VMID_CONTROL); 818 reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
875 reg |= WM9081_VMID_RAMP | 0x6; 819 reg |= WM9081_VMID_RAMP | 0x6;
876 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 820 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
877 821
878 mdelay(100); 822 mdelay(100);
879 823
880 /* Normal bias enable & soft start off */ 824 /* Normal bias enable & soft start off */
881 reg |= WM9081_BIAS_ENA; 825 reg |= WM9081_BIAS_ENA;
882 reg &= ~WM9081_VMID_RAMP; 826 reg &= ~WM9081_VMID_RAMP;
883 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 827 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
884 828
885 /* Standard bias source */ 829 /* Standard bias source */
886 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 830 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
887 reg &= ~WM9081_BIAS_SRC; 831 reg &= ~WM9081_BIAS_SRC;
888 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 832 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
889 } 833 }
890 834
891 /* VMID 2*240k */ 835 /* VMID 2*240k */
892 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 836 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
893 reg &= ~WM9081_VMID_SEL_MASK; 837 reg &= ~WM9081_VMID_SEL_MASK;
894 reg |= 0x40; 838 reg |= 0x40;
895 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 839 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
896 840
897 /* Standby bias current on */ 841 /* Standby bias current on */
898 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 842 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
899 reg |= WM9081_STBY_BIAS_ENA; 843 reg |= WM9081_STBY_BIAS_ENA;
900 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 844 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
901 break; 845 break;
902 846
903 case SND_SOC_BIAS_OFF: 847 case SND_SOC_BIAS_OFF:
904 /* Startup bias source */ 848 /* Startup bias source */
905 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 849 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
906 reg |= WM9081_BIAS_SRC; 850 reg |= WM9081_BIAS_SRC;
907 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 851 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
908 852
909 /* Disable VMID and biases with soft ramping */ 853 /* Disable VMID and biases with soft ramping */
910 reg = wm9081_read(codec, WM9081_VMID_CONTROL); 854 reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
911 reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA); 855 reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA);
912 reg |= WM9081_VMID_RAMP; 856 reg |= WM9081_VMID_RAMP;
913 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 857 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
914 858
915 /* Actively discharge LINEOUT */ 859 /* Actively discharge LINEOUT */
916 reg = wm9081_read(codec, WM9081_ANTI_POP_CONTROL); 860 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
917 reg |= WM9081_LINEOUT_DISCH; 861 reg |= WM9081_LINEOUT_DISCH;
918 wm9081_write(codec, WM9081_ANTI_POP_CONTROL, reg); 862 snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
919 break; 863 break;
920 } 864 }
921 865
@@ -929,7 +873,7 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
929{ 873{
930 struct snd_soc_codec *codec = dai->codec; 874 struct snd_soc_codec *codec = dai->codec;
931 struct wm9081_priv *wm9081 = codec->private_data; 875 struct wm9081_priv *wm9081 = codec->private_data;
932 unsigned int aif2 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_2); 876 unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
933 877
934 aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV | 878 aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV |
935 WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK); 879 WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK);
@@ -1010,7 +954,7 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
1010 return -EINVAL; 954 return -EINVAL;
1011 } 955 }
1012 956
1013 wm9081_write(codec, WM9081_AUDIO_INTERFACE_2, aif2); 957 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);
1014 958
1015 return 0; 959 return 0;
1016} 960}
@@ -1024,47 +968,51 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1024 int ret, i, best, best_val, cur_val; 968 int ret, i, best, best_val, cur_val;
1025 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4; 969 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4;
1026 970
1027 clk_ctrl2 = wm9081_read(codec, WM9081_CLOCK_CONTROL_2); 971 clk_ctrl2 = snd_soc_read(codec, WM9081_CLOCK_CONTROL_2);
1028 clk_ctrl2 &= ~(WM9081_CLK_SYS_RATE_MASK | WM9081_SAMPLE_RATE_MASK); 972 clk_ctrl2 &= ~(WM9081_CLK_SYS_RATE_MASK | WM9081_SAMPLE_RATE_MASK);
1029 973
1030 aif1 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_1); 974 aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
1031 975
1032 aif2 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_2); 976 aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
1033 aif2 &= ~WM9081_AIF_WL_MASK; 977 aif2 &= ~WM9081_AIF_WL_MASK;
1034 978
1035 aif3 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_3); 979 aif3 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_3);
1036 aif3 &= ~WM9081_BCLK_DIV_MASK; 980 aif3 &= ~WM9081_BCLK_DIV_MASK;
1037 981
1038 aif4 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_4); 982 aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4);
1039 aif4 &= ~WM9081_LRCLK_RATE_MASK; 983 aif4 &= ~WM9081_LRCLK_RATE_MASK;
1040 984
1041 /* What BCLK do we need? */
1042 wm9081->fs = params_rate(params); 985 wm9081->fs = params_rate(params);
1043 wm9081->bclk = 2 * wm9081->fs;
1044 switch (params_format(params)) {
1045 case SNDRV_PCM_FORMAT_S16_LE:
1046 wm9081->bclk *= 16;
1047 break;
1048 case SNDRV_PCM_FORMAT_S20_3LE:
1049 wm9081->bclk *= 20;
1050 aif2 |= 0x4;
1051 break;
1052 case SNDRV_PCM_FORMAT_S24_LE:
1053 wm9081->bclk *= 24;
1054 aif2 |= 0x8;
1055 break;
1056 case SNDRV_PCM_FORMAT_S32_LE:
1057 wm9081->bclk *= 32;
1058 aif2 |= 0xc;
1059 break;
1060 default:
1061 return -EINVAL;
1062 }
1063 986
1064 if (aif1 & WM9081_AIFDAC_TDM_MODE_MASK) { 987 if (wm9081->tdm_width) {
988 /* If TDM is set up then that fixes our BCLK. */
1065 int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >> 989 int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >>
1066 WM9081_AIFDAC_TDM_MODE_SHIFT) + 1; 990 WM9081_AIFDAC_TDM_MODE_SHIFT) + 1;
1067 wm9081->bclk *= slots; 991
992 wm9081->bclk = wm9081->fs * wm9081->tdm_width * slots;
993 } else {
994 /* Otherwise work out a BCLK from the sample size */
995 wm9081->bclk = 2 * wm9081->fs;
996
997 switch (params_format(params)) {
998 case SNDRV_PCM_FORMAT_S16_LE:
999 wm9081->bclk *= 16;
1000 break;
1001 case SNDRV_PCM_FORMAT_S20_3LE:
1002 wm9081->bclk *= 20;
1003 aif2 |= 0x4;
1004 break;
1005 case SNDRV_PCM_FORMAT_S24_LE:
1006 wm9081->bclk *= 24;
1007 aif2 |= 0x8;
1008 break;
1009 case SNDRV_PCM_FORMAT_S32_LE:
1010 wm9081->bclk *= 32;
1011 aif2 |= 0xc;
1012 break;
1013 default:
1014 return -EINVAL;
1015 }
1068 } 1016 }
1069 1017
1070 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk); 1018 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk);
@@ -1149,22 +1097,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1149 s->name, s->rate); 1097 s->name, s->rate);
1150 1098
1151 /* If the EQ is enabled then disable it while we write out */ 1099 /* If the EQ is enabled then disable it while we write out */
1152 eq1 = wm9081_read(codec, WM9081_EQ_1) & WM9081_EQ_ENA; 1100 eq1 = snd_soc_read(codec, WM9081_EQ_1) & WM9081_EQ_ENA;
1153 if (eq1 & WM9081_EQ_ENA) 1101 if (eq1 & WM9081_EQ_ENA)
1154 wm9081_write(codec, WM9081_EQ_1, 0); 1102 snd_soc_write(codec, WM9081_EQ_1, 0);
1155 1103
1156 /* Write out the other values */ 1104 /* Write out the other values */
1157 for (i = 1; i < ARRAY_SIZE(s->config); i++) 1105 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1158 wm9081_write(codec, WM9081_EQ_1 + i, s->config[i]); 1106 snd_soc_write(codec, WM9081_EQ_1 + i, s->config[i]);
1159 1107
1160 eq1 |= (s->config[0] & ~WM9081_EQ_ENA); 1108 eq1 |= (s->config[0] & ~WM9081_EQ_ENA);
1161 wm9081_write(codec, WM9081_EQ_1, eq1); 1109 snd_soc_write(codec, WM9081_EQ_1, eq1);
1162 } 1110 }
1163 1111
1164 wm9081_write(codec, WM9081_CLOCK_CONTROL_2, clk_ctrl2); 1112 snd_soc_write(codec, WM9081_CLOCK_CONTROL_2, clk_ctrl2);
1165 wm9081_write(codec, WM9081_AUDIO_INTERFACE_2, aif2); 1113 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);
1166 wm9081_write(codec, WM9081_AUDIO_INTERFACE_3, aif3); 1114 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_3, aif3);
1167 wm9081_write(codec, WM9081_AUDIO_INTERFACE_4, aif4); 1115 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_4, aif4);
1168 1116
1169 return 0; 1117 return 0;
1170} 1118}
@@ -1174,14 +1122,14 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1174 struct snd_soc_codec *codec = codec_dai->codec; 1122 struct snd_soc_codec *codec = codec_dai->codec;
1175 unsigned int reg; 1123 unsigned int reg;
1176 1124
1177 reg = wm9081_read(codec, WM9081_DAC_DIGITAL_2); 1125 reg = snd_soc_read(codec, WM9081_DAC_DIGITAL_2);
1178 1126
1179 if (mute) 1127 if (mute)
1180 reg |= WM9081_DAC_MUTE; 1128 reg |= WM9081_DAC_MUTE;
1181 else 1129 else
1182 reg &= ~WM9081_DAC_MUTE; 1130 reg &= ~WM9081_DAC_MUTE;
1183 1131
1184 wm9081_write(codec, WM9081_DAC_DIGITAL_2, reg); 1132 snd_soc_write(codec, WM9081_DAC_DIGITAL_2, reg);
1185 1133
1186 return 0; 1134 return 0;
1187} 1135}
@@ -1207,19 +1155,25 @@ static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai,
1207} 1155}
1208 1156
1209static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, 1157static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1210 unsigned int mask, int slots) 1158 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
1211{ 1159{
1212 struct snd_soc_codec *codec = dai->codec; 1160 struct snd_soc_codec *codec = dai->codec;
1213 unsigned int aif1 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_1); 1161 struct wm9081_priv *wm9081 = codec->private_data;
1162 unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
1214 1163
1215 aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); 1164 aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK);
1216 1165
1217 if (slots < 1 || slots > 4) 1166 if (slots < 0 || slots > 4)
1218 return -EINVAL; 1167 return -EINVAL;
1219 1168
1169 wm9081->tdm_width = slot_width;
1170
1171 if (slots == 0)
1172 slots = 1;
1173
1220 aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT; 1174 aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT;
1221 1175
1222 switch (mask) { 1176 switch (rx_mask) {
1223 case 1: 1177 case 1:
1224 break; 1178 break;
1225 case 2: 1179 case 2:
@@ -1235,7 +1189,7 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1235 return -EINVAL; 1189 return -EINVAL;
1236 } 1190 }
1237 1191
1238 wm9081_write(codec, WM9081_AUDIO_INTERFACE_1, aif1); 1192 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_1, aif1);
1239 1193
1240 return 0; 1194 return 0;
1241} 1195}
@@ -1357,7 +1311,7 @@ static int wm9081_resume(struct platform_device *pdev)
1357 if (i == WM9081_SOFTWARE_RESET) 1311 if (i == WM9081_SOFTWARE_RESET)
1358 continue; 1312 continue;
1359 1313
1360 wm9081_write(codec, i, reg_cache[i]); 1314 snd_soc_write(codec, i, reg_cache[i]);
1361 } 1315 }
1362 1316
1363 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1317 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1377,7 +1331,8 @@ struct snd_soc_codec_device soc_codec_dev_wm9081 = {
1377}; 1331};
1378EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081); 1332EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081);
1379 1333
1380static int wm9081_register(struct wm9081_priv *wm9081) 1334static int wm9081_register(struct wm9081_priv *wm9081,
1335 enum snd_soc_control_type control)
1381{ 1336{
1382 struct snd_soc_codec *codec = &wm9081->codec; 1337 struct snd_soc_codec *codec = &wm9081->codec;
1383 int ret; 1338 int ret;
@@ -1396,19 +1351,24 @@ static int wm9081_register(struct wm9081_priv *wm9081)
1396 codec->private_data = wm9081; 1351 codec->private_data = wm9081;
1397 codec->name = "WM9081"; 1352 codec->name = "WM9081";
1398 codec->owner = THIS_MODULE; 1353 codec->owner = THIS_MODULE;
1399 codec->read = wm9081_read;
1400 codec->write = wm9081_write;
1401 codec->dai = &wm9081_dai; 1354 codec->dai = &wm9081_dai;
1402 codec->num_dai = 1; 1355 codec->num_dai = 1;
1403 codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache); 1356 codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache);
1404 codec->reg_cache = &wm9081->reg_cache; 1357 codec->reg_cache = &wm9081->reg_cache;
1405 codec->bias_level = SND_SOC_BIAS_OFF; 1358 codec->bias_level = SND_SOC_BIAS_OFF;
1406 codec->set_bias_level = wm9081_set_bias_level; 1359 codec->set_bias_level = wm9081_set_bias_level;
1360 codec->volatile_register = wm9081_volatile_register;
1407 1361
1408 memcpy(codec->reg_cache, wm9081_reg_defaults, 1362 memcpy(codec->reg_cache, wm9081_reg_defaults,
1409 sizeof(wm9081_reg_defaults)); 1363 sizeof(wm9081_reg_defaults));
1410 1364
1411 reg = wm9081_read_hw(codec, WM9081_SOFTWARE_RESET); 1365 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
1366 if (ret != 0) {
1367 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1368 return ret;
1369 }
1370
1371 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
1412 if (reg != 0x9081) { 1372 if (reg != 0x9081) {
1413 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg); 1373 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
1414 ret = -EINVAL; 1374 ret = -EINVAL;
@@ -1424,10 +1384,10 @@ static int wm9081_register(struct wm9081_priv *wm9081)
1424 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1384 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1425 1385
1426 /* Enable zero cross by default */ 1386 /* Enable zero cross by default */
1427 reg = wm9081_read(codec, WM9081_ANALOGUE_LINEOUT); 1387 reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
1428 wm9081_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC); 1388 snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
1429 reg = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_PGA); 1389 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
1430 wm9081_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, 1390 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1431 reg | WM9081_SPKPGAZC); 1391 reg | WM9081_SPKPGAZC);
1432 1392
1433 wm9081_dai.dev = codec->dev; 1393 wm9081_dai.dev = codec->dev;
@@ -1482,7 +1442,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1482 1442
1483 codec->dev = &i2c->dev; 1443 codec->dev = &i2c->dev;
1484 1444
1485 return wm9081_register(wm9081); 1445 return wm9081_register(wm9081, SND_SOC_I2C);
1486} 1446}
1487 1447
1488static __devexit int wm9081_i2c_remove(struct i2c_client *client) 1448static __devexit int wm9081_i2c_remove(struct i2c_client *client)
@@ -1492,6 +1452,21 @@ static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1492 return 0; 1452 return 0;
1493} 1453}
1494 1454
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
1495static const struct i2c_device_id wm9081_i2c_id[] = { 1470static const struct i2c_device_id wm9081_i2c_id[] = {
1496 { "wm9081", 0 }, 1471 { "wm9081", 0 },
1497 { } 1472 { }
@@ -1505,6 +1480,8 @@ static struct i2c_driver wm9081_i2c_driver = {
1505 }, 1480 },
1506 .probe = wm9081_i2c_probe, 1481 .probe = wm9081_i2c_probe,
1507 .remove = __devexit_p(wm9081_i2c_remove), 1482 .remove = __devexit_p(wm9081_i2c_remove),
1483 .suspend = wm9081_i2c_suspend,
1484 .resume = wm9081_i2c_resume,
1508 .id_table = wm9081_i2c_id, 1485 .id_table = wm9081_i2c_id,
1509}; 1486};
1510 1487
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index d1744e96f303..abed37acf787 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -710,7 +710,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source)
710 Ndiv = target / source; 710 Ndiv = target / source;
711 if ((Ndiv < 5) || (Ndiv > 12)) 711 if ((Ndiv < 5) || (Ndiv > 12))
712 printk(KERN_WARNING 712 printk(KERN_WARNING
713 "WM9713 PLL N value %d out of recommended range!\n", 713 "WM9713 PLL N value %u out of recommended range!\n",
714 Ndiv); 714 Ndiv);
715 715
716 pll_div->n = Ndiv; 716 pll_div->n = Ndiv;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
new file mode 100644
index 000000000000..e8fc474ba5cf
--- /dev/null
+++ b/sound/soc/codecs/wm_hubs.c
@@ -0,0 +1,758 @@
1/*
2 * wm_hubs.c -- WM8993/4 common code
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29
30#include "wm8993.h"
31#include "wm_hubs.h"
32
33const DECLARE_TLV_DB_SCALE(wm_hubs_spkmix_tlv, -300, 300, 0);
34EXPORT_SYMBOL_GPL(wm_hubs_spkmix_tlv);
35
36static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1650, 150, 0);
37static const DECLARE_TLV_DB_SCALE(inmix_sw_tlv, 0, 3000, 0);
38static const DECLARE_TLV_DB_SCALE(inmix_tlv, -1500, 300, 1);
39static const DECLARE_TLV_DB_SCALE(earpiece_tlv, -600, 600, 0);
40static const DECLARE_TLV_DB_SCALE(outmix_tlv, -2100, 300, 0);
41static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1);
42static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0);
43static const unsigned int spkboost_tlv[] = {
44 TLV_DB_RANGE_HEAD(7),
45 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
46 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
47};
48static const DECLARE_TLV_DB_SCALE(line_tlv, -600, 600, 0);
49
50static const char *speaker_ref_text[] = {
51 "SPKVDD/2",
52 "VMID",
53};
54
55static const struct soc_enum speaker_ref =
56 SOC_ENUM_SINGLE(WM8993_SPEAKER_MIXER, 8, 2, speaker_ref_text);
57
58static const char *speaker_mode_text[] = {
59 "Class D",
60 "Class AB",
61};
62
63static const struct soc_enum speaker_mode =
64 SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
65
66static void wait_for_dc_servo(struct snd_soc_codec *codec)
67{
68 unsigned int reg;
69 int count = 0;
70
71 dev_dbg(codec->dev, "Waiting for DC servo...\n");
72 do {
73 count++;
74 msleep(1);
75 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
76 dev_dbg(codec->dev, "DC servo status: %x\n", reg);
77 } while ((reg & WM8993_DCS_CAL_COMPLETE_MASK)
78 != WM8993_DCS_CAL_COMPLETE_MASK && count < 1000);
79
80 if ((reg & WM8993_DCS_CAL_COMPLETE_MASK)
81 != WM8993_DCS_CAL_COMPLETE_MASK)
82 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
83}
84
85/*
86 * Update the DC servo calibration on gain changes
87 */
88static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
89 struct snd_ctl_elem_value *ucontrol)
90{
91 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
92 int ret;
93
94 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
95
96 /* Only need to do this if the outputs are active */
97 if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
98 & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
99 snd_soc_update_bits(codec,
100 WM8993_DC_SERVO_0,
101 WM8993_DCS_TRIG_SINGLE_0 |
102 WM8993_DCS_TRIG_SINGLE_1,
103 WM8993_DCS_TRIG_SINGLE_0 |
104 WM8993_DCS_TRIG_SINGLE_1);
105
106 return ret;
107}
108
109static const struct snd_kcontrol_new analogue_snd_controls[] = {
110SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
111 inpga_tlv),
112SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
113SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 0),
114
115SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
116 inpga_tlv),
117SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
118SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 0),
119
120
121SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
122 inpga_tlv),
123SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
124SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 0),
125
126SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
127 inpga_tlv),
128SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
129SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 0),
130
131SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0,
132 inmix_sw_tlv),
133SOC_SINGLE_TLV("MIXINL IN1L Volume", WM8993_INPUT_MIXER3, 4, 1, 0,
134 inmix_sw_tlv),
135SOC_SINGLE_TLV("MIXINL Output Record Volume", WM8993_INPUT_MIXER3, 0, 7, 0,
136 inmix_tlv),
137SOC_SINGLE_TLV("MIXINL IN1LP Volume", WM8993_INPUT_MIXER5, 6, 7, 0, inmix_tlv),
138SOC_SINGLE_TLV("MIXINL Direct Voice Volume", WM8993_INPUT_MIXER5, 0, 6, 0,
139 inmix_tlv),
140
141SOC_SINGLE_TLV("MIXINR IN2R Volume", WM8993_INPUT_MIXER4, 7, 1, 0,
142 inmix_sw_tlv),
143SOC_SINGLE_TLV("MIXINR IN1R Volume", WM8993_INPUT_MIXER4, 4, 1, 0,
144 inmix_sw_tlv),
145SOC_SINGLE_TLV("MIXINR Output Record Volume", WM8993_INPUT_MIXER4, 0, 7, 0,
146 inmix_tlv),
147SOC_SINGLE_TLV("MIXINR IN1RP Volume", WM8993_INPUT_MIXER6, 6, 7, 0, inmix_tlv),
148SOC_SINGLE_TLV("MIXINR Direct Voice Volume", WM8993_INPUT_MIXER6, 0, 6, 0,
149 inmix_tlv),
150
151SOC_SINGLE_TLV("Left Output Mixer IN2RN Volume", WM8993_OUTPUT_MIXER5, 6, 7, 1,
152 outmix_tlv),
153SOC_SINGLE_TLV("Left Output Mixer IN2LN Volume", WM8993_OUTPUT_MIXER3, 6, 7, 1,
154 outmix_tlv),
155SOC_SINGLE_TLV("Left Output Mixer IN2LP Volume", WM8993_OUTPUT_MIXER3, 9, 7, 1,
156 outmix_tlv),
157SOC_SINGLE_TLV("Left Output Mixer IN1L Volume", WM8993_OUTPUT_MIXER3, 0, 7, 1,
158 outmix_tlv),
159SOC_SINGLE_TLV("Left Output Mixer IN1R Volume", WM8993_OUTPUT_MIXER3, 3, 7, 1,
160 outmix_tlv),
161SOC_SINGLE_TLV("Left Output Mixer Right Input Volume",
162 WM8993_OUTPUT_MIXER5, 3, 7, 1, outmix_tlv),
163SOC_SINGLE_TLV("Left Output Mixer Left Input Volume",
164 WM8993_OUTPUT_MIXER5, 0, 7, 1, outmix_tlv),
165SOC_SINGLE_TLV("Left Output Mixer DAC Volume", WM8993_OUTPUT_MIXER5, 9, 7, 1,
166 outmix_tlv),
167
168SOC_SINGLE_TLV("Right Output Mixer IN2LN Volume",
169 WM8993_OUTPUT_MIXER6, 6, 7, 1, outmix_tlv),
170SOC_SINGLE_TLV("Right Output Mixer IN2RN Volume",
171 WM8993_OUTPUT_MIXER4, 6, 7, 1, outmix_tlv),
172SOC_SINGLE_TLV("Right Output Mixer IN1L Volume",
173 WM8993_OUTPUT_MIXER4, 3, 7, 1, outmix_tlv),
174SOC_SINGLE_TLV("Right Output Mixer IN1R Volume",
175 WM8993_OUTPUT_MIXER4, 0, 7, 1, outmix_tlv),
176SOC_SINGLE_TLV("Right Output Mixer IN2RP Volume",
177 WM8993_OUTPUT_MIXER4, 9, 7, 1, outmix_tlv),
178SOC_SINGLE_TLV("Right Output Mixer Left Input Volume",
179 WM8993_OUTPUT_MIXER6, 3, 7, 1, outmix_tlv),
180SOC_SINGLE_TLV("Right Output Mixer Right Input Volume",
181 WM8993_OUTPUT_MIXER6, 6, 7, 1, outmix_tlv),
182SOC_SINGLE_TLV("Right Output Mixer DAC Volume",
183 WM8993_OUTPUT_MIXER6, 9, 7, 1, outmix_tlv),
184
185SOC_DOUBLE_R_TLV("Output Volume", WM8993_LEFT_OPGA_VOLUME,
186 WM8993_RIGHT_OPGA_VOLUME, 0, 63, 0, outpga_tlv),
187SOC_DOUBLE_R("Output Switch", WM8993_LEFT_OPGA_VOLUME,
188 WM8993_RIGHT_OPGA_VOLUME, 6, 1, 0),
189SOC_DOUBLE_R("Output ZC Switch", WM8993_LEFT_OPGA_VOLUME,
190 WM8993_RIGHT_OPGA_VOLUME, 7, 1, 0),
191
192SOC_SINGLE("Earpiece Switch", WM8993_HPOUT2_VOLUME, 5, 1, 1),
193SOC_SINGLE_TLV("Earpiece Volume", WM8993_HPOUT2_VOLUME, 4, 1, 1, earpiece_tlv),
194
195SOC_SINGLE_TLV("SPKL Input Volume", WM8993_SPKMIXL_ATTENUATION,
196 5, 1, 1, wm_hubs_spkmix_tlv),
197SOC_SINGLE_TLV("SPKL IN1LP Volume", WM8993_SPKMIXL_ATTENUATION,
198 4, 1, 1, wm_hubs_spkmix_tlv),
199SOC_SINGLE_TLV("SPKL Output Volume", WM8993_SPKMIXL_ATTENUATION,
200 3, 1, 1, wm_hubs_spkmix_tlv),
201
202SOC_SINGLE_TLV("SPKR Input Volume", WM8993_SPKMIXR_ATTENUATION,
203 5, 1, 1, wm_hubs_spkmix_tlv),
204SOC_SINGLE_TLV("SPKR IN1RP Volume", WM8993_SPKMIXR_ATTENUATION,
205 4, 1, 1, wm_hubs_spkmix_tlv),
206SOC_SINGLE_TLV("SPKR Output Volume", WM8993_SPKMIXR_ATTENUATION,
207 3, 1, 1, wm_hubs_spkmix_tlv),
208
209SOC_DOUBLE_R_TLV("Speaker Mixer Volume",
210 WM8993_SPKMIXL_ATTENUATION, WM8993_SPKMIXR_ATTENUATION,
211 0, 3, 1, spkmixout_tlv),
212SOC_DOUBLE_R_TLV("Speaker Volume",
213 WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
214 0, 63, 0, outpga_tlv),
215SOC_DOUBLE_R("Speaker Switch",
216 WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
217 6, 1, 0),
218SOC_DOUBLE_R("Speaker ZC Switch",
219 WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
220 7, 1, 0),
221SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0,
222 spkboost_tlv),
223SOC_ENUM("Speaker Reference", speaker_ref),
224SOC_ENUM("Speaker Mode", speaker_mode),
225
226{
227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Headphone Volume",
228 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
229 SNDRV_CTL_ELEM_ACCESS_READWRITE,
230 .tlv.p = outpga_tlv,
231 .info = snd_soc_info_volsw_2r,
232 .get = snd_soc_get_volsw_2r, .put = wm8993_put_dc_servo,
233 .private_value = (unsigned long)&(struct soc_mixer_control) {
234 .reg = WM8993_LEFT_OUTPUT_VOLUME,
235 .rreg = WM8993_RIGHT_OUTPUT_VOLUME,
236 .shift = 0, .max = 63
237 },
238},
239SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME,
240 WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0),
241SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME,
242 WM8993_RIGHT_OUTPUT_VOLUME, 7, 1, 0),
243
244SOC_SINGLE("LINEOUT1N Switch", WM8993_LINE_OUTPUTS_VOLUME, 6, 1, 1),
245SOC_SINGLE("LINEOUT1P Switch", WM8993_LINE_OUTPUTS_VOLUME, 5, 1, 1),
246SOC_SINGLE_TLV("LINEOUT1 Volume", WM8993_LINE_OUTPUTS_VOLUME, 4, 1, 1,
247 line_tlv),
248
249SOC_SINGLE("LINEOUT2N Switch", WM8993_LINE_OUTPUTS_VOLUME, 2, 1, 1),
250SOC_SINGLE("LINEOUT2P Switch", WM8993_LINE_OUTPUTS_VOLUME, 1, 1, 1),
251SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
252 line_tlv),
253};
254
255static int hp_event(struct snd_soc_dapm_widget *w,
256 struct snd_kcontrol *kcontrol, int event)
257{
258 struct snd_soc_codec *codec = w->codec;
259 unsigned int reg = snd_soc_read(codec, WM8993_ANALOGUE_HP_0);
260
261 switch (event) {
262 case SND_SOC_DAPM_POST_PMU:
263 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
264 WM8993_CP_ENA, WM8993_CP_ENA);
265
266 msleep(5);
267
268 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
269 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
270 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA);
271
272 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
273 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
274
275 /* Start the DC servo */
276 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
277 WM8993_DCS_ENA_CHAN_0 |
278 WM8993_DCS_ENA_CHAN_1 |
279 WM8993_DCS_TRIG_STARTUP_1 |
280 WM8993_DCS_TRIG_STARTUP_0,
281 WM8993_DCS_ENA_CHAN_0 |
282 WM8993_DCS_ENA_CHAN_1 |
283 WM8993_DCS_TRIG_STARTUP_1 |
284 WM8993_DCS_TRIG_STARTUP_0);
285 wait_for_dc_servo(codec);
286 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
287 WM8993_DCS_TIMER_PERIOD_01_MASK, 0xa);
288
289 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
290 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
291 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
292 break;
293
294 case SND_SOC_DAPM_PRE_PMD:
295 reg &= ~(WM8993_HPOUT1L_RMV_SHORT |
296 WM8993_HPOUT1L_DLY |
297 WM8993_HPOUT1L_OUTP |
298 WM8993_HPOUT1R_RMV_SHORT |
299 WM8993_HPOUT1R_DLY |
300 WM8993_HPOUT1R_OUTP);
301
302 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
303 WM8993_DCS_TIMER_PERIOD_01_MASK, 0);
304 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
305 WM8993_DCS_ENA_CHAN_0 |
306 WM8993_DCS_ENA_CHAN_1, 0);
307
308 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
309 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
310 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
311 0);
312
313 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
314 WM8993_CP_ENA, 0);
315 break;
316 }
317
318 return 0;
319}
320
321static int earpiece_event(struct snd_soc_dapm_widget *w,
322 struct snd_kcontrol *control, int event)
323{
324 struct snd_soc_codec *codec = w->codec;
325 u16 reg = snd_soc_read(codec, WM8993_ANTIPOP1) & ~WM8993_HPOUT2_IN_ENA;
326
327 switch (event) {
328 case SND_SOC_DAPM_PRE_PMU:
329 reg |= WM8993_HPOUT2_IN_ENA;
330 snd_soc_write(codec, WM8993_ANTIPOP1, reg);
331 udelay(50);
332 break;
333
334 case SND_SOC_DAPM_POST_PMD:
335 snd_soc_write(codec, WM8993_ANTIPOP1, reg);
336 break;
337
338 default:
339 BUG();
340 break;
341 }
342
343 return 0;
344}
345
346static const struct snd_kcontrol_new in1l_pga[] = {
347SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0),
348SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0),
349};
350
351static const struct snd_kcontrol_new in1r_pga[] = {
352SOC_DAPM_SINGLE("IN1RP Switch", WM8993_INPUT_MIXER2, 1, 1, 0),
353SOC_DAPM_SINGLE("IN1RN Switch", WM8993_INPUT_MIXER2, 0, 1, 0),
354};
355
356static const struct snd_kcontrol_new in2l_pga[] = {
357SOC_DAPM_SINGLE("IN2LP Switch", WM8993_INPUT_MIXER2, 7, 1, 0),
358SOC_DAPM_SINGLE("IN2LN Switch", WM8993_INPUT_MIXER2, 6, 1, 0),
359};
360
361static const struct snd_kcontrol_new in2r_pga[] = {
362SOC_DAPM_SINGLE("IN2RP Switch", WM8993_INPUT_MIXER2, 3, 1, 0),
363SOC_DAPM_SINGLE("IN2RN Switch", WM8993_INPUT_MIXER2, 2, 1, 0),
364};
365
366static const struct snd_kcontrol_new mixinl[] = {
367SOC_DAPM_SINGLE("IN2L Switch", WM8993_INPUT_MIXER3, 8, 1, 0),
368SOC_DAPM_SINGLE("IN1L Switch", WM8993_INPUT_MIXER3, 5, 1, 0),
369};
370
371static const struct snd_kcontrol_new mixinr[] = {
372SOC_DAPM_SINGLE("IN2R Switch", WM8993_INPUT_MIXER4, 8, 1, 0),
373SOC_DAPM_SINGLE("IN1R Switch", WM8993_INPUT_MIXER4, 5, 1, 0),
374};
375
376static const struct snd_kcontrol_new left_output_mixer[] = {
377SOC_DAPM_SINGLE("Right Input Switch", WM8993_OUTPUT_MIXER1, 7, 1, 0),
378SOC_DAPM_SINGLE("Left Input Switch", WM8993_OUTPUT_MIXER1, 6, 1, 0),
379SOC_DAPM_SINGLE("IN2RN Switch", WM8993_OUTPUT_MIXER1, 5, 1, 0),
380SOC_DAPM_SINGLE("IN2LN Switch", WM8993_OUTPUT_MIXER1, 4, 1, 0),
381SOC_DAPM_SINGLE("IN2LP Switch", WM8993_OUTPUT_MIXER1, 1, 1, 0),
382SOC_DAPM_SINGLE("IN1R Switch", WM8993_OUTPUT_MIXER1, 3, 1, 0),
383SOC_DAPM_SINGLE("IN1L Switch", WM8993_OUTPUT_MIXER1, 2, 1, 0),
384SOC_DAPM_SINGLE("DAC Switch", WM8993_OUTPUT_MIXER1, 0, 1, 0),
385};
386
387static const struct snd_kcontrol_new right_output_mixer[] = {
388SOC_DAPM_SINGLE("Left Input Switch", WM8993_OUTPUT_MIXER2, 7, 1, 0),
389SOC_DAPM_SINGLE("Right Input Switch", WM8993_OUTPUT_MIXER2, 6, 1, 0),
390SOC_DAPM_SINGLE("IN2LN Switch", WM8993_OUTPUT_MIXER2, 5, 1, 0),
391SOC_DAPM_SINGLE("IN2RN Switch", WM8993_OUTPUT_MIXER2, 4, 1, 0),
392SOC_DAPM_SINGLE("IN1L Switch", WM8993_OUTPUT_MIXER2, 3, 1, 0),
393SOC_DAPM_SINGLE("IN1R Switch", WM8993_OUTPUT_MIXER2, 2, 1, 0),
394SOC_DAPM_SINGLE("IN2RP Switch", WM8993_OUTPUT_MIXER2, 1, 1, 0),
395SOC_DAPM_SINGLE("DAC Switch", WM8993_OUTPUT_MIXER2, 0, 1, 0),
396};
397
398static const struct snd_kcontrol_new earpiece_mixer[] = {
399SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_HPOUT2_MIXER, 5, 1, 0),
400SOC_DAPM_SINGLE("Left Output Switch", WM8993_HPOUT2_MIXER, 4, 1, 0),
401SOC_DAPM_SINGLE("Right Output Switch", WM8993_HPOUT2_MIXER, 3, 1, 0),
402};
403
404static const struct snd_kcontrol_new left_speaker_boost[] = {
405SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_SPKOUT_MIXERS, 5, 1, 0),
406SOC_DAPM_SINGLE("SPKL Switch", WM8993_SPKOUT_MIXERS, 4, 1, 0),
407SOC_DAPM_SINGLE("SPKR Switch", WM8993_SPKOUT_MIXERS, 3, 1, 0),
408};
409
410static const struct snd_kcontrol_new right_speaker_boost[] = {
411SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_SPKOUT_MIXERS, 2, 1, 0),
412SOC_DAPM_SINGLE("SPKL Switch", WM8993_SPKOUT_MIXERS, 1, 1, 0),
413SOC_DAPM_SINGLE("SPKR Switch", WM8993_SPKOUT_MIXERS, 0, 1, 0),
414};
415
416static const struct snd_kcontrol_new line1_mix[] = {
417SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER1, 2, 1, 0),
418SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER1, 1, 1, 0),
419SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
420};
421
422static const struct snd_kcontrol_new line1n_mix[] = {
423SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 6, 1, 0),
424SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER1, 5, 1, 0),
425};
426
427static const struct snd_kcontrol_new line1p_mix[] = {
428SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
429};
430
431static const struct snd_kcontrol_new line2_mix[] = {
432SOC_DAPM_SINGLE("IN2R Switch", WM8993_LINE_MIXER2, 2, 1, 0),
433SOC_DAPM_SINGLE("IN2L Switch", WM8993_LINE_MIXER2, 1, 1, 0),
434SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
435};
436
437static const struct snd_kcontrol_new line2n_mix[] = {
438SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 6, 1, 0),
439SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 5, 1, 0),
440};
441
442static const struct snd_kcontrol_new line2p_mix[] = {
443SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
444};
445
446static const struct snd_soc_dapm_widget analogue_dapm_widgets[] = {
447SND_SOC_DAPM_INPUT("IN1LN"),
448SND_SOC_DAPM_INPUT("IN1LP"),
449SND_SOC_DAPM_INPUT("IN2LN"),
450SND_SOC_DAPM_INPUT("IN2LP/VXRN"),
451SND_SOC_DAPM_INPUT("IN1RN"),
452SND_SOC_DAPM_INPUT("IN1RP"),
453SND_SOC_DAPM_INPUT("IN2RN"),
454SND_SOC_DAPM_INPUT("IN2RP/VXRP"),
455
456SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0),
457SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0),
458
459SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
460 in1l_pga, ARRAY_SIZE(in1l_pga)),
461SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0,
462 in1r_pga, ARRAY_SIZE(in1r_pga)),
463
464SND_SOC_DAPM_MIXER("IN2L PGA", WM8993_POWER_MANAGEMENT_2, 7, 0,
465 in2l_pga, ARRAY_SIZE(in2l_pga)),
466SND_SOC_DAPM_MIXER("IN2R PGA", WM8993_POWER_MANAGEMENT_2, 5, 0,
467 in2r_pga, ARRAY_SIZE(in2r_pga)),
468
469/* Dummy widgets to represent differential paths */
470SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
471
472SND_SOC_DAPM_MIXER("MIXINL", WM8993_POWER_MANAGEMENT_2, 9, 0,
473 mixinl, ARRAY_SIZE(mixinl)),
474SND_SOC_DAPM_MIXER("MIXINR", WM8993_POWER_MANAGEMENT_2, 8, 0,
475 mixinr, ARRAY_SIZE(mixinr)),
476
477SND_SOC_DAPM_ADC("ADCL", "Capture", WM8993_POWER_MANAGEMENT_2, 1, 0),
478SND_SOC_DAPM_ADC("ADCR", "Capture", WM8993_POWER_MANAGEMENT_2, 0, 0),
479
480SND_SOC_DAPM_DAC("DACL", "Playback", WM8993_POWER_MANAGEMENT_3, 1, 0),
481SND_SOC_DAPM_DAC("DACR", "Playback", WM8993_POWER_MANAGEMENT_3, 0, 0),
482
483SND_SOC_DAPM_MIXER("Left Output Mixer", WM8993_POWER_MANAGEMENT_3, 5, 0,
484 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
485SND_SOC_DAPM_MIXER("Right Output Mixer", WM8993_POWER_MANAGEMENT_3, 4, 0,
486 right_output_mixer, ARRAY_SIZE(right_output_mixer)),
487
488SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0),
489SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
490
491SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0,
492 NULL, 0,
493 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
494
495SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
496 earpiece_mixer, ARRAY_SIZE(earpiece_mixer)),
497SND_SOC_DAPM_PGA_E("Earpiece Driver", WM8993_POWER_MANAGEMENT_1, 11, 0,
498 NULL, 0, earpiece_event,
499 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
500
501SND_SOC_DAPM_MIXER("SPKL Boost", SND_SOC_NOPM, 0, 0,
502 left_speaker_boost, ARRAY_SIZE(left_speaker_boost)),
503SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
504 right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
505
506SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
507 NULL, 0),
508SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
509 NULL, 0),
510
511SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
512 line1_mix, ARRAY_SIZE(line1_mix)),
513SND_SOC_DAPM_MIXER("LINEOUT2 Mixer", SND_SOC_NOPM, 0, 0,
514 line2_mix, ARRAY_SIZE(line2_mix)),
515
516SND_SOC_DAPM_MIXER("LINEOUT1N Mixer", SND_SOC_NOPM, 0, 0,
517 line1n_mix, ARRAY_SIZE(line1n_mix)),
518SND_SOC_DAPM_MIXER("LINEOUT1P Mixer", SND_SOC_NOPM, 0, 0,
519 line1p_mix, ARRAY_SIZE(line1p_mix)),
520SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
521 line2n_mix, ARRAY_SIZE(line2n_mix)),
522SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
523 line2p_mix, ARRAY_SIZE(line2p_mix)),
524
525SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
526 NULL, 0),
527SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
528 NULL, 0),
529SND_SOC_DAPM_PGA("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
530 NULL, 0),
531SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
532 NULL, 0),
533
534SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
535SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
536SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
537SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
538SND_SOC_DAPM_OUTPUT("HPOUT1L"),
539SND_SOC_DAPM_OUTPUT("HPOUT1R"),
540SND_SOC_DAPM_OUTPUT("HPOUT2P"),
541SND_SOC_DAPM_OUTPUT("HPOUT2N"),
542SND_SOC_DAPM_OUTPUT("LINEOUT1P"),
543SND_SOC_DAPM_OUTPUT("LINEOUT1N"),
544SND_SOC_DAPM_OUTPUT("LINEOUT2P"),
545SND_SOC_DAPM_OUTPUT("LINEOUT2N"),
546};
547
548static const struct snd_soc_dapm_route analogue_routes[] = {
549 { "IN1L PGA", "IN1LP Switch", "IN1LP" },
550 { "IN1L PGA", "IN1LN Switch", "IN1LN" },
551
552 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
553 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
554
555 { "IN2L PGA", "IN2LP Switch", "IN2LP/VXRN" },
556 { "IN2L PGA", "IN2LN Switch", "IN2LN" },
557
558 { "IN2R PGA", "IN2RP Switch", "IN2RP/VXRP" },
559 { "IN2R PGA", "IN2RN Switch", "IN2RN" },
560
561 { "Direct Voice", NULL, "IN2LP/VXRN" },
562 { "Direct Voice", NULL, "IN2RP/VXRP" },
563
564 { "MIXINL", "IN1L Switch", "IN1L PGA" },
565 { "MIXINL", "IN2L Switch", "IN2L PGA" },
566 { "MIXINL", NULL, "Direct Voice" },
567 { "MIXINL", NULL, "IN1LP" },
568 { "MIXINL", NULL, "Left Output Mixer" },
569
570 { "MIXINR", "IN1R Switch", "IN1R PGA" },
571 { "MIXINR", "IN2R Switch", "IN2R PGA" },
572 { "MIXINR", NULL, "Direct Voice" },
573 { "MIXINR", NULL, "IN1RP" },
574 { "MIXINR", NULL, "Right Output Mixer" },
575
576 { "ADCL", NULL, "MIXINL" },
577 { "ADCR", NULL, "MIXINR" },
578
579 { "Left Output Mixer", "Left Input Switch", "MIXINL" },
580 { "Left Output Mixer", "Right Input Switch", "MIXINR" },
581 { "Left Output Mixer", "IN2RN Switch", "IN2RN" },
582 { "Left Output Mixer", "IN2LN Switch", "IN2LN" },
583 { "Left Output Mixer", "IN2LP Switch", "IN2LP/VXRN" },
584 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" },
585 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" },
586
587 { "Right Output Mixer", "Left Input Switch", "MIXINL" },
588 { "Right Output Mixer", "Right Input Switch", "MIXINR" },
589 { "Right Output Mixer", "IN2LN Switch", "IN2LN" },
590 { "Right Output Mixer", "IN2RN Switch", "IN2RN" },
591 { "Right Output Mixer", "IN2RP Switch", "IN2RP/VXRP" },
592 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" },
593 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" },
594
595 { "Left Output PGA", NULL, "Left Output Mixer" },
596 { "Left Output PGA", NULL, "TOCLK" },
597
598 { "Right Output PGA", NULL, "Right Output Mixer" },
599 { "Right Output PGA", NULL, "TOCLK" },
600
601 { "Earpiece Mixer", "Direct Voice Switch", "Direct Voice" },
602 { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" },
603 { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" },
604
605 { "Earpiece Driver", NULL, "Earpiece Mixer" },
606 { "HPOUT2N", NULL, "Earpiece Driver" },
607 { "HPOUT2P", NULL, "Earpiece Driver" },
608
609 { "SPKL", "Input Switch", "MIXINL" },
610 { "SPKL", "IN1LP Switch", "IN1LP" },
611 { "SPKL", "Output Switch", "Left Output Mixer" },
612 { "SPKL", NULL, "TOCLK" },
613
614 { "SPKR", "Input Switch", "MIXINR" },
615 { "SPKR", "IN1RP Switch", "IN1RP" },
616 { "SPKR", "Output Switch", "Right Output Mixer" },
617 { "SPKR", NULL, "TOCLK" },
618
619 { "SPKL Boost", "Direct Voice Switch", "Direct Voice" },
620 { "SPKL Boost", "SPKL Switch", "SPKL" },
621 { "SPKL Boost", "SPKR Switch", "SPKR" },
622
623 { "SPKR Boost", "Direct Voice Switch", "Direct Voice" },
624 { "SPKR Boost", "SPKR Switch", "SPKR" },
625 { "SPKR Boost", "SPKL Switch", "SPKL" },
626
627 { "SPKL Driver", NULL, "SPKL Boost" },
628 { "SPKL Driver", NULL, "CLK_SYS" },
629
630 { "SPKR Driver", NULL, "SPKR Boost" },
631 { "SPKR Driver", NULL, "CLK_SYS" },
632
633 { "SPKOUTLP", NULL, "SPKL Driver" },
634 { "SPKOUTLN", NULL, "SPKL Driver" },
635 { "SPKOUTRP", NULL, "SPKR Driver" },
636 { "SPKOUTRN", NULL, "SPKR Driver" },
637
638 { "Left Headphone Mux", "Mixer", "Left Output Mixer" },
639 { "Right Headphone Mux", "Mixer", "Right Output Mixer" },
640
641 { "Headphone PGA", NULL, "Left Headphone Mux" },
642 { "Headphone PGA", NULL, "Right Headphone Mux" },
643 { "Headphone PGA", NULL, "CLK_SYS" },
644
645 { "HPOUT1L", NULL, "Headphone PGA" },
646 { "HPOUT1R", NULL, "Headphone PGA" },
647
648 { "LINEOUT1N", NULL, "LINEOUT1N Driver" },
649 { "LINEOUT1P", NULL, "LINEOUT1P Driver" },
650 { "LINEOUT2N", NULL, "LINEOUT2N Driver" },
651 { "LINEOUT2P", NULL, "LINEOUT2P Driver" },
652};
653
654static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
655 { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" },
656 { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" },
657 { "LINEOUT1 Mixer", "Output Switch", "Left Output Mixer" },
658
659 { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" },
660 { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" },
661};
662
663static const struct snd_soc_dapm_route lineout1_se_routes[] = {
664 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output Mixer" },
665 { "LINEOUT1N Mixer", "Right Output Switch", "Left Output Mixer" },
666
667 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output Mixer" },
668
669 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
670 { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" },
671};
672
673static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
674 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" },
675 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" },
676 { "LINEOUT2 Mixer", "Output Switch", "Right Output Mixer" },
677
678 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
679 { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" },
680};
681
682static const struct snd_soc_dapm_route lineout2_se_routes[] = {
683 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output Mixer" },
684 { "LINEOUT2N Mixer", "Right Output Switch", "Left Output Mixer" },
685
686 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output Mixer" },
687
688 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
689 { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" },
690};
691
692int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
693{
694 /* Latch volume update bits & default ZC on */
695 snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
696 WM8993_IN1_VU, WM8993_IN1_VU);
697 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_1_2_VOLUME,
698 WM8993_IN1_VU, WM8993_IN1_VU);
699 snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_3_4_VOLUME,
700 WM8993_IN2_VU, WM8993_IN2_VU);
701 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME,
702 WM8993_IN2_VU, WM8993_IN2_VU);
703
704 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT,
705 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
706
707 snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME,
708 WM8993_HPOUT1L_ZC, WM8993_HPOUT1L_ZC);
709 snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME,
710 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC,
711 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC);
712
713 snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME,
714 WM8993_MIXOUTL_ZC, WM8993_MIXOUTL_ZC);
715 snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME,
716 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
717 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
718
719 snd_soc_add_controls(codec, analogue_snd_controls,
720 ARRAY_SIZE(analogue_snd_controls));
721
722 snd_soc_dapm_new_controls(codec, analogue_dapm_widgets,
723 ARRAY_SIZE(analogue_dapm_widgets));
724 return 0;
725}
726EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
727
728int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
729 int lineout1_diff, int lineout2_diff)
730{
731 snd_soc_dapm_add_routes(codec, analogue_routes,
732 ARRAY_SIZE(analogue_routes));
733
734 if (lineout1_diff)
735 snd_soc_dapm_add_routes(codec,
736 lineout1_diff_routes,
737 ARRAY_SIZE(lineout1_diff_routes));
738 else
739 snd_soc_dapm_add_routes(codec,
740 lineout1_se_routes,
741 ARRAY_SIZE(lineout1_se_routes));
742
743 if (lineout2_diff)
744 snd_soc_dapm_add_routes(codec,
745 lineout2_diff_routes,
746 ARRAY_SIZE(lineout2_diff_routes));
747 else
748 snd_soc_dapm_add_routes(codec,
749 lineout2_se_routes,
750 ARRAY_SIZE(lineout2_se_routes));
751
752 return 0;
753}
754EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
755
756MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
757MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
758MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
new file mode 100644
index 000000000000..ec09cb6a2939
--- /dev/null
+++ b/sound/soc/codecs/wm_hubs.h
@@ -0,0 +1,24 @@
1/*
2 * wm_hubs.h -- WM899x common code
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#ifndef _WM_HUBS_H
15#define _WM_HUBS_H
16
17struct snd_soc_codec;
18
19extern const unsigned int wm_hubs_spkmix_tlv[];
20
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
23
24#endif