aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig100
-rw-r--r--sound/soc/codecs/Makefile26
-rw-r--r--sound/soc/codecs/ac97.c3
-rw-r--r--sound/soc/codecs/ad1980.c308
-rw-r--r--sound/soc/codecs/ad1980.h23
-rw-r--r--sound/soc/codecs/ad73311.c107
-rw-r--r--sound/soc/codecs/ad73311.h90
-rw-r--r--sound/soc/codecs/ak4535.c117
-rw-r--r--sound/soc/codecs/ak4535.h1
-rw-r--r--sound/soc/codecs/cs4270.c103
-rw-r--r--sound/soc/codecs/ssm2602.c775
-rw-r--r--sound/soc/codecs/ssm2602.h130
-rw-r--r--sound/soc/codecs/tlv320aic23.c714
-rw-r--r--sound/soc/codecs/tlv320aic23.h122
-rw-r--r--sound/soc/codecs/tlv320aic26.c520
-rw-r--r--sound/soc/codecs/tlv320aic26.h96
-rw-r--r--sound/soc/codecs/tlv320aic3x.c113
-rw-r--r--sound/soc/codecs/tlv320aic3x.h3
-rw-r--r--sound/soc/codecs/uda1380.c116
-rw-r--r--sound/soc/codecs/uda1380.h1
-rw-r--r--sound/soc/codecs/wm8510.c221
-rw-r--r--sound/soc/codecs/wm8510.h2
-rw-r--r--sound/soc/codecs/wm8580.c1053
-rw-r--r--sound/soc/codecs/wm8580.h42
-rw-r--r--sound/soc/codecs/wm8731.c179
-rw-r--r--sound/soc/codecs/wm8731.h2
-rw-r--r--sound/soc/codecs/wm8750.c178
-rw-r--r--sound/soc/codecs/wm8750.h2
-rw-r--r--sound/soc/codecs/wm8753.c181
-rw-r--r--sound/soc/codecs/wm8753.h5
-rw-r--r--sound/soc/codecs/wm8900.c1541
-rw-r--r--sound/soc/codecs/wm8900.h64
-rw-r--r--sound/soc/codecs/wm8903.c1813
-rw-r--r--sound/soc/codecs/wm8903.h1463
-rw-r--r--sound/soc/codecs/wm8971.c941
-rw-r--r--sound/soc/codecs/wm8971.h64
-rw-r--r--sound/soc/codecs/wm8990.c110
-rw-r--r--sound/soc/codecs/wm8990.h1
-rw-r--r--sound/soc/codecs/wm9712.c3
-rw-r--r--sound/soc/codecs/wm9713.c37
40 files changed, 10782 insertions, 588 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1db04a28a53d..38a0e3b620a7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1,32 +1,45 @@
1config SND_SOC_AC97_CODEC 1config SND_SOC_ALL_CODECS
2 tristate 2 tristate "Build all ASoC CODEC drivers"
3 select SND_AC97_CODEC 3 depends on I2C
4 4 select SPI
5config SND_SOC_AK4535 5 select SPI_MASTER
6 tristate 6 select SND_SOC_AD73311
7 7 select SND_SOC_AK4535
8config SND_SOC_UDA1380 8 select SND_SOC_CS4270
9 tristate 9 select SND_SOC_SSM2602
10 select SND_SOC_TLV320AIC23
11 select SND_SOC_TLV320AIC26
12 select SND_SOC_TLV320AIC3X
13 select SND_SOC_UDA1380
14 select SND_SOC_WM8510
15 select SND_SOC_WM8580
16 select SND_SOC_WM8731
17 select SND_SOC_WM8750
18 select SND_SOC_WM8753
19 select SND_SOC_WM8900
20 select SND_SOC_WM8903
21 select SND_SOC_WM8971
22 select SND_SOC_WM8990
23 help
24 Normally ASoC codec drivers are only built if a machine driver which
25 uses them is also built since they are only usable with a machine
26 driver. Selecting this option will allow these drivers to be built
27 without an explicit machine driver for test and development purposes.
10 28
11config SND_SOC_WM8510 29 If unsure select "N".
12 tristate
13 30
14config SND_SOC_WM8731
15 tristate
16 31
17config SND_SOC_WM8750 32config SND_SOC_AC97_CODEC
18 tristate
19
20config SND_SOC_WM8753
21 tristate 33 tristate
34 select SND_AC97_CODEC
22 35
23config SND_SOC_WM8990 36config SND_SOC_AD1980
24 tristate 37 tristate
25 38
26config SND_SOC_WM9712 39config SND_SOC_AD73311
27 tristate 40 tristate
28 41
29config SND_SOC_WM9713 42config SND_SOC_AK4535
30 tristate 43 tristate
31 44
32# Cirrus Logic CS4270 Codec 45# Cirrus Logic CS4270 Codec
@@ -47,6 +60,53 @@ config SND_SOC_CS4270_VD33_ERRATA
47 bool 60 bool
48 depends on SND_SOC_CS4270 61 depends on SND_SOC_CS4270
49 62
63config SND_SOC_SSM2602
64 tristate
65
66config SND_SOC_TLV320AIC23
67 tristate
68 depends on I2C
69
70config SND_SOC_TLV320AIC26
71 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
72 depends on SPI
73
50config SND_SOC_TLV320AIC3X 74config SND_SOC_TLV320AIC3X
51 tristate 75 tristate
52 depends on I2C 76 depends on I2C
77
78config SND_SOC_UDA1380
79 tristate
80
81config SND_SOC_WM8510
82 tristate
83
84config SND_SOC_WM8580
85 tristate
86
87config SND_SOC_WM8731
88 tristate
89
90config SND_SOC_WM8750
91 tristate
92
93config SND_SOC_WM8753
94 tristate
95
96config SND_SOC_WM8900
97 tristate
98
99config SND_SOC_WM8903
100 tristate
101
102config SND_SOC_WM8971
103 tristate
104
105config SND_SOC_WM8990
106 tristate
107
108config SND_SOC_WM9712
109 tristate
110
111config SND_SOC_WM9713
112 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index d7b97abcf729..90f0a585fc70 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,25 +1,43 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o
2snd-soc-ak4535-objs := ak4535.o 4snd-soc-ak4535-objs := ak4535.o
5snd-soc-cs4270-objs := cs4270.o
6snd-soc-ssm2602-objs := ssm2602.o
7snd-soc-tlv320aic23-objs := tlv320aic23.o
8snd-soc-tlv320aic26-objs := tlv320aic26.o
9snd-soc-tlv320aic3x-objs := tlv320aic3x.o
3snd-soc-uda1380-objs := uda1380.o 10snd-soc-uda1380-objs := uda1380.o
4snd-soc-wm8510-objs := wm8510.o 11snd-soc-wm8510-objs := wm8510.o
12snd-soc-wm8580-objs := wm8580.o
5snd-soc-wm8731-objs := wm8731.o 13snd-soc-wm8731-objs := wm8731.o
6snd-soc-wm8750-objs := wm8750.o 14snd-soc-wm8750-objs := wm8750.o
7snd-soc-wm8753-objs := wm8753.o 15snd-soc-wm8753-objs := wm8753.o
16snd-soc-wm8900-objs := wm8900.o
17snd-soc-wm8903-objs := wm8903.o
18snd-soc-wm8971-objs := wm8971.o
8snd-soc-wm8990-objs := wm8990.o 19snd-soc-wm8990-objs := wm8990.o
9snd-soc-wm9712-objs := wm9712.o 20snd-soc-wm9712-objs := wm9712.o
10snd-soc-wm9713-objs := wm9713.o 21snd-soc-wm9713-objs := wm9713.o
11snd-soc-cs4270-objs := cs4270.o
12snd-soc-tlv320aic3x-objs := tlv320aic3x.o
13 22
14obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 23obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
24obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
25obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
15obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 26obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
27obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
28obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
29obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
30obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
31obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
16obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 32obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
17obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 33obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
34obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
18obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 35obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
19obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 36obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
20obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 37obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
38obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
39obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
40obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
21obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 41obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
22obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 42obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
23obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o 43obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
24obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
25obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 61fd96ca7bc7..bd1ebdc6c86c 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -2,8 +2,7 @@
2 * ac97.c -- ALSA Soc AC97 codec support 2 * ac97.c -- ALSA Soc AC97 codec support
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
new file mode 100644
index 000000000000..1397b8e06c0b
--- /dev/null
+++ b/sound/soc/codecs/ad1980.c
@@ -0,0 +1,308 @@
1/*
2 * ad1980.c -- ALSA Soc AD1980 codec support
3 *
4 * Copyright: Analog Device Inc.
5 * Author: Roy Huang <roy.huang@analog.com>
6 * Cliff Cai <cliff.cai@analog.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/device.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/ac97_codec.h>
21#include <sound/initval.h>
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24
25#include "ad1980.h"
26
27static unsigned int ac97_read(struct snd_soc_codec *codec,
28 unsigned int reg);
29static int ac97_write(struct snd_soc_codec *codec,
30 unsigned int reg, unsigned int val);
31
32/*
33 * AD1980 register cache
34 */
35static const u16 ad1980_reg[] = {
36 0x0090, 0x8000, 0x8000, 0x8000, /* 0 - 6 */
37 0x0000, 0x0000, 0x8008, 0x8008, /* 8 - e */
38 0x8808, 0x8808, 0x0000, 0x8808, /* 10 - 16 */
39 0x8808, 0x0000, 0x8000, 0x0000, /* 18 - 1e */
40 0x0000, 0x0000, 0x0000, 0x0000, /* 20 - 26 */
41 0x03c7, 0x0000, 0xbb80, 0xbb80, /* 28 - 2e */
42 0xbb80, 0xbb80, 0x0000, 0x8080, /* 30 - 36 */
43 0x8080, 0x2000, 0x0000, 0x0000, /* 38 - 3e */
44 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
45 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
46 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
47 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
48 0x8080, 0x0000, 0x0000, 0x0000, /* 60 - 66 */
49 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
50 0x0000, 0x0000, 0x1001, 0x0000, /* 70 - 76 */
51 0x0000, 0x0000, 0x4144, 0x5370 /* 78 - 7e */
52};
53
54static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line",
55 "Stereo Mix", "Mono Mix", "Phone"};
56
57static const struct soc_enum ad1980_cap_src =
58 SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel);
59
60static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = {
61SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),
62SOC_SINGLE("Master Playback Switch", AC97_MASTER, 15, 1, 1),
63
64SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
65SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
66
67SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1),
68SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1),
69
70SOC_DOUBLE("PCM Capture Volume", AC97_REC_GAIN, 8, 0, 31, 0),
71SOC_SINGLE("PCM Capture Switch", AC97_REC_GAIN, 15, 1, 1),
72
73SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1),
74SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
75
76SOC_SINGLE("Phone Capture Volume", AC97_PHONE, 0, 31, 1),
77SOC_SINGLE("Phone Capture Switch", AC97_PHONE, 15, 1, 1),
78
79SOC_SINGLE("Mic Volume", AC97_MIC, 0, 31, 1),
80SOC_SINGLE("Mic Switch", AC97_MIC, 15, 1, 1),
81
82SOC_SINGLE("Stereo Mic Switch", AC97_AD_MISC, 6, 1, 0),
83SOC_DOUBLE("Line HP Swap Switch", AC97_AD_MISC, 10, 5, 1, 0),
84
85SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
86SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
87
88SOC_ENUM("Capture Source", ad1980_cap_src),
89
90SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
91};
92
93/* add non dapm controls */
94static int ad1980_add_controls(struct snd_soc_codec *codec)
95{
96 int err, i;
97
98 for (i = 0; i < ARRAY_SIZE(ad1980_snd_ac97_controls); i++) {
99 err = snd_ctl_add(codec->card, snd_soc_cnew(
100 &ad1980_snd_ac97_controls[i], codec, NULL));
101 if (err < 0)
102 return err;
103 }
104 return 0;
105}
106
107static unsigned int ac97_read(struct snd_soc_codec *codec,
108 unsigned int reg)
109{
110 u16 *cache = codec->reg_cache;
111
112 switch (reg) {
113 case AC97_RESET:
114 case AC97_INT_PAGING:
115 case AC97_POWERDOWN:
116 case AC97_EXTENDED_STATUS:
117 case AC97_VENDOR_ID1:
118 case AC97_VENDOR_ID2:
119 return soc_ac97_ops.read(codec->ac97, reg);
120 default:
121 reg = reg >> 1;
122
123 if (reg >= (ARRAY_SIZE(ad1980_reg)))
124 return -EINVAL;
125
126 return cache[reg];
127 }
128}
129
130static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
131 unsigned int val)
132{
133 u16 *cache = codec->reg_cache;
134
135 soc_ac97_ops.write(codec->ac97, reg, val);
136 reg = reg >> 1;
137 if (reg < (ARRAY_SIZE(ad1980_reg)))
138 cache[reg] = val;
139
140 return 0;
141}
142
143struct snd_soc_dai ad1980_dai = {
144 .name = "AC97",
145 .playback = {
146 .stream_name = "Playback",
147 .channels_min = 2,
148 .channels_max = 2,
149 .rates = SNDRV_PCM_RATE_48000,
150 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
151 .capture = {
152 .stream_name = "Capture",
153 .channels_min = 2,
154 .channels_max = 2,
155 .rates = SNDRV_PCM_RATE_48000,
156 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
157};
158EXPORT_SYMBOL_GPL(ad1980_dai);
159
160static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
161{
162 u16 retry_cnt = 0;
163
164retry:
165 if (try_warm && soc_ac97_ops.warm_reset) {
166 soc_ac97_ops.warm_reset(codec->ac97);
167 if (ac97_read(codec, AC97_RESET) == 0x0090)
168 return 1;
169 }
170
171 soc_ac97_ops.reset(codec->ac97);
172 /* Set bit 16slot in register 74h, then every slot will has only 16
173 * bits. This command is sent out in 20bit mode, in which case the
174 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
175 ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
176
177 if (ac97_read(codec, AC97_RESET) != 0x0090)
178 goto err;
179 return 0;
180
181err:
182 while (retry_cnt++ < 10)
183 goto retry;
184
185 printk(KERN_ERR "AD1980 AC97 reset failed\n");
186 return -EIO;
187}
188
189static int ad1980_soc_probe(struct platform_device *pdev)
190{
191 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
192 struct snd_soc_codec *codec;
193 int ret = 0;
194 u16 vendor_id2;
195
196 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
197
198 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
199 if (socdev->codec == NULL)
200 return -ENOMEM;
201 codec = socdev->codec;
202 mutex_init(&codec->mutex);
203
204 codec->reg_cache =
205 kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
206 if (codec->reg_cache == NULL) {
207 ret = -ENOMEM;
208 goto cache_err;
209 }
210 memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
211 ARRAY_SIZE(ad1980_reg));
212 codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
213 codec->reg_cache_step = 2;
214 codec->name = "AD1980";
215 codec->owner = THIS_MODULE;
216 codec->dai = &ad1980_dai;
217 codec->num_dai = 1;
218 codec->write = ac97_write;
219 codec->read = ac97_read;
220 INIT_LIST_HEAD(&codec->dapm_widgets);
221 INIT_LIST_HEAD(&codec->dapm_paths);
222
223 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
224 if (ret < 0) {
225 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
226 goto codec_err;
227 }
228
229 /* register pcms */
230 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
231 if (ret < 0)
232 goto pcm_err;
233
234
235 ret = ad1980_reset(codec, 0);
236 if (ret < 0) {
237 printk(KERN_ERR "AC97 link error\n");
238 goto reset_err;
239 }
240
241 /* Read out vendor ID to make sure it is ad1980 */
242 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144)
243 goto reset_err;
244
245 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2);
246
247 if (vendor_id2 != 0x5370) {
248 if (vendor_id2 != 0x5374)
249 goto reset_err;
250 else
251 printk(KERN_WARNING "ad1980: "
252 "Found AD1981 - only 2/2 IN/OUT Channels "
253 "supported\n");
254 }
255
256 ac97_write(codec, AC97_MASTER, 0x0000); /* unmute line out volume */
257 ac97_write(codec, AC97_PCM, 0x0000); /* unmute PCM out volume */
258 ac97_write(codec, AC97_REC_GAIN, 0x0000);/* unmute record volume */
259
260 ad1980_add_controls(codec);
261 ret = snd_soc_register_card(socdev);
262 if (ret < 0) {
263 printk(KERN_ERR "ad1980: failed to register card\n");
264 goto reset_err;
265 }
266
267 return 0;
268
269reset_err:
270 snd_soc_free_pcms(socdev);
271
272pcm_err:
273 snd_soc_free_ac97_codec(codec);
274
275codec_err:
276 kfree(codec->reg_cache);
277
278cache_err:
279 kfree(socdev->codec);
280 socdev->codec = NULL;
281 return ret;
282}
283
284static int ad1980_soc_remove(struct platform_device *pdev)
285{
286 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
287 struct snd_soc_codec *codec = socdev->codec;
288
289 if (codec == NULL)
290 return 0;
291
292 snd_soc_dapm_free(socdev);
293 snd_soc_free_pcms(socdev);
294 snd_soc_free_ac97_codec(codec);
295 kfree(codec->reg_cache);
296 kfree(codec);
297 return 0;
298}
299
300struct snd_soc_codec_device soc_codec_dev_ad1980 = {
301 .probe = ad1980_soc_probe,
302 .remove = ad1980_soc_remove,
303};
304EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980);
305
306MODULE_DESCRIPTION("ASoC ad1980 driver");
307MODULE_AUTHOR("Roy Huang, Cliff Cai");
308MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h
new file mode 100644
index 000000000000..db6c8500d66b
--- /dev/null
+++ b/sound/soc/codecs/ad1980.h
@@ -0,0 +1,23 @@
1/*
2 * ad1980.h -- ad1980 Soc Audio driver
3 */
4
5#ifndef _AD1980_H
6#define _AD1980_H
7/* Bit definition of Power-Down Control/Status Register */
8#define ADC 0x0001
9#define DAC 0x0002
10#define ANL 0x0004
11#define REF 0x0008
12#define PR0 0x0100
13#define PR1 0x0200
14#define PR2 0x0400
15#define PR3 0x0800
16#define PR4 0x1000
17#define PR5 0x2000
18#define PR6 0x4000
19
20extern struct snd_soc_dai ad1980_dai;
21extern struct snd_soc_codec_device soc_codec_dev_ad1980;
22
23#endif
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
new file mode 100644
index 000000000000..37af8607b00a
--- /dev/null
+++ b/sound/soc/codecs/ad73311.c
@@ -0,0 +1,107 @@
1/*
2 * ad73311.c -- ALSA Soc AD73311 codec support
3 *
4 * Copyright: Analog Device Inc.
5 * Author: Cliff Cai <cliff.cai@analog.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 * Revision history
13 * 25th Sep 2008 Initial version.
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/version.h>
19#include <linux/kernel.h>
20#include <linux/device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/ac97_codec.h>
24#include <sound/initval.h>
25#include <sound/soc.h>
26
27#include "ad73311.h"
28
29struct snd_soc_dai ad73311_dai = {
30 .name = "AD73311",
31 .playback = {
32 .stream_name = "Playback",
33 .channels_min = 1,
34 .channels_max = 1,
35 .rates = SNDRV_PCM_RATE_8000,
36 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
37 .capture = {
38 .stream_name = "Capture",
39 .channels_min = 1,
40 .channels_max = 1,
41 .rates = SNDRV_PCM_RATE_8000,
42 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
43};
44EXPORT_SYMBOL_GPL(ad73311_dai);
45
46static int ad73311_soc_probe(struct platform_device *pdev)
47{
48 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
49 struct snd_soc_codec *codec;
50 int ret = 0;
51
52 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
53 if (codec == NULL)
54 return -ENOMEM;
55 mutex_init(&codec->mutex);
56 codec->name = "AD73311";
57 codec->owner = THIS_MODULE;
58 codec->dai = &ad73311_dai;
59 codec->num_dai = 1;
60 socdev->codec = codec;
61 INIT_LIST_HEAD(&codec->dapm_widgets);
62 INIT_LIST_HEAD(&codec->dapm_paths);
63
64 /* register pcms */
65 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
66 if (ret < 0) {
67 printk(KERN_ERR "ad73311: failed to create pcms\n");
68 goto pcm_err;
69 }
70
71 ret = snd_soc_register_card(socdev);
72 if (ret < 0) {
73 printk(KERN_ERR "ad73311: failed to register card\n");
74 goto register_err;
75 }
76
77 return ret;
78
79register_err:
80 snd_soc_free_pcms(socdev);
81pcm_err:
82 kfree(socdev->codec);
83 socdev->codec = NULL;
84 return ret;
85}
86
87static int ad73311_soc_remove(struct platform_device *pdev)
88{
89 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
90 struct snd_soc_codec *codec = socdev->codec;
91
92 if (codec == NULL)
93 return 0;
94 snd_soc_free_pcms(socdev);
95 kfree(codec);
96 return 0;
97}
98
99struct snd_soc_codec_device soc_codec_dev_ad73311 = {
100 .probe = ad73311_soc_probe,
101 .remove = ad73311_soc_remove,
102};
103EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
104
105MODULE_DESCRIPTION("ASoC ad73311 driver");
106MODULE_AUTHOR("Cliff Cai ");
107MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad73311.h b/sound/soc/codecs/ad73311.h
new file mode 100644
index 000000000000..507ce0c30edf
--- /dev/null
+++ b/sound/soc/codecs/ad73311.h
@@ -0,0 +1,90 @@
1/*
2 * File: sound/soc/codec/ad73311.h
3 * Based on:
4 * Author: Cliff Cai <cliff.cai@analog.com>
5 *
6 * Created: Thur Sep 25, 2008
7 * Description: definitions for AD73311 registers
8 *
9 *
10 * Modified:
11 * Copyright 2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#ifndef __AD73311_H__
32#define __AD73311_H__
33
34#define AD_CONTROL 0x8000
35#define AD_DATA 0x0000
36#define AD_READ 0x4000
37#define AD_WRITE 0x0000
38
39/* Control register A */
40#define CTRL_REG_A (0 << 8)
41
42#define REGA_MODE_PRO 0x00
43#define REGA_MODE_DATA 0x01
44#define REGA_MODE_MIXED 0x03
45#define REGA_DLB 0x04
46#define REGA_SLB 0x08
47#define REGA_DEVC(x) ((x & 0x7) << 4)
48#define REGA_RESET 0x80
49
50/* Control register B */
51#define CTRL_REG_B (1 << 8)
52
53#define REGB_DIRATE(x) (x & 0x3)
54#define REGB_SCDIV(x) ((x & 0x3) << 2)
55#define REGB_MCDIV(x) ((x & 0x7) << 4)
56#define REGB_CEE (1 << 7)
57
58/* Control register C */
59#define CTRL_REG_C (2 << 8)
60
61#define REGC_PUDEV (1 << 0)
62#define REGC_PUADC (1 << 3)
63#define REGC_PUDAC (1 << 4)
64#define REGC_PUREF (1 << 5)
65#define REGC_REFUSE (1 << 6)
66
67/* Control register D */
68#define CTRL_REG_D (3 << 8)
69
70#define REGD_IGS(x) (x & 0x7)
71#define REGD_RMOD (1 << 3)
72#define REGD_OGS(x) ((x & 0x7) << 4)
73#define REGD_MUTE (x << 7)
74
75/* Control register E */
76#define CTRL_REG_E (4 << 8)
77
78#define REGE_DA(x) (x & 0x1f)
79#define REGE_IBYP (1 << 5)
80
81/* Control register F */
82#define CTRL_REG_F (5 << 8)
83
84#define REGF_SEEN (1 << 5)
85#define REGF_INV (1 << 6)
86#define REGF_ALB (1 << 7)
87
88extern struct snd_soc_dai ad73311_dai;
89extern struct snd_soc_codec_device soc_codec_dev_ad73311;
90#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 7da9f467b7b8..2a89b5888e11 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -28,7 +28,6 @@
28 28
29#include "ak4535.h" 29#include "ak4535.h"
30 30
31#define AUDIO_NAME "ak4535"
32#define AK4535_VERSION "0.3" 31#define AK4535_VERSION "0.3"
33 32
34struct snd_soc_codec_device soc_codec_dev_ak4535; 33struct snd_soc_codec_device soc_codec_dev_ak4535;
@@ -535,87 +534,85 @@ static struct snd_soc_device *ak4535_socdev;
535 534
536#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 535#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
537 536
538#define I2C_DRIVERID_AK4535 0xfefe /* liam - need a proper id */ 537static int ak4535_i2c_probe(struct i2c_client *i2c,
539 538 const struct i2c_device_id *id)
540static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
541
542/* Magic definition of all other variables and things */
543I2C_CLIENT_INSMOD;
544
545static struct i2c_driver ak4535_i2c_driver;
546static struct i2c_client client_template;
547
548/* If the i2c layer weren't so broken, we could pass this kind of data
549 around */
550static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
551{ 539{
552 struct snd_soc_device *socdev = ak4535_socdev; 540 struct snd_soc_device *socdev = ak4535_socdev;
553 struct ak4535_setup_data *setup = socdev->codec_data;
554 struct snd_soc_codec *codec = socdev->codec; 541 struct snd_soc_codec *codec = socdev->codec;
555 struct i2c_client *i2c;
556 int ret; 542 int ret;
557 543
558 if (addr != setup->i2c_address)
559 return -ENODEV;
560
561 client_template.adapter = adap;
562 client_template.addr = addr;
563
564 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
565 if (i2c == NULL)
566 return -ENOMEM;
567
568 i2c_set_clientdata(i2c, codec); 544 i2c_set_clientdata(i2c, codec);
569 codec->control_data = i2c; 545 codec->control_data = i2c;
570 546
571 ret = i2c_attach_client(i2c);
572 if (ret < 0) {
573 printk(KERN_ERR "failed to attach codec at addr %x\n", addr);
574 goto err;
575 }
576
577 ret = ak4535_init(socdev); 547 ret = ak4535_init(socdev);
578 if (ret < 0) { 548 if (ret < 0)
579 printk(KERN_ERR "failed to initialise AK4535\n"); 549 printk(KERN_ERR "failed to initialise AK4535\n");
580 goto err;
581 }
582 return ret;
583 550
584err:
585 kfree(i2c);
586 return ret; 551 return ret;
587} 552}
588 553
589static int ak4535_i2c_detach(struct i2c_client *client) 554static int ak4535_i2c_remove(struct i2c_client *client)
590{ 555{
591 struct snd_soc_codec *codec = i2c_get_clientdata(client); 556 struct snd_soc_codec *codec = i2c_get_clientdata(client);
592 i2c_detach_client(client);
593 kfree(codec->reg_cache); 557 kfree(codec->reg_cache);
594 kfree(client);
595 return 0; 558 return 0;
596} 559}
597 560
598static int ak4535_i2c_attach(struct i2c_adapter *adap) 561static const struct i2c_device_id ak4535_i2c_id[] = {
599{ 562 { "ak4535", 0 },
600 return i2c_probe(adap, &addr_data, ak4535_codec_probe); 563 { }
601} 564};
565MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
602 566
603/* corgi i2c codec control layer */
604static struct i2c_driver ak4535_i2c_driver = { 567static struct i2c_driver ak4535_i2c_driver = {
605 .driver = { 568 .driver = {
606 .name = "AK4535 I2C Codec", 569 .name = "AK4535 I2C Codec",
607 .owner = THIS_MODULE, 570 .owner = THIS_MODULE,
608 }, 571 },
609 .id = I2C_DRIVERID_AK4535, 572 .probe = ak4535_i2c_probe,
610 .attach_adapter = ak4535_i2c_attach, 573 .remove = ak4535_i2c_remove,
611 .detach_client = ak4535_i2c_detach, 574 .id_table = ak4535_i2c_id,
612 .command = NULL,
613}; 575};
614 576
615static struct i2c_client client_template = { 577static int ak4535_add_i2c_device(struct platform_device *pdev,
616 .name = "AK4535", 578 const struct ak4535_setup_data *setup)
617 .driver = &ak4535_i2c_driver, 579{
618}; 580 struct i2c_board_info info;
581 struct i2c_adapter *adapter;
582 struct i2c_client *client;
583 int ret;
584
585 ret = i2c_add_driver(&ak4535_i2c_driver);
586 if (ret != 0) {
587 dev_err(&pdev->dev, "can't add i2c driver\n");
588 return ret;
589 }
590
591 memset(&info, 0, sizeof(struct i2c_board_info));
592 info.addr = setup->i2c_address;
593 strlcpy(info.type, "ak4535", I2C_NAME_SIZE);
594
595 adapter = i2c_get_adapter(setup->i2c_bus);
596 if (!adapter) {
597 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
598 setup->i2c_bus);
599 goto err_driver;
600 }
601
602 client = i2c_new_device(adapter, &info);
603 i2c_put_adapter(adapter);
604 if (!client) {
605 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
606 (unsigned int)info.addr);
607 goto err_driver;
608 }
609
610 return 0;
611
612err_driver:
613 i2c_del_driver(&ak4535_i2c_driver);
614 return -ENODEV;
615}
619#endif 616#endif
620 617
621static int ak4535_probe(struct platform_device *pdev) 618static int ak4535_probe(struct platform_device *pdev)
@@ -624,7 +621,7 @@ static int ak4535_probe(struct platform_device *pdev)
624 struct ak4535_setup_data *setup; 621 struct ak4535_setup_data *setup;
625 struct snd_soc_codec *codec; 622 struct snd_soc_codec *codec;
626 struct ak4535_priv *ak4535; 623 struct ak4535_priv *ak4535;
627 int ret = 0; 624 int ret;
628 625
629 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); 626 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
630 627
@@ -646,17 +643,14 @@ static int ak4535_probe(struct platform_device *pdev)
646 INIT_LIST_HEAD(&codec->dapm_paths); 643 INIT_LIST_HEAD(&codec->dapm_paths);
647 644
648 ak4535_socdev = socdev; 645 ak4535_socdev = socdev;
646 ret = -ENODEV;
647
649#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 648#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
650 if (setup->i2c_address) { 649 if (setup->i2c_address) {
651 normal_i2c[0] = setup->i2c_address;
652 codec->hw_write = (hw_write_t)i2c_master_send; 650 codec->hw_write = (hw_write_t)i2c_master_send;
653 codec->hw_read = (hw_read_t)i2c_master_recv; 651 codec->hw_read = (hw_read_t)i2c_master_recv;
654 ret = i2c_add_driver(&ak4535_i2c_driver); 652 ret = ak4535_add_i2c_device(pdev, setup);
655 if (ret != 0)
656 printk(KERN_ERR "can't add i2c driver");
657 } 653 }
658#else
659 /* Add other interfaces here */
660#endif 654#endif
661 655
662 if (ret != 0) { 656 if (ret != 0) {
@@ -678,6 +672,7 @@ static int ak4535_remove(struct platform_device *pdev)
678 snd_soc_free_pcms(socdev); 672 snd_soc_free_pcms(socdev);
679 snd_soc_dapm_free(socdev); 673 snd_soc_dapm_free(socdev);
680#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 674#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
675 i2c_unregister_device(codec->control_data);
681 i2c_del_driver(&ak4535_i2c_driver); 676 i2c_del_driver(&ak4535_i2c_driver);
682#endif 677#endif
683 kfree(codec->private_data); 678 kfree(codec->private_data);
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index e9fe30e2c056..c7a58703ea39 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -37,6 +37,7 @@
37#define AK4535_CACHEREGNUM 0x10 37#define AK4535_CACHEREGNUM 0x10
38 38
39struct ak4535_setup_data { 39struct ak4535_setup_data {
40 int i2c_bus;
40 unsigned short i2c_address; 41 unsigned short i2c_address;
41}; 42};
42 43
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 9deb8c74fdfd..0bbd94501d7e 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -490,34 +490,7 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
490 490
491#endif 491#endif
492 492
493static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind); 493static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
494
495/*
496 * Notify the driver that a new I2C bus has been found.
497 *
498 * This function is called for each I2C bus in the system. The function
499 * then asks the I2C subsystem to probe that bus at the addresses on which
500 * our device (the CS4270) could exist. If a device is found at one of
501 * those addresses, then our probe function (cs4270_i2c_probe) is called.
502 */
503static int cs4270_i2c_attach(struct i2c_adapter *adapter)
504{
505 return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
506}
507
508static int cs4270_i2c_detach(struct i2c_client *client)
509{
510 struct snd_soc_codec *codec = i2c_get_clientdata(client);
511
512 i2c_detach_client(client);
513 codec->control_data = NULL;
514
515 kfree(codec->reg_cache);
516 codec->reg_cache = NULL;
517
518 kfree(client);
519 return 0;
520}
521 494
522/* A list of non-DAPM controls that the CS4270 supports */ 495/* A list of non-DAPM controls that the CS4270 supports */
523static const struct snd_kcontrol_new cs4270_snd_controls[] = { 496static const struct snd_kcontrol_new cs4270_snd_controls[] = {
@@ -525,14 +498,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
525 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) 498 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
526}; 499};
527 500
501static const struct i2c_device_id cs4270_id[] = {
502 {"cs4270", 0},
503 {}
504};
505MODULE_DEVICE_TABLE(i2c, cs4270_id);
506
528static struct i2c_driver cs4270_i2c_driver = { 507static struct i2c_driver cs4270_i2c_driver = {
529 .driver = { 508 .driver = {
530 .name = "CS4270 I2C", 509 .name = "CS4270 I2C",
531 .owner = THIS_MODULE, 510 .owner = THIS_MODULE,
532 }, 511 },
533 .id = I2C_DRIVERID_CS4270, 512 .id_table = cs4270_id,
534 .attach_adapter = cs4270_i2c_attach, 513 .probe = cs4270_i2c_probe,
535 .detach_client = cs4270_i2c_detach,
536}; 514};
537 515
538/* 516/*
@@ -561,11 +539,11 @@ static struct snd_soc_device *cs4270_socdev;
561 * Note: snd_soc_new_pcms() must be called before this function can be called, 539 * Note: snd_soc_new_pcms() must be called before this function can be called,
562 * because of snd_ctl_add(). 540 * because of snd_ctl_add().
563 */ 541 */
564static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) 542static int cs4270_i2c_probe(struct i2c_client *i2c_client,
543 const struct i2c_device_id *id)
565{ 544{
566 struct snd_soc_device *socdev = cs4270_socdev; 545 struct snd_soc_device *socdev = cs4270_socdev;
567 struct snd_soc_codec *codec = socdev->codec; 546 struct snd_soc_codec *codec = socdev->codec;
568 struct i2c_client *i2c_client = NULL;
569 int i; 547 int i;
570 int ret = 0; 548 int ret = 0;
571 549
@@ -578,12 +556,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
578 556
579 /* Note: codec_dai->codec is NULL here */ 557 /* Note: codec_dai->codec is NULL here */
580 558
581 i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
582 if (!i2c_client) {
583 printk(KERN_ERR "cs4270: could not allocate I2C client\n");
584 return -ENOMEM;
585 }
586
587 codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL); 559 codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
588 if (!codec->reg_cache) { 560 if (!codec->reg_cache) {
589 printk(KERN_ERR "cs4270: could not allocate register cache\n"); 561 printk(KERN_ERR "cs4270: could not allocate register cache\n");
@@ -591,13 +563,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
591 goto error; 563 goto error;
592 } 564 }
593 565
594 i2c_set_clientdata(i2c_client, codec);
595 strcpy(i2c_client->name, "CS4270");
596
597 i2c_client->driver = &cs4270_i2c_driver;
598 i2c_client->adapter = adapter;
599 i2c_client->addr = addr;
600
601 /* Verify that we have a CS4270 */ 566 /* Verify that we have a CS4270 */
602 567
603 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); 568 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -612,18 +577,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
612 goto error; 577 goto error;
613 } 578 }
614 579
615 printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr); 580 printk(KERN_INFO "cs4270: found device at I2C address %X\n",
581 i2c_client->addr);
616 printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF); 582 printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
617 583
618 /* Tell the I2C layer a new client has arrived */
619
620 ret = i2c_attach_client(i2c_client);
621 if (ret) {
622 printk(KERN_ERR "cs4270: could not attach codec, "
623 "I2C address %x, error code %i\n", addr, ret);
624 goto error;
625 }
626
627 codec->control_data = i2c_client; 584 codec->control_data = i2c_client;
628 codec->read = cs4270_read_reg_cache; 585 codec->read = cs4270_read_reg_cache;
629 codec->write = cs4270_i2c_write; 586 codec->write = cs4270_i2c_write;
@@ -648,20 +605,17 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
648 goto error; 605 goto error;
649 } 606 }
650 607
608 i2c_set_clientdata(i2c_client, codec);
609
651 return 0; 610 return 0;
652 611
653error: 612error:
654 if (codec->control_data) { 613 codec->control_data = NULL;
655 i2c_detach_client(i2c_client);
656 codec->control_data = NULL;
657 }
658 614
659 kfree(codec->reg_cache); 615 kfree(codec->reg_cache);
660 codec->reg_cache = NULL; 616 codec->reg_cache = NULL;
661 codec->reg_cache_size = 0; 617 codec->reg_cache_size = 0;
662 618
663 kfree(i2c_client);
664
665 return ret; 619 return ret;
666} 620}
667 621
@@ -727,7 +681,7 @@ static int cs4270_probe(struct platform_device *pdev)
727 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 681 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
728 if (ret < 0) { 682 if (ret < 0) {
729 printk(KERN_ERR "cs4270: failed to create PCMs\n"); 683 printk(KERN_ERR "cs4270: failed to create PCMs\n");
730 return ret; 684 goto error_free_codec;
731 } 685 }
732 686
733#ifdef USE_I2C 687#ifdef USE_I2C
@@ -736,8 +690,7 @@ static int cs4270_probe(struct platform_device *pdev)
736 ret = i2c_add_driver(&cs4270_i2c_driver); 690 ret = i2c_add_driver(&cs4270_i2c_driver);
737 if (ret) { 691 if (ret) {
738 printk(KERN_ERR "cs4270: failed to attach driver"); 692 printk(KERN_ERR "cs4270: failed to attach driver");
739 snd_soc_free_pcms(socdev); 693 goto error_free_pcms;
740 return ret;
741 } 694 }
742 695
743 /* Did we find a CS4270 on the I2C bus? */ 696 /* Did we find a CS4270 on the I2C bus? */
@@ -759,10 +712,23 @@ static int cs4270_probe(struct platform_device *pdev)
759 ret = snd_soc_register_card(socdev); 712 ret = snd_soc_register_card(socdev);
760 if (ret < 0) { 713 if (ret < 0) {
761 printk(KERN_ERR "cs4270: failed to register card\n"); 714 printk(KERN_ERR "cs4270: failed to register card\n");
762 snd_soc_free_pcms(socdev); 715 goto error_del_driver;
763 return ret;
764 } 716 }
765 717
718 return 0;
719
720error_del_driver:
721#ifdef USE_I2C
722 i2c_del_driver(&cs4270_i2c_driver);
723
724error_free_pcms:
725#endif
726 snd_soc_free_pcms(socdev);
727
728error_free_codec:
729 kfree(socdev->codec);
730 socdev->codec = NULL;
731
766 return ret; 732 return ret;
767} 733}
768 734
@@ -773,8 +739,7 @@ static int cs4270_remove(struct platform_device *pdev)
773 snd_soc_free_pcms(socdev); 739 snd_soc_free_pcms(socdev);
774 740
775#ifdef USE_I2C 741#ifdef USE_I2C
776 if (socdev->codec->control_data) 742 i2c_del_driver(&cs4270_i2c_driver);
777 i2c_del_driver(&cs4270_i2c_driver);
778#endif 743#endif
779 744
780 kfree(socdev->codec); 745 kfree(socdev->codec);
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
new file mode 100644
index 000000000000..44ef0dacd564
--- /dev/null
+++ b/sound/soc/codecs/ssm2602.c
@@ -0,0 +1,775 @@
1/*
2 * File: sound/soc/codecs/ssm2602.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: Driver for ssm2602 sound chip
7 *
8 * Modified:
9 * Copyright 2008 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/module.h>
30#include <linux/moduleparam.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/pm.h>
34#include <linux/i2c.h>
35#include <linux/platform_device.h>
36#include <sound/core.h>
37#include <sound/pcm.h>
38#include <sound/pcm_params.h>
39#include <sound/soc.h>
40#include <sound/soc-dapm.h>
41#include <sound/initval.h>
42
43#include "ssm2602.h"
44
45#define SSM2602_VERSION "0.1"
46
47struct snd_soc_codec_device soc_codec_dev_ssm2602;
48
49/* codec private data */
50struct ssm2602_priv {
51 unsigned int sysclk;
52 struct snd_pcm_substream *master_substream;
53 struct snd_pcm_substream *slave_substream;
54};
55
56/*
57 * ssm2602 register cache
58 * We can't read the ssm2602 register space when we are
59 * using 2 wire for device control, so we cache them instead.
60 * There is no point in caching the reset register
61 */
62static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
63 0x0017, 0x0017, 0x0079, 0x0079,
64 0x0000, 0x0000, 0x0000, 0x000a,
65 0x0000, 0x0000
66};
67
68/*
69 * read ssm2602 register cache
70 */
71static inline unsigned int ssm2602_read_reg_cache(struct snd_soc_codec *codec,
72 unsigned int reg)
73{
74 u16 *cache = codec->reg_cache;
75 if (reg == SSM2602_RESET)
76 return 0;
77 if (reg >= SSM2602_CACHEREGNUM)
78 return -1;
79 return cache[reg];
80}
81
82/*
83 * write ssm2602 register cache
84 */
85static inline void ssm2602_write_reg_cache(struct snd_soc_codec *codec,
86 u16 reg, unsigned int value)
87{
88 u16 *cache = codec->reg_cache;
89 if (reg >= SSM2602_CACHEREGNUM)
90 return;
91 cache[reg] = value;
92}
93
94/*
95 * write to the ssm2602 register space
96 */
97static int ssm2602_write(struct snd_soc_codec *codec, unsigned int reg,
98 unsigned int value)
99{
100 u8 data[2];
101
102 /* data is
103 * D15..D9 ssm2602 register offset
104 * D8...D0 register data
105 */
106 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
107 data[1] = value & 0x00ff;
108
109 ssm2602_write_reg_cache(codec, reg, value);
110 if (codec->hw_write(codec->control_data, data, 2) == 2)
111 return 0;
112 else
113 return -EIO;
114}
115
116#define ssm2602_reset(c) ssm2602_write(c, SSM2602_RESET, 0)
117
118/*Appending several "None"s just for OSS mixer use*/
119static const char *ssm2602_input_select[] = {
120 "Line", "Mic", "None", "None", "None",
121 "None", "None", "None",
122};
123
124static const char *ssm2602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
125
126static const struct soc_enum ssm2602_enum[] = {
127 SOC_ENUM_SINGLE(SSM2602_APANA, 2, 2, ssm2602_input_select),
128 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph),
129};
130
131static const struct snd_kcontrol_new ssm2602_snd_controls[] = {
132
133SOC_DOUBLE_R("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V,
134 0, 127, 0),
135SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
136 7, 1, 0),
137
138SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0),
139SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
140
141SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
142SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
143
144SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1),
145
146SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1),
147SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0),
148
149SOC_ENUM("Capture Source", ssm2602_enum[0]),
150
151SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
152};
153
154/* add non dapm controls */
155static int ssm2602_add_controls(struct snd_soc_codec *codec)
156{
157 int err, i;
158
159 for (i = 0; i < ARRAY_SIZE(ssm2602_snd_controls); i++) {
160 err = snd_ctl_add(codec->card,
161 snd_soc_cnew(&ssm2602_snd_controls[i], codec, NULL));
162 if (err < 0)
163 return err;
164 }
165
166 return 0;
167}
168
169/* Output Mixer */
170static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = {
171SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
172SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
173SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0),
174};
175
176/* Input mux */
177static const struct snd_kcontrol_new ssm2602_input_mux_controls =
178SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]);
179
180static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = {
181SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
182 &ssm2602_output_mixer_controls[0],
183 ARRAY_SIZE(ssm2602_output_mixer_controls)),
184SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1),
185SND_SOC_DAPM_OUTPUT("LOUT"),
186SND_SOC_DAPM_OUTPUT("LHPOUT"),
187SND_SOC_DAPM_OUTPUT("ROUT"),
188SND_SOC_DAPM_OUTPUT("RHPOUT"),
189SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1),
190SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls),
191SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
192SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1),
193SND_SOC_DAPM_INPUT("MICIN"),
194SND_SOC_DAPM_INPUT("RLINEIN"),
195SND_SOC_DAPM_INPUT("LLINEIN"),
196};
197
198static const struct snd_soc_dapm_route audio_conn[] = {
199 /* output mixer */
200 {"Output Mixer", "Line Bypass Switch", "Line Input"},
201 {"Output Mixer", "HiFi Playback Switch", "DAC"},
202 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
203
204 /* outputs */
205 {"RHPOUT", NULL, "Output Mixer"},
206 {"ROUT", NULL, "Output Mixer"},
207 {"LHPOUT", NULL, "Output Mixer"},
208 {"LOUT", NULL, "Output Mixer"},
209
210 /* input mux */
211 {"Input Mux", "Line", "Line Input"},
212 {"Input Mux", "Mic", "Mic Bias"},
213 {"ADC", NULL, "Input Mux"},
214
215 /* inputs */
216 {"Line Input", NULL, "LLINEIN"},
217 {"Line Input", NULL, "RLINEIN"},
218 {"Mic Bias", NULL, "MICIN"},
219};
220
221static int ssm2602_add_widgets(struct snd_soc_codec *codec)
222{
223 snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets,
224 ARRAY_SIZE(ssm2602_dapm_widgets));
225
226 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
227
228 snd_soc_dapm_new_widgets(codec);
229 return 0;
230}
231
232struct _coeff_div {
233 u32 mclk;
234 u32 rate;
235 u16 fs;
236 u8 sr:4;
237 u8 bosr:1;
238 u8 usb:1;
239};
240
241/* codec mclk clock divider coefficients */
242static const struct _coeff_div coeff_div[] = {
243 /* 48k */
244 {12288000, 48000, 256, 0x0, 0x0, 0x0},
245 {18432000, 48000, 384, 0x0, 0x1, 0x0},
246 {12000000, 48000, 250, 0x0, 0x0, 0x1},
247
248 /* 32k */
249 {12288000, 32000, 384, 0x6, 0x0, 0x0},
250 {18432000, 32000, 576, 0x6, 0x1, 0x0},
251 {12000000, 32000, 375, 0x6, 0x0, 0x1},
252
253 /* 8k */
254 {12288000, 8000, 1536, 0x3, 0x0, 0x0},
255 {18432000, 8000, 2304, 0x3, 0x1, 0x0},
256 {11289600, 8000, 1408, 0xb, 0x0, 0x0},
257 {16934400, 8000, 2112, 0xb, 0x1, 0x0},
258 {12000000, 8000, 1500, 0x3, 0x0, 0x1},
259
260 /* 96k */
261 {12288000, 96000, 128, 0x7, 0x0, 0x0},
262 {18432000, 96000, 192, 0x7, 0x1, 0x0},
263 {12000000, 96000, 125, 0x7, 0x0, 0x1},
264
265 /* 44.1k */
266 {11289600, 44100, 256, 0x8, 0x0, 0x0},
267 {16934400, 44100, 384, 0x8, 0x1, 0x0},
268 {12000000, 44100, 272, 0x8, 0x1, 0x1},
269
270 /* 88.2k */
271 {11289600, 88200, 128, 0xf, 0x0, 0x0},
272 {16934400, 88200, 192, 0xf, 0x1, 0x0},
273 {12000000, 88200, 136, 0xf, 0x1, 0x1},
274};
275
276static inline int get_coeff(int mclk, int rate)
277{
278 int i;
279
280 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
281 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
282 return i;
283 }
284 return i;
285}
286
287static int ssm2602_hw_params(struct snd_pcm_substream *substream,
288 struct snd_pcm_hw_params *params)
289{
290 u16 srate;
291 struct snd_soc_pcm_runtime *rtd = substream->private_data;
292 struct snd_soc_device *socdev = rtd->socdev;
293 struct snd_soc_codec *codec = socdev->codec;
294 struct ssm2602_priv *ssm2602 = codec->private_data;
295 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
296 int i = get_coeff(ssm2602->sysclk, params_rate(params));
297
298 /*no match is found*/
299 if (i == ARRAY_SIZE(coeff_div))
300 return -EINVAL;
301
302 srate = (coeff_div[i].sr << 2) |
303 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
304
305 ssm2602_write(codec, SSM2602_ACTIVE, 0);
306 ssm2602_write(codec, SSM2602_SRATE, srate);
307
308 /* bit size */
309 switch (params_format(params)) {
310 case SNDRV_PCM_FORMAT_S16_LE:
311 break;
312 case SNDRV_PCM_FORMAT_S20_3LE:
313 iface |= 0x0004;
314 break;
315 case SNDRV_PCM_FORMAT_S24_LE:
316 iface |= 0x0008;
317 break;
318 case SNDRV_PCM_FORMAT_S32_LE:
319 iface |= 0x000c;
320 break;
321 }
322 ssm2602_write(codec, SSM2602_IFACE, iface);
323 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
324 return 0;
325}
326
327static int ssm2602_startup(struct snd_pcm_substream *substream)
328{
329 struct snd_soc_pcm_runtime *rtd = substream->private_data;
330 struct snd_soc_device *socdev = rtd->socdev;
331 struct snd_soc_codec *codec = socdev->codec;
332 struct ssm2602_priv *ssm2602 = codec->private_data;
333 struct snd_pcm_runtime *master_runtime;
334
335 /* The DAI has shared clocks so if we already have a playback or
336 * capture going then constrain this substream to match it.
337 */
338 if (ssm2602->master_substream) {
339 master_runtime = ssm2602->master_substream->runtime;
340 snd_pcm_hw_constraint_minmax(substream->runtime,
341 SNDRV_PCM_HW_PARAM_RATE,
342 master_runtime->rate,
343 master_runtime->rate);
344
345 snd_pcm_hw_constraint_minmax(substream->runtime,
346 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
347 master_runtime->sample_bits,
348 master_runtime->sample_bits);
349
350 ssm2602->slave_substream = substream;
351 } else
352 ssm2602->master_substream = substream;
353
354 return 0;
355}
356
357static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
358{
359 struct snd_soc_pcm_runtime *rtd = substream->private_data;
360 struct snd_soc_device *socdev = rtd->socdev;
361 struct snd_soc_codec *codec = socdev->codec;
362 /* set active */
363 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
364
365 return 0;
366}
367
368static void ssm2602_shutdown(struct snd_pcm_substream *substream)
369{
370 struct snd_soc_pcm_runtime *rtd = substream->private_data;
371 struct snd_soc_device *socdev = rtd->socdev;
372 struct snd_soc_codec *codec = socdev->codec;
373 /* deactivate */
374 if (!codec->active)
375 ssm2602_write(codec, SSM2602_ACTIVE, 0);
376}
377
378static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
379{
380 struct snd_soc_codec *codec = dai->codec;
381 u16 mute_reg = ssm2602_read_reg_cache(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE;
382 if (mute)
383 ssm2602_write(codec, SSM2602_APDIGI,
384 mute_reg | APDIGI_ENABLE_DAC_MUTE);
385 else
386 ssm2602_write(codec, SSM2602_APDIGI, mute_reg);
387 return 0;
388}
389
390static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
391 int clk_id, unsigned int freq, int dir)
392{
393 struct snd_soc_codec *codec = codec_dai->codec;
394 struct ssm2602_priv *ssm2602 = codec->private_data;
395 switch (freq) {
396 case 11289600:
397 case 12000000:
398 case 12288000:
399 case 16934400:
400 case 18432000:
401 ssm2602->sysclk = freq;
402 return 0;
403 }
404 return -EINVAL;
405}
406
407static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
408 unsigned int fmt)
409{
410 struct snd_soc_codec *codec = codec_dai->codec;
411 u16 iface = 0;
412
413 /* set master/slave audio interface */
414 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
415 case SND_SOC_DAIFMT_CBM_CFM:
416 iface |= 0x0040;
417 break;
418 case SND_SOC_DAIFMT_CBS_CFS:
419 break;
420 default:
421 return -EINVAL;
422 }
423
424 /* interface format */
425 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
426 case SND_SOC_DAIFMT_I2S:
427 iface |= 0x0002;
428 break;
429 case SND_SOC_DAIFMT_RIGHT_J:
430 break;
431 case SND_SOC_DAIFMT_LEFT_J:
432 iface |= 0x0001;
433 break;
434 case SND_SOC_DAIFMT_DSP_A:
435 iface |= 0x0003;
436 break;
437 case SND_SOC_DAIFMT_DSP_B:
438 iface |= 0x0013;
439 break;
440 default:
441 return -EINVAL;
442 }
443
444 /* clock inversion */
445 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
446 case SND_SOC_DAIFMT_NB_NF:
447 break;
448 case SND_SOC_DAIFMT_IB_IF:
449 iface |= 0x0090;
450 break;
451 case SND_SOC_DAIFMT_IB_NF:
452 iface |= 0x0080;
453 break;
454 case SND_SOC_DAIFMT_NB_IF:
455 iface |= 0x0010;
456 break;
457 default:
458 return -EINVAL;
459 }
460
461 /* set iface */
462 ssm2602_write(codec, SSM2602_IFACE, iface);
463 return 0;
464}
465
466static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
467 enum snd_soc_bias_level level)
468{
469 u16 reg = ssm2602_read_reg_cache(codec, SSM2602_PWR) & 0xff7f;
470
471 switch (level) {
472 case SND_SOC_BIAS_ON:
473 /* vref/mid, osc on, dac unmute */
474 ssm2602_write(codec, SSM2602_PWR, reg);
475 break;
476 case SND_SOC_BIAS_PREPARE:
477 break;
478 case SND_SOC_BIAS_STANDBY:
479 /* everything off except vref/vmid, */
480 ssm2602_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN);
481 break;
482 case SND_SOC_BIAS_OFF:
483 /* everything off, dac mute, inactive */
484 ssm2602_write(codec, SSM2602_ACTIVE, 0);
485 ssm2602_write(codec, SSM2602_PWR, 0xffff);
486 break;
487
488 }
489 codec->bias_level = level;
490 return 0;
491}
492
493#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
494 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
495 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
496 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
497 SNDRV_PCM_RATE_96000)
498
499struct snd_soc_dai ssm2602_dai = {
500 .name = "SSM2602",
501 .playback = {
502 .stream_name = "Playback",
503 .channels_min = 2,
504 .channels_max = 2,
505 .rates = SSM2602_RATES,
506 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
507 .capture = {
508 .stream_name = "Capture",
509 .channels_min = 2,
510 .channels_max = 2,
511 .rates = SSM2602_RATES,
512 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
513 .ops = {
514 .startup = ssm2602_startup,
515 .prepare = ssm2602_pcm_prepare,
516 .hw_params = ssm2602_hw_params,
517 .shutdown = ssm2602_shutdown,
518 },
519 .dai_ops = {
520 .digital_mute = ssm2602_mute,
521 .set_sysclk = ssm2602_set_dai_sysclk,
522 .set_fmt = ssm2602_set_dai_fmt,
523 }
524};
525EXPORT_SYMBOL_GPL(ssm2602_dai);
526
527static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
528{
529 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
530 struct snd_soc_codec *codec = socdev->codec;
531
532 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
533 return 0;
534}
535
536static int ssm2602_resume(struct platform_device *pdev)
537{
538 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
539 struct snd_soc_codec *codec = socdev->codec;
540 int i;
541 u8 data[2];
542 u16 *cache = codec->reg_cache;
543
544 /* Sync reg_cache with the hardware */
545 for (i = 0; i < ARRAY_SIZE(ssm2602_reg); i++) {
546 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
547 data[1] = cache[i] & 0x00ff;
548 codec->hw_write(codec->control_data, data, 2);
549 }
550 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
551 ssm2602_set_bias_level(codec, codec->suspend_bias_level);
552 return 0;
553}
554
555/*
556 * initialise the ssm2602 driver
557 * register the mixer and dsp interfaces with the kernel
558 */
559static int ssm2602_init(struct snd_soc_device *socdev)
560{
561 struct snd_soc_codec *codec = socdev->codec;
562 int reg, ret = 0;
563
564 codec->name = "SSM2602";
565 codec->owner = THIS_MODULE;
566 codec->read = ssm2602_read_reg_cache;
567 codec->write = ssm2602_write;
568 codec->set_bias_level = ssm2602_set_bias_level;
569 codec->dai = &ssm2602_dai;
570 codec->num_dai = 1;
571 codec->reg_cache_size = sizeof(ssm2602_reg);
572 codec->reg_cache = kmemdup(ssm2602_reg, sizeof(ssm2602_reg),
573 GFP_KERNEL);
574 if (codec->reg_cache == NULL)
575 return -ENOMEM;
576
577 ssm2602_reset(codec);
578
579 /* register pcms */
580 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
581 if (ret < 0) {
582 pr_err("ssm2602: failed to create pcms\n");
583 goto pcm_err;
584 }
585 /*power on device*/
586 ssm2602_write(codec, SSM2602_ACTIVE, 0);
587 /* set the update bits */
588 reg = ssm2602_read_reg_cache(codec, SSM2602_LINVOL);
589 ssm2602_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH);
590 reg = ssm2602_read_reg_cache(codec, SSM2602_RINVOL);
591 ssm2602_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH);
592 reg = ssm2602_read_reg_cache(codec, SSM2602_LOUT1V);
593 ssm2602_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
594 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V);
595 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
596 /*select Line in as default input*/
597 ssm2602_write(codec, SSM2602_APANA,
598 APANA_ENABLE_MIC_BOOST2 | APANA_SELECT_DAC |
599 APANA_ENABLE_MIC_BOOST);
600 ssm2602_write(codec, SSM2602_PWR, 0);
601
602 ssm2602_add_controls(codec);
603 ssm2602_add_widgets(codec);
604 ret = snd_soc_register_card(socdev);
605 if (ret < 0) {
606 pr_err("ssm2602: failed to register card\n");
607 goto card_err;
608 }
609
610 return ret;
611
612card_err:
613 snd_soc_free_pcms(socdev);
614 snd_soc_dapm_free(socdev);
615pcm_err:
616 kfree(codec->reg_cache);
617 return ret;
618}
619
620static struct snd_soc_device *ssm2602_socdev;
621
622#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
623/*
624 * ssm2602 2 wire address is determined by GPIO5
625 * state during powerup.
626 * low = 0x1a
627 * high = 0x1b
628 */
629static int ssm2602_i2c_probe(struct i2c_client *i2c,
630 const struct i2c_device_id *id)
631{
632 struct snd_soc_device *socdev = ssm2602_socdev;
633 struct snd_soc_codec *codec = socdev->codec;
634 int ret;
635
636 i2c_set_clientdata(i2c, codec);
637 codec->control_data = i2c;
638
639 ret = ssm2602_init(socdev);
640 if (ret < 0)
641 pr_err("failed to initialise SSM2602\n");
642
643 return ret;
644}
645
646static int ssm2602_i2c_remove(struct i2c_client *client)
647{
648 struct snd_soc_codec *codec = i2c_get_clientdata(client);
649 kfree(codec->reg_cache);
650 return 0;
651}
652
653static const struct i2c_device_id ssm2602_i2c_id[] = {
654 { "ssm2602", 0 },
655 { }
656};
657MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
658/* corgi i2c codec control layer */
659static struct i2c_driver ssm2602_i2c_driver = {
660 .driver = {
661 .name = "SSM2602 I2C Codec",
662 .owner = THIS_MODULE,
663 },
664 .probe = ssm2602_i2c_probe,
665 .remove = ssm2602_i2c_remove,
666 .id_table = ssm2602_i2c_id,
667};
668
669static int ssm2602_add_i2c_device(struct platform_device *pdev,
670 const struct ssm2602_setup_data *setup)
671{
672 struct i2c_board_info info;
673 struct i2c_adapter *adapter;
674 struct i2c_client *client;
675 int ret;
676
677 ret = i2c_add_driver(&ssm2602_i2c_driver);
678 if (ret != 0) {
679 dev_err(&pdev->dev, "can't add i2c driver\n");
680 return ret;
681 }
682 memset(&info, 0, sizeof(struct i2c_board_info));
683 info.addr = setup->i2c_address;
684 strlcpy(info.type, "ssm2602", I2C_NAME_SIZE);
685 adapter = i2c_get_adapter(setup->i2c_bus);
686 if (!adapter) {
687 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
688 setup->i2c_bus);
689 goto err_driver;
690 }
691 client = i2c_new_device(adapter, &info);
692 i2c_put_adapter(adapter);
693 if (!client) {
694 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
695 (unsigned int)info.addr);
696 goto err_driver;
697 }
698 return 0;
699err_driver:
700 i2c_del_driver(&ssm2602_i2c_driver);
701 return -ENODEV;
702}
703#endif
704
705static int ssm2602_probe(struct platform_device *pdev)
706{
707 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
708 struct ssm2602_setup_data *setup;
709 struct snd_soc_codec *codec;
710 struct ssm2602_priv *ssm2602;
711 int ret = 0;
712
713 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
714
715 setup = socdev->codec_data;
716 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
717 if (codec == NULL)
718 return -ENOMEM;
719
720 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
721 if (ssm2602 == NULL) {
722 kfree(codec);
723 return -ENOMEM;
724 }
725
726 codec->private_data = ssm2602;
727 socdev->codec = codec;
728 mutex_init(&codec->mutex);
729 INIT_LIST_HEAD(&codec->dapm_widgets);
730 INIT_LIST_HEAD(&codec->dapm_paths);
731
732 ssm2602_socdev = socdev;
733#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
734 if (setup->i2c_address) {
735 codec->hw_write = (hw_write_t)i2c_master_send;
736 ret = ssm2602_add_i2c_device(pdev, setup);
737 }
738#else
739 /* other interfaces */
740#endif
741 return ret;
742}
743
744/* remove everything here */
745static int ssm2602_remove(struct platform_device *pdev)
746{
747 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
748 struct snd_soc_codec *codec = socdev->codec;
749
750 if (codec->control_data)
751 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
752
753 snd_soc_free_pcms(socdev);
754 snd_soc_dapm_free(socdev);
755#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
756 i2c_unregister_device(codec->control_data);
757 i2c_del_driver(&ssm2602_i2c_driver);
758#endif
759 kfree(codec->private_data);
760 kfree(codec);
761
762 return 0;
763}
764
765struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
766 .probe = ssm2602_probe,
767 .remove = ssm2602_remove,
768 .suspend = ssm2602_suspend,
769 .resume = ssm2602_resume,
770};
771EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
772
773MODULE_DESCRIPTION("ASoC ssm2602 driver");
774MODULE_AUTHOR("Cliff Cai");
775MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
new file mode 100644
index 000000000000..f344e6d76e31
--- /dev/null
+++ b/sound/soc/codecs/ssm2602.h
@@ -0,0 +1,130 @@
1/*
2 * File: sound/soc/codecs/ssm2602.h
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 *
7 * Modified:
8 * Copyright 2008 Analog Devices Inc.
9 *
10 * Bugs: Enter bugs at http://blackfin.uclinux.org/
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 as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see the file COPYING, or write
24 * to the Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28#ifndef _SSM2602_H
29#define _SSM2602_H
30
31/* SSM2602 Codec Register definitions */
32
33#define SSM2602_LINVOL 0x00
34#define SSM2602_RINVOL 0x01
35#define SSM2602_LOUT1V 0x02
36#define SSM2602_ROUT1V 0x03
37#define SSM2602_APANA 0x04
38#define SSM2602_APDIGI 0x05
39#define SSM2602_PWR 0x06
40#define SSM2602_IFACE 0x07
41#define SSM2602_SRATE 0x08
42#define SSM2602_ACTIVE 0x09
43#define SSM2602_RESET 0x0f
44
45/*SSM2602 Codec Register Field definitions
46 *(Mask value to extract the corresponding Register field)
47 */
48
49/*Left ADC Volume Control (SSM2602_REG_LEFT_ADC_VOL)*/
50#define LINVOL_LIN_VOL 0x01F /* Left Channel PGA Volume control */
51#define LINVOL_LIN_ENABLE_MUTE 0x080 /* Left Channel Input Mute */
52#define LINVOL_LRIN_BOTH 0x100 /* Left Channel Line Input Volume update */
53
54/*Right ADC Volume Control (SSM2602_REG_RIGHT_ADC_VOL)*/
55#define RINVOL_RIN_VOL 0x01F /* Right Channel PGA Volume control */
56#define RINVOL_RIN_ENABLE_MUTE 0x080 /* Right Channel Input Mute */
57#define RINVOL_RLIN_BOTH 0x100 /* Right Channel Line Input Volume update */
58
59/*Left DAC Volume Control (SSM2602_REG_LEFT_DAC_VOL)*/
60#define LOUT1V_LHP_VOL 0x07F /* Left Channel Headphone volume control */
61#define LOUT1V_ENABLE_LZC 0x080 /* Left Channel Zero cross detect enable */
62#define LOUT1V_LRHP_BOTH 0x100 /* Left Channel Headphone volume update */
63
64/*Right DAC Volume Control (SSM2602_REG_RIGHT_DAC_VOL)*/
65#define ROUT1V_RHP_VOL 0x07F /* Right Channel Headphone volume control */
66#define ROUT1V_ENABLE_RZC 0x080 /* Right Channel Zero cross detect enable */
67#define ROUT1V_RLHP_BOTH 0x100 /* Right Channel Headphone volume update */
68
69/*Analogue Audio Path Control (SSM2602_REG_ANALOGUE_PATH)*/
70#define APANA_ENABLE_MIC_BOOST 0x001 /* Primary Microphone Amplifier gain booster control */
71#define APANA_ENABLE_MIC_MUTE 0x002 /* Microphone Mute Control */
72#define APANA_ADC_IN_SELECT 0x004 /* Microphone/Line IN select to ADC (1=MIC, 0=Line In) */
73#define APANA_ENABLE_BYPASS 0x008 /* Line input bypass to line output */
74#define APANA_SELECT_DAC 0x010 /* Select DAC (1=Select DAC, 0=Don't Select DAC) */
75#define APANA_ENABLE_SIDETONE 0x020 /* Enable/Disable Side Tone */
76#define APANA_SIDETONE_ATTN 0x0C0 /* Side Tone Attenuation */
77#define APANA_ENABLE_MIC_BOOST2 0x100 /* Secondary Microphone Amplifier gain booster control */
78
79/*Digital Audio Path Control (SSM2602_REG_DIGITAL_PATH)*/
80#define APDIGI_ENABLE_ADC_HPF 0x001 /* Enable/Disable ADC Highpass Filter */
81#define APDIGI_DE_EMPHASIS 0x006 /* De-Emphasis Control */
82#define APDIGI_ENABLE_DAC_MUTE 0x008 /* DAC Mute Control */
83#define APDIGI_STORE_OFFSET 0x010 /* Store/Clear DC offset when HPF is disabled */
84
85/*Power Down Control (SSM2602_REG_POWER)
86 *(1=Enable PowerDown, 0=Disable PowerDown)
87 */
88#define PWR_LINE_IN_PDN 0x001 /* Line Input Power Down */
89#define PWR_MIC_PDN 0x002 /* Microphone Input & Bias Power Down */
90#define PWR_ADC_PDN 0x004 /* ADC Power Down */
91#define PWR_DAC_PDN 0x008 /* DAC Power Down */
92#define PWR_OUT_PDN 0x010 /* Outputs Power Down */
93#define PWR_OSC_PDN 0x020 /* Oscillator Power Down */
94#define PWR_CLK_OUT_PDN 0x040 /* CLKOUT Power Down */
95#define PWR_POWER_OFF 0x080 /* POWEROFF Mode */
96
97/*Digital Audio Interface Format (SSM2602_REG_DIGITAL_IFACE)*/
98#define IFACE_IFACE_FORMAT 0x003 /* Digital Audio input format control */
99#define IFACE_AUDIO_DATA_LEN 0x00C /* Audio Data word length control */
100#define IFACE_DAC_LR_POLARITY 0x010 /* Polarity Control for clocks in RJ,LJ and I2S modes */
101#define IFACE_DAC_LR_SWAP 0x020 /* Swap DAC data control */
102#define IFACE_ENABLE_MASTER 0x040 /* Enable/Disable Master Mode */
103#define IFACE_BCLK_INVERT 0x080 /* Bit Clock Inversion control */
104
105/*Sampling Control (SSM2602_REG_SAMPLING_CTRL)*/
106#define SRATE_ENABLE_USB_MODE 0x001 /* Enable/Disable USB Mode */
107#define SRATE_BOS_RATE 0x002 /* Base Over-Sampling rate */
108#define SRATE_SAMPLE_RATE 0x03C /* Clock setting condition (Sampling rate control) */
109#define SRATE_CORECLK_DIV2 0x040 /* Core Clock divider select */
110#define SRATE_CLKOUT_DIV2 0x080 /* Clock Out divider select */
111
112/*Active Control (SSM2602_REG_ACTIVE_CTRL)*/
113#define ACTIVE_ACTIVATE_CODEC 0x001 /* Activate Codec Digital Audio Interface */
114
115/*********************************************************************/
116
117#define SSM2602_CACHEREGNUM 10
118
119#define SSM2602_SYSCLK 0
120#define SSM2602_DAI 0
121
122struct ssm2602_setup_data {
123 int i2c_bus;
124 unsigned short i2c_address;
125};
126
127extern struct snd_soc_dai ssm2602_dai;
128extern struct snd_soc_codec_device soc_codec_dev_ssm2602;
129
130#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
new file mode 100644
index 000000000000..44308dac9e18
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -0,0 +1,714 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
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 * Notes:
14 * The AIC23 is a driver for a low power stereo audio
15 * codec tlv320aic23
16 *
17 * The machine layer should disable unsupported inputs/outputs by
18 * snd_soc_dapm_disable_pin(codec, "LHPOUT"), etc.
19 */
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/platform_device.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h>
34#include <sound/initval.h>
35
36#include "tlv320aic23.h"
37
38#define AIC23_VERSION "0.1"
39
40struct tlv320aic23_srate_reg_info {
41 u32 sample_rate;
42 u8 control; /* SR3, SR2, SR1, SR0 and BOSR */
43 u8 divider; /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
44};
45
46/*
47 * AIC23 register cache
48 */
49static const u16 tlv320aic23_reg[] = {
50 0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */
51 0x001A, 0x0004, 0x0007, 0x0001, /* 4 */
52 0x0020, 0x0000, 0x0000, 0x0000, /* 8 */
53 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
54};
55
56/*
57 * read tlv320aic23 register cache
58 */
59static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
60 *codec, unsigned int reg)
61{
62 u16 *cache = codec->reg_cache;
63 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
64 return -1;
65 return cache[reg];
66}
67
68/*
69 * write tlv320aic23 register cache
70 */
71static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
72 u8 reg, u16 value)
73{
74 u16 *cache = codec->reg_cache;
75 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
76 return;
77 cache[reg] = value;
78}
79
80/*
81 * write to the tlv320aic23 register space
82 */
83static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
84 unsigned int value)
85{
86
87 u8 data[2];
88
89 /* TLV320AIC23 has 7 bit address and 9 bits of data
90 * so we need to switch one data bit into reg and rest
91 * of data into val
92 */
93
94 if ((reg < 0 || reg > 9) && (reg != 15)) {
95 printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg);
96 return -1;
97 }
98
99 data[0] = (reg << 1) | (value >> 8 & 0x01);
100 data[1] = value & 0xff;
101
102 tlv320aic23_write_reg_cache(codec, reg, value);
103
104 if (codec->hw_write(codec->control_data, data, 2) == 2)
105 return 0;
106
107 printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
108 value, reg);
109
110 return -EIO;
111}
112
113static const char *rec_src_text[] = { "Line", "Mic" };
114static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
115
116static const struct soc_enum rec_src_enum =
117 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
118
119static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
120SOC_DAPM_ENUM("Input Select", rec_src_enum);
121
122static const struct soc_enum tlv320aic23_rec_src =
123 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
124static const struct soc_enum tlv320aic23_deemph =
125 SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
126
127static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
128static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
129static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
130
131static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
132 struct snd_ctl_elem_value *ucontrol)
133{
134 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
135 u16 val, reg;
136
137 val = (ucontrol->value.integer.value[0] & 0x07);
138
139 /* linear conversion to userspace
140 * 000 = -6db
141 * 001 = -9db
142 * 010 = -12db
143 * 011 = -18db (Min)
144 * 100 = 0db (Max)
145 */
146 val = (val >= 4) ? 4 : (3 - val);
147
148 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0);
149 tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
150
151 return 0;
152}
153
154static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
155 struct snd_ctl_elem_value *ucontrol)
156{
157 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
158 u16 val;
159
160 val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0);
161 val = val >> 6;
162 val = (val >= 4) ? 4 : (3 - val);
163 ucontrol->value.integer.value[0] = val;
164 return 0;
165
166}
167
168#define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
169{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
170 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
171 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
172 .tlv.p = (tlv_array), \
173 .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\
174 .put = snd_soc_tlv320aic23_put_volsw, \
175 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
176
177static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
178 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
179 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
180 SOC_SINGLE("Digital Playback Switch", TLV320AIC23_DIGT, 3, 1, 1),
181 SOC_DOUBLE_R("Line Input Switch", TLV320AIC23_LINVOL,
182 TLV320AIC23_RINVOL, 7, 1, 0),
183 SOC_DOUBLE_R_TLV("Line Input Volume", TLV320AIC23_LINVOL,
184 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
185 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
186 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
187 SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG,
188 6, 4, 0, sidetone_vol_tlv),
189 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
190};
191
192/* add non dapm controls */
193static int tlv320aic23_add_controls(struct snd_soc_codec *codec)
194{
195
196 int err, i;
197
198 for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) {
199 err = snd_ctl_add(codec->card,
200 snd_soc_cnew(&tlv320aic23_snd_controls[i],
201 codec, NULL));
202 if (err < 0)
203 return err;
204 }
205
206 return 0;
207
208}
209
210/* PGA Mixer controls for Line and Mic switch */
211static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = {
212 SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0),
213 SOC_DAPM_SINGLE("Mic Sidetone Switch", TLV320AIC23_ANLG, 5, 1, 0),
214 SOC_DAPM_SINGLE("Playback Switch", TLV320AIC23_ANLG, 4, 1, 0),
215};
216
217static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
218 SND_SOC_DAPM_DAC("DAC", "Playback", TLV320AIC23_PWR, 3, 1),
219 SND_SOC_DAPM_ADC("ADC", "Capture", TLV320AIC23_PWR, 2, 1),
220 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
221 &tlv320aic23_rec_src_mux_controls),
222 SND_SOC_DAPM_MIXER("Output Mixer", TLV320AIC23_PWR, 4, 1,
223 &tlv320aic23_output_mixer_controls[0],
224 ARRAY_SIZE(tlv320aic23_output_mixer_controls)),
225 SND_SOC_DAPM_PGA("Line Input", TLV320AIC23_PWR, 0, 1, NULL, 0),
226 SND_SOC_DAPM_PGA("Mic Input", TLV320AIC23_PWR, 1, 1, NULL, 0),
227
228 SND_SOC_DAPM_OUTPUT("LHPOUT"),
229 SND_SOC_DAPM_OUTPUT("RHPOUT"),
230 SND_SOC_DAPM_OUTPUT("LOUT"),
231 SND_SOC_DAPM_OUTPUT("ROUT"),
232
233 SND_SOC_DAPM_INPUT("LLINEIN"),
234 SND_SOC_DAPM_INPUT("RLINEIN"),
235
236 SND_SOC_DAPM_INPUT("MICIN"),
237};
238
239static const struct snd_soc_dapm_route intercon[] = {
240 /* Output Mixer */
241 {"Output Mixer", "Line Bypass Switch", "Line Input"},
242 {"Output Mixer", "Playback Switch", "DAC"},
243 {"Output Mixer", "Mic Sidetone Switch", "Mic Input"},
244
245 /* Outputs */
246 {"RHPOUT", NULL, "Output Mixer"},
247 {"LHPOUT", NULL, "Output Mixer"},
248 {"LOUT", NULL, "Output Mixer"},
249 {"ROUT", NULL, "Output Mixer"},
250
251 /* Inputs */
252 {"Line Input", "NULL", "LLINEIN"},
253 {"Line Input", "NULL", "RLINEIN"},
254
255 {"Mic Input", "NULL", "MICIN"},
256
257 /* input mux */
258 {"Capture Source", "Line", "Line Input"},
259 {"Capture Source", "Mic", "Mic Input"},
260 {"ADC", NULL, "Capture Source"},
261
262};
263
264/* tlv320aic23 related */
265static const struct tlv320aic23_srate_reg_info srate_reg_info[] = {
266 {4000, 0x06, 1}, /* 4000 */
267 {8000, 0x06, 0}, /* 8000 */
268 {16000, 0x0C, 1}, /* 16000 */
269 {22050, 0x11, 1}, /* 22050 */
270 {24000, 0x00, 1}, /* 24000 */
271 {32000, 0x0C, 0}, /* 32000 */
272 {44100, 0x11, 0}, /* 44100 */
273 {48000, 0x00, 0}, /* 48000 */
274 {88200, 0x1F, 0}, /* 88200 */
275 {96000, 0x0E, 0}, /* 96000 */
276};
277
278static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
279{
280 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
281 ARRAY_SIZE(tlv320aic23_dapm_widgets));
282
283 /* set up audio path interconnects */
284 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
285
286 snd_soc_dapm_new_widgets(codec);
287 return 0;
288}
289
290static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *params)
292{
293 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 struct snd_soc_device *socdev = rtd->socdev;
295 struct snd_soc_codec *codec = socdev->codec;
296 u16 iface_reg, data;
297 u8 count = 0;
298
299 iface_reg =
300 tlv320aic23_read_reg_cache(codec,
301 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
302
303 /* Search for the right sample rate */
304 /* Verify what happens if the rate is not supported
305 * now it goes to 96Khz */
306 while ((srate_reg_info[count].sample_rate != params_rate(params)) &&
307 (count < ARRAY_SIZE(srate_reg_info))) {
308 count++;
309 }
310
311 data = (srate_reg_info[count].divider << TLV320AIC23_CLKIN_SHIFT) |
312 (srate_reg_info[count]. control << TLV320AIC23_BOSR_SHIFT) |
313 TLV320AIC23_USB_CLK_ON;
314
315 tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
316
317 switch (params_format(params)) {
318 case SNDRV_PCM_FORMAT_S16_LE:
319 break;
320 case SNDRV_PCM_FORMAT_S20_3LE:
321 iface_reg |= (0x01 << 2);
322 break;
323 case SNDRV_PCM_FORMAT_S24_LE:
324 iface_reg |= (0x02 << 2);
325 break;
326 case SNDRV_PCM_FORMAT_S32_LE:
327 iface_reg |= (0x03 << 2);
328 break;
329 }
330 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
331
332 return 0;
333}
334
335static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
336{
337 struct snd_soc_pcm_runtime *rtd = substream->private_data;
338 struct snd_soc_device *socdev = rtd->socdev;
339 struct snd_soc_codec *codec = socdev->codec;
340
341 /* set active */
342 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
343
344 return 0;
345}
346
347static void tlv320aic23_shutdown(struct snd_pcm_substream *substream)
348{
349 struct snd_soc_pcm_runtime *rtd = substream->private_data;
350 struct snd_soc_device *socdev = rtd->socdev;
351 struct snd_soc_codec *codec = socdev->codec;
352
353 /* deactivate */
354 if (!codec->active) {
355 udelay(50);
356 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
357 }
358}
359
360static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
361{
362 struct snd_soc_codec *codec = dai->codec;
363 u16 reg;
364
365 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT);
366 if (mute)
367 reg |= TLV320AIC23_DACM_MUTE;
368
369 else
370 reg &= ~TLV320AIC23_DACM_MUTE;
371
372 tlv320aic23_write(codec, TLV320AIC23_DIGT, reg);
373
374 return 0;
375}
376
377static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
378 unsigned int fmt)
379{
380 struct snd_soc_codec *codec = codec_dai->codec;
381 u16 iface_reg;
382
383 iface_reg =
384 tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
385
386 /* set master/slave audio interface */
387 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
388 case SND_SOC_DAIFMT_CBM_CFM:
389 iface_reg |= TLV320AIC23_MS_MASTER;
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 break;
393 default:
394 return -EINVAL;
395
396 }
397
398 /* interface format */
399 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
400 case SND_SOC_DAIFMT_I2S:
401 iface_reg |= TLV320AIC23_FOR_I2S;
402 break;
403 case SND_SOC_DAIFMT_DSP_A:
404 iface_reg |= TLV320AIC23_FOR_DSP;
405 break;
406 case SND_SOC_DAIFMT_RIGHT_J:
407 break;
408 case SND_SOC_DAIFMT_LEFT_J:
409 iface_reg |= TLV320AIC23_FOR_LJUST;
410 break;
411 default:
412 return -EINVAL;
413
414 }
415
416 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
417
418 return 0;
419}
420
421static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
422 int clk_id, unsigned int freq, int dir)
423{
424 struct snd_soc_codec *codec = codec_dai->codec;
425
426 switch (freq) {
427 case 12000000:
428 return 0;
429 }
430 return -EINVAL;
431}
432
433static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
434 enum snd_soc_bias_level level)
435{
436 u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f;
437
438 switch (level) {
439 case SND_SOC_BIAS_ON:
440 /* vref/mid, osc on, dac unmute */
441 tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
442 break;
443 case SND_SOC_BIAS_PREPARE:
444 break;
445 case SND_SOC_BIAS_STANDBY:
446 /* everything off except vref/vmid, */
447 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040);
448 break;
449 case SND_SOC_BIAS_OFF:
450 /* everything off, dac mute, inactive */
451 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
452 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
453 break;
454 }
455 codec->bias_level = level;
456 return 0;
457}
458
459#define AIC23_RATES SNDRV_PCM_RATE_8000_96000
460#define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
461 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
462
463struct snd_soc_dai tlv320aic23_dai = {
464 .name = "tlv320aic23",
465 .playback = {
466 .stream_name = "Playback",
467 .channels_min = 2,
468 .channels_max = 2,
469 .rates = AIC23_RATES,
470 .formats = AIC23_FORMATS,},
471 .capture = {
472 .stream_name = "Capture",
473 .channels_min = 2,
474 .channels_max = 2,
475 .rates = AIC23_RATES,
476 .formats = AIC23_FORMATS,},
477 .ops = {
478 .prepare = tlv320aic23_pcm_prepare,
479 .hw_params = tlv320aic23_hw_params,
480 .shutdown = tlv320aic23_shutdown,
481 },
482 .dai_ops = {
483 .digital_mute = tlv320aic23_mute,
484 .set_fmt = tlv320aic23_set_dai_fmt,
485 .set_sysclk = tlv320aic23_set_dai_sysclk,
486 }
487};
488EXPORT_SYMBOL_GPL(tlv320aic23_dai);
489
490static int tlv320aic23_suspend(struct platform_device *pdev,
491 pm_message_t state)
492{
493 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
494 struct snd_soc_codec *codec = socdev->codec;
495
496 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
497 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
498
499 return 0;
500}
501
502static int tlv320aic23_resume(struct platform_device *pdev)
503{
504 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
505 struct snd_soc_codec *codec = socdev->codec;
506 int i;
507 u16 reg;
508
509 /* Sync reg_cache with the hardware */
510 for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
511 u16 val = tlv320aic23_read_reg_cache(codec, reg);
512 tlv320aic23_write(codec, reg, val);
513 }
514
515 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
516 tlv320aic23_set_bias_level(codec, codec->suspend_bias_level);
517
518 return 0;
519}
520
521/*
522 * initialise the AIC23 driver
523 * register the mixer and dsp interfaces with the kernel
524 */
525static int tlv320aic23_init(struct snd_soc_device *socdev)
526{
527 struct snd_soc_codec *codec = socdev->codec;
528 int ret = 0;
529 u16 reg;
530
531 codec->name = "tlv320aic23";
532 codec->owner = THIS_MODULE;
533 codec->read = tlv320aic23_read_reg_cache;
534 codec->write = tlv320aic23_write;
535 codec->set_bias_level = tlv320aic23_set_bias_level;
536 codec->dai = &tlv320aic23_dai;
537 codec->num_dai = 1;
538 codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
539 codec->reg_cache =
540 kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
541 if (codec->reg_cache == NULL)
542 return -ENOMEM;
543
544 /* Reset codec */
545 tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
546
547 /* register pcms */
548 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
549 if (ret < 0) {
550 printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
551 goto pcm_err;
552 }
553
554 /* power on device */
555 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
556
557 tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
558
559 /* Unmute input */
560 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL);
561 tlv320aic23_write(codec, TLV320AIC23_LINVOL,
562 (reg & (~TLV320AIC23_LIM_MUTED)) |
563 (TLV320AIC23_LRS_ENABLED));
564
565 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL);
566 tlv320aic23_write(codec, TLV320AIC23_RINVOL,
567 (reg & (~TLV320AIC23_LIM_MUTED)) |
568 TLV320AIC23_LRS_ENABLED);
569
570 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG);
571 tlv320aic23_write(codec, TLV320AIC23_ANLG,
572 (reg) & (~TLV320AIC23_BYPASS_ON) &
573 (~TLV320AIC23_MICM_MUTED));
574
575 /* Default output volume */
576 tlv320aic23_write(codec, TLV320AIC23_LCHNVOL,
577 TLV320AIC23_DEFAULT_OUT_VOL &
578 TLV320AIC23_OUT_VOL_MASK);
579 tlv320aic23_write(codec, TLV320AIC23_RCHNVOL,
580 TLV320AIC23_DEFAULT_OUT_VOL &
581 TLV320AIC23_OUT_VOL_MASK);
582
583 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1);
584
585 tlv320aic23_add_controls(codec);
586 tlv320aic23_add_widgets(codec);
587 ret = snd_soc_register_card(socdev);
588 if (ret < 0) {
589 printk(KERN_ERR "tlv320aic23: failed to register card\n");
590 goto card_err;
591 }
592
593 return ret;
594
595card_err:
596 snd_soc_free_pcms(socdev);
597 snd_soc_dapm_free(socdev);
598pcm_err:
599 kfree(codec->reg_cache);
600 return ret;
601}
602static struct snd_soc_device *tlv320aic23_socdev;
603
604#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
605/*
606 * If the i2c layer weren't so broken, we could pass this kind of data
607 * around
608 */
609static int tlv320aic23_codec_probe(struct i2c_client *i2c,
610 const struct i2c_device_id *i2c_id)
611{
612 struct snd_soc_device *socdev = tlv320aic23_socdev;
613 struct snd_soc_codec *codec = socdev->codec;
614 int ret;
615
616 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
617 return -EINVAL;
618
619 i2c_set_clientdata(i2c, codec);
620 codec->control_data = i2c;
621
622 ret = tlv320aic23_init(socdev);
623 if (ret < 0) {
624 printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n");
625 goto err;
626 }
627 return ret;
628
629err:
630 kfree(codec);
631 kfree(i2c);
632 return ret;
633}
634static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
635{
636 put_device(&i2c->dev);
637 return 0;
638}
639
640static const struct i2c_device_id tlv320aic23_id[] = {
641 {"tlv320aic23", 0},
642 {}
643};
644
645MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
646
647static struct i2c_driver tlv320aic23_i2c_driver = {
648 .driver = {
649 .name = "tlv320aic23",
650 },
651 .probe = tlv320aic23_codec_probe,
652 .remove = __exit_p(tlv320aic23_i2c_remove),
653 .id_table = tlv320aic23_id,
654};
655
656#endif
657
658static int tlv320aic23_probe(struct platform_device *pdev)
659{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661 struct snd_soc_codec *codec;
662 int ret = 0;
663
664 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
665
666 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
667 if (codec == NULL)
668 return -ENOMEM;
669
670 socdev->codec = codec;
671 mutex_init(&codec->mutex);
672 INIT_LIST_HEAD(&codec->dapm_widgets);
673 INIT_LIST_HEAD(&codec->dapm_paths);
674
675 tlv320aic23_socdev = socdev;
676#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
677 codec->hw_write = (hw_write_t) i2c_master_send;
678 codec->hw_read = NULL;
679 ret = i2c_add_driver(&tlv320aic23_i2c_driver);
680 if (ret != 0)
681 printk(KERN_ERR "can't add i2c driver");
682#endif
683 return ret;
684}
685
686static int tlv320aic23_remove(struct platform_device *pdev)
687{
688 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
689 struct snd_soc_codec *codec = socdev->codec;
690
691 if (codec->control_data)
692 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
693
694 snd_soc_free_pcms(socdev);
695 snd_soc_dapm_free(socdev);
696#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
697 i2c_del_driver(&tlv320aic23_i2c_driver);
698#endif
699 kfree(codec->reg_cache);
700 kfree(codec);
701
702 return 0;
703}
704struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
705 .probe = tlv320aic23_probe,
706 .remove = tlv320aic23_remove,
707 .suspend = tlv320aic23_suspend,
708 .resume = tlv320aic23_resume,
709};
710EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
711
712MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
713MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
714MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
new file mode 100644
index 000000000000..79d1faf8e570
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -0,0 +1,122 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd
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 _TLV320AIC23_H
13#define _TLV320AIC23_H
14
15/* Codec TLV320AIC23 */
16#define TLV320AIC23_LINVOL 0x00
17#define TLV320AIC23_RINVOL 0x01
18#define TLV320AIC23_LCHNVOL 0x02
19#define TLV320AIC23_RCHNVOL 0x03
20#define TLV320AIC23_ANLG 0x04
21#define TLV320AIC23_DIGT 0x05
22#define TLV320AIC23_PWR 0x06
23#define TLV320AIC23_DIGT_FMT 0x07
24#define TLV320AIC23_SRATE 0x08
25#define TLV320AIC23_ACTIVE 0x09
26#define TLV320AIC23_RESET 0x0F
27
28/* Left (right) line input volume control register */
29#define TLV320AIC23_LRS_ENABLED 0x0100
30#define TLV320AIC23_LIM_MUTED 0x0080
31#define TLV320AIC23_LIV_DEFAULT 0x0017
32#define TLV320AIC23_LIV_MAX 0x001f
33#define TLV320AIC23_LIV_MIN 0x0000
34
35/* Left (right) channel headphone volume control register */
36#define TLV320AIC23_LZC_ON 0x0080
37#define TLV320AIC23_LHV_DEFAULT 0x0079
38#define TLV320AIC23_LHV_MAX 0x007f
39#define TLV320AIC23_LHV_MIN 0x0000
40
41/* Analog audio path control register */
42#define TLV320AIC23_STA_REG(x) ((x)<<6)
43#define TLV320AIC23_STE_ENABLED 0x0020
44#define TLV320AIC23_DAC_SELECTED 0x0010
45#define TLV320AIC23_BYPASS_ON 0x0008
46#define TLV320AIC23_INSEL_MIC 0x0004
47#define TLV320AIC23_MICM_MUTED 0x0002
48#define TLV320AIC23_MICB_20DB 0x0001
49
50/* Digital audio path control register */
51#define TLV320AIC23_DACM_MUTE 0x0008
52#define TLV320AIC23_DEEMP_32K 0x0002
53#define TLV320AIC23_DEEMP_44K 0x0004
54#define TLV320AIC23_DEEMP_48K 0x0006
55#define TLV320AIC23_ADCHP_ON 0x0001
56
57/* Power control down register */
58#define TLV320AIC23_DEVICE_PWR_OFF 0x0080
59#define TLV320AIC23_CLK_OFF 0x0040
60#define TLV320AIC23_OSC_OFF 0x0020
61#define TLV320AIC23_OUT_OFF 0x0010
62#define TLV320AIC23_DAC_OFF 0x0008
63#define TLV320AIC23_ADC_OFF 0x0004
64#define TLV320AIC23_MIC_OFF 0x0002
65#define TLV320AIC23_LINE_OFF 0x0001
66
67/* Digital audio interface register */
68#define TLV320AIC23_MS_MASTER 0x0040
69#define TLV320AIC23_LRSWAP_ON 0x0020
70#define TLV320AIC23_LRP_ON 0x0010
71#define TLV320AIC23_IWL_16 0x0000
72#define TLV320AIC23_IWL_20 0x0004
73#define TLV320AIC23_IWL_24 0x0008
74#define TLV320AIC23_IWL_32 0x000C
75#define TLV320AIC23_FOR_I2S 0x0002
76#define TLV320AIC23_FOR_DSP 0x0003
77#define TLV320AIC23_FOR_LJUST 0x0001
78
79/* Sample rate control register */
80#define TLV320AIC23_CLKOUT_HALF 0x0080
81#define TLV320AIC23_CLKIN_HALF 0x0040
82#define TLV320AIC23_BOSR_384fs 0x0002 /* BOSR_272fs in USB mode */
83#define TLV320AIC23_USB_CLK_ON 0x0001
84#define TLV320AIC23_SR_MASK 0xf
85#define TLV320AIC23_CLKOUT_SHIFT 7
86#define TLV320AIC23_CLKIN_SHIFT 6
87#define TLV320AIC23_SR_SHIFT 2
88#define TLV320AIC23_BOSR_SHIFT 1
89
90/* Digital interface register */
91#define TLV320AIC23_ACT_ON 0x0001
92
93/*
94 * AUDIO related MACROS
95 */
96
97#define TLV320AIC23_DEFAULT_OUT_VOL 0x70
98#define TLV320AIC23_DEFAULT_IN_VOLUME 0x10
99
100#define TLV320AIC23_OUT_VOL_MIN TLV320AIC23_LHV_MIN
101#define TLV320AIC23_OUT_VOL_MAX TLV320AIC23_LHV_MAX
102#define TLV320AIC23_OUT_VO_RANGE (TLV320AIC23_OUT_VOL_MAX - \
103 TLV320AIC23_OUT_VOL_MIN)
104#define TLV320AIC23_OUT_VOL_MASK TLV320AIC23_OUT_VOL_MAX
105
106#define TLV320AIC23_IN_VOL_MIN TLV320AIC23_LIV_MIN
107#define TLV320AIC23_IN_VOL_MAX TLV320AIC23_LIV_MAX
108#define TLV320AIC23_IN_VOL_RANGE (TLV320AIC23_IN_VOL_MAX - \
109 TLV320AIC23_IN_VOL_MIN)
110#define TLV320AIC23_IN_VOL_MASK TLV320AIC23_IN_VOL_MAX
111
112#define TLV320AIC23_SIDETONE_MASK 0x1c0
113#define TLV320AIC23_SIDETONE_0 0x100
114#define TLV320AIC23_SIDETONE_6 0x000
115#define TLV320AIC23_SIDETONE_9 0x040
116#define TLV320AIC23_SIDETONE_12 0x080
117#define TLV320AIC23_SIDETONE_18 0x0c0
118
119extern struct snd_soc_dai tlv320aic23_dai;
120extern struct snd_soc_codec_device soc_codec_dev_tlv320aic23;
121
122#endif /* _TLV320AIC23_H */
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
new file mode 100644
index 000000000000..bed8a9e63ddc
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -0,0 +1,520 @@
1/*
2 * Texas Instruments TLV320AIC26 low power audio CODEC
3 * ALSA SoC CODEC driver
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/pm.h>
13#include <linux/device.h>
14#include <linux/sysfs.h>
15#include <linux/spi/spi.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/soc-of-simple.h>
22#include <sound/initval.h>
23
24#include "tlv320aic26.h"
25
26MODULE_DESCRIPTION("ASoC TLV320AIC26 codec driver");
27MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
28MODULE_LICENSE("GPL");
29
30/* AIC26 driver private data */
31struct aic26 {
32 struct spi_device *spi;
33 struct snd_soc_codec codec;
34 u16 reg_cache[AIC26_NUM_REGS]; /* shadow registers */
35 int master;
36 int datfm;
37 int mclk;
38
39 /* Keyclick parameters */
40 int keyclick_amplitude;
41 int keyclick_freq;
42 int keyclick_len;
43};
44
45/* ---------------------------------------------------------------------
46 * Register access routines
47 */
48static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
49 unsigned int reg)
50{
51 struct aic26 *aic26 = codec->private_data;
52 u16 *cache = codec->reg_cache;
53 u16 cmd, value;
54 u8 buffer[2];
55 int rc;
56
57 if (reg >= AIC26_NUM_REGS) {
58 WARN_ON_ONCE(1);
59 return 0;
60 }
61
62 /* Do SPI transfer; first 16bits are command; remaining is
63 * register contents */
64 cmd = AIC26_READ_COMMAND_WORD(reg);
65 buffer[0] = (cmd >> 8) & 0xff;
66 buffer[1] = cmd & 0xff;
67 rc = spi_write_then_read(aic26->spi, buffer, 2, buffer, 2);
68 if (rc) {
69 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
70 return -EIO;
71 }
72 value = (buffer[0] << 8) | buffer[1];
73
74 /* Update the cache before returning with the value */
75 cache[reg] = value;
76 return value;
77}
78
79static unsigned int aic26_reg_read_cache(struct snd_soc_codec *codec,
80 unsigned int reg)
81{
82 u16 *cache = codec->reg_cache;
83
84 if (reg >= AIC26_NUM_REGS) {
85 WARN_ON_ONCE(1);
86 return 0;
87 }
88
89 return cache[reg];
90}
91
92static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
93 unsigned int value)
94{
95 struct aic26 *aic26 = codec->private_data;
96 u16 *cache = codec->reg_cache;
97 u16 cmd;
98 u8 buffer[4];
99 int rc;
100
101 if (reg >= AIC26_NUM_REGS) {
102 WARN_ON_ONCE(1);
103 return -EINVAL;
104 }
105
106 /* Do SPI transfer; first 16bits are command; remaining is data
107 * to write into register */
108 cmd = AIC26_WRITE_COMMAND_WORD(reg);
109 buffer[0] = (cmd >> 8) & 0xff;
110 buffer[1] = cmd & 0xff;
111 buffer[2] = value >> 8;
112 buffer[3] = value;
113 rc = spi_write(aic26->spi, buffer, 4);
114 if (rc) {
115 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
116 return -EIO;
117 }
118
119 /* update cache before returning */
120 cache[reg] = value;
121 return 0;
122}
123
124/* ---------------------------------------------------------------------
125 * Digital Audio Interface Operations
126 */
127static int aic26_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params)
129{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_device *socdev = rtd->socdev;
132 struct snd_soc_codec *codec = socdev->codec;
133 struct aic26 *aic26 = codec->private_data;
134 int fsref, divisor, wlen, pval, jval, dval, qval;
135 u16 reg;
136
137 dev_dbg(&aic26->spi->dev, "aic26_hw_params(substream=%p, params=%p)\n",
138 substream, params);
139 dev_dbg(&aic26->spi->dev, "rate=%i format=%i\n", params_rate(params),
140 params_format(params));
141
142 switch (params_rate(params)) {
143 case 8000: fsref = 48000; divisor = AIC26_DIV_6; break;
144 case 11025: fsref = 44100; divisor = AIC26_DIV_4; break;
145 case 12000: fsref = 48000; divisor = AIC26_DIV_4; break;
146 case 16000: fsref = 48000; divisor = AIC26_DIV_3; break;
147 case 22050: fsref = 44100; divisor = AIC26_DIV_2; break;
148 case 24000: fsref = 48000; divisor = AIC26_DIV_2; break;
149 case 32000: fsref = 48000; divisor = AIC26_DIV_1_5; break;
150 case 44100: fsref = 44100; divisor = AIC26_DIV_1; break;
151 case 48000: fsref = 48000; divisor = AIC26_DIV_1; break;
152 default:
153 dev_dbg(&aic26->spi->dev, "bad rate\n"); return -EINVAL;
154 }
155
156 /* select data word length */
157 switch (params_format(params)) {
158 case SNDRV_PCM_FORMAT_S8: wlen = AIC26_WLEN_16; break;
159 case SNDRV_PCM_FORMAT_S16_BE: wlen = AIC26_WLEN_16; break;
160 case SNDRV_PCM_FORMAT_S24_BE: wlen = AIC26_WLEN_24; break;
161 case SNDRV_PCM_FORMAT_S32_BE: wlen = AIC26_WLEN_32; break;
162 default:
163 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
164 }
165
166 /* Configure PLL */
167 pval = 1;
168 jval = (fsref == 44100) ? 7 : 8;
169 dval = (fsref == 44100) ? 5264 : 1920;
170 qval = 0;
171 reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
172 aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg);
173 reg = dval << 2;
174 aic26_reg_write(codec, AIC26_REG_PLL_PROG2, reg);
175
176 /* Audio Control 3 (master mode, fsref rate) */
177 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL3);
178 reg &= ~0xf800;
179 if (aic26->master)
180 reg |= 0x0800;
181 if (fsref == 48000)
182 reg |= 0x2000;
183 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
184
185 /* Audio Control 1 (FSref divisor) */
186 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL1);
187 reg &= ~0x0fff;
188 reg |= wlen | aic26->datfm | (divisor << 3) | divisor;
189 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL1, reg);
190
191 return 0;
192}
193
194/**
195 * aic26_mute - Mute control to reduce noise when changing audio format
196 */
197static int aic26_mute(struct snd_soc_dai *dai, int mute)
198{
199 struct snd_soc_codec *codec = dai->codec;
200 struct aic26 *aic26 = codec->private_data;
201 u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN);
202
203 dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
204 dai, mute);
205
206 if (mute)
207 reg |= 0x8080;
208 else
209 reg &= ~0x8080;
210 aic26_reg_write(codec, AIC26_REG_DAC_GAIN, reg);
211
212 return 0;
213}
214
215static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
216 int clk_id, unsigned int freq, int dir)
217{
218 struct snd_soc_codec *codec = codec_dai->codec;
219 struct aic26 *aic26 = codec->private_data;
220
221 dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
222 " freq=%i, dir=%i)\n",
223 codec_dai, clk_id, freq, dir);
224
225 /* MCLK needs to fall between 2MHz and 50 MHz */
226 if ((freq < 2000000) || (freq > 50000000))
227 return -EINVAL;
228
229 aic26->mclk = freq;
230 return 0;
231}
232
233static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
234{
235 struct snd_soc_codec *codec = codec_dai->codec;
236 struct aic26 *aic26 = codec->private_data;
237
238 dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
239 codec_dai, fmt);
240
241 /* set master/slave audio interface */
242 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
243 case SND_SOC_DAIFMT_CBM_CFM: aic26->master = 1; break;
244 case SND_SOC_DAIFMT_CBS_CFS: aic26->master = 0; break;
245 default:
246 dev_dbg(&aic26->spi->dev, "bad master\n"); return -EINVAL;
247 }
248
249 /* interface format */
250 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
251 case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break;
252 case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break;
253 case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break;
254 case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break;
255 default:
256 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
257 }
258
259 return 0;
260}
261
262/* ---------------------------------------------------------------------
263 * Digital Audio Interface Definition
264 */
265#define AIC26_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
266 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
267 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
268 SNDRV_PCM_RATE_48000)
269#define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\
270 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
271
272struct snd_soc_dai aic26_dai = {
273 .name = "tlv320aic26",
274 .playback = {
275 .stream_name = "Playback",
276 .channels_min = 2,
277 .channels_max = 2,
278 .rates = AIC26_RATES,
279 .formats = AIC26_FORMATS,
280 },
281 .capture = {
282 .stream_name = "Capture",
283 .channels_min = 2,
284 .channels_max = 2,
285 .rates = AIC26_RATES,
286 .formats = AIC26_FORMATS,
287 },
288 .ops = {
289 .hw_params = aic26_hw_params,
290 },
291 .dai_ops = {
292 .digital_mute = aic26_mute,
293 .set_sysclk = aic26_set_sysclk,
294 .set_fmt = aic26_set_fmt,
295 },
296};
297EXPORT_SYMBOL_GPL(aic26_dai);
298
299/* ---------------------------------------------------------------------
300 * ALSA controls
301 */
302static const char *aic26_capture_src_text[] = {"Mic", "Aux"};
303static const struct soc_enum aic26_capture_src_enum =
304 SOC_ENUM_SINGLE(AIC26_REG_AUDIO_CTRL1, 12, 2, aic26_capture_src_text);
305
306static const struct snd_kcontrol_new aic26_snd_controls[] = {
307 /* Output */
308 SOC_DOUBLE("PCM Playback Volume", AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1),
309 SOC_DOUBLE("PCM Playback Switch", AIC26_REG_DAC_GAIN, 15, 7, 1, 1),
310 SOC_SINGLE("PCM Capture Volume", AIC26_REG_ADC_GAIN, 8, 0x7f, 0),
311 SOC_SINGLE("PCM Capture Mute", AIC26_REG_ADC_GAIN, 15, 1, 1),
312 SOC_SINGLE("Keyclick activate", AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0),
313 SOC_SINGLE("Keyclick amplitude", AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0),
314 SOC_SINGLE("Keyclick frequency", AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0),
315 SOC_SINGLE("Keyclick period", AIC26_REG_AUDIO_CTRL2, 4, 0xf, 0),
316 SOC_ENUM("Capture Source", aic26_capture_src_enum),
317};
318
319/* ---------------------------------------------------------------------
320 * SoC CODEC portion of driver: probe and release routines
321 */
322static int aic26_probe(struct platform_device *pdev)
323{
324 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
325 struct snd_soc_codec *codec;
326 struct snd_kcontrol *kcontrol;
327 struct aic26 *aic26;
328 int i, ret, err;
329
330 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
331 dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
332 dev_dbg(&pdev->dev, "codec_data=%p\n", socdev->codec_data);
333
334 /* Fetch the relevant aic26 private data here (it's already been
335 * stored in the .codec pointer) */
336 aic26 = socdev->codec_data;
337 if (aic26 == NULL) {
338 dev_err(&pdev->dev, "aic26: missing codec pointer\n");
339 return -ENODEV;
340 }
341 codec = &aic26->codec;
342 socdev->codec = codec;
343
344 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
345 &pdev->dev, socdev->dev);
346 /* register pcms */
347 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
348 if (ret < 0) {
349 dev_err(&pdev->dev, "aic26: failed to create pcms\n");
350 return -ENODEV;
351 }
352
353 /* register controls */
354 dev_dbg(&pdev->dev, "Registering controls\n");
355 for (i = 0; i < ARRAY_SIZE(aic26_snd_controls); i++) {
356 kcontrol = snd_soc_cnew(&aic26_snd_controls[i], codec, NULL);
357 err = snd_ctl_add(codec->card, kcontrol);
358 WARN_ON(err < 0);
359 }
360
361 /* CODEC is setup, we can register the card now */
362 dev_dbg(&pdev->dev, "Registering card\n");
363 ret = snd_soc_register_card(socdev);
364 if (ret < 0) {
365 dev_err(&pdev->dev, "aic26: failed to register card\n");
366 goto card_err;
367 }
368 return 0;
369
370 card_err:
371 snd_soc_free_pcms(socdev);
372 return ret;
373}
374
375static int aic26_remove(struct platform_device *pdev)
376{
377 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
378 snd_soc_free_pcms(socdev);
379 return 0;
380}
381
382struct snd_soc_codec_device aic26_soc_codec_dev = {
383 .probe = aic26_probe,
384 .remove = aic26_remove,
385};
386EXPORT_SYMBOL_GPL(aic26_soc_codec_dev);
387
388/* ---------------------------------------------------------------------
389 * SPI device portion of driver: sysfs files for debugging
390 */
391
392static ssize_t aic26_keyclick_show(struct device *dev,
393 struct device_attribute *attr, char *buf)
394{
395 struct aic26 *aic26 = dev_get_drvdata(dev);
396 int val, amp, freq, len;
397
398 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
399 amp = (val >> 12) & 0x7;
400 freq = (125 << ((val >> 8) & 0x7)) >> 1;
401 len = 2 * (1 + ((val >> 4) & 0xf));
402
403 return sprintf(buf, "amp=%x freq=%iHz len=%iclks\n", amp, freq, len);
404}
405
406/* Any write to the keyclick attribute will trigger the keyclick event */
407static ssize_t aic26_keyclick_set(struct device *dev,
408 struct device_attribute *attr,
409 const char *buf, size_t count)
410{
411 struct aic26 *aic26 = dev_get_drvdata(dev);
412 int val;
413
414 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
415 val |= 0x8000;
416 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL2, val);
417
418 return count;
419}
420
421static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
422
423/* ---------------------------------------------------------------------
424 * SPI device portion of driver: probe and release routines and SPI
425 * driver registration.
426 */
427static int aic26_spi_probe(struct spi_device *spi)
428{
429 struct aic26 *aic26;
430 int rc, i, reg;
431
432 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
433
434 /* Allocate driver data */
435 aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
436 if (!aic26)
437 return -ENOMEM;
438
439 /* Initialize the driver data */
440 aic26->spi = spi;
441 dev_set_drvdata(&spi->dev, aic26);
442
443 /* Setup what we can in the codec structure so that the register
444 * access functions will work as expected. More will be filled
445 * out when it is probed by the SoC CODEC part of this driver */
446 aic26->codec.private_data = aic26;
447 aic26->codec.name = "aic26";
448 aic26->codec.owner = THIS_MODULE;
449 aic26->codec.dai = &aic26_dai;
450 aic26->codec.num_dai = 1;
451 aic26->codec.read = aic26_reg_read;
452 aic26->codec.write = aic26_reg_write;
453 aic26->master = 1;
454 mutex_init(&aic26->codec.mutex);
455 INIT_LIST_HEAD(&aic26->codec.dapm_widgets);
456 INIT_LIST_HEAD(&aic26->codec.dapm_paths);
457 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
458 aic26->codec.reg_cache = aic26->reg_cache;
459
460 /* Reset the codec to power on defaults */
461 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
462
463 /* Power up CODEC */
464 aic26_reg_write(&aic26->codec, AIC26_REG_POWER_CTRL, 0);
465
466 /* Audio Control 3 (master mode, fsref rate) */
467 reg = aic26_reg_read(&aic26->codec, AIC26_REG_AUDIO_CTRL3);
468 reg &= ~0xf800;
469 reg |= 0x0800; /* set master mode */
470 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL3, reg);
471
472 /* Fill register cache */
473 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++)
474 aic26_reg_read(&aic26->codec, i);
475
476 /* Register the sysfs files for debugging */
477 /* Create SysFS files */
478 rc = device_create_file(&spi->dev, &dev_attr_keyclick);
479 if (rc)
480 dev_info(&spi->dev, "error creating sysfs files\n");
481
482#if defined(CONFIG_SND_SOC_OF_SIMPLE)
483 /* Tell the of_soc helper about this codec */
484 of_snd_soc_register_codec(&aic26_soc_codec_dev, aic26, &aic26_dai,
485 spi->dev.archdata.of_node);
486#endif
487
488 dev_dbg(&spi->dev, "SPI device initialized\n");
489 return 0;
490}
491
492static int aic26_spi_remove(struct spi_device *spi)
493{
494 struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
495
496 kfree(aic26);
497
498 return 0;
499}
500
501static struct spi_driver aic26_spi = {
502 .driver = {
503 .name = "tlv320aic26",
504 .owner = THIS_MODULE,
505 },
506 .probe = aic26_spi_probe,
507 .remove = aic26_spi_remove,
508};
509
510static int __init aic26_init(void)
511{
512 return spi_register_driver(&aic26_spi);
513}
514module_init(aic26_init);
515
516static void __exit aic26_exit(void)
517{
518 spi_unregister_driver(&aic26_spi);
519}
520module_exit(aic26_exit);
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
new file mode 100644
index 000000000000..786ba16c945f
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -0,0 +1,96 @@
1/*
2 * Texas Instruments TLV320AIC26 low power audio CODEC
3 * register definitions
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#ifndef _TLV320AIC16_H_
9#define _TLV320AIC16_H_
10
11/* AIC26 Registers */
12#define AIC26_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5))
13#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
14#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
15#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
16
17/* Page 0: Auxillary data registers */
18#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
19#define AIC26_REG_BAT2 AIC26_PAGE_ADDR(0, 0x06)
20#define AIC26_REG_AUX AIC26_PAGE_ADDR(0, 0x07)
21#define AIC26_REG_TEMP1 AIC26_PAGE_ADDR(0, 0x09)
22#define AIC26_REG_TEMP2 AIC26_PAGE_ADDR(0, 0x0A)
23
24/* Page 1: Auxillary control registers */
25#define AIC26_REG_AUX_ADC AIC26_PAGE_ADDR(1, 0x00)
26#define AIC26_REG_STATUS AIC26_PAGE_ADDR(1, 0x01)
27#define AIC26_REG_REFERENCE AIC26_PAGE_ADDR(1, 0x03)
28#define AIC26_REG_RESET AIC26_PAGE_ADDR(1, 0x04)
29
30/* Page 2: Audio control registers */
31#define AIC26_REG_AUDIO_CTRL1 AIC26_PAGE_ADDR(2, 0x00)
32#define AIC26_REG_ADC_GAIN AIC26_PAGE_ADDR(2, 0x01)
33#define AIC26_REG_DAC_GAIN AIC26_PAGE_ADDR(2, 0x02)
34#define AIC26_REG_SIDETONE AIC26_PAGE_ADDR(2, 0x03)
35#define AIC26_REG_AUDIO_CTRL2 AIC26_PAGE_ADDR(2, 0x04)
36#define AIC26_REG_POWER_CTRL AIC26_PAGE_ADDR(2, 0x05)
37#define AIC26_REG_AUDIO_CTRL3 AIC26_PAGE_ADDR(2, 0x06)
38
39#define AIC26_REG_FILTER_COEFF_L_N0 AIC26_PAGE_ADDR(2, 0x07)
40#define AIC26_REG_FILTER_COEFF_L_N1 AIC26_PAGE_ADDR(2, 0x08)
41#define AIC26_REG_FILTER_COEFF_L_N2 AIC26_PAGE_ADDR(2, 0x09)
42#define AIC26_REG_FILTER_COEFF_L_N3 AIC26_PAGE_ADDR(2, 0x0A)
43#define AIC26_REG_FILTER_COEFF_L_N4 AIC26_PAGE_ADDR(2, 0x0B)
44#define AIC26_REG_FILTER_COEFF_L_N5 AIC26_PAGE_ADDR(2, 0x0C)
45#define AIC26_REG_FILTER_COEFF_L_D1 AIC26_PAGE_ADDR(2, 0x0D)
46#define AIC26_REG_FILTER_COEFF_L_D2 AIC26_PAGE_ADDR(2, 0x0E)
47#define AIC26_REG_FILTER_COEFF_L_D4 AIC26_PAGE_ADDR(2, 0x0F)
48#define AIC26_REG_FILTER_COEFF_L_D5 AIC26_PAGE_ADDR(2, 0x10)
49#define AIC26_REG_FILTER_COEFF_R_N0 AIC26_PAGE_ADDR(2, 0x11)
50#define AIC26_REG_FILTER_COEFF_R_N1 AIC26_PAGE_ADDR(2, 0x12)
51#define AIC26_REG_FILTER_COEFF_R_N2 AIC26_PAGE_ADDR(2, 0x13)
52#define AIC26_REG_FILTER_COEFF_R_N3 AIC26_PAGE_ADDR(2, 0x14)
53#define AIC26_REG_FILTER_COEFF_R_N4 AIC26_PAGE_ADDR(2, 0x15)
54#define AIC26_REG_FILTER_COEFF_R_N5 AIC26_PAGE_ADDR(2, 0x16)
55#define AIC26_REG_FILTER_COEFF_R_D1 AIC26_PAGE_ADDR(2, 0x17)
56#define AIC26_REG_FILTER_COEFF_R_D2 AIC26_PAGE_ADDR(2, 0x18)
57#define AIC26_REG_FILTER_COEFF_R_D4 AIC26_PAGE_ADDR(2, 0x19)
58#define AIC26_REG_FILTER_COEFF_R_D5 AIC26_PAGE_ADDR(2, 0x1A)
59
60#define AIC26_REG_PLL_PROG1 AIC26_PAGE_ADDR(2, 0x1B)
61#define AIC26_REG_PLL_PROG2 AIC26_PAGE_ADDR(2, 0x1C)
62#define AIC26_REG_AUDIO_CTRL4 AIC26_PAGE_ADDR(2, 0x1D)
63#define AIC26_REG_AUDIO_CTRL5 AIC26_PAGE_ADDR(2, 0x1E)
64
65/* fsref dividers; used in register 'Audio Control 1' */
66enum aic26_divisors {
67 AIC26_DIV_1 = 0,
68 AIC26_DIV_1_5 = 1,
69 AIC26_DIV_2 = 2,
70 AIC26_DIV_3 = 3,
71 AIC26_DIV_4 = 4,
72 AIC26_DIV_5 = 5,
73 AIC26_DIV_5_5 = 6,
74 AIC26_DIV_6 = 7,
75};
76
77/* Digital data format */
78enum aic26_datfm {
79 AIC26_DATFM_I2S = 0 << 8,
80 AIC26_DATFM_DSP = 1 << 8,
81 AIC26_DATFM_RIGHTJ = 2 << 8, /* right justified */
82 AIC26_DATFM_LEFTJ = 3 << 8, /* left justified */
83};
84
85/* Sample word length in bits; used in register 'Audio Control 1' */
86enum aic26_wlen {
87 AIC26_WLEN_16 = 0 << 10,
88 AIC26_WLEN_20 = 1 << 10,
89 AIC26_WLEN_24 = 2 << 10,
90 AIC26_WLEN_32 = 3 << 10,
91};
92
93extern struct snd_soc_dai aic26_dai;
94extern struct snd_soc_codec_device aic26_soc_codec_dev;
95
96#endif /* _TLV320AIC16_H_ */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 5f9abb199435..05336ed7e493 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC TLV320AIC3X codec driver 2 * ALSA SoC TLV320AIC3X codec driver
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood 7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
@@ -48,7 +48,6 @@
48 48
49#include "tlv320aic3x.h" 49#include "tlv320aic3x.h"
50 50
51#define AUDIO_NAME "aic3x"
52#define AIC3X_VERSION "0.2" 51#define AIC3X_VERSION "0.2"
53 52
54/* codec private data */ 53/* codec private data */
@@ -991,7 +990,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
991 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 990 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
992 991
993struct snd_soc_dai aic3x_dai = { 992struct snd_soc_dai aic3x_dai = {
994 .name = "aic3x", 993 .name = "tlv320aic3x",
995 .playback = { 994 .playback = {
996 .stream_name = "Playback", 995 .stream_name = "Playback",
997 .channels_min = 1, 996 .channels_min = 1,
@@ -1055,7 +1054,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
1055 struct aic3x_setup_data *setup = socdev->codec_data; 1054 struct aic3x_setup_data *setup = socdev->codec_data;
1056 int reg, ret = 0; 1055 int reg, ret = 0;
1057 1056
1058 codec->name = "aic3x"; 1057 codec->name = "tlv320aic3x";
1059 codec->owner = THIS_MODULE; 1058 codec->owner = THIS_MODULE;
1060 codec->read = aic3x_read_reg_cache; 1059 codec->read = aic3x_read_reg_cache;
1061 codec->write = aic3x_write; 1060 codec->write = aic3x_write;
@@ -1172,71 +1171,39 @@ static struct snd_soc_device *aic3x_socdev;
1172 * AIC3X 2 wire address can be up to 4 devices with device addresses 1171 * AIC3X 2 wire address can be up to 4 devices with device addresses
1173 * 0x18, 0x19, 0x1A, 0x1B 1172 * 0x18, 0x19, 0x1A, 0x1B
1174 */ 1173 */
1175static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1176
1177/* Magic definition of all other variables and things */
1178I2C_CLIENT_INSMOD;
1179
1180static struct i2c_driver aic3x_i2c_driver;
1181static struct i2c_client client_template;
1182 1174
1183/* 1175/*
1184 * If the i2c layer weren't so broken, we could pass this kind of data 1176 * If the i2c layer weren't so broken, we could pass this kind of data
1185 * around 1177 * around
1186 */ 1178 */
1187static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) 1179static int aic3x_i2c_probe(struct i2c_client *i2c,
1180 const struct i2c_device_id *id)
1188{ 1181{
1189 struct snd_soc_device *socdev = aic3x_socdev; 1182 struct snd_soc_device *socdev = aic3x_socdev;
1190 struct aic3x_setup_data *setup = socdev->codec_data;
1191 struct snd_soc_codec *codec = socdev->codec; 1183 struct snd_soc_codec *codec = socdev->codec;
1192 struct i2c_client *i2c;
1193 int ret; 1184 int ret;
1194 1185
1195 if (addr != setup->i2c_address)
1196 return -ENODEV;
1197
1198 client_template.adapter = adap;
1199 client_template.addr = addr;
1200
1201 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1202 if (i2c == NULL)
1203 return -ENOMEM;
1204
1205 i2c_set_clientdata(i2c, codec); 1186 i2c_set_clientdata(i2c, codec);
1206 codec->control_data = i2c; 1187 codec->control_data = i2c;
1207 1188
1208 ret = i2c_attach_client(i2c);
1209 if (ret < 0) {
1210 printk(KERN_ERR "aic3x: failed to attach codec at addr %x\n",
1211 addr);
1212 goto err;
1213 }
1214
1215 ret = aic3x_init(socdev); 1189 ret = aic3x_init(socdev);
1216 if (ret < 0) { 1190 if (ret < 0)
1217 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); 1191 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n");
1218 goto err;
1219 }
1220 return ret;
1221
1222err:
1223 kfree(i2c);
1224 return ret; 1192 return ret;
1225} 1193}
1226 1194
1227static int aic3x_i2c_detach(struct i2c_client *client) 1195static int aic3x_i2c_remove(struct i2c_client *client)
1228{ 1196{
1229 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1197 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1230 i2c_detach_client(client);
1231 kfree(codec->reg_cache); 1198 kfree(codec->reg_cache);
1232 kfree(client);
1233 return 0; 1199 return 0;
1234} 1200}
1235 1201
1236static int aic3x_i2c_attach(struct i2c_adapter *adap) 1202static const struct i2c_device_id aic3x_i2c_id[] = {
1237{ 1203 { "tlv320aic3x", 0 },
1238 return i2c_probe(adap, &addr_data, aic3x_codec_probe); 1204 { }
1239} 1205};
1206MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1240 1207
1241/* machine i2c codec control layer */ 1208/* machine i2c codec control layer */
1242static struct i2c_driver aic3x_i2c_driver = { 1209static struct i2c_driver aic3x_i2c_driver = {
@@ -1244,13 +1211,9 @@ static struct i2c_driver aic3x_i2c_driver = {
1244 .name = "aic3x I2C Codec", 1211 .name = "aic3x I2C Codec",
1245 .owner = THIS_MODULE, 1212 .owner = THIS_MODULE,
1246 }, 1213 },
1247 .attach_adapter = aic3x_i2c_attach, 1214 .probe = aic3x_i2c_probe,
1248 .detach_client = aic3x_i2c_detach, 1215 .remove = aic3x_i2c_remove,
1249}; 1216 .id_table = aic3x_i2c_id,
1250
1251static struct i2c_client client_template = {
1252 .name = "AIC3X",
1253 .driver = &aic3x_i2c_driver,
1254}; 1217};
1255 1218
1256static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) 1219static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
@@ -1258,6 +1221,46 @@ static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
1258 value[0] = i2c_smbus_read_byte_data(client, value[0]); 1221 value[0] = i2c_smbus_read_byte_data(client, value[0]);
1259 return (len == 1); 1222 return (len == 1);
1260} 1223}
1224
1225static int aic3x_add_i2c_device(struct platform_device *pdev,
1226 const struct aic3x_setup_data *setup)
1227{
1228 struct i2c_board_info info;
1229 struct i2c_adapter *adapter;
1230 struct i2c_client *client;
1231 int ret;
1232
1233 ret = i2c_add_driver(&aic3x_i2c_driver);
1234 if (ret != 0) {
1235 dev_err(&pdev->dev, "can't add i2c driver\n");
1236 return ret;
1237 }
1238
1239 memset(&info, 0, sizeof(struct i2c_board_info));
1240 info.addr = setup->i2c_address;
1241 strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE);
1242
1243 adapter = i2c_get_adapter(setup->i2c_bus);
1244 if (!adapter) {
1245 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1246 setup->i2c_bus);
1247 goto err_driver;
1248 }
1249
1250 client = i2c_new_device(adapter, &info);
1251 i2c_put_adapter(adapter);
1252 if (!client) {
1253 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1254 (unsigned int)info.addr);
1255 goto err_driver;
1256 }
1257
1258 return 0;
1259
1260err_driver:
1261 i2c_del_driver(&aic3x_i2c_driver);
1262 return -ENODEV;
1263}
1261#endif 1264#endif
1262 1265
1263static int aic3x_probe(struct platform_device *pdev) 1266static int aic3x_probe(struct platform_device *pdev)
@@ -1290,12 +1293,9 @@ static int aic3x_probe(struct platform_device *pdev)
1290 aic3x_socdev = socdev; 1293 aic3x_socdev = socdev;
1291#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1294#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1292 if (setup->i2c_address) { 1295 if (setup->i2c_address) {
1293 normal_i2c[0] = setup->i2c_address;
1294 codec->hw_write = (hw_write_t) i2c_master_send; 1296 codec->hw_write = (hw_write_t) i2c_master_send;
1295 codec->hw_read = (hw_read_t) aic3x_i2c_read; 1297 codec->hw_read = (hw_read_t) aic3x_i2c_read;
1296 ret = i2c_add_driver(&aic3x_i2c_driver); 1298 ret = aic3x_add_i2c_device(pdev, setup);
1297 if (ret != 0)
1298 printk(KERN_ERR "can't add i2c driver");
1299 } 1299 }
1300#else 1300#else
1301 /* Add other interfaces here */ 1301 /* Add other interfaces here */
@@ -1320,6 +1320,7 @@ static int aic3x_remove(struct platform_device *pdev)
1320 snd_soc_free_pcms(socdev); 1320 snd_soc_free_pcms(socdev);
1321 snd_soc_dapm_free(socdev); 1321 snd_soc_dapm_free(socdev);
1322#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1322#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1323 i2c_unregister_device(codec->control_data);
1323 i2c_del_driver(&aic3x_i2c_driver); 1324 i2c_del_driver(&aic3x_i2c_driver);
1324#endif 1325#endif
1325 kfree(codec->private_data); 1326 kfree(codec->private_data);
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index d76c079b86e7..00a195aa02e4 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC TLV320AIC3X codec driver 2 * ALSA SoC TLV320AIC3X codec driver
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -224,6 +224,7 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
224int aic3x_headset_detected(struct snd_soc_codec *codec); 224int aic3x_headset_detected(struct snd_soc_codec *codec);
225 225
226struct aic3x_setup_data { 226struct aic3x_setup_data {
227 int i2c_bus;
227 unsigned short i2c_address; 228 unsigned short i2c_address;
228 unsigned int gpio_func[2]; 229 unsigned int gpio_func[2];
229}; 230};
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 807318fbdc8f..a69ee72a7af5 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -36,7 +36,6 @@
36#include "uda1380.h" 36#include "uda1380.h"
37 37
38#define UDA1380_VERSION "0.6" 38#define UDA1380_VERSION "0.6"
39#define AUDIO_NAME "uda1380"
40 39
41/* 40/*
42 * uda1380 register cache 41 * uda1380 register cache
@@ -701,87 +700,86 @@ static struct snd_soc_device *uda1380_socdev;
701 700
702#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 701#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
703 702
704#define I2C_DRIVERID_UDA1380 0xfefe /* liam - need a proper id */ 703static int uda1380_i2c_probe(struct i2c_client *i2c,
705 704 const struct i2c_device_id *id)
706static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
707
708/* Magic definition of all other variables and things */
709I2C_CLIENT_INSMOD;
710
711static struct i2c_driver uda1380_i2c_driver;
712static struct i2c_client client_template;
713
714/* If the i2c layer weren't so broken, we could pass this kind of data
715 around */
716
717static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
718{ 705{
719 struct snd_soc_device *socdev = uda1380_socdev; 706 struct snd_soc_device *socdev = uda1380_socdev;
720 struct uda1380_setup_data *setup = socdev->codec_data; 707 struct uda1380_setup_data *setup = socdev->codec_data;
721 struct snd_soc_codec *codec = socdev->codec; 708 struct snd_soc_codec *codec = socdev->codec;
722 struct i2c_client *i2c;
723 int ret; 709 int ret;
724 710
725 if (addr != setup->i2c_address)
726 return -ENODEV;
727
728 client_template.adapter = adap;
729 client_template.addr = addr;
730
731 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
732 if (i2c == NULL)
733 return -ENOMEM;
734
735 i2c_set_clientdata(i2c, codec); 711 i2c_set_clientdata(i2c, codec);
736 codec->control_data = i2c; 712 codec->control_data = i2c;
737 713
738 ret = i2c_attach_client(i2c);
739 if (ret < 0) {
740 pr_err("uda1380: failed to attach codec at addr %x\n", addr);
741 goto err;
742 }
743
744 ret = uda1380_init(socdev, setup->dac_clk); 714 ret = uda1380_init(socdev, setup->dac_clk);
745 if (ret < 0) { 715 if (ret < 0)
746 pr_err("uda1380: failed to initialise UDA1380\n"); 716 pr_err("uda1380: failed to initialise UDA1380\n");
747 goto err;
748 }
749 return ret;
750 717
751err:
752 kfree(i2c);
753 return ret; 718 return ret;
754} 719}
755 720
756static int uda1380_i2c_detach(struct i2c_client *client) 721static int uda1380_i2c_remove(struct i2c_client *client)
757{ 722{
758 struct snd_soc_codec *codec = i2c_get_clientdata(client); 723 struct snd_soc_codec *codec = i2c_get_clientdata(client);
759 i2c_detach_client(client);
760 kfree(codec->reg_cache); 724 kfree(codec->reg_cache);
761 kfree(client);
762 return 0; 725 return 0;
763} 726}
764 727
765static int uda1380_i2c_attach(struct i2c_adapter *adap) 728static const struct i2c_device_id uda1380_i2c_id[] = {
766{ 729 { "uda1380", 0 },
767 return i2c_probe(adap, &addr_data, uda1380_codec_probe); 730 { }
768} 731};
732MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
769 733
770static struct i2c_driver uda1380_i2c_driver = { 734static struct i2c_driver uda1380_i2c_driver = {
771 .driver = { 735 .driver = {
772 .name = "UDA1380 I2C Codec", 736 .name = "UDA1380 I2C Codec",
773 .owner = THIS_MODULE, 737 .owner = THIS_MODULE,
774 }, 738 },
775 .id = I2C_DRIVERID_UDA1380, 739 .probe = uda1380_i2c_probe,
776 .attach_adapter = uda1380_i2c_attach, 740 .remove = uda1380_i2c_remove,
777 .detach_client = uda1380_i2c_detach, 741 .id_table = uda1380_i2c_id,
778 .command = NULL,
779}; 742};
780 743
781static struct i2c_client client_template = { 744static int uda1380_add_i2c_device(struct platform_device *pdev,
782 .name = "UDA1380", 745 const struct uda1380_setup_data *setup)
783 .driver = &uda1380_i2c_driver, 746{
784}; 747 struct i2c_board_info info;
748 struct i2c_adapter *adapter;
749 struct i2c_client *client;
750 int ret;
751
752 ret = i2c_add_driver(&uda1380_i2c_driver);
753 if (ret != 0) {
754 dev_err(&pdev->dev, "can't add i2c driver\n");
755 return ret;
756 }
757
758 memset(&info, 0, sizeof(struct i2c_board_info));
759 info.addr = setup->i2c_address;
760 strlcpy(info.type, "uda1380", I2C_NAME_SIZE);
761
762 adapter = i2c_get_adapter(setup->i2c_bus);
763 if (!adapter) {
764 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
765 setup->i2c_bus);
766 goto err_driver;
767 }
768
769 client = i2c_new_device(adapter, &info);
770 i2c_put_adapter(adapter);
771 if (!client) {
772 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
773 (unsigned int)info.addr);
774 goto err_driver;
775 }
776
777 return 0;
778
779err_driver:
780 i2c_del_driver(&uda1380_i2c_driver);
781 return -ENODEV;
782}
785#endif 783#endif
786 784
787static int uda1380_probe(struct platform_device *pdev) 785static int uda1380_probe(struct platform_device *pdev)
@@ -789,7 +787,7 @@ static int uda1380_probe(struct platform_device *pdev)
789 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 787 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
790 struct uda1380_setup_data *setup; 788 struct uda1380_setup_data *setup;
791 struct snd_soc_codec *codec; 789 struct snd_soc_codec *codec;
792 int ret = 0; 790 int ret;
793 791
794 pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION); 792 pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION);
795 793
@@ -804,16 +802,13 @@ static int uda1380_probe(struct platform_device *pdev)
804 INIT_LIST_HEAD(&codec->dapm_paths); 802 INIT_LIST_HEAD(&codec->dapm_paths);
805 803
806 uda1380_socdev = socdev; 804 uda1380_socdev = socdev;
805 ret = -ENODEV;
806
807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
808 if (setup->i2c_address) { 808 if (setup->i2c_address) {
809 normal_i2c[0] = setup->i2c_address;
810 codec->hw_write = (hw_write_t)i2c_master_send; 809 codec->hw_write = (hw_write_t)i2c_master_send;
811 ret = i2c_add_driver(&uda1380_i2c_driver); 810 ret = uda1380_add_i2c_device(pdev, setup);
812 if (ret != 0)
813 printk(KERN_ERR "can't add i2c driver");
814 } 811 }
815#else
816 /* Add other interfaces here */
817#endif 812#endif
818 813
819 if (ret != 0) 814 if (ret != 0)
@@ -833,6 +828,7 @@ static int uda1380_remove(struct platform_device *pdev)
833 snd_soc_free_pcms(socdev); 828 snd_soc_free_pcms(socdev);
834 snd_soc_dapm_free(socdev); 829 snd_soc_dapm_free(socdev);
835#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 830#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
831 i2c_unregister_device(codec->control_data);
836 i2c_del_driver(&uda1380_i2c_driver); 832 i2c_del_driver(&uda1380_i2c_driver);
837#endif 833#endif
838 kfree(codec); 834 kfree(codec);
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
index 50c603e2c9f2..c55c17a52a12 100644
--- a/sound/soc/codecs/uda1380.h
+++ b/sound/soc/codecs/uda1380.h
@@ -73,6 +73,7 @@
73#define R23_AGC_EN 0x0001 73#define R23_AGC_EN 0x0001
74 74
75struct uda1380_setup_data { 75struct uda1380_setup_data {
76 int i2c_bus;
76 unsigned short i2c_address; 77 unsigned short i2c_address;
77 int dac_clk; 78 int dac_clk;
78#define UDA1380_DAC_CLK_SYSCLK 0 79#define UDA1380_DAC_CLK_SYSCLK 0
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 3d998e6a997e..d8ca2da8d634 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 6 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License version 2 as
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/spi/spi.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -27,7 +28,6 @@
27 28
28#include "wm8510.h" 29#include "wm8510.h"
29 30
30#define AUDIO_NAME "wm8510"
31#define WM8510_VERSION "0.6" 31#define WM8510_VERSION "0.6"
32 32
33struct snd_soc_codec_device soc_codec_dev_wm8510; 33struct snd_soc_codec_device soc_codec_dev_wm8510;
@@ -55,6 +55,9 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
55 0x0001, 55 0x0001,
56}; 56};
57 57
58#define WM8510_POWER1_BIASEN 0x08
59#define WM8510_POWER1_BUFIOEN 0x10
60
58/* 61/*
59 * read wm8510 register cache 62 * read wm8510 register cache
60 */ 63 */
@@ -199,7 +202,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8510_MONOMIX, 0, 1, 0),
199}; 202};
200 203
201static const struct snd_kcontrol_new wm8510_boost_controls[] = { 204static const struct snd_kcontrol_new wm8510_boost_controls[] = {
202SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 0), 205SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 1),
203SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0), 206SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0),
204SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0), 207SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0),
205}; 208};
@@ -224,9 +227,9 @@ SND_SOC_DAPM_PGA("SpkN Out", WM8510_POWER3, 5, 0, NULL, 0),
224SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0), 227SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0),
225SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0), 228SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0),
226 229
227SND_SOC_DAPM_PGA("Mic PGA", WM8510_POWER2, 2, 0, 230SND_SOC_DAPM_MIXER("Mic PGA", WM8510_POWER2, 2, 0,
228 &wm8510_micpga_controls[0], 231 &wm8510_micpga_controls[0],
229 ARRAY_SIZE(wm8510_micpga_controls)), 232 ARRAY_SIZE(wm8510_micpga_controls)),
230SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0, 233SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0,
231 &wm8510_boost_controls[0], 234 &wm8510_boost_controls[0],
232 ARRAY_SIZE(wm8510_boost_controls)), 235 ARRAY_SIZE(wm8510_boost_controls)),
@@ -526,23 +529,35 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
526static int wm8510_set_bias_level(struct snd_soc_codec *codec, 529static int wm8510_set_bias_level(struct snd_soc_codec *codec,
527 enum snd_soc_bias_level level) 530 enum snd_soc_bias_level level)
528{ 531{
532 u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3;
529 533
530 switch (level) { 534 switch (level) {
531 case SND_SOC_BIAS_ON: 535 case SND_SOC_BIAS_ON:
532 wm8510_write(codec, WM8510_POWER1, 0x1ff);
533 wm8510_write(codec, WM8510_POWER2, 0x1ff);
534 wm8510_write(codec, WM8510_POWER3, 0x1ff);
535 break;
536 case SND_SOC_BIAS_PREPARE: 536 case SND_SOC_BIAS_PREPARE:
537 power1 |= 0x1; /* VMID 50k */
538 wm8510_write(codec, WM8510_POWER1, power1);
539 break;
540
537 case SND_SOC_BIAS_STANDBY: 541 case SND_SOC_BIAS_STANDBY:
542 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
543
544 if (codec->bias_level == SND_SOC_BIAS_OFF) {
545 /* Initial cap charge at VMID 5k */
546 wm8510_write(codec, WM8510_POWER1, power1 | 0x3);
547 mdelay(100);
548 }
549
550 power1 |= 0x2; /* VMID 500k */
551 wm8510_write(codec, WM8510_POWER1, power1);
538 break; 552 break;
553
539 case SND_SOC_BIAS_OFF: 554 case SND_SOC_BIAS_OFF:
540 /* everything off, dac mute, inactive */ 555 wm8510_write(codec, WM8510_POWER1, 0);
541 wm8510_write(codec, WM8510_POWER1, 0x0); 556 wm8510_write(codec, WM8510_POWER2, 0);
542 wm8510_write(codec, WM8510_POWER2, 0x0); 557 wm8510_write(codec, WM8510_POWER3, 0);
543 wm8510_write(codec, WM8510_POWER3, 0x0);
544 break; 558 break;
545 } 559 }
560
546 codec->bias_level = level; 561 codec->bias_level = level;
547 return 0; 562 return 0;
548} 563}
@@ -640,6 +655,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
640 } 655 }
641 656
642 /* power on device */ 657 /* power on device */
658 codec->bias_level = SND_SOC_BIAS_OFF;
643 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 659 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
644 wm8510_add_controls(codec); 660 wm8510_add_controls(codec);
645 wm8510_add_widgets(codec); 661 wm8510_add_widgets(codec);
@@ -665,90 +681,144 @@ static struct snd_soc_device *wm8510_socdev;
665/* 681/*
666 * WM8510 2 wire address is 0x1a 682 * WM8510 2 wire address is 0x1a
667 */ 683 */
668#define I2C_DRIVERID_WM8510 0xfefe /* liam - need a proper id */
669
670static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
671 684
672/* Magic definition of all other variables and things */ 685static int wm8510_i2c_probe(struct i2c_client *i2c,
673I2C_CLIENT_INSMOD; 686 const struct i2c_device_id *id)
674
675static struct i2c_driver wm8510_i2c_driver;
676static struct i2c_client client_template;
677
678/* If the i2c layer weren't so broken, we could pass this kind of data
679 around */
680
681static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind)
682{ 687{
683 struct snd_soc_device *socdev = wm8510_socdev; 688 struct snd_soc_device *socdev = wm8510_socdev;
684 struct wm8510_setup_data *setup = socdev->codec_data;
685 struct snd_soc_codec *codec = socdev->codec; 689 struct snd_soc_codec *codec = socdev->codec;
686 struct i2c_client *i2c;
687 int ret; 690 int ret;
688 691
689 if (addr != setup->i2c_address)
690 return -ENODEV;
691
692 client_template.adapter = adap;
693 client_template.addr = addr;
694
695 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
696 if (i2c == NULL)
697 return -ENOMEM;
698
699 i2c_set_clientdata(i2c, codec); 692 i2c_set_clientdata(i2c, codec);
700 codec->control_data = i2c; 693 codec->control_data = i2c;
701 694
702 ret = i2c_attach_client(i2c);
703 if (ret < 0) {
704 pr_err("failed to attach codec at addr %x\n", addr);
705 goto err;
706 }
707
708 ret = wm8510_init(socdev); 695 ret = wm8510_init(socdev);
709 if (ret < 0) { 696 if (ret < 0)
710 pr_err("failed to initialise WM8510\n"); 697 pr_err("failed to initialise WM8510\n");
711 goto err;
712 }
713 return ret;
714 698
715err:
716 kfree(i2c);
717 return ret; 699 return ret;
718} 700}
719 701
720static int wm8510_i2c_detach(struct i2c_client *client) 702static int wm8510_i2c_remove(struct i2c_client *client)
721{ 703{
722 struct snd_soc_codec *codec = i2c_get_clientdata(client); 704 struct snd_soc_codec *codec = i2c_get_clientdata(client);
723 i2c_detach_client(client);
724 kfree(codec->reg_cache); 705 kfree(codec->reg_cache);
725 kfree(client);
726 return 0; 706 return 0;
727} 707}
728 708
729static int wm8510_i2c_attach(struct i2c_adapter *adap) 709static const struct i2c_device_id wm8510_i2c_id[] = {
730{ 710 { "wm8510", 0 },
731 return i2c_probe(adap, &addr_data, wm8510_codec_probe); 711 { }
732} 712};
713MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
733 714
734/* corgi i2c codec control layer */
735static struct i2c_driver wm8510_i2c_driver = { 715static struct i2c_driver wm8510_i2c_driver = {
736 .driver = { 716 .driver = {
737 .name = "WM8510 I2C Codec", 717 .name = "WM8510 I2C Codec",
738 .owner = THIS_MODULE, 718 .owner = THIS_MODULE,
739 }, 719 },
740 .id = I2C_DRIVERID_WM8510, 720 .probe = wm8510_i2c_probe,
741 .attach_adapter = wm8510_i2c_attach, 721 .remove = wm8510_i2c_remove,
742 .detach_client = wm8510_i2c_detach, 722 .id_table = wm8510_i2c_id,
743 .command = NULL,
744}; 723};
745 724
746static struct i2c_client client_template = { 725static int wm8510_add_i2c_device(struct platform_device *pdev,
747 .name = "WM8510", 726 const struct wm8510_setup_data *setup)
748 .driver = &wm8510_i2c_driver, 727{
749}; 728 struct i2c_board_info info;
729 struct i2c_adapter *adapter;
730 struct i2c_client *client;
731 int ret;
732
733 ret = i2c_add_driver(&wm8510_i2c_driver);
734 if (ret != 0) {
735 dev_err(&pdev->dev, "can't add i2c driver\n");
736 return ret;
737 }
738
739 memset(&info, 0, sizeof(struct i2c_board_info));
740 info.addr = setup->i2c_address;
741 strlcpy(info.type, "wm8510", I2C_NAME_SIZE);
742
743 adapter = i2c_get_adapter(setup->i2c_bus);
744 if (!adapter) {
745 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
746 setup->i2c_bus);
747 goto err_driver;
748 }
749
750 client = i2c_new_device(adapter, &info);
751 i2c_put_adapter(adapter);
752 if (!client) {
753 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
754 (unsigned int)info.addr);
755 goto err_driver;
756 }
757
758 return 0;
759
760err_driver:
761 i2c_del_driver(&wm8510_i2c_driver);
762 return -ENODEV;
763}
750#endif 764#endif
751 765
766#if defined(CONFIG_SPI_MASTER)
767static int __devinit wm8510_spi_probe(struct spi_device *spi)
768{
769 struct snd_soc_device *socdev = wm8510_socdev;
770 struct snd_soc_codec *codec = socdev->codec;
771 int ret;
772
773 codec->control_data = spi;
774
775 ret = wm8510_init(socdev);
776 if (ret < 0)
777 dev_err(&spi->dev, "failed to initialise WM8510\n");
778
779 return ret;
780}
781
782static int __devexit wm8510_spi_remove(struct spi_device *spi)
783{
784 return 0;
785}
786
787static struct spi_driver wm8510_spi_driver = {
788 .driver = {
789 .name = "wm8510",
790 .bus = &spi_bus_type,
791 .owner = THIS_MODULE,
792 },
793 .probe = wm8510_spi_probe,
794 .remove = __devexit_p(wm8510_spi_remove),
795};
796
797static int wm8510_spi_write(struct spi_device *spi, const char *data, int len)
798{
799 struct spi_transfer t;
800 struct spi_message m;
801 u8 msg[2];
802
803 if (len <= 0)
804 return 0;
805
806 msg[0] = data[0];
807 msg[1] = data[1];
808
809 spi_message_init(&m);
810 memset(&t, 0, (sizeof t));
811
812 t.tx_buf = &msg[0];
813 t.len = len;
814
815 spi_message_add_tail(&t, &m);
816 spi_sync(spi, &m);
817
818 return len;
819}
820#endif /* CONFIG_SPI_MASTER */
821
752static int wm8510_probe(struct platform_device *pdev) 822static int wm8510_probe(struct platform_device *pdev)
753{ 823{
754 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 824 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -771,14 +841,17 @@ static int wm8510_probe(struct platform_device *pdev)
771 wm8510_socdev = socdev; 841 wm8510_socdev = socdev;
772#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 842#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
773 if (setup->i2c_address) { 843 if (setup->i2c_address) {
774 normal_i2c[0] = setup->i2c_address;
775 codec->hw_write = (hw_write_t)i2c_master_send; 844 codec->hw_write = (hw_write_t)i2c_master_send;
776 ret = i2c_add_driver(&wm8510_i2c_driver); 845 ret = wm8510_add_i2c_device(pdev, setup);
846 }
847#endif
848#if defined(CONFIG_SPI_MASTER)
849 if (setup->spi) {
850 codec->hw_write = (hw_write_t)wm8510_spi_write;
851 ret = spi_register_driver(&wm8510_spi_driver);
777 if (ret != 0) 852 if (ret != 0)
778 printk(KERN_ERR "can't add i2c driver"); 853 printk(KERN_ERR "can't add spi driver");
779 } 854 }
780#else
781 /* Add other interfaces here */
782#endif 855#endif
783 856
784 if (ret != 0) 857 if (ret != 0)
@@ -798,8 +871,12 @@ static int wm8510_remove(struct platform_device *pdev)
798 snd_soc_free_pcms(socdev); 871 snd_soc_free_pcms(socdev);
799 snd_soc_dapm_free(socdev); 872 snd_soc_dapm_free(socdev);
800#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 873#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
874 i2c_unregister_device(codec->control_data);
801 i2c_del_driver(&wm8510_i2c_driver); 875 i2c_del_driver(&wm8510_i2c_driver);
802#endif 876#endif
877#if defined(CONFIG_SPI_MASTER)
878 spi_unregister_driver(&wm8510_spi_driver);
879#endif
803 kfree(codec); 880 kfree(codec);
804 881
805 return 0; 882 return 0;
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
index f5d2e42eb3f4..bdefcf5c69ff 100644
--- a/sound/soc/codecs/wm8510.h
+++ b/sound/soc/codecs/wm8510.h
@@ -94,6 +94,8 @@
94#define WM8510_MCLKDIV_12 (7 << 5) 94#define WM8510_MCLKDIV_12 (7 << 5)
95 95
96struct wm8510_setup_data { 96struct wm8510_setup_data {
97 int spi;
98 int i2c_bus;
97 unsigned short i2c_address; 99 unsigned short i2c_address;
98}; 100};
99 101
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
new file mode 100644
index 000000000000..627ebfb4209b
--- /dev/null
+++ b/sound/soc/codecs/wm8580.c
@@ -0,0 +1,1053 @@
1/*
2 * wm8580.c -- WM8580 ALSA Soc Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
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 * Notes:
12 * The WM8580 is a multichannel codec with S/PDIF support, featuring six
13 * DAC channels and two ADC channels.
14 *
15 * Currently only the primary audio interface is supported - S/PDIF and
16 * the secondary audio interfaces are not.
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/pm.h>
25#include <linux/i2c.h>
26#include <linux/platform_device.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/tlv.h>
33#include <sound/initval.h>
34#include <asm/div64.h>
35
36#include "wm8580.h"
37
38#define WM8580_VERSION "0.1"
39
40struct pll_state {
41 unsigned int in;
42 unsigned int out;
43};
44
45/* codec private data */
46struct wm8580_priv {
47 struct pll_state a;
48 struct pll_state b;
49};
50
51/* WM8580 register space */
52#define WM8580_PLLA1 0x00
53#define WM8580_PLLA2 0x01
54#define WM8580_PLLA3 0x02
55#define WM8580_PLLA4 0x03
56#define WM8580_PLLB1 0x04
57#define WM8580_PLLB2 0x05
58#define WM8580_PLLB3 0x06
59#define WM8580_PLLB4 0x07
60#define WM8580_CLKSEL 0x08
61#define WM8580_PAIF1 0x09
62#define WM8580_PAIF2 0x0A
63#define WM8580_SAIF1 0x0B
64#define WM8580_PAIF3 0x0C
65#define WM8580_PAIF4 0x0D
66#define WM8580_SAIF2 0x0E
67#define WM8580_DAC_CONTROL1 0x0F
68#define WM8580_DAC_CONTROL2 0x10
69#define WM8580_DAC_CONTROL3 0x11
70#define WM8580_DAC_CONTROL4 0x12
71#define WM8580_DAC_CONTROL5 0x13
72#define WM8580_DIGITAL_ATTENUATION_DACL1 0x14
73#define WM8580_DIGITAL_ATTENUATION_DACR1 0x15
74#define WM8580_DIGITAL_ATTENUATION_DACL2 0x16
75#define WM8580_DIGITAL_ATTENUATION_DACR2 0x17
76#define WM8580_DIGITAL_ATTENUATION_DACL3 0x18
77#define WM8580_DIGITAL_ATTENUATION_DACR3 0x19
78#define WM8580_MASTER_DIGITAL_ATTENUATION 0x1C
79#define WM8580_ADC_CONTROL1 0x1D
80#define WM8580_SPDTXCHAN0 0x1E
81#define WM8580_SPDTXCHAN1 0x1F
82#define WM8580_SPDTXCHAN2 0x20
83#define WM8580_SPDTXCHAN3 0x21
84#define WM8580_SPDTXCHAN4 0x22
85#define WM8580_SPDTXCHAN5 0x23
86#define WM8580_SPDMODE 0x24
87#define WM8580_INTMASK 0x25
88#define WM8580_GPO1 0x26
89#define WM8580_GPO2 0x27
90#define WM8580_GPO3 0x28
91#define WM8580_GPO4 0x29
92#define WM8580_GPO5 0x2A
93#define WM8580_INTSTAT 0x2B
94#define WM8580_SPDRXCHAN1 0x2C
95#define WM8580_SPDRXCHAN2 0x2D
96#define WM8580_SPDRXCHAN3 0x2E
97#define WM8580_SPDRXCHAN4 0x2F
98#define WM8580_SPDRXCHAN5 0x30
99#define WM8580_SPDSTAT 0x31
100#define WM8580_PWRDN1 0x32
101#define WM8580_PWRDN2 0x33
102#define WM8580_READBACK 0x34
103#define WM8580_RESET 0x35
104
105/* PLLB4 (register 7h) */
106#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
107#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
108#define WM8580_PLLB4_MCLKOUTSRC_PLLB 0x40
109#define WM8580_PLLB4_MCLKOUTSRC_OSC 0x60
110
111#define WM8580_PLLB4_CLKOUTSRC_MASK 0x180
112#define WM8580_PLLB4_CLKOUTSRC_PLLACLK 0x080
113#define WM8580_PLLB4_CLKOUTSRC_PLLBCLK 0x100
114#define WM8580_PLLB4_CLKOUTSRC_OSCCLK 0x180
115
116/* CLKSEL (register 8h) */
117#define WM8580_CLKSEL_DAC_CLKSEL_MASK 0x03
118#define WM8580_CLKSEL_DAC_CLKSEL_PLLA 0x01
119#define WM8580_CLKSEL_DAC_CLKSEL_PLLB 0x02
120
121/* AIF control 1 (registers 9h-bh) */
122#define WM8580_AIF_RATE_MASK 0x7
123#define WM8580_AIF_RATE_128 0x0
124#define WM8580_AIF_RATE_192 0x1
125#define WM8580_AIF_RATE_256 0x2
126#define WM8580_AIF_RATE_384 0x3
127#define WM8580_AIF_RATE_512 0x4
128#define WM8580_AIF_RATE_768 0x5
129#define WM8580_AIF_RATE_1152 0x6
130
131#define WM8580_AIF_BCLKSEL_MASK 0x18
132#define WM8580_AIF_BCLKSEL_64 0x00
133#define WM8580_AIF_BCLKSEL_128 0x08
134#define WM8580_AIF_BCLKSEL_256 0x10
135#define WM8580_AIF_BCLKSEL_SYSCLK 0x18
136
137#define WM8580_AIF_MS 0x20
138
139#define WM8580_AIF_CLKSRC_MASK 0xc0
140#define WM8580_AIF_CLKSRC_PLLA 0x40
141#define WM8580_AIF_CLKSRC_PLLB 0x40
142#define WM8580_AIF_CLKSRC_MCLK 0xc0
143
144/* AIF control 2 (registers ch-eh) */
145#define WM8580_AIF_FMT_MASK 0x03
146#define WM8580_AIF_FMT_RIGHTJ 0x00
147#define WM8580_AIF_FMT_LEFTJ 0x01
148#define WM8580_AIF_FMT_I2S 0x02
149#define WM8580_AIF_FMT_DSP 0x03
150
151#define WM8580_AIF_LENGTH_MASK 0x0c
152#define WM8580_AIF_LENGTH_16 0x00
153#define WM8580_AIF_LENGTH_20 0x04
154#define WM8580_AIF_LENGTH_24 0x08
155#define WM8580_AIF_LENGTH_32 0x0c
156
157#define WM8580_AIF_LRP 0x10
158#define WM8580_AIF_BCP 0x20
159
160/* Powerdown Register 1 (register 32h) */
161#define WM8580_PWRDN1_PWDN 0x001
162#define WM8580_PWRDN1_ALLDACPD 0x040
163
164/* Powerdown Register 2 (register 33h) */
165#define WM8580_PWRDN2_OSSCPD 0x001
166#define WM8580_PWRDN2_PLLAPD 0x002
167#define WM8580_PWRDN2_PLLBPD 0x004
168#define WM8580_PWRDN2_SPDIFPD 0x008
169#define WM8580_PWRDN2_SPDIFTXD 0x010
170#define WM8580_PWRDN2_SPDIFRXD 0x020
171
172#define WM8580_DAC_CONTROL5_MUTEALL 0x10
173
174/*
175 * wm8580 register cache
176 * We can't read the WM8580 register space when we
177 * are using 2 wire for device control, so we cache them instead.
178 */
179static const u16 wm8580_reg[] = {
180 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
181 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
182 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
183 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
184 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
185 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
186 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R27*/
187 0x01f0, 0x0040, 0x0000, 0x0000, /*R31(0x1F)*/
188 0x0000, 0x0000, 0x0031, 0x000b, /*R35*/
189 0x0039, 0x0000, 0x0010, 0x0032, /*R39*/
190 0x0054, 0x0076, 0x0098, 0x0000, /*R43(0x2B)*/
191 0x0000, 0x0000, 0x0000, 0x0000, /*R47*/
192 0x0000, 0x0000, 0x005e, 0x003e, /*R51(0x33)*/
193 0x0000, 0x0000 /*R53*/
194};
195
196/*
197 * read wm8580 register cache
198 */
199static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
200 unsigned int reg)
201{
202 u16 *cache = codec->reg_cache;
203 BUG_ON(reg > ARRAY_SIZE(wm8580_reg));
204 return cache[reg];
205}
206
207/*
208 * write wm8580 register cache
209 */
210static inline void wm8580_write_reg_cache(struct snd_soc_codec *codec,
211 unsigned int reg, unsigned int value)
212{
213 u16 *cache = codec->reg_cache;
214
215 cache[reg] = value;
216}
217
218/*
219 * write to the WM8580 register space
220 */
221static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
222 unsigned int value)
223{
224 u8 data[2];
225
226 BUG_ON(reg > ARRAY_SIZE(wm8580_reg));
227
228 /* Registers are 9 bits wide */
229 value &= 0x1ff;
230
231 switch (reg) {
232 case WM8580_RESET:
233 /* Uncached */
234 break;
235 default:
236 if (value == wm8580_read_reg_cache(codec, reg))
237 return 0;
238 }
239
240 /* data is
241 * D15..D9 WM8580 register offset
242 * D8...D0 register data
243 */
244 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
245 data[1] = value & 0x00ff;
246
247 wm8580_write_reg_cache(codec, reg, value);
248 if (codec->hw_write(codec->control_data, data, 2) == 2)
249 return 0;
250 else
251 return -EIO;
252}
253
254static inline unsigned int wm8580_read(struct snd_soc_codec *codec,
255 unsigned int reg)
256{
257 switch (reg) {
258 default:
259 return wm8580_read_reg_cache(codec, reg);
260 }
261}
262
263static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
264
265static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
266 struct snd_ctl_elem_value *ucontrol)
267{
268 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
269 int reg = kcontrol->private_value & 0xff;
270 int reg2 = (kcontrol->private_value >> 24) & 0xff;
271 int ret;
272 u16 val;
273
274 /* Clear the register cache so we write without VU set */
275 wm8580_write_reg_cache(codec, reg, 0);
276 wm8580_write_reg_cache(codec, reg2, 0);
277
278 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
279 if (ret < 0)
280 return ret;
281
282 /* Now write again with the volume update bit set */
283 val = wm8580_read_reg_cache(codec, reg);
284 wm8580_write(codec, reg, val | 0x0100);
285
286 val = wm8580_read_reg_cache(codec, reg2);
287 wm8580_write(codec, reg2, val | 0x0100);
288
289 return 0;
290}
291
292#define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, shift, max, invert, tlv_array) \
293{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
294 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
295 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
296 .tlv.p = (tlv_array), \
297 .info = snd_soc_info_volsw_2r, \
298 .get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \
299 .private_value = (reg_left) | ((shift) << 8) | \
300 ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
301
302static const struct snd_kcontrol_new wm8580_snd_controls[] = {
303SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume",
304 WM8580_DIGITAL_ATTENUATION_DACL1,
305 WM8580_DIGITAL_ATTENUATION_DACR1,
306 0, 0xff, 0, dac_tlv),
307SOC_WM8580_OUT_DOUBLE_R_TLV("DAC2 Playback Volume",
308 WM8580_DIGITAL_ATTENUATION_DACL2,
309 WM8580_DIGITAL_ATTENUATION_DACR2,
310 0, 0xff, 0, dac_tlv),
311SOC_WM8580_OUT_DOUBLE_R_TLV("DAC3 Playback Volume",
312 WM8580_DIGITAL_ATTENUATION_DACL3,
313 WM8580_DIGITAL_ATTENUATION_DACR3,
314 0, 0xff, 0, dac_tlv),
315
316SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),
317SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),
318SOC_SINGLE("DAC3 Deemphasis Switch", WM8580_DAC_CONTROL3, 2, 1, 0),
319
320SOC_DOUBLE("DAC1 Invert Switch", WM8580_DAC_CONTROL4, 0, 1, 1, 0),
321SOC_DOUBLE("DAC2 Invert Switch", WM8580_DAC_CONTROL4, 2, 3, 1, 0),
322SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0),
323
324SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0),
325SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 0),
326SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 0),
327SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 0),
328
329SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
330SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
331};
332
333/* Add non-DAPM controls */
334static int wm8580_add_controls(struct snd_soc_codec *codec)
335{
336 int err, i;
337
338 for (i = 0; i < ARRAY_SIZE(wm8580_snd_controls); i++) {
339 err = snd_ctl_add(codec->card,
340 snd_soc_cnew(&wm8580_snd_controls[i],
341 codec, NULL));
342 if (err < 0)
343 return err;
344 }
345 return 0;
346}
347static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
348SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),
349SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),
350SND_SOC_DAPM_DAC("DAC3", "Playback", WM8580_PWRDN1, 4, 1),
351
352SND_SOC_DAPM_OUTPUT("VOUT1L"),
353SND_SOC_DAPM_OUTPUT("VOUT1R"),
354SND_SOC_DAPM_OUTPUT("VOUT2L"),
355SND_SOC_DAPM_OUTPUT("VOUT2R"),
356SND_SOC_DAPM_OUTPUT("VOUT3L"),
357SND_SOC_DAPM_OUTPUT("VOUT3R"),
358
359SND_SOC_DAPM_ADC("ADC", "Capture", WM8580_PWRDN1, 1, 1),
360
361SND_SOC_DAPM_INPUT("AINL"),
362SND_SOC_DAPM_INPUT("AINR"),
363};
364
365static const struct snd_soc_dapm_route audio_map[] = {
366 { "VOUT1L", NULL, "DAC1" },
367 { "VOUT1R", NULL, "DAC1" },
368
369 { "VOUT2L", NULL, "DAC2" },
370 { "VOUT2R", NULL, "DAC2" },
371
372 { "VOUT3L", NULL, "DAC3" },
373 { "VOUT3R", NULL, "DAC3" },
374
375 { "ADC", NULL, "AINL" },
376 { "ADC", NULL, "AINR" },
377};
378
379static int wm8580_add_widgets(struct snd_soc_codec *codec)
380{
381 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets,
382 ARRAY_SIZE(wm8580_dapm_widgets));
383
384 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
385
386 snd_soc_dapm_new_widgets(codec);
387 return 0;
388}
389
390/* PLL divisors */
391struct _pll_div {
392 u32 prescale:1;
393 u32 postscale:1;
394 u32 freqmode:2;
395 u32 n:4;
396 u32 k:24;
397};
398
399/* The size in bits of the pll divide */
400#define FIXED_PLL_SIZE (1 << 22)
401
402/* PLL rate to output rate divisions */
403static struct {
404 unsigned int div;
405 unsigned int freqmode;
406 unsigned int postscale;
407} post_table[] = {
408 { 2, 0, 0 },
409 { 4, 0, 1 },
410 { 4, 1, 0 },
411 { 8, 1, 1 },
412 { 8, 2, 0 },
413 { 16, 2, 1 },
414 { 12, 3, 0 },
415 { 24, 3, 1 }
416};
417
418static int pll_factors(struct _pll_div *pll_div, unsigned int target,
419 unsigned int source)
420{
421 u64 Kpart;
422 unsigned int K, Ndiv, Nmod;
423 int i;
424
425 pr_debug("wm8580: PLL %dHz->%dHz\n", source, target);
426
427 /* Scale the output frequency up; the PLL should run in the
428 * region of 90-100MHz.
429 */
430 for (i = 0; i < ARRAY_SIZE(post_table); i++) {
431 if (target * post_table[i].div >= 90000000 &&
432 target * post_table[i].div <= 100000000) {
433 pll_div->freqmode = post_table[i].freqmode;
434 pll_div->postscale = post_table[i].postscale;
435 target *= post_table[i].div;
436 break;
437 }
438 }
439
440 if (i == ARRAY_SIZE(post_table)) {
441 printk(KERN_ERR "wm8580: Unable to scale output frequency "
442 "%u\n", target);
443 return -EINVAL;
444 }
445
446 Ndiv = target / source;
447
448 if (Ndiv < 5) {
449 source /= 2;
450 pll_div->prescale = 1;
451 Ndiv = target / source;
452 } else
453 pll_div->prescale = 0;
454
455 if ((Ndiv < 5) || (Ndiv > 13)) {
456 printk(KERN_ERR
457 "WM8580 N=%d outside supported range\n", Ndiv);
458 return -EINVAL;
459 }
460
461 pll_div->n = Ndiv;
462 Nmod = target % source;
463 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
464
465 do_div(Kpart, source);
466
467 K = Kpart & 0xFFFFFFFF;
468
469 pll_div->k = K;
470
471 pr_debug("PLL %x.%x prescale %d freqmode %d postscale %d\n",
472 pll_div->n, pll_div->k, pll_div->prescale, pll_div->freqmode,
473 pll_div->postscale);
474
475 return 0;
476}
477
478static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
479 int pll_id, unsigned int freq_in, unsigned int freq_out)
480{
481 int offset;
482 struct snd_soc_codec *codec = codec_dai->codec;
483 struct wm8580_priv *wm8580 = codec->private_data;
484 struct pll_state *state;
485 struct _pll_div pll_div;
486 unsigned int reg;
487 unsigned int pwr_mask;
488 int ret;
489
490 /* GCC isn't able to work out the ifs below for initialising/using
491 * pll_div so suppress warnings.
492 */
493 memset(&pll_div, 0, sizeof(pll_div));
494
495 switch (pll_id) {
496 case WM8580_PLLA:
497 state = &wm8580->a;
498 offset = 0;
499 pwr_mask = WM8580_PWRDN2_PLLAPD;
500 break;
501 case WM8580_PLLB:
502 state = &wm8580->b;
503 offset = 4;
504 pwr_mask = WM8580_PWRDN2_PLLBPD;
505 break;
506 default:
507 return -ENODEV;
508 }
509
510 if (freq_in && freq_out) {
511 ret = pll_factors(&pll_div, freq_out, freq_in);
512 if (ret != 0)
513 return ret;
514 }
515
516 state->in = freq_in;
517 state->out = freq_out;
518
519 /* Always disable the PLL - it is not safe to leave it running
520 * while reprogramming it.
521 */
522 reg = wm8580_read(codec, WM8580_PWRDN2);
523 wm8580_write(codec, WM8580_PWRDN2, reg | pwr_mask);
524
525 if (!freq_in || !freq_out)
526 return 0;
527
528 wm8580_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
529 wm8580_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff);
530 wm8580_write(codec, WM8580_PLLA3 + offset,
531 (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
532
533 reg = wm8580_read(codec, WM8580_PLLA4 + offset);
534 reg &= ~0x3f;
535 reg |= pll_div.prescale | pll_div.postscale << 1 |
536 pll_div.freqmode << 4;
537
538 wm8580_write(codec, WM8580_PLLA4 + offset, reg);
539
540 /* All done, turn it on */
541 reg = wm8580_read(codec, WM8580_PWRDN2);
542 wm8580_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
543
544 return 0;
545}
546
547/*
548 * Set PCM DAI bit size and sample rate.
549 */
550static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
551 struct snd_pcm_hw_params *params)
552{
553 struct snd_soc_pcm_runtime *rtd = substream->private_data;
554 struct snd_soc_dai_link *dai = rtd->dai;
555 struct snd_soc_device *socdev = rtd->socdev;
556 struct snd_soc_codec *codec = socdev->codec;
557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->codec_dai->id);
558
559 paifb &= ~WM8580_AIF_LENGTH_MASK;
560 /* bit size */
561 switch (params_format(params)) {
562 case SNDRV_PCM_FORMAT_S16_LE:
563 break;
564 case SNDRV_PCM_FORMAT_S20_3LE:
565 paifb |= WM8580_AIF_LENGTH_20;
566 break;
567 case SNDRV_PCM_FORMAT_S24_LE:
568 paifb |= WM8580_AIF_LENGTH_24;
569 break;
570 case SNDRV_PCM_FORMAT_S32_LE:
571 paifb |= WM8580_AIF_LENGTH_24;
572 break;
573 default:
574 return -EINVAL;
575 }
576
577 wm8580_write(codec, WM8580_PAIF3 + dai->codec_dai->id, paifb);
578 return 0;
579}
580
581static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
582 unsigned int fmt)
583{
584 struct snd_soc_codec *codec = codec_dai->codec;
585 unsigned int aifa;
586 unsigned int aifb;
587 int can_invert_lrclk;
588
589 aifa = wm8580_read(codec, WM8580_PAIF1 + codec_dai->id);
590 aifb = wm8580_read(codec, WM8580_PAIF3 + codec_dai->id);
591
592 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
593
594 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
595 case SND_SOC_DAIFMT_CBS_CFS:
596 aifa &= ~WM8580_AIF_MS;
597 break;
598 case SND_SOC_DAIFMT_CBM_CFM:
599 aifa |= WM8580_AIF_MS;
600 break;
601 default:
602 return -EINVAL;
603 }
604
605 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
606 case SND_SOC_DAIFMT_I2S:
607 can_invert_lrclk = 1;
608 aifb |= WM8580_AIF_FMT_I2S;
609 break;
610 case SND_SOC_DAIFMT_RIGHT_J:
611 can_invert_lrclk = 1;
612 aifb |= WM8580_AIF_FMT_RIGHTJ;
613 break;
614 case SND_SOC_DAIFMT_LEFT_J:
615 can_invert_lrclk = 1;
616 aifb |= WM8580_AIF_FMT_LEFTJ;
617 break;
618 case SND_SOC_DAIFMT_DSP_A:
619 can_invert_lrclk = 0;
620 aifb |= WM8580_AIF_FMT_DSP;
621 break;
622 case SND_SOC_DAIFMT_DSP_B:
623 can_invert_lrclk = 0;
624 aifb |= WM8580_AIF_FMT_DSP;
625 aifb |= WM8580_AIF_LRP;
626 break;
627 default:
628 return -EINVAL;
629 }
630
631 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
632 case SND_SOC_DAIFMT_NB_NF:
633 break;
634
635 case SND_SOC_DAIFMT_IB_IF:
636 if (!can_invert_lrclk)
637 return -EINVAL;
638 aifb |= WM8580_AIF_BCP;
639 aifb |= WM8580_AIF_LRP;
640 break;
641
642 case SND_SOC_DAIFMT_IB_NF:
643 aifb |= WM8580_AIF_BCP;
644 break;
645
646 case SND_SOC_DAIFMT_NB_IF:
647 if (!can_invert_lrclk)
648 return -EINVAL;
649 aifb |= WM8580_AIF_LRP;
650 break;
651
652 default:
653 return -EINVAL;
654 }
655
656 wm8580_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
657 wm8580_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
658
659 return 0;
660}
661
662static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
663 int div_id, int div)
664{
665 struct snd_soc_codec *codec = codec_dai->codec;
666 unsigned int reg;
667
668 switch (div_id) {
669 case WM8580_MCLK:
670 reg = wm8580_read(codec, WM8580_PLLB4);
671 reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
672
673 switch (div) {
674 case WM8580_CLKSRC_MCLK:
675 /* Input */
676 break;
677
678 case WM8580_CLKSRC_PLLA:
679 reg |= WM8580_PLLB4_MCLKOUTSRC_PLLA;
680 break;
681 case WM8580_CLKSRC_PLLB:
682 reg |= WM8580_PLLB4_MCLKOUTSRC_PLLB;
683 break;
684
685 case WM8580_CLKSRC_OSC:
686 reg |= WM8580_PLLB4_MCLKOUTSRC_OSC;
687 break;
688
689 default:
690 return -EINVAL;
691 }
692 wm8580_write(codec, WM8580_PLLB4, reg);
693 break;
694
695 case WM8580_DAC_CLKSEL:
696 reg = wm8580_read(codec, WM8580_CLKSEL);
697 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
698
699 switch (div) {
700 case WM8580_CLKSRC_MCLK:
701 break;
702
703 case WM8580_CLKSRC_PLLA:
704 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLA;
705 break;
706
707 case WM8580_CLKSRC_PLLB:
708 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLB;
709 break;
710
711 default:
712 return -EINVAL;
713 }
714 wm8580_write(codec, WM8580_CLKSEL, reg);
715 break;
716
717 case WM8580_CLKOUTSRC:
718 reg = wm8580_read(codec, WM8580_PLLB4);
719 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
720
721 switch (div) {
722 case WM8580_CLKSRC_NONE:
723 break;
724
725 case WM8580_CLKSRC_PLLA:
726 reg |= WM8580_PLLB4_CLKOUTSRC_PLLACLK;
727 break;
728
729 case WM8580_CLKSRC_PLLB:
730 reg |= WM8580_PLLB4_CLKOUTSRC_PLLBCLK;
731 break;
732
733 case WM8580_CLKSRC_OSC:
734 reg |= WM8580_PLLB4_CLKOUTSRC_OSCCLK;
735 break;
736
737 default:
738 return -EINVAL;
739 }
740 wm8580_write(codec, WM8580_PLLB4, reg);
741 break;
742
743 default:
744 return -EINVAL;
745 }
746
747 return 0;
748}
749
750static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
751{
752 struct snd_soc_codec *codec = codec_dai->codec;
753 unsigned int reg;
754
755 reg = wm8580_read(codec, WM8580_DAC_CONTROL5);
756
757 if (mute)
758 reg |= WM8580_DAC_CONTROL5_MUTEALL;
759 else
760 reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
761
762 wm8580_write(codec, WM8580_DAC_CONTROL5, reg);
763
764 return 0;
765}
766
767static int wm8580_set_bias_level(struct snd_soc_codec *codec,
768 enum snd_soc_bias_level level)
769{
770 u16 reg;
771 switch (level) {
772 case SND_SOC_BIAS_ON:
773 case SND_SOC_BIAS_PREPARE:
774 case SND_SOC_BIAS_STANDBY:
775 break;
776 case SND_SOC_BIAS_OFF:
777 reg = wm8580_read(codec, WM8580_PWRDN1);
778 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
779 break;
780 }
781 codec->bias_level = level;
782 return 0;
783}
784
785#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
786 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
787
788struct snd_soc_dai wm8580_dai[] = {
789 {
790 .name = "WM8580 PAIFRX",
791 .id = 0,
792 .playback = {
793 .stream_name = "Playback",
794 .channels_min = 1,
795 .channels_max = 6,
796 .rates = SNDRV_PCM_RATE_8000_192000,
797 .formats = WM8580_FORMATS,
798 },
799 .ops = {
800 .hw_params = wm8580_paif_hw_params,
801 },
802 .dai_ops = {
803 .set_fmt = wm8580_set_paif_dai_fmt,
804 .set_clkdiv = wm8580_set_dai_clkdiv,
805 .set_pll = wm8580_set_dai_pll,
806 .digital_mute = wm8580_digital_mute,
807 },
808 },
809 {
810 .name = "WM8580 PAIFTX",
811 .id = 1,
812 .capture = {
813 .stream_name = "Capture",
814 .channels_min = 2,
815 .channels_max = 2,
816 .rates = SNDRV_PCM_RATE_8000_192000,
817 .formats = WM8580_FORMATS,
818 },
819 .ops = {
820 .hw_params = wm8580_paif_hw_params,
821 },
822 .dai_ops = {
823 .set_fmt = wm8580_set_paif_dai_fmt,
824 .set_clkdiv = wm8580_set_dai_clkdiv,
825 .set_pll = wm8580_set_dai_pll,
826 },
827 },
828};
829EXPORT_SYMBOL_GPL(wm8580_dai);
830
831/*
832 * initialise the WM8580 driver
833 * register the mixer and dsp interfaces with the kernel
834 */
835static int wm8580_init(struct snd_soc_device *socdev)
836{
837 struct snd_soc_codec *codec = socdev->codec;
838 int ret = 0;
839
840 codec->name = "WM8580";
841 codec->owner = THIS_MODULE;
842 codec->read = wm8580_read_reg_cache;
843 codec->write = wm8580_write;
844 codec->set_bias_level = wm8580_set_bias_level;
845 codec->dai = wm8580_dai;
846 codec->num_dai = ARRAY_SIZE(wm8580_dai);
847 codec->reg_cache_size = ARRAY_SIZE(wm8580_reg);
848 codec->reg_cache = kmemdup(wm8580_reg, sizeof(wm8580_reg),
849 GFP_KERNEL);
850
851 if (codec->reg_cache == NULL)
852 return -ENOMEM;
853
854 /* Get the codec into a known state */
855 wm8580_write(codec, WM8580_RESET, 0);
856
857 /* Power up and get individual control of the DACs */
858 wm8580_write(codec, WM8580_PWRDN1, wm8580_read(codec, WM8580_PWRDN1) &
859 ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD));
860
861 /* Make VMID high impedence */
862 wm8580_write(codec, WM8580_ADC_CONTROL1,
863 wm8580_read(codec, WM8580_ADC_CONTROL1) & ~0x100);
864
865 /* register pcms */
866 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1,
867 SNDRV_DEFAULT_STR1);
868 if (ret < 0) {
869 printk(KERN_ERR "wm8580: failed to create pcms\n");
870 goto pcm_err;
871 }
872
873 wm8580_add_controls(codec);
874 wm8580_add_widgets(codec);
875
876 ret = snd_soc_register_card(socdev);
877 if (ret < 0) {
878 printk(KERN_ERR "wm8580: failed to register card\n");
879 goto card_err;
880 }
881 return ret;
882
883card_err:
884 snd_soc_free_pcms(socdev);
885 snd_soc_dapm_free(socdev);
886pcm_err:
887 kfree(codec->reg_cache);
888 return ret;
889}
890
891/* If the i2c layer weren't so broken, we could pass this kind of data
892 around */
893static struct snd_soc_device *wm8580_socdev;
894
895#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
896
897/*
898 * WM8580 2 wire address is determined by GPIO5
899 * state during powerup.
900 * low = 0x1a
901 * high = 0x1b
902 */
903static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
904
905/* Magic definition of all other variables and things */
906I2C_CLIENT_INSMOD;
907
908static struct i2c_driver wm8580_i2c_driver;
909static struct i2c_client client_template;
910
911static int wm8580_codec_probe(struct i2c_adapter *adap, int addr, int kind)
912{
913 struct snd_soc_device *socdev = wm8580_socdev;
914 struct wm8580_setup_data *setup = socdev->codec_data;
915 struct snd_soc_codec *codec = socdev->codec;
916 struct i2c_client *i2c;
917 int ret;
918
919 if (addr != setup->i2c_address)
920 return -ENODEV;
921
922 client_template.adapter = adap;
923 client_template.addr = addr;
924
925 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
926 if (i2c == NULL) {
927 kfree(codec);
928 return -ENOMEM;
929 }
930 i2c_set_clientdata(i2c, codec);
931 codec->control_data = i2c;
932
933 ret = i2c_attach_client(i2c);
934 if (ret < 0) {
935 dev_err(&i2c->dev, "failed to attach codec at addr %x\n", addr);
936 goto err;
937 }
938
939 ret = wm8580_init(socdev);
940 if (ret < 0) {
941 dev_err(&i2c->dev, "failed to initialise WM8580\n");
942 goto err;
943 }
944
945 return ret;
946
947err:
948 kfree(codec);
949 kfree(i2c);
950 return ret;
951}
952
953static int wm8580_i2c_detach(struct i2c_client *client)
954{
955 struct snd_soc_codec *codec = i2c_get_clientdata(client);
956 i2c_detach_client(client);
957 kfree(codec->reg_cache);
958 kfree(client);
959 return 0;
960}
961
962static int wm8580_i2c_attach(struct i2c_adapter *adap)
963{
964 return i2c_probe(adap, &addr_data, wm8580_codec_probe);
965}
966
967/* corgi i2c codec control layer */
968static struct i2c_driver wm8580_i2c_driver = {
969 .driver = {
970 .name = "WM8580 I2C Codec",
971 .owner = THIS_MODULE,
972 },
973 .attach_adapter = wm8580_i2c_attach,
974 .detach_client = wm8580_i2c_detach,
975 .command = NULL,
976};
977
978static struct i2c_client client_template = {
979 .name = "WM8580",
980 .driver = &wm8580_i2c_driver,
981};
982#endif
983
984static int wm8580_probe(struct platform_device *pdev)
985{
986 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
987 struct wm8580_setup_data *setup;
988 struct snd_soc_codec *codec;
989 struct wm8580_priv *wm8580;
990 int ret = 0;
991
992 pr_info("WM8580 Audio Codec %s\n", WM8580_VERSION);
993
994 setup = socdev->codec_data;
995 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
996 if (codec == NULL)
997 return -ENOMEM;
998
999 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
1000 if (wm8580 == NULL) {
1001 kfree(codec);
1002 return -ENOMEM;
1003 }
1004
1005 codec->private_data = wm8580;
1006 socdev->codec = codec;
1007 mutex_init(&codec->mutex);
1008 INIT_LIST_HEAD(&codec->dapm_widgets);
1009 INIT_LIST_HEAD(&codec->dapm_paths);
1010 wm8580_socdev = socdev;
1011
1012#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1013 if (setup->i2c_address) {
1014 normal_i2c[0] = setup->i2c_address;
1015 codec->hw_write = (hw_write_t)i2c_master_send;
1016 ret = i2c_add_driver(&wm8580_i2c_driver);
1017 if (ret != 0)
1018 printk(KERN_ERR "can't add i2c driver");
1019 }
1020#else
1021 /* Add other interfaces here */
1022#endif
1023 return ret;
1024}
1025
1026/* power down chip */
1027static int wm8580_remove(struct platform_device *pdev)
1028{
1029 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1030 struct snd_soc_codec *codec = socdev->codec;
1031
1032 if (codec->control_data)
1033 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
1034 snd_soc_free_pcms(socdev);
1035 snd_soc_dapm_free(socdev);
1036#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1037 i2c_del_driver(&wm8580_i2c_driver);
1038#endif
1039 kfree(codec->private_data);
1040 kfree(codec);
1041
1042 return 0;
1043}
1044
1045struct snd_soc_codec_device soc_codec_dev_wm8580 = {
1046 .probe = wm8580_probe,
1047 .remove = wm8580_remove,
1048};
1049EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
1050
1051MODULE_DESCRIPTION("ASoC WM8580 driver");
1052MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1053MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
new file mode 100644
index 000000000000..589ddaba21d7
--- /dev/null
+++ b/sound/soc/codecs/wm8580.h
@@ -0,0 +1,42 @@
1/*
2 * wm8580.h -- audio driver for WM8580
3 *
4 * Copyright 2008 Samsung Electronics.
5 * Author: Ryu Euiyoul
6 * ryu.real@gmail.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef _WM8580_H
16#define _WM8580_H
17
18#define WM8580_PLLA 1
19#define WM8580_PLLB 2
20
21#define WM8580_MCLK 1
22#define WM8580_DAC_CLKSEL 2
23#define WM8580_CLKOUTSRC 3
24
25#define WM8580_CLKSRC_MCLK 1
26#define WM8580_CLKSRC_PLLA 2
27#define WM8580_CLKSRC_PLLB 3
28#define WM8580_CLKSRC_OSC 4
29#define WM8580_CLKSRC_NONE 5
30
31struct wm8580_setup_data {
32 unsigned short i2c_address;
33};
34
35#define WM8580_DAI_PAIFRX 0
36#define WM8580_DAI_PAIFTX 1
37
38extern struct snd_soc_dai wm8580_dai[];
39extern struct snd_soc_codec_device soc_codec_dev_wm8580;
40
41#endif
42
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 9402fcaf04fa..7f8a7e36b33e 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -28,7 +29,6 @@
28 29
29#include "wm8731.h" 30#include "wm8731.h"
30 31
31#define AUDIO_NAME "wm8731"
32#define WM8731_VERSION "0.13" 32#define WM8731_VERSION "0.13"
33 33
34struct snd_soc_codec_device soc_codec_dev_wm8731; 34struct snd_soc_codec_device soc_codec_dev_wm8731;
@@ -570,88 +570,144 @@ static struct snd_soc_device *wm8731_socdev;
570 * low = 0x1a 570 * low = 0x1a
571 * high = 0x1b 571 * high = 0x1b
572 */ 572 */
573static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
574 573
575/* Magic definition of all other variables and things */ 574static int wm8731_i2c_probe(struct i2c_client *i2c,
576I2C_CLIENT_INSMOD; 575 const struct i2c_device_id *id)
577
578static struct i2c_driver wm8731_i2c_driver;
579static struct i2c_client client_template;
580
581/* If the i2c layer weren't so broken, we could pass this kind of data
582 around */
583
584static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
585{ 576{
586 struct snd_soc_device *socdev = wm8731_socdev; 577 struct snd_soc_device *socdev = wm8731_socdev;
587 struct wm8731_setup_data *setup = socdev->codec_data;
588 struct snd_soc_codec *codec = socdev->codec; 578 struct snd_soc_codec *codec = socdev->codec;
589 struct i2c_client *i2c;
590 int ret; 579 int ret;
591 580
592 if (addr != setup->i2c_address)
593 return -ENODEV;
594
595 client_template.adapter = adap;
596 client_template.addr = addr;
597
598 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
599 if (i2c == NULL)
600 return -ENOMEM;
601
602 i2c_set_clientdata(i2c, codec); 581 i2c_set_clientdata(i2c, codec);
603 codec->control_data = i2c; 582 codec->control_data = i2c;
604 583
605 ret = i2c_attach_client(i2c);
606 if (ret < 0) {
607 pr_err("failed to attach codec at addr %x\n", addr);
608 goto err;
609 }
610
611 ret = wm8731_init(socdev); 584 ret = wm8731_init(socdev);
612 if (ret < 0) { 585 if (ret < 0)
613 pr_err("failed to initialise WM8731\n"); 586 pr_err("failed to initialise WM8731\n");
614 goto err;
615 }
616 return ret;
617 587
618err:
619 kfree(i2c);
620 return ret; 588 return ret;
621} 589}
622 590
623static int wm8731_i2c_detach(struct i2c_client *client) 591static int wm8731_i2c_remove(struct i2c_client *client)
624{ 592{
625 struct snd_soc_codec *codec = i2c_get_clientdata(client); 593 struct snd_soc_codec *codec = i2c_get_clientdata(client);
626 i2c_detach_client(client);
627 kfree(codec->reg_cache); 594 kfree(codec->reg_cache);
628 kfree(client);
629 return 0; 595 return 0;
630} 596}
631 597
632static int wm8731_i2c_attach(struct i2c_adapter *adap) 598static const struct i2c_device_id wm8731_i2c_id[] = {
633{ 599 { "wm8731", 0 },
634 return i2c_probe(adap, &addr_data, wm8731_codec_probe); 600 { }
635} 601};
602MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
636 603
637/* corgi i2c codec control layer */
638static struct i2c_driver wm8731_i2c_driver = { 604static struct i2c_driver wm8731_i2c_driver = {
639 .driver = { 605 .driver = {
640 .name = "WM8731 I2C Codec", 606 .name = "WM8731 I2C Codec",
641 .owner = THIS_MODULE, 607 .owner = THIS_MODULE,
642 }, 608 },
643 .id = I2C_DRIVERID_WM8731, 609 .probe = wm8731_i2c_probe,
644 .attach_adapter = wm8731_i2c_attach, 610 .remove = wm8731_i2c_remove,
645 .detach_client = wm8731_i2c_detach, 611 .id_table = wm8731_i2c_id,
646 .command = NULL,
647}; 612};
648 613
649static struct i2c_client client_template = { 614static int wm8731_add_i2c_device(struct platform_device *pdev,
650 .name = "WM8731", 615 const struct wm8731_setup_data *setup)
651 .driver = &wm8731_i2c_driver, 616{
652}; 617 struct i2c_board_info info;
618 struct i2c_adapter *adapter;
619 struct i2c_client *client;
620 int ret;
621
622 ret = i2c_add_driver(&wm8731_i2c_driver);
623 if (ret != 0) {
624 dev_err(&pdev->dev, "can't add i2c driver\n");
625 return ret;
626 }
627
628 memset(&info, 0, sizeof(struct i2c_board_info));
629 info.addr = setup->i2c_address;
630 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
631
632 adapter = i2c_get_adapter(setup->i2c_bus);
633 if (!adapter) {
634 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
635 setup->i2c_bus);
636 goto err_driver;
637 }
638
639 client = i2c_new_device(adapter, &info);
640 i2c_put_adapter(adapter);
641 if (!client) {
642 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
643 (unsigned int)info.addr);
644 goto err_driver;
645 }
646
647 return 0;
648
649err_driver:
650 i2c_del_driver(&wm8731_i2c_driver);
651 return -ENODEV;
652}
653#endif 653#endif
654 654
655#if defined(CONFIG_SPI_MASTER)
656static int __devinit wm8731_spi_probe(struct spi_device *spi)
657{
658 struct snd_soc_device *socdev = wm8731_socdev;
659 struct snd_soc_codec *codec = socdev->codec;
660 int ret;
661
662 codec->control_data = spi;
663
664 ret = wm8731_init(socdev);
665 if (ret < 0)
666 dev_err(&spi->dev, "failed to initialise WM8731\n");
667
668 return ret;
669}
670
671static int __devexit wm8731_spi_remove(struct spi_device *spi)
672{
673 return 0;
674}
675
676static struct spi_driver wm8731_spi_driver = {
677 .driver = {
678 .name = "wm8731",
679 .bus = &spi_bus_type,
680 .owner = THIS_MODULE,
681 },
682 .probe = wm8731_spi_probe,
683 .remove = __devexit_p(wm8731_spi_remove),
684};
685
686static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
687{
688 struct spi_transfer t;
689 struct spi_message m;
690 u8 msg[2];
691
692 if (len <= 0)
693 return 0;
694
695 msg[0] = data[0];
696 msg[1] = data[1];
697
698 spi_message_init(&m);
699 memset(&t, 0, (sizeof t));
700
701 t.tx_buf = &msg[0];
702 t.len = len;
703
704 spi_message_add_tail(&t, &m);
705 spi_sync(spi, &m);
706
707 return len;
708}
709#endif /* CONFIG_SPI_MASTER */
710
655static int wm8731_probe(struct platform_device *pdev) 711static int wm8731_probe(struct platform_device *pdev)
656{ 712{
657 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 713 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -680,16 +736,21 @@ static int wm8731_probe(struct platform_device *pdev)
680 INIT_LIST_HEAD(&codec->dapm_paths); 736 INIT_LIST_HEAD(&codec->dapm_paths);
681 737
682 wm8731_socdev = socdev; 738 wm8731_socdev = socdev;
739 ret = -ENODEV;
740
683#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 741#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
684 if (setup->i2c_address) { 742 if (setup->i2c_address) {
685 normal_i2c[0] = setup->i2c_address;
686 codec->hw_write = (hw_write_t)i2c_master_send; 743 codec->hw_write = (hw_write_t)i2c_master_send;
687 ret = i2c_add_driver(&wm8731_i2c_driver); 744 ret = wm8731_add_i2c_device(pdev, setup);
745 }
746#endif
747#if defined(CONFIG_SPI_MASTER)
748 if (setup->spi) {
749 codec->hw_write = (hw_write_t)wm8731_spi_write;
750 ret = spi_register_driver(&wm8731_spi_driver);
688 if (ret != 0) 751 if (ret != 0)
689 printk(KERN_ERR "can't add i2c driver"); 752 printk(KERN_ERR "can't add spi driver");
690 } 753 }
691#else
692 /* Add other interfaces here */
693#endif 754#endif
694 755
695 if (ret != 0) { 756 if (ret != 0) {
@@ -711,8 +772,12 @@ static int wm8731_remove(struct platform_device *pdev)
711 snd_soc_free_pcms(socdev); 772 snd_soc_free_pcms(socdev);
712 snd_soc_dapm_free(socdev); 773 snd_soc_dapm_free(socdev);
713#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 774#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
775 i2c_unregister_device(codec->control_data);
714 i2c_del_driver(&wm8731_i2c_driver); 776 i2c_del_driver(&wm8731_i2c_driver);
715#endif 777#endif
778#if defined(CONFIG_SPI_MASTER)
779 spi_unregister_driver(&wm8731_spi_driver);
780#endif
716 kfree(codec->private_data); 781 kfree(codec->private_data);
717 kfree(codec); 782 kfree(codec);
718 783
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index 99f2e3c60e33..95190e9c0c14 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -35,6 +35,8 @@
35#define WM8731_DAI 0 35#define WM8731_DAI 0
36 36
37struct wm8731_setup_data { 37struct wm8731_setup_data {
38 int spi;
39 int i2c_bus;
38 unsigned short i2c_address; 40 unsigned short i2c_address;
39}; 41};
40 42
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index dd1f55404b29..9b7296ee5b08 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -28,7 +29,6 @@
28 29
29#include "wm8750.h" 30#include "wm8750.h"
30 31
31#define AUDIO_NAME "WM8750"
32#define WM8750_VERSION "0.12" 32#define WM8750_VERSION "0.12"
33 33
34/* codec private data */ 34/* codec private data */
@@ -841,88 +841,147 @@ static struct snd_soc_device *wm8750_socdev;
841#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 841#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
842 842
843/* 843/*
844 * WM8731 2 wire address is determined by GPIO5 844 * WM8750 2 wire address is determined by GPIO5
845 * state during powerup. 845 * state during powerup.
846 * low = 0x1a 846 * low = 0x1a
847 * high = 0x1b 847 * high = 0x1b
848 */ 848 */
849static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
850 849
851/* Magic definition of all other variables and things */ 850static int wm8750_i2c_probe(struct i2c_client *i2c,
852I2C_CLIENT_INSMOD; 851 const struct i2c_device_id *id)
853
854static struct i2c_driver wm8750_i2c_driver;
855static struct i2c_client client_template;
856
857static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
858{ 852{
859 struct snd_soc_device *socdev = wm8750_socdev; 853 struct snd_soc_device *socdev = wm8750_socdev;
860 struct wm8750_setup_data *setup = socdev->codec_data;
861 struct snd_soc_codec *codec = socdev->codec; 854 struct snd_soc_codec *codec = socdev->codec;
862 struct i2c_client *i2c;
863 int ret; 855 int ret;
864 856
865 if (addr != setup->i2c_address)
866 return -ENODEV;
867
868 client_template.adapter = adap;
869 client_template.addr = addr;
870
871 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
872 if (i2c == NULL)
873 return -ENOMEM;
874
875 i2c_set_clientdata(i2c, codec); 857 i2c_set_clientdata(i2c, codec);
876 codec->control_data = i2c; 858 codec->control_data = i2c;
877 859
878 ret = i2c_attach_client(i2c);
879 if (ret < 0) {
880 pr_err("failed to attach codec at addr %x\n", addr);
881 goto err;
882 }
883
884 ret = wm8750_init(socdev); 860 ret = wm8750_init(socdev);
885 if (ret < 0) { 861 if (ret < 0)
886 pr_err("failed to initialise WM8750\n"); 862 pr_err("failed to initialise WM8750\n");
887 goto err;
888 }
889 return ret;
890 863
891err:
892 kfree(i2c);
893 return ret; 864 return ret;
894} 865}
895 866
896static int wm8750_i2c_detach(struct i2c_client *client) 867static int wm8750_i2c_remove(struct i2c_client *client)
897{ 868{
898 struct snd_soc_codec *codec = i2c_get_clientdata(client); 869 struct snd_soc_codec *codec = i2c_get_clientdata(client);
899 i2c_detach_client(client);
900 kfree(codec->reg_cache); 870 kfree(codec->reg_cache);
901 kfree(client);
902 return 0; 871 return 0;
903} 872}
904 873
905static int wm8750_i2c_attach(struct i2c_adapter *adap) 874static const struct i2c_device_id wm8750_i2c_id[] = {
906{ 875 { "wm8750", 0 },
907 return i2c_probe(adap, &addr_data, wm8750_codec_probe); 876 { }
908} 877};
878MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
909 879
910/* corgi i2c codec control layer */
911static struct i2c_driver wm8750_i2c_driver = { 880static struct i2c_driver wm8750_i2c_driver = {
912 .driver = { 881 .driver = {
913 .name = "WM8750 I2C Codec", 882 .name = "WM8750 I2C Codec",
914 .owner = THIS_MODULE, 883 .owner = THIS_MODULE,
915 }, 884 },
916 .id = I2C_DRIVERID_WM8750, 885 .probe = wm8750_i2c_probe,
917 .attach_adapter = wm8750_i2c_attach, 886 .remove = wm8750_i2c_remove,
918 .detach_client = wm8750_i2c_detach, 887 .id_table = wm8750_i2c_id,
919 .command = NULL,
920}; 888};
921 889
922static struct i2c_client client_template = { 890static int wm8750_add_i2c_device(struct platform_device *pdev,
923 .name = "WM8750", 891 const struct wm8750_setup_data *setup)
924 .driver = &wm8750_i2c_driver, 892{
893 struct i2c_board_info info;
894 struct i2c_adapter *adapter;
895 struct i2c_client *client;
896 int ret;
897
898 ret = i2c_add_driver(&wm8750_i2c_driver);
899 if (ret != 0) {
900 dev_err(&pdev->dev, "can't add i2c driver\n");
901 return ret;
902 }
903
904 memset(&info, 0, sizeof(struct i2c_board_info));
905 info.addr = setup->i2c_address;
906 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
907
908 adapter = i2c_get_adapter(setup->i2c_bus);
909 if (!adapter) {
910 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
911 setup->i2c_bus);
912 goto err_driver;
913 }
914
915 client = i2c_new_device(adapter, &info);
916 i2c_put_adapter(adapter);
917 if (!client) {
918 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
919 (unsigned int)info.addr);
920 goto err_driver;
921 }
922
923 return 0;
924
925err_driver:
926 i2c_del_driver(&wm8750_i2c_driver);
927 return -ENODEV;
928}
929#endif
930
931#if defined(CONFIG_SPI_MASTER)
932static int __devinit wm8750_spi_probe(struct spi_device *spi)
933{
934 struct snd_soc_device *socdev = wm8750_socdev;
935 struct snd_soc_codec *codec = socdev->codec;
936 int ret;
937
938 codec->control_data = spi;
939
940 ret = wm8750_init(socdev);
941 if (ret < 0)
942 dev_err(&spi->dev, "failed to initialise WM8750\n");
943
944 return ret;
945}
946
947static int __devexit wm8750_spi_remove(struct spi_device *spi)
948{
949 return 0;
950}
951
952static struct spi_driver wm8750_spi_driver = {
953 .driver = {
954 .name = "wm8750",
955 .bus = &spi_bus_type,
956 .owner = THIS_MODULE,
957 },
958 .probe = wm8750_spi_probe,
959 .remove = __devexit_p(wm8750_spi_remove),
925}; 960};
961
962static int wm8750_spi_write(struct spi_device *spi, const char *data, int len)
963{
964 struct spi_transfer t;
965 struct spi_message m;
966 u8 msg[2];
967
968 if (len <= 0)
969 return 0;
970
971 msg[0] = data[0];
972 msg[1] = data[1];
973
974 spi_message_init(&m);
975 memset(&t, 0, (sizeof t));
976
977 t.tx_buf = &msg[0];
978 t.len = len;
979
980 spi_message_add_tail(&t, &m);
981 spi_sync(spi, &m);
982
983 return len;
984}
926#endif 985#endif
927 986
928static int wm8750_probe(struct platform_device *pdev) 987static int wm8750_probe(struct platform_device *pdev)
@@ -931,7 +990,7 @@ static int wm8750_probe(struct platform_device *pdev)
931 struct wm8750_setup_data *setup = socdev->codec_data; 990 struct wm8750_setup_data *setup = socdev->codec_data;
932 struct snd_soc_codec *codec; 991 struct snd_soc_codec *codec;
933 struct wm8750_priv *wm8750; 992 struct wm8750_priv *wm8750;
934 int ret = 0; 993 int ret;
935 994
936 pr_info("WM8750 Audio Codec %s", WM8750_VERSION); 995 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
937 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 996 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
@@ -952,16 +1011,21 @@ static int wm8750_probe(struct platform_device *pdev)
952 wm8750_socdev = socdev; 1011 wm8750_socdev = socdev;
953 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work); 1012 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work);
954 1013
1014 ret = -ENODEV;
1015
955#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1016#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
956 if (setup->i2c_address) { 1017 if (setup->i2c_address) {
957 normal_i2c[0] = setup->i2c_address;
958 codec->hw_write = (hw_write_t)i2c_master_send; 1018 codec->hw_write = (hw_write_t)i2c_master_send;
959 ret = i2c_add_driver(&wm8750_i2c_driver); 1019 ret = wm8750_add_i2c_device(pdev, setup);
1020 }
1021#endif
1022#if defined(CONFIG_SPI_MASTER)
1023 if (setup->spi) {
1024 codec->hw_write = (hw_write_t)wm8750_spi_write;
1025 ret = spi_register_driver(&wm8750_spi_driver);
960 if (ret != 0) 1026 if (ret != 0)
961 printk(KERN_ERR "can't add i2c driver"); 1027 printk(KERN_ERR "can't add spi driver");
962 } 1028 }
963#else
964 /* Add other interfaces here */
965#endif 1029#endif
966 1030
967 if (ret != 0) { 1031 if (ret != 0) {
@@ -1002,8 +1066,12 @@ static int wm8750_remove(struct platform_device *pdev)
1002 snd_soc_free_pcms(socdev); 1066 snd_soc_free_pcms(socdev);
1003 snd_soc_dapm_free(socdev); 1067 snd_soc_dapm_free(socdev);
1004#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1068#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1069 i2c_unregister_device(codec->control_data);
1005 i2c_del_driver(&wm8750_i2c_driver); 1070 i2c_del_driver(&wm8750_i2c_driver);
1006#endif 1071#endif
1072#if defined(CONFIG_SPI_MASTER)
1073 spi_unregister_driver(&wm8750_spi_driver);
1074#endif
1007 kfree(codec->private_data); 1075 kfree(codec->private_data);
1008 kfree(codec); 1076 kfree(codec);
1009 1077
diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h
index 8ef30e628b21..1dc100e19cfe 100644
--- a/sound/soc/codecs/wm8750.h
+++ b/sound/soc/codecs/wm8750.h
@@ -58,6 +58,8 @@
58#define WM8750_SYSCLK 0 58#define WM8750_SYSCLK 0
59 59
60struct wm8750_setup_data { 60struct wm8750_setup_data {
61 int spi;
62 int i2c_bus;
61 unsigned short i2c_address; 63 unsigned short i2c_address;
62}; 64};
63 65
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5761164fe16d..d426eaa22185 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -2,8 +2,7 @@
2 * wm8753.c -- WM8753 ALSA Soc Audio driver 2 * wm8753.c -- WM8753 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -40,6 +39,7 @@
40#include <linux/pm.h> 39#include <linux/pm.h>
41#include <linux/i2c.h> 40#include <linux/i2c.h>
42#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/spi/spi.h>
43#include <sound/core.h> 43#include <sound/core.h>
44#include <sound/pcm.h> 44#include <sound/pcm.h>
45#include <sound/pcm_params.h> 45#include <sound/pcm_params.h>
@@ -51,7 +51,6 @@
51 51
52#include "wm8753.h" 52#include "wm8753.h"
53 53
54#define AUDIO_NAME "wm8753"
55#define WM8753_VERSION "0.16" 54#define WM8753_VERSION "0.16"
56 55
57static int caps_charge = 2000; 56static int caps_charge = 2000;
@@ -583,7 +582,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
583 582
584 /* out 4 */ 583 /* out 4 */
585 {"Out4 Mux", "VREF", "VREF"}, 584 {"Out4 Mux", "VREF", "VREF"},
586 {"Out4 Mux", "Capture ST", "Capture ST Mixer"}, 585 {"Out4 Mux", "Capture ST", "Playback Mixer"},
587 {"Out4 Mux", "LOUT2", "LOUT2"}, 586 {"Out4 Mux", "LOUT2", "LOUT2"},
588 {"Out 4", NULL, "Out4 Mux"}, 587 {"Out 4", NULL, "Out4 Mux"},
589 {"OUT4", NULL, "Out 4"}, 588 {"OUT4", NULL, "Out 4"},
@@ -607,7 +606,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
607 /* Capture Right Mux */ 606 /* Capture Right Mux */
608 {"Capture Right Mux", "PGA", "Right Capture Volume"}, 607 {"Capture Right Mux", "PGA", "Right Capture Volume"},
609 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"}, 608 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
610 {"Capture Right Mux", "Sidetone", "Capture ST Mixer"}, 609 {"Capture Right Mux", "Sidetone", "Playback Mixer"},
611 610
612 /* Mono Capture mixer-mux */ 611 /* Mono Capture mixer-mux */
613 {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, 612 {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
@@ -1637,86 +1636,145 @@ static struct snd_soc_device *wm8753_socdev;
1637 * low = 0x1a 1636 * low = 0x1a
1638 * high = 0x1b 1637 * high = 0x1b
1639 */ 1638 */
1640static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1641 1639
1642/* Magic definition of all other variables and things */ 1640static int wm8753_i2c_probe(struct i2c_client *i2c,
1643I2C_CLIENT_INSMOD; 1641 const struct i2c_device_id *id)
1644
1645static struct i2c_driver wm8753_i2c_driver;
1646static struct i2c_client client_template;
1647
1648static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1649{ 1642{
1650 struct snd_soc_device *socdev = wm8753_socdev; 1643 struct snd_soc_device *socdev = wm8753_socdev;
1651 struct wm8753_setup_data *setup = socdev->codec_data;
1652 struct snd_soc_codec *codec = socdev->codec; 1644 struct snd_soc_codec *codec = socdev->codec;
1653 struct i2c_client *i2c;
1654 int ret; 1645 int ret;
1655 1646
1656 if (addr != setup->i2c_address)
1657 return -ENODEV;
1658
1659 client_template.adapter = adap;
1660 client_template.addr = addr;
1661
1662 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1663 if (!i2c)
1664 return -ENOMEM;
1665
1666 i2c_set_clientdata(i2c, codec); 1647 i2c_set_clientdata(i2c, codec);
1667 codec->control_data = i2c; 1648 codec->control_data = i2c;
1668 1649
1669 ret = i2c_attach_client(i2c);
1670 if (ret < 0) {
1671 pr_err("failed to attach codec at addr %x\n", addr);
1672 goto err;
1673 }
1674
1675 ret = wm8753_init(socdev); 1650 ret = wm8753_init(socdev);
1676 if (ret < 0) { 1651 if (ret < 0)
1677 pr_err("failed to initialise WM8753\n"); 1652 pr_err("failed to initialise WM8753\n");
1678 goto err;
1679 }
1680
1681 return ret;
1682 1653
1683err:
1684 kfree(i2c);
1685 return ret; 1654 return ret;
1686} 1655}
1687 1656
1688static int wm8753_i2c_detach(struct i2c_client *client) 1657static int wm8753_i2c_remove(struct i2c_client *client)
1689{ 1658{
1690 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1659 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1691 i2c_detach_client(client);
1692 kfree(codec->reg_cache); 1660 kfree(codec->reg_cache);
1693 kfree(client);
1694 return 0; 1661 return 0;
1695} 1662}
1696 1663
1697static int wm8753_i2c_attach(struct i2c_adapter *adap) 1664static const struct i2c_device_id wm8753_i2c_id[] = {
1698{ 1665 { "wm8753", 0 },
1699 return i2c_probe(adap, &addr_data, wm8753_codec_probe); 1666 { }
1700} 1667};
1668MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1701 1669
1702/* corgi i2c codec control layer */
1703static struct i2c_driver wm8753_i2c_driver = { 1670static struct i2c_driver wm8753_i2c_driver = {
1704 .driver = { 1671 .driver = {
1705 .name = "WM8753 I2C Codec", 1672 .name = "WM8753 I2C Codec",
1706 .owner = THIS_MODULE, 1673 .owner = THIS_MODULE,
1707 }, 1674 },
1708 .id = I2C_DRIVERID_WM8753, 1675 .probe = wm8753_i2c_probe,
1709 .attach_adapter = wm8753_i2c_attach, 1676 .remove = wm8753_i2c_remove,
1710 .detach_client = wm8753_i2c_detach, 1677 .id_table = wm8753_i2c_id,
1711 .command = NULL,
1712}; 1678};
1713 1679
1714static struct i2c_client client_template = { 1680static int wm8753_add_i2c_device(struct platform_device *pdev,
1715 .name = "WM8753", 1681 const struct wm8753_setup_data *setup)
1716 .driver = &wm8753_i2c_driver, 1682{
1683 struct i2c_board_info info;
1684 struct i2c_adapter *adapter;
1685 struct i2c_client *client;
1686 int ret;
1687
1688 ret = i2c_add_driver(&wm8753_i2c_driver);
1689 if (ret != 0) {
1690 dev_err(&pdev->dev, "can't add i2c driver\n");
1691 return ret;
1692 }
1693
1694 memset(&info, 0, sizeof(struct i2c_board_info));
1695 info.addr = setup->i2c_address;
1696 strlcpy(info.type, "wm8753", I2C_NAME_SIZE);
1697
1698 adapter = i2c_get_adapter(setup->i2c_bus);
1699 if (!adapter) {
1700 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1701 setup->i2c_bus);
1702 goto err_driver;
1703 }
1704
1705 client = i2c_new_device(adapter, &info);
1706 i2c_put_adapter(adapter);
1707 if (!client) {
1708 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1709 (unsigned int)info.addr);
1710 goto err_driver;
1711 }
1712
1713 return 0;
1714
1715err_driver:
1716 i2c_del_driver(&wm8753_i2c_driver);
1717 return -ENODEV;
1718}
1719#endif
1720
1721#if defined(CONFIG_SPI_MASTER)
1722static int __devinit wm8753_spi_probe(struct spi_device *spi)
1723{
1724 struct snd_soc_device *socdev = wm8753_socdev;
1725 struct snd_soc_codec *codec = socdev->codec;
1726 int ret;
1727
1728 codec->control_data = spi;
1729
1730 ret = wm8753_init(socdev);
1731 if (ret < 0)
1732 dev_err(&spi->dev, "failed to initialise WM8753\n");
1733
1734 return ret;
1735}
1736
1737static int __devexit wm8753_spi_remove(struct spi_device *spi)
1738{
1739 return 0;
1740}
1741
1742static struct spi_driver wm8753_spi_driver = {
1743 .driver = {
1744 .name = "wm8753",
1745 .bus = &spi_bus_type,
1746 .owner = THIS_MODULE,
1747 },
1748 .probe = wm8753_spi_probe,
1749 .remove = __devexit_p(wm8753_spi_remove),
1717}; 1750};
1751
1752static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1753{
1754 struct spi_transfer t;
1755 struct spi_message m;
1756 u8 msg[2];
1757
1758 if (len <= 0)
1759 return 0;
1760
1761 msg[0] = data[0];
1762 msg[1] = data[1];
1763
1764 spi_message_init(&m);
1765 memset(&t, 0, (sizeof t));
1766
1767 t.tx_buf = &msg[0];
1768 t.len = len;
1769
1770 spi_message_add_tail(&t, &m);
1771 spi_sync(spi, &m);
1772
1773 return len;
1774}
1718#endif 1775#endif
1719 1776
1777
1720static int wm8753_probe(struct platform_device *pdev) 1778static int wm8753_probe(struct platform_device *pdev)
1721{ 1779{
1722 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1780 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1748,14 +1806,17 @@ static int wm8753_probe(struct platform_device *pdev)
1748 1806
1749#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1750 if (setup->i2c_address) { 1808 if (setup->i2c_address) {
1751 normal_i2c[0] = setup->i2c_address;
1752 codec->hw_write = (hw_write_t)i2c_master_send; 1809 codec->hw_write = (hw_write_t)i2c_master_send;
1753 ret = i2c_add_driver(&wm8753_i2c_driver); 1810 ret = wm8753_add_i2c_device(pdev, setup);
1811 }
1812#endif
1813#if defined(CONFIG_SPI_MASTER)
1814 if (setup->spi) {
1815 codec->hw_write = (hw_write_t)wm8753_spi_write;
1816 ret = spi_register_driver(&wm8753_spi_driver);
1754 if (ret != 0) 1817 if (ret != 0)
1755 printk(KERN_ERR "can't add i2c driver"); 1818 printk(KERN_ERR "can't add spi driver");
1756 } 1819 }
1757#else
1758 /* Add other interfaces here */
1759#endif 1820#endif
1760 1821
1761 if (ret != 0) { 1822 if (ret != 0) {
@@ -1796,8 +1857,12 @@ static int wm8753_remove(struct platform_device *pdev)
1796 snd_soc_free_pcms(socdev); 1857 snd_soc_free_pcms(socdev);
1797 snd_soc_dapm_free(socdev); 1858 snd_soc_dapm_free(socdev);
1798#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1859#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1860 i2c_unregister_device(codec->control_data);
1799 i2c_del_driver(&wm8753_i2c_driver); 1861 i2c_del_driver(&wm8753_i2c_driver);
1800#endif 1862#endif
1863#if defined(CONFIG_SPI_MASTER)
1864 spi_unregister_driver(&wm8753_spi_driver);
1865#endif
1801 kfree(codec->private_data); 1866 kfree(codec->private_data);
1802 kfree(codec); 1867 kfree(codec);
1803 1868
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 44f5f1ff0cc7..f55704ce931b 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -2,8 +2,7 @@
2 * wm8753.h -- audio driver for WM8753 2 * wm8753.h -- audio driver for WM8753
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -79,6 +78,8 @@
79#define WM8753_ADCTL2 0x3f 78#define WM8753_ADCTL2 0x3f
80 79
81struct wm8753_setup_data { 80struct wm8753_setup_data {
81 int spi;
82 int i2c_bus;
82 unsigned short i2c_address; 83 unsigned short i2c_address;
83}; 84};
84 85
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
new file mode 100644
index 000000000000..3b326c9b5586
--- /dev/null
+++ b/sound/soc/codecs/wm8900.c
@@ -0,0 +1,1541 @@
1/*
2 * wm8900.c -- WM8900 ALSA Soc Audio driver
3 *
4 * Copyright 2007, 2008 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:
13 * - Tristating.
14 * - TDM.
15 * - Jack detect.
16 * - FLL source configuration, currently only MCLK is supported.
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/pm.h>
25#include <linux/i2c.h>
26#include <linux/platform_device.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/initval.h>
33#include <sound/tlv.h>
34
35#include "wm8900.h"
36
37/* WM8900 register space */
38#define WM8900_REG_RESET 0x0
39#define WM8900_REG_ID 0x0
40#define WM8900_REG_POWER1 0x1
41#define WM8900_REG_POWER2 0x2
42#define WM8900_REG_POWER3 0x3
43#define WM8900_REG_AUDIO1 0x4
44#define WM8900_REG_AUDIO2 0x5
45#define WM8900_REG_CLOCKING1 0x6
46#define WM8900_REG_CLOCKING2 0x7
47#define WM8900_REG_AUDIO3 0x8
48#define WM8900_REG_AUDIO4 0x9
49#define WM8900_REG_DACCTRL 0xa
50#define WM8900_REG_LDAC_DV 0xb
51#define WM8900_REG_RDAC_DV 0xc
52#define WM8900_REG_SIDETONE 0xd
53#define WM8900_REG_ADCCTRL 0xe
54#define WM8900_REG_LADC_DV 0xf
55#define WM8900_REG_RADC_DV 0x10
56#define WM8900_REG_GPIO 0x12
57#define WM8900_REG_INCTL 0x15
58#define WM8900_REG_LINVOL 0x16
59#define WM8900_REG_RINVOL 0x17
60#define WM8900_REG_INBOOSTMIX1 0x18
61#define WM8900_REG_INBOOSTMIX2 0x19
62#define WM8900_REG_ADCPATH 0x1a
63#define WM8900_REG_AUXBOOST 0x1b
64#define WM8900_REG_ADDCTL 0x1e
65#define WM8900_REG_FLLCTL1 0x24
66#define WM8900_REG_FLLCTL2 0x25
67#define WM8900_REG_FLLCTL3 0x26
68#define WM8900_REG_FLLCTL4 0x27
69#define WM8900_REG_FLLCTL5 0x28
70#define WM8900_REG_FLLCTL6 0x29
71#define WM8900_REG_LOUTMIXCTL1 0x2c
72#define WM8900_REG_ROUTMIXCTL1 0x2d
73#define WM8900_REG_BYPASS1 0x2e
74#define WM8900_REG_BYPASS2 0x2f
75#define WM8900_REG_AUXOUT_CTL 0x30
76#define WM8900_REG_LOUT1CTL 0x33
77#define WM8900_REG_ROUT1CTL 0x34
78#define WM8900_REG_LOUT2CTL 0x35
79#define WM8900_REG_ROUT2CTL 0x36
80#define WM8900_REG_HPCTL1 0x3a
81#define WM8900_REG_OUTBIASCTL 0x73
82
83#define WM8900_MAXREG 0x80
84
85#define WM8900_REG_ADDCTL_OUT1_DIS 0x80
86#define WM8900_REG_ADDCTL_OUT2_DIS 0x40
87#define WM8900_REG_ADDCTL_VMID_DIS 0x20
88#define WM8900_REG_ADDCTL_BIAS_SRC 0x10
89#define WM8900_REG_ADDCTL_VMID_SOFTST 0x04
90#define WM8900_REG_ADDCTL_TEMP_SD 0x02
91
92#define WM8900_REG_GPIO_TEMP_ENA 0x2
93
94#define WM8900_REG_POWER1_STARTUP_BIAS_ENA 0x0100
95#define WM8900_REG_POWER1_BIAS_ENA 0x0008
96#define WM8900_REG_POWER1_VMID_BUF_ENA 0x0004
97#define WM8900_REG_POWER1_FLL_ENA 0x0040
98
99#define WM8900_REG_POWER2_SYSCLK_ENA 0x8000
100#define WM8900_REG_POWER2_ADCL_ENA 0x0002
101#define WM8900_REG_POWER2_ADCR_ENA 0x0001
102
103#define WM8900_REG_POWER3_DACL_ENA 0x0002
104#define WM8900_REG_POWER3_DACR_ENA 0x0001
105
106#define WM8900_REG_AUDIO1_AIF_FMT_MASK 0x0018
107#define WM8900_REG_AUDIO1_LRCLK_INV 0x0080
108#define WM8900_REG_AUDIO1_BCLK_INV 0x0100
109
110#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1
111#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100
112#define WM8900_REG_CLOCKING1_BCLK_MASK (~0x01e)
113#define WM8900_REG_CLOCKING1_OPCLK_MASK (~0x7000)
114
115#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0
116#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
117
118#define WM8900_REG_DACCTRL_MUTE 0x004
119#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400
120
121#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800
122
123#define WM8900_REG_AUDIO4_DACLRC_DIR 0x0800
124
125#define WM8900_REG_FLLCTL1_OSC_ENA 0x100
126
127#define WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF 0x100
128
129#define WM8900_REG_HPCTL1_HP_IPSTAGE_ENA 0x80
130#define WM8900_REG_HPCTL1_HP_OPSTAGE_ENA 0x40
131#define WM8900_REG_HPCTL1_HP_CLAMP_IP 0x20
132#define WM8900_REG_HPCTL1_HP_CLAMP_OP 0x10
133#define WM8900_REG_HPCTL1_HP_SHORT 0x08
134#define WM8900_REG_HPCTL1_HP_SHORT2 0x04
135
136#define WM8900_LRC_MASK 0xfc00
137
138struct snd_soc_codec_device soc_codec_dev_wm8900;
139
140struct wm8900_priv {
141 u32 fll_in; /* FLL input frequency */
142 u32 fll_out; /* FLL output frequency */
143};
144
145/*
146 * wm8900 register cache. We can't read the entire register space and we
147 * have slow control buses so we cache the registers.
148 */
149static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
150 0x8900, 0x0000,
151 0xc000, 0x0000,
152 0x4050, 0x4000,
153 0x0008, 0x0000,
154 0x0040, 0x0040,
155 0x1004, 0x00c0,
156 0x00c0, 0x0000,
157 0x0100, 0x00c0,
158 0x00c0, 0x0000,
159 0xb001, 0x0000,
160 0x0000, 0x0044,
161 0x004c, 0x004c,
162 0x0044, 0x0044,
163 0x0000, 0x0044,
164 0x0000, 0x0000,
165 0x0002, 0x0000,
166 0x0000, 0x0000,
167 0x0000, 0x0000,
168 0x0008, 0x0000,
169 0x0000, 0x0008,
170 0x0097, 0x0100,
171 0x0000, 0x0000,
172 0x0050, 0x0050,
173 0x0055, 0x0055,
174 0x0055, 0x0000,
175 0x0000, 0x0079,
176 0x0079, 0x0079,
177 0x0079, 0x0000,
178 /* Remaining registers all zero */
179};
180
181/*
182 * read wm8900 register cache
183 */
184static inline unsigned int wm8900_read_reg_cache(struct snd_soc_codec *codec,
185 unsigned int reg)
186{
187 u16 *cache = codec->reg_cache;
188
189 BUG_ON(reg >= WM8900_MAXREG);
190
191 if (reg == WM8900_REG_ID)
192 return 0;
193
194 return cache[reg];
195}
196
197/*
198 * write wm8900 register cache
199 */
200static inline void wm8900_write_reg_cache(struct snd_soc_codec *codec,
201 u16 reg, unsigned int value)
202{
203 u16 *cache = codec->reg_cache;
204
205 BUG_ON(reg >= WM8900_MAXREG);
206
207 cache[reg] = value;
208}
209
210/*
211 * write to the WM8900 register space
212 */
213static int wm8900_write(struct snd_soc_codec *codec, unsigned int reg,
214 unsigned int value)
215{
216 u8 data[3];
217
218 if (value == wm8900_read_reg_cache(codec, reg))
219 return 0;
220
221 /* data is
222 * D15..D9 WM8900 register offset
223 * D8...D0 register data
224 */
225 data[0] = reg;
226 data[1] = value >> 8;
227 data[2] = value & 0x00ff;
228
229 wm8900_write_reg_cache(codec, reg, value);
230 if (codec->hw_write(codec->control_data, data, 3) == 3)
231 return 0;
232 else
233 return -EIO;
234}
235
236/*
237 * Read from the wm8900.
238 */
239static unsigned int wm8900_chip_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 BUG_ON(reg != WM8900_REG_ID && reg != WM8900_REG_POWER1);
247
248 /* Write register */
249 xfer[0].addr = client->addr;
250 xfer[0].flags = 0;
251 xfer[0].len = 1;
252 xfer[0].buf = &reg;
253
254 /* Read data */
255 xfer[1].addr = client->addr;
256 xfer[1].flags = I2C_M_RD;
257 xfer[1].len = 2;
258 xfer[1].buf = (u8 *)&data;
259
260 ret = i2c_transfer(client->adapter, xfer, 2);
261 if (ret != 2) {
262 printk(KERN_CRIT "i2c_transfer returned %d\n", ret);
263 return 0;
264 }
265
266 return (data >> 8) | ((data & 0xff) << 8);
267}
268
269/*
270 * Read from the WM8900 register space. Most registers can't be read
271 * and are therefore supplied from cache.
272 */
273static unsigned int wm8900_read(struct snd_soc_codec *codec, unsigned int reg)
274{
275 switch (reg) {
276 case WM8900_REG_ID:
277 return wm8900_chip_read(codec, reg);
278 default:
279 return wm8900_read_reg_cache(codec, reg);
280 }
281}
282
283static void wm8900_reset(struct snd_soc_codec *codec)
284{
285 wm8900_write(codec, WM8900_REG_RESET, 0);
286
287 memcpy(codec->reg_cache, wm8900_reg_defaults,
288 sizeof(codec->reg_cache));
289}
290
291static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
292 struct snd_kcontrol *kcontrol, int event)
293{
294 struct snd_soc_codec *codec = w->codec;
295 u16 hpctl1 = wm8900_read(codec, WM8900_REG_HPCTL1);
296
297 switch (event) {
298 case SND_SOC_DAPM_PRE_PMU:
299 /* Clamp headphone outputs */
300 hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
301 WM8900_REG_HPCTL1_HP_CLAMP_OP;
302 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
303 break;
304
305 case SND_SOC_DAPM_POST_PMU:
306 /* Enable the input stage */
307 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_IP;
308 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
309 WM8900_REG_HPCTL1_HP_SHORT2 |
310 WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
311 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
312
313 msleep(400);
314
315 /* Enable the output stage */
316 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
317 hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
318 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
319
320 /* Remove the shorts */
321 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
322 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
323 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
324 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
325 break;
326
327 case SND_SOC_DAPM_PRE_PMD:
328 /* Short the output */
329 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
330 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
331
332 /* Disable the output stage */
333 hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
334 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
335
336 /* Clamp the outputs and power down input */
337 hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
338 WM8900_REG_HPCTL1_HP_CLAMP_OP;
339 hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
340 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
341 break;
342
343 case SND_SOC_DAPM_POST_PMD:
344 /* Disable everything */
345 wm8900_write(codec, WM8900_REG_HPCTL1, 0);
346 break;
347
348 default:
349 BUG();
350 }
351
352 return 0;
353}
354
355static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 100, 0);
356
357static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 0);
358
359static const DECLARE_TLV_DB_SCALE(in_boost_tlv, -1200, 600, 0);
360
361static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1200, 100, 0);
362
363static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
364
365static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1);
366
367static const DECLARE_TLV_DB_SCALE(adc_svol_tlv, -3600, 300, 0);
368
369static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
370
371static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" };
372
373static const struct soc_enum mic_bias_level =
374SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt);
375
376static const char *dac_mute_rate_txt[] = { "Fast", "Slow" };
377
378static const struct soc_enum dac_mute_rate =
379SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt);
380
381static const char *dac_deemphasis_txt[] = {
382 "Disabled", "32kHz", "44.1kHz", "48kHz"
383};
384
385static const struct soc_enum dac_deemphasis =
386SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt);
387
388static const char *adc_hpf_cut_txt[] = {
389 "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"
390};
391
392static const struct soc_enum adc_hpf_cut =
393SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt);
394
395static const char *lr_txt[] = {
396 "Left", "Right"
397};
398
399static const struct soc_enum aifl_src =
400SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt);
401
402static const struct soc_enum aifr_src =
403SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt);
404
405static const struct soc_enum dacl_src =
406SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt);
407
408static const struct soc_enum dacr_src =
409SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt);
410
411static const char *sidetone_txt[] = {
412 "Disabled", "Left ADC", "Right ADC"
413};
414
415static const struct soc_enum dacl_sidetone =
416SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt);
417
418static const struct soc_enum dacr_sidetone =
419SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt);
420
421static const struct snd_kcontrol_new wm8900_snd_controls[] = {
422SOC_ENUM("Mic Bias Level", mic_bias_level),
423
424SOC_SINGLE_TLV("Left Input PGA Volume", WM8900_REG_LINVOL, 0, 31, 0,
425 in_pga_tlv),
426SOC_SINGLE("Left Input PGA Switch", WM8900_REG_LINVOL, 6, 1, 1),
427SOC_SINGLE("Left Input PGA ZC Switch", WM8900_REG_LINVOL, 7, 1, 0),
428
429SOC_SINGLE_TLV("Right Input PGA Volume", WM8900_REG_RINVOL, 0, 31, 0,
430 in_pga_tlv),
431SOC_SINGLE("Right Input PGA Switch", WM8900_REG_RINVOL, 6, 1, 1),
432SOC_SINGLE("Right Input PGA ZC Switch", WM8900_REG_RINVOL, 7, 1, 0),
433
434SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1),
435SOC_ENUM("DAC Mute Rate", dac_mute_rate),
436SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0),
437SOC_ENUM("DAC Deemphasis", dac_deemphasis),
438SOC_SINGLE("DAC Sloping Stopband Filter Switch", WM8900_REG_DACCTRL, 8, 1, 0),
439SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL,
440 12, 1, 0),
441
442SOC_SINGLE("ADC HPF Switch", WM8900_REG_ADCCTRL, 8, 1, 0),
443SOC_ENUM("ADC HPF Cut-Off", adc_hpf_cut),
444SOC_DOUBLE("ADC Invert Switch", WM8900_REG_ADCCTRL, 1, 0, 1, 0),
445SOC_SINGLE_TLV("Left ADC Sidetone Volume", WM8900_REG_SIDETONE, 9, 12, 0,
446 adc_svol_tlv),
447SOC_SINGLE_TLV("Right ADC Sidetone Volume", WM8900_REG_SIDETONE, 5, 12, 0,
448 adc_svol_tlv),
449SOC_ENUM("Left Digital Audio Source", aifl_src),
450SOC_ENUM("Right Digital Audio Source", aifr_src),
451
452SOC_SINGLE_TLV("DAC Input Boost Volume", WM8900_REG_AUDIO2, 10, 4, 0,
453 dac_boost_tlv),
454SOC_ENUM("Left DAC Source", dacl_src),
455SOC_ENUM("Right DAC Source", dacr_src),
456SOC_ENUM("Left DAC Sidetone", dacl_sidetone),
457SOC_ENUM("Right DAC Sidetone", dacr_sidetone),
458SOC_DOUBLE("DAC Invert Switch", WM8900_REG_DACCTRL, 1, 0, 1, 0),
459
460SOC_DOUBLE_R_TLV("Digital Playback Volume",
461 WM8900_REG_LDAC_DV, WM8900_REG_RDAC_DV,
462 1, 96, 0, dac_tlv),
463SOC_DOUBLE_R_TLV("Digital Capture Volume",
464 WM8900_REG_LADC_DV, WM8900_REG_RADC_DV, 1, 119, 0, adc_tlv),
465
466SOC_SINGLE_TLV("LINPUT3 Bypass Volume", WM8900_REG_LOUTMIXCTL1, 4, 7, 0,
467 out_mix_tlv),
468SOC_SINGLE_TLV("RINPUT3 Bypass Volume", WM8900_REG_ROUTMIXCTL1, 4, 7, 0,
469 out_mix_tlv),
470SOC_SINGLE_TLV("Left AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 4, 7, 0,
471 out_mix_tlv),
472SOC_SINGLE_TLV("Right AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 0, 7, 0,
473 out_mix_tlv),
474
475SOC_SINGLE_TLV("LeftIn to RightOut Mixer Volume", WM8900_REG_BYPASS1, 0, 7, 0,
476 out_mix_tlv),
477SOC_SINGLE_TLV("LeftIn to LeftOut Mixer Volume", WM8900_REG_BYPASS1, 4, 7, 0,
478 out_mix_tlv),
479SOC_SINGLE_TLV("RightIn to LeftOut Mixer Volume", WM8900_REG_BYPASS2, 0, 7, 0,
480 out_mix_tlv),
481SOC_SINGLE_TLV("RightIn to RightOut Mixer Volume", WM8900_REG_BYPASS2, 4, 7, 0,
482 out_mix_tlv),
483
484SOC_SINGLE_TLV("IN2L Boost Volume", WM8900_REG_INBOOSTMIX1, 0, 3, 0,
485 in_boost_tlv),
486SOC_SINGLE_TLV("IN3L Boost Volume", WM8900_REG_INBOOSTMIX1, 4, 3, 0,
487 in_boost_tlv),
488SOC_SINGLE_TLV("IN2R Boost Volume", WM8900_REG_INBOOSTMIX2, 0, 3, 0,
489 in_boost_tlv),
490SOC_SINGLE_TLV("IN3R Boost Volume", WM8900_REG_INBOOSTMIX2, 4, 3, 0,
491 in_boost_tlv),
492SOC_SINGLE_TLV("Left AUX Boost Volume", WM8900_REG_AUXBOOST, 4, 3, 0,
493 in_boost_tlv),
494SOC_SINGLE_TLV("Right AUX Boost Volume", WM8900_REG_AUXBOOST, 0, 3, 0,
495 in_boost_tlv),
496
497SOC_DOUBLE_R_TLV("LINEOUT1 Volume", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
498 0, 63, 0, out_pga_tlv),
499SOC_DOUBLE_R("LINEOUT1 Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
500 6, 1, 1),
501SOC_DOUBLE_R("LINEOUT1 ZC Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
502 7, 1, 0),
503
504SOC_DOUBLE_R_TLV("LINEOUT2 Volume",
505 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL,
506 0, 63, 0, out_pga_tlv),
507SOC_DOUBLE_R("LINEOUT2 Switch",
508 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 6, 1, 1),
509SOC_DOUBLE_R("LINEOUT2 ZC Switch",
510 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 7, 1, 0),
511SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1,
512 0, 1, 1),
513
514};
515
516/* add non dapm controls */
517static int wm8900_add_controls(struct snd_soc_codec *codec)
518{
519 int err, i;
520
521 for (i = 0; i < ARRAY_SIZE(wm8900_snd_controls); i++) {
522 err = snd_ctl_add(codec->card,
523 snd_soc_cnew(&wm8900_snd_controls[i],
524 codec, NULL));
525 if (err < 0)
526 return err;
527 }
528
529 return 0;
530}
531
532static const struct snd_kcontrol_new wm8900_dapm_loutput2_control =
533SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0);
534
535static const struct snd_kcontrol_new wm8900_dapm_routput2_control =
536SOC_DAPM_SINGLE("LINEOUT2R Switch", WM8900_REG_POWER3, 5, 1, 0);
537
538static const struct snd_kcontrol_new wm8900_loutmix_controls[] = {
539SOC_DAPM_SINGLE("LINPUT3 Bypass Switch", WM8900_REG_LOUTMIXCTL1, 7, 1, 0),
540SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 7, 1, 0),
541SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 7, 1, 0),
542SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 3, 1, 0),
543SOC_DAPM_SINGLE("DACL Switch", WM8900_REG_LOUTMIXCTL1, 8, 1, 0),
544};
545
546static const struct snd_kcontrol_new wm8900_routmix_controls[] = {
547SOC_DAPM_SINGLE("RINPUT3 Bypass Switch", WM8900_REG_ROUTMIXCTL1, 7, 1, 0),
548SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 3, 1, 0),
549SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 3, 1, 0),
550SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 7, 1, 0),
551SOC_DAPM_SINGLE("DACR Switch", WM8900_REG_ROUTMIXCTL1, 8, 1, 0),
552};
553
554static const struct snd_kcontrol_new wm8900_linmix_controls[] = {
555SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INBOOSTMIX1, 2, 1, 1),
556SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INBOOSTMIX1, 6, 1, 1),
557SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 6, 1, 1),
558SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 6, 1, 0),
559};
560
561static const struct snd_kcontrol_new wm8900_rinmix_controls[] = {
562SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INBOOSTMIX2, 2, 1, 1),
563SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INBOOSTMIX2, 6, 1, 1),
564SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 2, 1, 1),
565SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 2, 1, 0),
566};
567
568static const struct snd_kcontrol_new wm8900_linpga_controls[] = {
569SOC_DAPM_SINGLE("LINPUT1 Switch", WM8900_REG_INCTL, 6, 1, 0),
570SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INCTL, 5, 1, 0),
571SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INCTL, 4, 1, 0),
572};
573
574static const struct snd_kcontrol_new wm8900_rinpga_controls[] = {
575SOC_DAPM_SINGLE("RINPUT1 Switch", WM8900_REG_INCTL, 2, 1, 0),
576SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INCTL, 1, 1, 0),
577SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
578};
579
580static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" };
581
582static const struct soc_enum wm8900_lineout2_lp_mux =
583SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux);
584
585static const struct snd_kcontrol_new wm8900_lineout2_lp =
586SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
587
588static const struct snd_soc_dapm_widget wm8900_dapm_widgets[] = {
589
590/* Externally visible pins */
591SND_SOC_DAPM_OUTPUT("LINEOUT1L"),
592SND_SOC_DAPM_OUTPUT("LINEOUT1R"),
593SND_SOC_DAPM_OUTPUT("LINEOUT2L"),
594SND_SOC_DAPM_OUTPUT("LINEOUT2R"),
595SND_SOC_DAPM_OUTPUT("HP_L"),
596SND_SOC_DAPM_OUTPUT("HP_R"),
597
598SND_SOC_DAPM_INPUT("RINPUT1"),
599SND_SOC_DAPM_INPUT("LINPUT1"),
600SND_SOC_DAPM_INPUT("RINPUT2"),
601SND_SOC_DAPM_INPUT("LINPUT2"),
602SND_SOC_DAPM_INPUT("RINPUT3"),
603SND_SOC_DAPM_INPUT("LINPUT3"),
604SND_SOC_DAPM_INPUT("AUX"),
605
606SND_SOC_DAPM_VMID("VMID"),
607
608/* Input */
609SND_SOC_DAPM_MIXER("Left Input PGA", WM8900_REG_POWER2, 3, 0,
610 wm8900_linpga_controls,
611 ARRAY_SIZE(wm8900_linpga_controls)),
612SND_SOC_DAPM_MIXER("Right Input PGA", WM8900_REG_POWER2, 2, 0,
613 wm8900_rinpga_controls,
614 ARRAY_SIZE(wm8900_rinpga_controls)),
615
616SND_SOC_DAPM_MIXER("Left Input Mixer", WM8900_REG_POWER2, 5, 0,
617 wm8900_linmix_controls,
618 ARRAY_SIZE(wm8900_linmix_controls)),
619SND_SOC_DAPM_MIXER("Right Input Mixer", WM8900_REG_POWER2, 4, 0,
620 wm8900_rinmix_controls,
621 ARRAY_SIZE(wm8900_rinmix_controls)),
622
623SND_SOC_DAPM_MICBIAS("Mic Bias", WM8900_REG_POWER1, 4, 0),
624
625SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0),
626SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0),
627
628/* Output */
629SND_SOC_DAPM_DAC("DACL", "Left HiFi Playback", WM8900_REG_POWER3, 1, 0),
630SND_SOC_DAPM_DAC("DACR", "Right HiFi Playback", WM8900_REG_POWER3, 0, 0),
631
632SND_SOC_DAPM_PGA_E("Headphone Amplifier", WM8900_REG_POWER3, 7, 0, NULL, 0,
633 wm8900_hp_event,
634 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
635 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
636
637SND_SOC_DAPM_PGA("LINEOUT1L PGA", WM8900_REG_POWER2, 8, 0, NULL, 0),
638SND_SOC_DAPM_PGA("LINEOUT1R PGA", WM8900_REG_POWER2, 7, 0, NULL, 0),
639
640SND_SOC_DAPM_MUX("LINEOUT2 LP", SND_SOC_NOPM, 0, 0, &wm8900_lineout2_lp),
641SND_SOC_DAPM_PGA("LINEOUT2L PGA", WM8900_REG_POWER3, 6, 0, NULL, 0),
642SND_SOC_DAPM_PGA("LINEOUT2R PGA", WM8900_REG_POWER3, 5, 0, NULL, 0),
643
644SND_SOC_DAPM_MIXER("Left Output Mixer", WM8900_REG_POWER3, 3, 0,
645 wm8900_loutmix_controls,
646 ARRAY_SIZE(wm8900_loutmix_controls)),
647SND_SOC_DAPM_MIXER("Right Output Mixer", WM8900_REG_POWER3, 2, 0,
648 wm8900_routmix_controls,
649 ARRAY_SIZE(wm8900_routmix_controls)),
650};
651
652/* Target, Path, Source */
653static const struct snd_soc_dapm_route audio_map[] = {
654/* Inputs */
655{"Left Input PGA", "LINPUT1 Switch", "LINPUT1"},
656{"Left Input PGA", "LINPUT2 Switch", "LINPUT2"},
657{"Left Input PGA", "LINPUT3 Switch", "LINPUT3"},
658
659{"Right Input PGA", "RINPUT1 Switch", "RINPUT1"},
660{"Right Input PGA", "RINPUT2 Switch", "RINPUT2"},
661{"Right Input PGA", "RINPUT3 Switch", "RINPUT3"},
662
663{"Left Input Mixer", "LINPUT2 Switch", "LINPUT2"},
664{"Left Input Mixer", "LINPUT3 Switch", "LINPUT3"},
665{"Left Input Mixer", "AUX Switch", "AUX"},
666{"Left Input Mixer", "Input PGA Switch", "Left Input PGA"},
667
668{"Right Input Mixer", "RINPUT2 Switch", "RINPUT2"},
669{"Right Input Mixer", "RINPUT3 Switch", "RINPUT3"},
670{"Right Input Mixer", "AUX Switch", "AUX"},
671{"Right Input Mixer", "Input PGA Switch", "Right Input PGA"},
672
673{"ADCL", NULL, "Left Input Mixer"},
674{"ADCR", NULL, "Right Input Mixer"},
675
676/* Outputs */
677{"LINEOUT1L", NULL, "LINEOUT1L PGA"},
678{"LINEOUT1L PGA", NULL, "Left Output Mixer"},
679{"LINEOUT1R", NULL, "LINEOUT1R PGA"},
680{"LINEOUT1R PGA", NULL, "Right Output Mixer"},
681
682{"LINEOUT2L PGA", NULL, "Left Output Mixer"},
683{"LINEOUT2 LP", "Disabled", "LINEOUT2L PGA"},
684{"LINEOUT2 LP", "Enabled", "Left Output Mixer"},
685{"LINEOUT2L", NULL, "LINEOUT2 LP"},
686
687{"LINEOUT2R PGA", NULL, "Right Output Mixer"},
688{"LINEOUT2 LP", "Disabled", "LINEOUT2R PGA"},
689{"LINEOUT2 LP", "Enabled", "Right Output Mixer"},
690{"LINEOUT2R", NULL, "LINEOUT2 LP"},
691
692{"Left Output Mixer", "LINPUT3 Bypass Switch", "LINPUT3"},
693{"Left Output Mixer", "AUX Bypass Switch", "AUX"},
694{"Left Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
695{"Left Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
696{"Left Output Mixer", "DACL Switch", "DACL"},
697
698{"Right Output Mixer", "RINPUT3 Bypass Switch", "RINPUT3"},
699{"Right Output Mixer", "AUX Bypass Switch", "AUX"},
700{"Right Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
701{"Right Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
702{"Right Output Mixer", "DACR Switch", "DACR"},
703
704/* Note that the headphone output stage needs to be connected
705 * externally to LINEOUT2 via DC blocking capacitors. Other
706 * configurations are not supported.
707 *
708 * Note also that left and right headphone paths are treated as a
709 * mono path.
710 */
711{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
712{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
713{"HP_L", NULL, "Headphone Amplifier"},
714{"HP_R", NULL, "Headphone Amplifier"},
715};
716
717static int wm8900_add_widgets(struct snd_soc_codec *codec)
718{
719 snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets,
720 ARRAY_SIZE(wm8900_dapm_widgets));
721
722 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
723
724 snd_soc_dapm_new_widgets(codec);
725
726 return 0;
727}
728
729static int wm8900_hw_params(struct snd_pcm_substream *substream,
730 struct snd_pcm_hw_params *params)
731{
732 struct snd_soc_pcm_runtime *rtd = substream->private_data;
733 struct snd_soc_device *socdev = rtd->socdev;
734 struct snd_soc_codec *codec = socdev->codec;
735 u16 reg;
736
737 reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60;
738
739 switch (params_format(params)) {
740 case SNDRV_PCM_FORMAT_S16_LE:
741 break;
742 case SNDRV_PCM_FORMAT_S20_3LE:
743 reg |= 0x20;
744 break;
745 case SNDRV_PCM_FORMAT_S24_LE:
746 reg |= 0x40;
747 break;
748 case SNDRV_PCM_FORMAT_S32_LE:
749 reg |= 0x60;
750 break;
751 default:
752 return -EINVAL;
753 }
754
755 wm8900_write(codec, WM8900_REG_AUDIO1, reg);
756
757 return 0;
758}
759
760/* FLL divisors */
761struct _fll_div {
762 u16 fll_ratio;
763 u16 fllclk_div;
764 u16 fll_slow_lock_ref;
765 u16 n;
766 u16 k;
767};
768
769/* The size in bits of the FLL divide multiplied by 10
770 * to allow rounding later */
771#define FIXED_FLL_SIZE ((1 << 16) * 10)
772
773static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
774 unsigned int Fout)
775{
776 u64 Kpart;
777 unsigned int K, Ndiv, Nmod, target;
778 unsigned int div;
779
780 BUG_ON(!Fout);
781
782 /* The FLL must run at 90-100MHz which is then scaled down to
783 * the output value by FLLCLK_DIV. */
784 target = Fout;
785 div = 1;
786 while (target < 90000000) {
787 div *= 2;
788 target *= 2;
789 }
790
791 if (target > 100000000)
792 printk(KERN_WARNING "wm8900: FLL rate %d out of range, Fref=%d"
793 " Fout=%d\n", target, Fref, Fout);
794 if (div > 32) {
795 printk(KERN_ERR "wm8900: Invalid FLL division rate %u, "
796 "Fref=%d, Fout=%d, target=%d\n",
797 div, Fref, Fout, target);
798 return -EINVAL;
799 }
800
801 fll_div->fllclk_div = div >> 2;
802
803 if (Fref < 48000)
804 fll_div->fll_slow_lock_ref = 1;
805 else
806 fll_div->fll_slow_lock_ref = 0;
807
808 Ndiv = target / Fref;
809
810 if (Fref < 1000000)
811 fll_div->fll_ratio = 8;
812 else
813 fll_div->fll_ratio = 1;
814
815 fll_div->n = Ndiv / fll_div->fll_ratio;
816 Nmod = (target / fll_div->fll_ratio) % Fref;
817
818 /* Calculate fractional part - scale up so we can round. */
819 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
820
821 do_div(Kpart, Fref);
822
823 K = Kpart & 0xFFFFFFFF;
824
825 if ((K % 10) >= 5)
826 K += 5;
827
828 /* Move down to proper range now rounding is done */
829 fll_div->k = K / 10;
830
831 BUG_ON(target != Fout * (fll_div->fllclk_div << 2));
832 BUG_ON(!K && target != Fref * fll_div->fll_ratio * fll_div->n);
833
834 return 0;
835}
836
837static int wm8900_set_fll(struct snd_soc_codec *codec,
838 int fll_id, unsigned int freq_in, unsigned int freq_out)
839{
840 struct wm8900_priv *wm8900 = codec->private_data;
841 struct _fll_div fll_div;
842 unsigned int reg;
843
844 if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out)
845 return 0;
846
847 /* The digital side should be disabled during any change. */
848 reg = wm8900_read(codec, WM8900_REG_POWER1);
849 wm8900_write(codec, WM8900_REG_POWER1,
850 reg & (~WM8900_REG_POWER1_FLL_ENA));
851
852 /* Disable the FLL? */
853 if (!freq_in || !freq_out) {
854 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
855 wm8900_write(codec, WM8900_REG_CLOCKING1,
856 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC));
857
858 reg = wm8900_read(codec, WM8900_REG_FLLCTL1);
859 wm8900_write(codec, WM8900_REG_FLLCTL1,
860 reg & (~WM8900_REG_FLLCTL1_OSC_ENA));
861
862 wm8900->fll_in = freq_in;
863 wm8900->fll_out = freq_out;
864
865 return 0;
866 }
867
868 if (fll_factors(&fll_div, freq_in, freq_out) != 0)
869 goto reenable;
870
871 wm8900->fll_in = freq_in;
872 wm8900->fll_out = freq_out;
873
874 /* The osclilator *MUST* be enabled before we enable the
875 * digital circuit. */
876 wm8900_write(codec, WM8900_REG_FLLCTL1,
877 fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA);
878
879 wm8900_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
880 wm8900_write(codec, WM8900_REG_FLLCTL5,
881 (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f));
882
883 if (fll_div.k) {
884 wm8900_write(codec, WM8900_REG_FLLCTL2,
885 (fll_div.k >> 8) | 0x100);
886 wm8900_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
887 } else
888 wm8900_write(codec, WM8900_REG_FLLCTL2, 0);
889
890 if (fll_div.fll_slow_lock_ref)
891 wm8900_write(codec, WM8900_REG_FLLCTL6,
892 WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF);
893 else
894 wm8900_write(codec, WM8900_REG_FLLCTL6, 0);
895
896 reg = wm8900_read(codec, WM8900_REG_POWER1);
897 wm8900_write(codec, WM8900_REG_POWER1,
898 reg | WM8900_REG_POWER1_FLL_ENA);
899
900reenable:
901 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
902 wm8900_write(codec, WM8900_REG_CLOCKING1,
903 reg | WM8900_REG_CLOCKING1_MCLK_SRC);
904
905 return 0;
906}
907
908static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai,
909 int pll_id, unsigned int freq_in, unsigned int freq_out)
910{
911 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
912}
913
914static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
915 int div_id, int div)
916{
917 struct snd_soc_codec *codec = codec_dai->codec;
918 unsigned int reg;
919
920 switch (div_id) {
921 case WM8900_BCLK_DIV:
922 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
923 wm8900_write(codec, WM8900_REG_CLOCKING1,
924 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK));
925 break;
926 case WM8900_OPCLK_DIV:
927 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
928 wm8900_write(codec, WM8900_REG_CLOCKING1,
929 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK));
930 break;
931 case WM8900_DAC_LRCLK:
932 reg = wm8900_read(codec, WM8900_REG_AUDIO4);
933 wm8900_write(codec, WM8900_REG_AUDIO4,
934 div | (reg & WM8900_LRC_MASK));
935 break;
936 case WM8900_ADC_LRCLK:
937 reg = wm8900_read(codec, WM8900_REG_AUDIO3);
938 wm8900_write(codec, WM8900_REG_AUDIO3,
939 div | (reg & WM8900_LRC_MASK));
940 break;
941 case WM8900_DAC_CLKDIV:
942 reg = wm8900_read(codec, WM8900_REG_CLOCKING2);
943 wm8900_write(codec, WM8900_REG_CLOCKING2,
944 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV));
945 break;
946 case WM8900_ADC_CLKDIV:
947 reg = wm8900_read(codec, WM8900_REG_CLOCKING2);
948 wm8900_write(codec, WM8900_REG_CLOCKING2,
949 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV));
950 break;
951 case WM8900_LRCLK_MODE:
952 reg = wm8900_read(codec, WM8900_REG_DACCTRL);
953 wm8900_write(codec, WM8900_REG_DACCTRL,
954 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE));
955 break;
956 default:
957 return -EINVAL;
958 }
959
960 return 0;
961}
962
963
964static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
965 unsigned int fmt)
966{
967 struct snd_soc_codec *codec = codec_dai->codec;
968 unsigned int clocking1, aif1, aif3, aif4;
969
970 clocking1 = wm8900_read(codec, WM8900_REG_CLOCKING1);
971 aif1 = wm8900_read(codec, WM8900_REG_AUDIO1);
972 aif3 = wm8900_read(codec, WM8900_REG_AUDIO3);
973 aif4 = wm8900_read(codec, WM8900_REG_AUDIO4);
974
975 /* set master/slave audio interface */
976 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
977 case SND_SOC_DAIFMT_CBS_CFS:
978 clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR;
979 aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR;
980 aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR;
981 break;
982 case SND_SOC_DAIFMT_CBS_CFM:
983 clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR;
984 aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR;
985 aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR;
986 break;
987 case SND_SOC_DAIFMT_CBM_CFM:
988 clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR;
989 aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR;
990 aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR;
991 break;
992 case SND_SOC_DAIFMT_CBM_CFS:
993 clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR;
994 aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR;
995 aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR;
996 break;
997 default:
998 return -EINVAL;
999 }
1000
1001 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1002 case SND_SOC_DAIFMT_DSP_A:
1003 aif1 |= WM8900_REG_AUDIO1_AIF_FMT_MASK;
1004 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1005 break;
1006 case SND_SOC_DAIFMT_DSP_B:
1007 aif1 |= WM8900_REG_AUDIO1_AIF_FMT_MASK;
1008 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1009 break;
1010 case SND_SOC_DAIFMT_I2S:
1011 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1012 aif1 |= 0x10;
1013 break;
1014 case SND_SOC_DAIFMT_RIGHT_J:
1015 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1016 break;
1017 case SND_SOC_DAIFMT_LEFT_J:
1018 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1019 aif1 |= 0x8;
1020 break;
1021 default:
1022 return -EINVAL;
1023 }
1024
1025 /* Clock inversion */
1026 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1027 case SND_SOC_DAIFMT_DSP_A:
1028 case SND_SOC_DAIFMT_DSP_B:
1029 /* frame inversion not valid for DSP modes */
1030 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1031 case SND_SOC_DAIFMT_NB_NF:
1032 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1033 break;
1034 case SND_SOC_DAIFMT_IB_NF:
1035 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1036 break;
1037 default:
1038 return -EINVAL;
1039 }
1040 break;
1041 case SND_SOC_DAIFMT_I2S:
1042 case SND_SOC_DAIFMT_RIGHT_J:
1043 case SND_SOC_DAIFMT_LEFT_J:
1044 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1045 case SND_SOC_DAIFMT_NB_NF:
1046 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1047 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1048 break;
1049 case SND_SOC_DAIFMT_IB_IF:
1050 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1051 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1052 break;
1053 case SND_SOC_DAIFMT_IB_NF:
1054 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1055 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1056 break;
1057 case SND_SOC_DAIFMT_NB_IF:
1058 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1059 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1060 break;
1061 default:
1062 return -EINVAL;
1063 }
1064 break;
1065 default:
1066 return -EINVAL;
1067 }
1068
1069 wm8900_write(codec, WM8900_REG_CLOCKING1, clocking1);
1070 wm8900_write(codec, WM8900_REG_AUDIO1, aif1);
1071 wm8900_write(codec, WM8900_REG_AUDIO3, aif3);
1072 wm8900_write(codec, WM8900_REG_AUDIO4, aif4);
1073
1074 return 0;
1075}
1076
1077static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1078{
1079 struct snd_soc_codec *codec = codec_dai->codec;
1080 u16 reg;
1081
1082 reg = wm8900_read(codec, WM8900_REG_DACCTRL);
1083
1084 if (mute)
1085 reg |= WM8900_REG_DACCTRL_MUTE;
1086 else
1087 reg &= ~WM8900_REG_DACCTRL_MUTE;
1088
1089 wm8900_write(codec, WM8900_REG_DACCTRL, reg);
1090
1091 return 0;
1092}
1093
1094#define WM8900_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
1095 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
1096 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1097
1098#define WM8900_PCM_FORMATS \
1099 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
1100 SNDRV_PCM_FORMAT_S24_LE)
1101
1102struct snd_soc_dai wm8900_dai = {
1103 .name = "WM8900 HiFi",
1104 .playback = {
1105 .stream_name = "HiFi Playback",
1106 .channels_min = 1,
1107 .channels_max = 2,
1108 .rates = WM8900_RATES,
1109 .formats = WM8900_PCM_FORMATS,
1110 },
1111 .capture = {
1112 .stream_name = "HiFi Capture",
1113 .channels_min = 1,
1114 .channels_max = 2,
1115 .rates = WM8900_RATES,
1116 .formats = WM8900_PCM_FORMATS,
1117 },
1118 .ops = {
1119 .hw_params = wm8900_hw_params,
1120 },
1121 .dai_ops = {
1122 .set_clkdiv = wm8900_set_dai_clkdiv,
1123 .set_pll = wm8900_set_dai_pll,
1124 .set_fmt = wm8900_set_dai_fmt,
1125 .digital_mute = wm8900_digital_mute,
1126 },
1127};
1128EXPORT_SYMBOL_GPL(wm8900_dai);
1129
1130static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1131 enum snd_soc_bias_level level)
1132{
1133 u16 reg;
1134
1135 switch (level) {
1136 case SND_SOC_BIAS_ON:
1137 /* Enable thermal shutdown */
1138 reg = wm8900_read(codec, WM8900_REG_GPIO);
1139 wm8900_write(codec, WM8900_REG_GPIO,
1140 reg | WM8900_REG_GPIO_TEMP_ENA);
1141 reg = wm8900_read(codec, WM8900_REG_ADDCTL);
1142 wm8900_write(codec, WM8900_REG_ADDCTL,
1143 reg | WM8900_REG_ADDCTL_TEMP_SD);
1144 break;
1145
1146 case SND_SOC_BIAS_PREPARE:
1147 break;
1148
1149 case SND_SOC_BIAS_STANDBY:
1150 /* Charge capacitors if initial power up */
1151 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1152 /* STARTUP_BIAS_ENA on */
1153 wm8900_write(codec, WM8900_REG_POWER1,
1154 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1155
1156 /* Startup bias mode */
1157 wm8900_write(codec, WM8900_REG_ADDCTL,
1158 WM8900_REG_ADDCTL_BIAS_SRC |
1159 WM8900_REG_ADDCTL_VMID_SOFTST);
1160
1161 /* VMID 2x50k */
1162 wm8900_write(codec, WM8900_REG_POWER1,
1163 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1);
1164
1165 /* Allow capacitors to charge */
1166 schedule_timeout_interruptible(msecs_to_jiffies(400));
1167
1168 /* Enable bias */
1169 wm8900_write(codec, WM8900_REG_POWER1,
1170 WM8900_REG_POWER1_STARTUP_BIAS_ENA |
1171 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1172
1173 wm8900_write(codec, WM8900_REG_ADDCTL, 0);
1174
1175 wm8900_write(codec, WM8900_REG_POWER1,
1176 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1177 }
1178
1179 reg = wm8900_read(codec, WM8900_REG_POWER1);
1180 wm8900_write(codec, WM8900_REG_POWER1,
1181 (reg & WM8900_REG_POWER1_FLL_ENA) |
1182 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1183 wm8900_write(codec, WM8900_REG_POWER2,
1184 WM8900_REG_POWER2_SYSCLK_ENA);
1185 wm8900_write(codec, WM8900_REG_POWER3, 0);
1186 break;
1187
1188 case SND_SOC_BIAS_OFF:
1189 /* Startup bias enable */
1190 reg = wm8900_read(codec, WM8900_REG_POWER1);
1191 wm8900_write(codec, WM8900_REG_POWER1,
1192 reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1193 wm8900_write(codec, WM8900_REG_ADDCTL,
1194 WM8900_REG_ADDCTL_BIAS_SRC |
1195 WM8900_REG_ADDCTL_VMID_SOFTST);
1196
1197 /* Discharge caps */
1198 wm8900_write(codec, WM8900_REG_POWER1,
1199 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1200 schedule_timeout_interruptible(msecs_to_jiffies(500));
1201
1202 /* Remove clamp */
1203 wm8900_write(codec, WM8900_REG_HPCTL1, 0);
1204
1205 /* Power down */
1206 wm8900_write(codec, WM8900_REG_ADDCTL, 0);
1207 wm8900_write(codec, WM8900_REG_POWER1, 0);
1208 wm8900_write(codec, WM8900_REG_POWER2, 0);
1209 wm8900_write(codec, WM8900_REG_POWER3, 0);
1210
1211 /* Need to let things settle before stopping the clock
1212 * to ensure that restart works, see "Stopping the
1213 * master clock" in the datasheet. */
1214 schedule_timeout_interruptible(msecs_to_jiffies(1));
1215 wm8900_write(codec, WM8900_REG_POWER2,
1216 WM8900_REG_POWER2_SYSCLK_ENA);
1217 break;
1218 }
1219 codec->bias_level = level;
1220 return 0;
1221}
1222
1223static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1224{
1225 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1226 struct snd_soc_codec *codec = socdev->codec;
1227 struct wm8900_priv *wm8900 = codec->private_data;
1228 int fll_out = wm8900->fll_out;
1229 int fll_in = wm8900->fll_in;
1230 int ret;
1231
1232 /* Stop the FLL in an orderly fashion */
1233 ret = wm8900_set_fll(codec, 0, 0, 0);
1234 if (ret != 0) {
1235 dev_err(&pdev->dev, "Failed to stop FLL\n");
1236 return ret;
1237 }
1238
1239 wm8900->fll_out = fll_out;
1240 wm8900->fll_in = fll_in;
1241
1242 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1243
1244 return 0;
1245}
1246
1247static int wm8900_resume(struct platform_device *pdev)
1248{
1249 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1250 struct snd_soc_codec *codec = socdev->codec;
1251 struct wm8900_priv *wm8900 = codec->private_data;
1252 u16 *cache;
1253 int i, ret;
1254
1255 cache = kmemdup(codec->reg_cache, sizeof(wm8900_reg_defaults),
1256 GFP_KERNEL);
1257
1258 wm8900_reset(codec);
1259 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1260
1261 /* Restart the FLL? */
1262 if (wm8900->fll_out) {
1263 int fll_out = wm8900->fll_out;
1264 int fll_in = wm8900->fll_in;
1265
1266 wm8900->fll_in = 0;
1267 wm8900->fll_out = 0;
1268
1269 ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
1270 if (ret != 0) {
1271 dev_err(&pdev->dev, "Failed to restart FLL\n");
1272 return ret;
1273 }
1274 }
1275
1276 if (cache) {
1277 for (i = 0; i < WM8900_MAXREG; i++)
1278 wm8900_write(codec, i, cache[i]);
1279 kfree(cache);
1280 } else
1281 dev_err(&pdev->dev, "Unable to allocate register cache\n");
1282
1283 return 0;
1284}
1285
1286/*
1287 * initialise the WM8900 driver
1288 * register the mixer and dsp interfaces with the kernel
1289 */
1290static int wm8900_init(struct snd_soc_device *socdev)
1291{
1292 struct snd_soc_codec *codec = socdev->codec;
1293 int ret = 0;
1294 unsigned int reg;
1295 struct i2c_client *i2c_client = socdev->codec->control_data;
1296
1297 codec->name = "WM8900";
1298 codec->owner = THIS_MODULE;
1299 codec->read = wm8900_read;
1300 codec->write = wm8900_write;
1301 codec->dai = &wm8900_dai;
1302 codec->num_dai = 1;
1303 codec->reg_cache_size = WM8900_MAXREG;
1304 codec->reg_cache = kmemdup(wm8900_reg_defaults,
1305 sizeof(wm8900_reg_defaults), GFP_KERNEL);
1306
1307 if (codec->reg_cache == NULL)
1308 return -ENOMEM;
1309
1310 reg = wm8900_read(codec, WM8900_REG_ID);
1311 if (reg != 0x8900) {
1312 dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n",
1313 reg);
1314 return -ENODEV;
1315 }
1316
1317 codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1318 if (codec->private_data == NULL) {
1319 ret = -ENOMEM;
1320 goto priv_err;
1321 }
1322
1323 /* Read back from the chip */
1324 reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
1325 reg = (reg >> 12) & 0xf;
1326 dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg);
1327
1328 wm8900_reset(codec);
1329
1330 /* Latch the volume update bits */
1331 wm8900_write(codec, WM8900_REG_LINVOL,
1332 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
1333 wm8900_write(codec, WM8900_REG_RINVOL,
1334 wm8900_read(codec, WM8900_REG_RINVOL) | 0x100);
1335 wm8900_write(codec, WM8900_REG_LOUT1CTL,
1336 wm8900_read(codec, WM8900_REG_LOUT1CTL) | 0x100);
1337 wm8900_write(codec, WM8900_REG_ROUT1CTL,
1338 wm8900_read(codec, WM8900_REG_ROUT1CTL) | 0x100);
1339 wm8900_write(codec, WM8900_REG_LOUT2CTL,
1340 wm8900_read(codec, WM8900_REG_LOUT2CTL) | 0x100);
1341 wm8900_write(codec, WM8900_REG_ROUT2CTL,
1342 wm8900_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
1343 wm8900_write(codec, WM8900_REG_LDAC_DV,
1344 wm8900_read(codec, WM8900_REG_LDAC_DV) | 0x100);
1345 wm8900_write(codec, WM8900_REG_RDAC_DV,
1346 wm8900_read(codec, WM8900_REG_RDAC_DV) | 0x100);
1347 wm8900_write(codec, WM8900_REG_LADC_DV,
1348 wm8900_read(codec, WM8900_REG_LADC_DV) | 0x100);
1349 wm8900_write(codec, WM8900_REG_RADC_DV,
1350 wm8900_read(codec, WM8900_REG_RADC_DV) | 0x100);
1351
1352 /* Set the DAC and mixer output bias */
1353 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1354
1355 /* Register pcms */
1356 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1357 if (ret < 0) {
1358 dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
1359 goto pcm_err;
1360 }
1361
1362 /* Turn the chip on */
1363 codec->bias_level = SND_SOC_BIAS_OFF;
1364 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1365
1366 wm8900_add_controls(codec);
1367 wm8900_add_widgets(codec);
1368
1369 ret = snd_soc_register_card(socdev);
1370 if (ret < 0) {
1371 dev_err(&i2c_client->dev, "Failed to register card\n");
1372 goto card_err;
1373 }
1374 return ret;
1375
1376card_err:
1377 snd_soc_free_pcms(socdev);
1378 snd_soc_dapm_free(socdev);
1379pcm_err:
1380 kfree(codec->reg_cache);
1381priv_err:
1382 kfree(codec->private_data);
1383 return ret;
1384}
1385
1386static struct snd_soc_device *wm8900_socdev;
1387
1388#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1389
1390static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1391
1392/* Magic definition of all other variables and things */
1393I2C_CLIENT_INSMOD;
1394
1395static struct i2c_driver wm8900_i2c_driver;
1396static struct i2c_client client_template;
1397
1398/* If the i2c layer weren't so broken, we could pass this kind of data
1399 around */
1400static int wm8900_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1401{
1402 struct snd_soc_device *socdev = wm8900_socdev;
1403 struct wm8900_setup_data *setup = socdev->codec_data;
1404 struct snd_soc_codec *codec = socdev->codec;
1405 struct i2c_client *i2c;
1406 int ret;
1407
1408 if (addr != setup->i2c_address)
1409 return -ENODEV;
1410
1411 dev_err(&adap->dev, "Probe on %x\n", addr);
1412
1413 client_template.adapter = adap;
1414 client_template.addr = addr;
1415
1416 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1417 if (i2c == NULL) {
1418 kfree(codec);
1419 return -ENOMEM;
1420 }
1421 i2c_set_clientdata(i2c, codec);
1422 codec->control_data = i2c;
1423
1424 ret = i2c_attach_client(i2c);
1425 if (ret < 0) {
1426 dev_err(&adap->dev,
1427 "failed to attach codec at addr %x\n", addr);
1428 goto err;
1429 }
1430
1431 ret = wm8900_init(socdev);
1432 if (ret < 0) {
1433 dev_err(&adap->dev, "failed to initialise WM8900\n");
1434 goto err;
1435 }
1436 return ret;
1437
1438err:
1439 kfree(codec);
1440 kfree(i2c);
1441 return ret;
1442}
1443
1444static int wm8900_i2c_detach(struct i2c_client *client)
1445{
1446 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1447 i2c_detach_client(client);
1448 kfree(codec->reg_cache);
1449 kfree(client);
1450 return 0;
1451}
1452
1453static int wm8900_i2c_attach(struct i2c_adapter *adap)
1454{
1455 return i2c_probe(adap, &addr_data, wm8900_codec_probe);
1456}
1457
1458/* corgi i2c codec control layer */
1459static struct i2c_driver wm8900_i2c_driver = {
1460 .driver = {
1461 .name = "WM8900 I2C codec",
1462 .owner = THIS_MODULE,
1463 },
1464 .attach_adapter = wm8900_i2c_attach,
1465 .detach_client = wm8900_i2c_detach,
1466 .command = NULL,
1467};
1468
1469static struct i2c_client client_template = {
1470 .name = "WM8900",
1471 .driver = &wm8900_i2c_driver,
1472};
1473#endif
1474
1475static int wm8900_probe(struct platform_device *pdev)
1476{
1477 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1478 struct wm8900_setup_data *setup;
1479 struct snd_soc_codec *codec;
1480 int ret = 0;
1481
1482 dev_info(&pdev->dev, "WM8900 Audio Codec\n");
1483
1484 setup = socdev->codec_data;
1485 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1486 if (codec == NULL)
1487 return -ENOMEM;
1488
1489 mutex_init(&codec->mutex);
1490 INIT_LIST_HEAD(&codec->dapm_widgets);
1491 INIT_LIST_HEAD(&codec->dapm_paths);
1492
1493 socdev->codec = codec;
1494
1495 codec->set_bias_level = wm8900_set_bias_level;
1496
1497 wm8900_socdev = socdev;
1498#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1499 if (setup->i2c_address) {
1500 normal_i2c[0] = setup->i2c_address;
1501 codec->hw_write = (hw_write_t)i2c_master_send;
1502 ret = i2c_add_driver(&wm8900_i2c_driver);
1503 if (ret != 0)
1504 printk(KERN_ERR "can't add i2c driver");
1505 }
1506#else
1507#error Non-I2C interfaces not yet supported
1508#endif
1509 return ret;
1510}
1511
1512/* power down chip */
1513static int wm8900_remove(struct platform_device *pdev)
1514{
1515 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1516 struct snd_soc_codec *codec = socdev->codec;
1517
1518 if (codec->control_data)
1519 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1520
1521 snd_soc_free_pcms(socdev);
1522 snd_soc_dapm_free(socdev);
1523#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1524 i2c_del_driver(&wm8900_i2c_driver);
1525#endif
1526 kfree(codec);
1527
1528 return 0;
1529}
1530
1531struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1532 .probe = wm8900_probe,
1533 .remove = wm8900_remove,
1534 .suspend = wm8900_suspend,
1535 .resume = wm8900_resume,
1536};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1538
1539MODULE_DESCRIPTION("ASoC WM8900 driver");
1540MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
1541MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
new file mode 100644
index 000000000000..ba450d99e902
--- /dev/null
+++ b/sound/soc/codecs/wm8900.h
@@ -0,0 +1,64 @@
1/*
2 * wm8900.h -- WM890 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 _WM8900_H
10#define _WM8900_H
11
12#define WM8900_FLL 1
13
14#define WM8900_BCLK_DIV 1
15#define WM8900_ADC_CLKDIV 2
16#define WM8900_DAC_CLKDIV 3
17#define WM8900_ADC_LRCLK 4
18#define WM8900_DAC_LRCLK 5
19#define WM8900_OPCLK_DIV 6
20#define WM8900_LRCLK_MODE 7
21
22#define WM8900_BCLK_DIV_1 0x00
23#define WM8900_BCLK_DIV_1_5 0x02
24#define WM8900_BCLK_DIV_2 0x04
25#define WM8900_BCLK_DIV_3 0x06
26#define WM8900_BCLK_DIV_4 0x08
27#define WM8900_BCLK_DIV_5_5 0x0a
28#define WM8900_BCLK_DIV_6 0x0c
29#define WM8900_BCLK_DIV_8 0x0e
30#define WM8900_BCLK_DIV_11 0x10
31#define WM8900_BCLK_DIV_12 0x12
32#define WM8900_BCLK_DIV_16 0x14
33#define WM8900_BCLK_DIV_22 0x16
34#define WM8900_BCLK_DIV_24 0x18
35#define WM8900_BCLK_DIV_32 0x1a
36#define WM8900_BCLK_DIV_44 0x1c
37#define WM8900_BCLK_DIV_48 0x1e
38
39#define WM8900_ADC_CLKDIV_1 0x00
40#define WM8900_ADC_CLKDIV_1_5 0x20
41#define WM8900_ADC_CLKDIV_2 0x40
42#define WM8900_ADC_CLKDIV_3 0x60
43#define WM8900_ADC_CLKDIV_4 0x80
44#define WM8900_ADC_CLKDIV_5_5 0xa0
45#define WM8900_ADC_CLKDIV_6 0xc0
46
47#define WM8900_DAC_CLKDIV_1 0x00
48#define WM8900_DAC_CLKDIV_1_5 0x04
49#define WM8900_DAC_CLKDIV_2 0x08
50#define WM8900_DAC_CLKDIV_3 0x0c
51#define WM8900_DAC_CLKDIV_4 0x10
52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18
54
55#define WM8900_
56
57struct wm8900_setup_data {
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8900_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8900;
63
64#endif
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
new file mode 100644
index 000000000000..ce40d7877605
--- /dev/null
+++ b/sound/soc/codecs/wm8903.c
@@ -0,0 +1,1813 @@
1/*
2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics
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:
13 * - TDM mode configuration.
14 * - Mic detect.
15 * - Digital microphone support.
16 * - Interrupt support (mic detect and sequencer).
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/tlv.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/initval.h>
33
34#include "wm8903.h"
35
36struct wm8903_priv {
37 int sysclk;
38
39 /* Reference counts */
40 int charge_pump_users;
41 int class_w_users;
42 int playback_active;
43 int capture_active;
44
45 struct snd_pcm_substream *master_substream;
46 struct snd_pcm_substream *slave_substream;
47};
48
49/* Register defaults at reset */
50static u16 wm8903_reg_defaults[] = {
51 0x8903, /* R0 - SW Reset and ID */
52 0x0000, /* R1 - Revision Number */
53 0x0000, /* R2 */
54 0x0000, /* R3 */
55 0x0018, /* R4 - Bias Control 0 */
56 0x0000, /* R5 - VMID Control 0 */
57 0x0000, /* R6 - Mic Bias Control 0 */
58 0x0000, /* R7 */
59 0x0001, /* R8 - Analogue DAC 0 */
60 0x0000, /* R9 */
61 0x0001, /* R10 - Analogue ADC 0 */
62 0x0000, /* R11 */
63 0x0000, /* R12 - Power Management 0 */
64 0x0000, /* R13 - Power Management 1 */
65 0x0000, /* R14 - Power Management 2 */
66 0x0000, /* R15 - Power Management 3 */
67 0x0000, /* R16 - Power Management 4 */
68 0x0000, /* R17 - Power Management 5 */
69 0x0000, /* R18 - Power Management 6 */
70 0x0000, /* R19 */
71 0x0400, /* R20 - Clock Rates 0 */
72 0x0D07, /* R21 - Clock Rates 1 */
73 0x0000, /* R22 - Clock Rates 2 */
74 0x0000, /* R23 */
75 0x0050, /* R24 - Audio Interface 0 */
76 0x0242, /* R25 - Audio Interface 1 */
77 0x0008, /* R26 - Audio Interface 2 */
78 0x0022, /* R27 - Audio Interface 3 */
79 0x0000, /* R28 */
80 0x0000, /* R29 */
81 0x00C0, /* R30 - DAC Digital Volume Left */
82 0x00C0, /* R31 - DAC Digital Volume Right */
83 0x0000, /* R32 - DAC Digital 0 */
84 0x0000, /* R33 - DAC Digital 1 */
85 0x0000, /* R34 */
86 0x0000, /* R35 */
87 0x00C0, /* R36 - ADC Digital Volume Left */
88 0x00C0, /* R37 - ADC Digital Volume Right */
89 0x0000, /* R38 - ADC Digital 0 */
90 0x0073, /* R39 - Digital Microphone 0 */
91 0x09BF, /* R40 - DRC 0 */
92 0x3241, /* R41 - DRC 1 */
93 0x0020, /* R42 - DRC 2 */
94 0x0000, /* R43 - DRC 3 */
95 0x0085, /* R44 - Analogue Left Input 0 */
96 0x0085, /* R45 - Analogue Right Input 0 */
97 0x0044, /* R46 - Analogue Left Input 1 */
98 0x0044, /* R47 - Analogue Right Input 1 */
99 0x0000, /* R48 */
100 0x0000, /* R49 */
101 0x0008, /* R50 - Analogue Left Mix 0 */
102 0x0004, /* R51 - Analogue Right Mix 0 */
103 0x0000, /* R52 - Analogue Spk Mix Left 0 */
104 0x0000, /* R53 - Analogue Spk Mix Left 1 */
105 0x0000, /* R54 - Analogue Spk Mix Right 0 */
106 0x0000, /* R55 - Analogue Spk Mix Right 1 */
107 0x0000, /* R56 */
108 0x002D, /* R57 - Analogue OUT1 Left */
109 0x002D, /* R58 - Analogue OUT1 Right */
110 0x0039, /* R59 - Analogue OUT2 Left */
111 0x0039, /* R60 - Analogue OUT2 Right */
112 0x0100, /* R61 */
113 0x0139, /* R62 - Analogue OUT3 Left */
114 0x0139, /* R63 - Analogue OUT3 Right */
115 0x0000, /* R64 */
116 0x0000, /* R65 - Analogue SPK Output Control 0 */
117 0x0000, /* R66 */
118 0x0010, /* R67 - DC Servo 0 */
119 0x0100, /* R68 */
120 0x00A4, /* R69 - DC Servo 2 */
121 0x0807, /* R70 */
122 0x0000, /* R71 */
123 0x0000, /* R72 */
124 0x0000, /* R73 */
125 0x0000, /* R74 */
126 0x0000, /* R75 */
127 0x0000, /* R76 */
128 0x0000, /* R77 */
129 0x0000, /* R78 */
130 0x000E, /* R79 */
131 0x0000, /* R80 */
132 0x0000, /* R81 */
133 0x0000, /* R82 */
134 0x0000, /* R83 */
135 0x0000, /* R84 */
136 0x0000, /* R85 */
137 0x0000, /* R86 */
138 0x0006, /* R87 */
139 0x0000, /* R88 */
140 0x0000, /* R89 */
141 0x0000, /* R90 - Analogue HP 0 */
142 0x0060, /* R91 */
143 0x0000, /* R92 */
144 0x0000, /* R93 */
145 0x0000, /* R94 - Analogue Lineout 0 */
146 0x0060, /* R95 */
147 0x0000, /* R96 */
148 0x0000, /* R97 */
149 0x0000, /* R98 - Charge Pump 0 */
150 0x1F25, /* R99 */
151 0x2B19, /* R100 */
152 0x01C0, /* R101 */
153 0x01EF, /* R102 */
154 0x2B00, /* R103 */
155 0x0000, /* R104 - Class W 0 */
156 0x01C0, /* R105 */
157 0x1C10, /* R106 */
158 0x0000, /* R107 */
159 0x0000, /* R108 - Write Sequencer 0 */
160 0x0000, /* R109 - Write Sequencer 1 */
161 0x0000, /* R110 - Write Sequencer 2 */
162 0x0000, /* R111 - Write Sequencer 3 */
163 0x0000, /* R112 - Write Sequencer 4 */
164 0x0000, /* R113 */
165 0x0000, /* R114 - Control Interface */
166 0x0000, /* R115 */
167 0x00A8, /* R116 - GPIO Control 1 */
168 0x00A8, /* R117 - GPIO Control 2 */
169 0x00A8, /* R118 - GPIO Control 3 */
170 0x0220, /* R119 - GPIO Control 4 */
171 0x01A0, /* R120 - GPIO Control 5 */
172 0x0000, /* R121 - Interrupt Status 1 */
173 0xFFFF, /* R122 - Interrupt Status 1 Mask */
174 0x0000, /* R123 - Interrupt Polarity 1 */
175 0x0000, /* R124 */
176 0x0003, /* R125 */
177 0x0000, /* R126 - Interrupt Control */
178 0x0000, /* R127 */
179 0x0005, /* R128 */
180 0x0000, /* R129 - Control Interface Test 1 */
181 0x0000, /* R130 */
182 0x0000, /* R131 */
183 0x0000, /* R132 */
184 0x0000, /* R133 */
185 0x0000, /* R134 */
186 0x03FF, /* R135 */
187 0x0007, /* R136 */
188 0x0040, /* R137 */
189 0x0000, /* R138 */
190 0x0000, /* R139 */
191 0x0000, /* R140 */
192 0x0000, /* R141 */
193 0x0000, /* R142 */
194 0x0000, /* R143 */
195 0x0000, /* R144 */
196 0x0000, /* R145 */
197 0x0000, /* R146 */
198 0x0000, /* R147 */
199 0x4000, /* R148 */
200 0x6810, /* R149 - Charge Pump Test 1 */
201 0x0004, /* R150 */
202 0x0000, /* R151 */
203 0x0000, /* R152 */
204 0x0000, /* R153 */
205 0x0000, /* R154 */
206 0x0000, /* R155 */
207 0x0000, /* R156 */
208 0x0000, /* R157 */
209 0x0000, /* R158 */
210 0x0000, /* R159 */
211 0x0000, /* R160 */
212 0x0000, /* R161 */
213 0x0000, /* R162 */
214 0x0000, /* R163 */
215 0x0028, /* R164 - Clock Rate Test 4 */
216 0x0004, /* R165 */
217 0x0000, /* R166 */
218 0x0060, /* R167 */
219 0x0000, /* R168 */
220 0x0000, /* R169 */
221 0x0000, /* R170 */
222 0x0000, /* R171 */
223 0x0000, /* R172 - Analogue Output Bias 0 */
224};
225
226static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
227 unsigned int reg)
228{
229 u16 *cache = codec->reg_cache;
230
231 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
232
233 return cache[reg];
234}
235
236static unsigned int wm8903_hw_read(struct snd_soc_codec *codec, u8 reg)
237{
238 struct i2c_msg xfer[2];
239 u16 data;
240 int ret;
241 struct i2c_client *client = codec->control_data;
242
243 /* Write register */
244 xfer[0].addr = client->addr;
245 xfer[0].flags = 0;
246 xfer[0].len = 1;
247 xfer[0].buf = &reg;
248
249 /* Read data */
250 xfer[1].addr = client->addr;
251 xfer[1].flags = I2C_M_RD;
252 xfer[1].len = 2;
253 xfer[1].buf = (u8 *)&data;
254
255 ret = i2c_transfer(client->adapter, xfer, 2);
256 if (ret != 2) {
257 pr_err("i2c_transfer returned %d\n", ret);
258 return 0;
259 }
260
261 return (data >> 8) | ((data & 0xff) << 8);
262}
263
264static unsigned int wm8903_read(struct snd_soc_codec *codec,
265 unsigned int reg)
266{
267 switch (reg) {
268 case WM8903_SW_RESET_AND_ID:
269 case WM8903_REVISION_NUMBER:
270 case WM8903_INTERRUPT_STATUS_1:
271 case WM8903_WRITE_SEQUENCER_4:
272 return wm8903_hw_read(codec, reg);
273
274 default:
275 return wm8903_read_reg_cache(codec, reg);
276 }
277}
278
279static void wm8903_write_reg_cache(struct snd_soc_codec *codec,
280 u16 reg, unsigned int value)
281{
282 u16 *cache = codec->reg_cache;
283
284 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
285
286 switch (reg) {
287 case WM8903_SW_RESET_AND_ID:
288 case WM8903_REVISION_NUMBER:
289 break;
290
291 default:
292 cache[reg] = value;
293 break;
294 }
295}
296
297static int wm8903_write(struct snd_soc_codec *codec, unsigned int reg,
298 unsigned int value)
299{
300 u8 data[3];
301
302 wm8903_write_reg_cache(codec, reg, value);
303
304 /* Data format is 1 byte of address followed by 2 bytes of data */
305 data[0] = reg;
306 data[1] = (value >> 8) & 0xff;
307 data[2] = value & 0xff;
308
309 if (codec->hw_write(codec->control_data, data, 3) == 2)
310 return 0;
311 else
312 return -EIO;
313}
314
315static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
316{
317 u16 reg[5];
318 struct i2c_client *i2c = codec->control_data;
319
320 BUG_ON(start > 48);
321
322 /* Enable the sequencer */
323 reg[0] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_0);
324 reg[0] |= WM8903_WSEQ_ENA;
325 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
326
327 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
328
329 wm8903_write(codec, WM8903_WRITE_SEQUENCER_3,
330 start | WM8903_WSEQ_START);
331
332 /* Wait for it to complete. If we have the interrupt wired up then
333 * we could block waiting for an interrupt, though polling may still
334 * be desirable for diagnostic purposes.
335 */
336 do {
337 msleep(10);
338
339 reg[4] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_4);
340 } while (reg[4] & WM8903_WSEQ_BUSY);
341
342 dev_dbg(&i2c->dev, "Sequence complete\n");
343
344 /* Disable the sequencer again */
345 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0,
346 reg[0] & ~WM8903_WSEQ_ENA);
347
348 return 0;
349}
350
351static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
352{
353 int i;
354
355 /* There really ought to be something better we can do here :/ */
356 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
357 cache[i] = wm8903_hw_read(codec, i);
358}
359
360static void wm8903_reset(struct snd_soc_codec *codec)
361{
362 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
363}
364
365#define WM8903_OUTPUT_SHORT 0x8
366#define WM8903_OUTPUT_OUT 0x4
367#define WM8903_OUTPUT_INT 0x2
368#define WM8903_OUTPUT_IN 0x1
369
370/*
371 * Event for headphone and line out amplifier power changes. Special
372 * power up/down sequences are required in order to maximise pop/click
373 * performance.
374 */
375static int wm8903_output_event(struct snd_soc_dapm_widget *w,
376 struct snd_kcontrol *kcontrol, int event)
377{
378 struct snd_soc_codec *codec = w->codec;
379 struct wm8903_priv *wm8903 = codec->private_data;
380 struct i2c_client *i2c = codec->control_data;
381 u16 val;
382 u16 reg;
383 int shift;
384 u16 cp_reg = wm8903_read(codec, WM8903_CHARGE_PUMP_0);
385
386 switch (w->reg) {
387 case WM8903_POWER_MANAGEMENT_2:
388 reg = WM8903_ANALOGUE_HP_0;
389 break;
390 case WM8903_POWER_MANAGEMENT_3:
391 reg = WM8903_ANALOGUE_LINEOUT_0;
392 break;
393 default:
394 BUG();
395 }
396
397 switch (w->shift) {
398 case 0:
399 shift = 0;
400 break;
401 case 1:
402 shift = 4;
403 break;
404 default:
405 BUG();
406 }
407
408 if (event & SND_SOC_DAPM_PRE_PMU) {
409 val = wm8903_read(codec, reg);
410
411 /* Short the output */
412 val &= ~(WM8903_OUTPUT_SHORT << shift);
413 wm8903_write(codec, reg, val);
414
415 wm8903->charge_pump_users++;
416
417 dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
418 wm8903->charge_pump_users);
419
420 if (wm8903->charge_pump_users == 1) {
421 dev_dbg(&i2c->dev, "Enabling charge pump\n");
422 wm8903_write(codec, WM8903_CHARGE_PUMP_0,
423 cp_reg | WM8903_CP_ENA);
424 mdelay(4);
425 }
426 }
427
428 if (event & SND_SOC_DAPM_POST_PMU) {
429 val = wm8903_read(codec, reg);
430
431 val |= (WM8903_OUTPUT_IN << shift);
432 wm8903_write(codec, reg, val);
433
434 val |= (WM8903_OUTPUT_INT << shift);
435 wm8903_write(codec, reg, val);
436
437 /* Turn on the output ENA_OUTP */
438 val |= (WM8903_OUTPUT_OUT << shift);
439 wm8903_write(codec, reg, val);
440
441 /* Remove the short */
442 val |= (WM8903_OUTPUT_SHORT << shift);
443 wm8903_write(codec, reg, val);
444 }
445
446 if (event & SND_SOC_DAPM_PRE_PMD) {
447 val = wm8903_read(codec, reg);
448
449 /* Short the output */
450 val &= ~(WM8903_OUTPUT_SHORT << shift);
451 wm8903_write(codec, reg, val);
452
453 /* Then disable the intermediate and output stages */
454 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
455 WM8903_OUTPUT_IN) << shift);
456 wm8903_write(codec, reg, val);
457 }
458
459 if (event & SND_SOC_DAPM_POST_PMD) {
460 wm8903->charge_pump_users--;
461
462 dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
463 wm8903->charge_pump_users);
464
465 if (wm8903->charge_pump_users == 0) {
466 dev_dbg(&i2c->dev, "Disabling charge pump\n");
467 wm8903_write(codec, WM8903_CHARGE_PUMP_0,
468 cp_reg & ~WM8903_CP_ENA);
469 }
470 }
471
472 return 0;
473}
474
475/*
476 * When used with DAC outputs only the WM8903 charge pump supports
477 * operation in class W mode, providing very low power consumption
478 * when used with digital sources. Enable and disable this mode
479 * automatically depending on the mixer configuration.
480 *
481 * All the relevant controls are simple switches.
482 */
483static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
484 struct snd_ctl_elem_value *ucontrol)
485{
486 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
487 struct snd_soc_codec *codec = widget->codec;
488 struct wm8903_priv *wm8903 = codec->private_data;
489 struct i2c_client *i2c = codec->control_data;
490 u16 reg;
491 int ret;
492
493 reg = wm8903_read(codec, WM8903_CLASS_W_0);
494
495 /* Turn it off if we're about to enable bypass */
496 if (ucontrol->value.integer.value[0]) {
497 if (wm8903->class_w_users == 0) {
498 dev_dbg(&i2c->dev, "Disabling Class W\n");
499 wm8903_write(codec, WM8903_CLASS_W_0, reg &
500 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
501 }
502 wm8903->class_w_users++;
503 }
504
505 /* Implement the change */
506 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
507
508 /* If we've just disabled the last bypass path turn Class W on */
509 if (!ucontrol->value.integer.value[0]) {
510 if (wm8903->class_w_users == 1) {
511 dev_dbg(&i2c->dev, "Enabling Class W\n");
512 wm8903_write(codec, WM8903_CLASS_W_0, reg |
513 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
514 }
515 wm8903->class_w_users--;
516 }
517
518 dev_dbg(&i2c->dev, "Bypass use count now %d\n",
519 wm8903->class_w_users);
520
521 return ret;
522}
523
524#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \
525{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
526 .info = snd_soc_info_volsw, \
527 .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \
528 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
529
530
531/* ALSA can only do steps of .01dB */
532static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
533
534static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
535
536static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0);
537static const DECLARE_TLV_DB_SCALE(drc_tlv_amp, -2250, 75, 0);
538static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
539static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
540static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
541
542static const char *drc_slope_text[] = {
543 "1", "1/2", "1/4", "1/8", "1/16", "0"
544};
545
546static const struct soc_enum drc_slope_r0 =
547 SOC_ENUM_SINGLE(WM8903_DRC_2, 3, 6, drc_slope_text);
548
549static const struct soc_enum drc_slope_r1 =
550 SOC_ENUM_SINGLE(WM8903_DRC_2, 0, 6, drc_slope_text);
551
552static const char *drc_attack_text[] = {
553 "instantaneous",
554 "363us", "762us", "1.45ms", "2.9ms", "5.8ms", "11.6ms", "23.2ms",
555 "46.4ms", "92.8ms", "185.6ms"
556};
557
558static const struct soc_enum drc_attack =
559 SOC_ENUM_SINGLE(WM8903_DRC_1, 12, 11, drc_attack_text);
560
561static const char *drc_decay_text[] = {
562 "186ms", "372ms", "743ms", "1.49s", "2.97s", "5.94s", "11.89s",
563 "23.87s", "47.56s"
564};
565
566static const struct soc_enum drc_decay =
567 SOC_ENUM_SINGLE(WM8903_DRC_1, 8, 9, drc_decay_text);
568
569static const char *drc_ff_delay_text[] = {
570 "5 samples", "9 samples"
571};
572
573static const struct soc_enum drc_ff_delay =
574 SOC_ENUM_SINGLE(WM8903_DRC_0, 5, 2, drc_ff_delay_text);
575
576static const char *drc_qr_decay_text[] = {
577 "0.725ms", "1.45ms", "5.8ms"
578};
579
580static const struct soc_enum drc_qr_decay =
581 SOC_ENUM_SINGLE(WM8903_DRC_1, 4, 3, drc_qr_decay_text);
582
583static const char *drc_smoothing_text[] = {
584 "Low", "Medium", "High"
585};
586
587static const struct soc_enum drc_smoothing =
588 SOC_ENUM_SINGLE(WM8903_DRC_0, 11, 3, drc_smoothing_text);
589
590static const char *soft_mute_text[] = {
591 "Fast (fs/2)", "Slow (fs/32)"
592};
593
594static const struct soc_enum soft_mute =
595 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 10, 2, soft_mute_text);
596
597static const char *mute_mode_text[] = {
598 "Hard", "Soft"
599};
600
601static const struct soc_enum mute_mode =
602 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
603
604static const char *dac_deemphasis_text[] = {
605 "Disabled", "32kHz", "44.1kHz", "48kHz"
606};
607
608static const struct soc_enum dac_deemphasis =
609 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);
610
611static const char *companding_text[] = {
612 "ulaw", "alaw"
613};
614
615static const struct soc_enum dac_companding =
616 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 0, 2, companding_text);
617
618static const struct soc_enum adc_companding =
619 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 2, 2, companding_text);
620
621static const char *input_mode_text[] = {
622 "Single-Ended", "Differential Line", "Differential Mic"
623};
624
625static const struct soc_enum linput_mode_enum =
626 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
627
628static const struct soc_enum rinput_mode_enum =
629 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
630
631static const char *linput_mux_text[] = {
632 "IN1L", "IN2L", "IN3L"
633};
634
635static const struct soc_enum linput_enum =
636 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 2, 3, linput_mux_text);
637
638static const struct soc_enum linput_inv_enum =
639 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 4, 3, linput_mux_text);
640
641static const char *rinput_mux_text[] = {
642 "IN1R", "IN2R", "IN3R"
643};
644
645static const struct soc_enum rinput_enum =
646 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 2, 3, rinput_mux_text);
647
648static const struct soc_enum rinput_inv_enum =
649 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text);
650
651
652static const struct snd_kcontrol_new wm8903_snd_controls[] = {
653
654/* Input PGAs - No TLV since the scale depends on PGA mode */
655SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0,
656 7, 1, 1),
657SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0,
658 0, 31, 0),
659SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1,
660 6, 1, 0),
661
662SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0,
663 7, 1, 1),
664SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0,
665 0, 31, 0),
666SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
667 6, 1, 0),
668
669/* ADCs */
670SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
671SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
672SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
673SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1,
674 drc_tlv_thresh),
675SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
676SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
677SOC_SINGLE_TLV("DRC Maximum Gain Volume", WM8903_DRC_1, 0, 3, 0, drc_tlv_max),
678SOC_ENUM("DRC Attack Rate", drc_attack),
679SOC_ENUM("DRC Decay Rate", drc_decay),
680SOC_ENUM("DRC FF Delay", drc_ff_delay),
681SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
682SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
683SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
684SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
685SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
686SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
687SOC_ENUM("DRC Smoothing Threashold", drc_smoothing),
688SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
689
690SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
691 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
692SOC_ENUM("ADC Companding Mode", adc_companding),
693SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
694
695/* DAC */
696SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
697 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
698SOC_ENUM("DAC Soft Mute Rate", soft_mute),
699SOC_ENUM("DAC Mute Mode", mute_mode),
700SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
701SOC_ENUM("DAC De-emphasis", dac_deemphasis),
702SOC_SINGLE("DAC Sloping Stopband Filter Switch",
703 WM8903_DAC_DIGITAL_1, 11, 1, 0),
704SOC_ENUM("DAC Companding Mode", dac_companding),
705SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
706
707/* Headphones */
708SOC_DOUBLE_R("Headphone Switch",
709 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
710 8, 1, 1),
711SOC_DOUBLE_R("Headphone ZC Switch",
712 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
713 6, 1, 0),
714SOC_DOUBLE_R_TLV("Headphone Volume",
715 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
716 0, 63, 0, out_tlv),
717
718/* Line out */
719SOC_DOUBLE_R("Line Out Switch",
720 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
721 8, 1, 1),
722SOC_DOUBLE_R("Line Out ZC Switch",
723 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
724 6, 1, 0),
725SOC_DOUBLE_R_TLV("Line Out Volume",
726 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
727 0, 63, 0, out_tlv),
728
729/* Speaker */
730SOC_DOUBLE_R("Speaker Switch",
731 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT, 8, 1, 1),
732SOC_DOUBLE_R("Speaker ZC Switch",
733 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT, 6, 1, 0),
734SOC_DOUBLE_R_TLV("Speaker Volume",
735 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT,
736 0, 63, 0, out_tlv),
737};
738
739static int wm8903_add_controls(struct snd_soc_codec *codec)
740{
741 int err, i;
742
743 for (i = 0; i < ARRAY_SIZE(wm8903_snd_controls); i++) {
744 err = snd_ctl_add(codec->card,
745 snd_soc_cnew(&wm8903_snd_controls[i],
746 codec, NULL));
747 if (err < 0)
748 return err;
749 }
750
751 return 0;
752}
753
754static const struct snd_kcontrol_new linput_mode_mux =
755 SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum);
756
757static const struct snd_kcontrol_new rinput_mode_mux =
758 SOC_DAPM_ENUM("Right Input Mode Mux", rinput_mode_enum);
759
760static const struct snd_kcontrol_new linput_mux =
761 SOC_DAPM_ENUM("Left Input Mux", linput_enum);
762
763static const struct snd_kcontrol_new linput_inv_mux =
764 SOC_DAPM_ENUM("Left Inverting Input Mux", linput_inv_enum);
765
766static const struct snd_kcontrol_new rinput_mux =
767 SOC_DAPM_ENUM("Right Input Mux", rinput_enum);
768
769static const struct snd_kcontrol_new rinput_inv_mux =
770 SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum);
771
772static const struct snd_kcontrol_new left_output_mixer[] = {
773SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
774SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
775SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
776SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
777};
778
779static const struct snd_kcontrol_new right_output_mixer[] = {
780SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0),
781SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0),
782SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
783SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
784};
785
786static const struct snd_kcontrol_new left_speaker_mixer[] = {
787SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 3, 1, 0),
788SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0),
789SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0),
790SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0,
791 1, 1, 0),
792};
793
794static const struct snd_kcontrol_new right_speaker_mixer[] = {
795SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 3, 1, 0),
796SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 2, 1, 0),
797SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
798 1, 1, 0),
799SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
800 1, 1, 0),
801};
802
803static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
804SND_SOC_DAPM_INPUT("IN1L"),
805SND_SOC_DAPM_INPUT("IN1R"),
806SND_SOC_DAPM_INPUT("IN2L"),
807SND_SOC_DAPM_INPUT("IN2R"),
808SND_SOC_DAPM_INPUT("IN3L"),
809SND_SOC_DAPM_INPUT("IN3R"),
810
811SND_SOC_DAPM_OUTPUT("HPOUTL"),
812SND_SOC_DAPM_OUTPUT("HPOUTR"),
813SND_SOC_DAPM_OUTPUT("LINEOUTL"),
814SND_SOC_DAPM_OUTPUT("LINEOUTR"),
815SND_SOC_DAPM_OUTPUT("LOP"),
816SND_SOC_DAPM_OUTPUT("LON"),
817SND_SOC_DAPM_OUTPUT("ROP"),
818SND_SOC_DAPM_OUTPUT("RON"),
819
820SND_SOC_DAPM_MICBIAS("Mic Bias", WM8903_MIC_BIAS_CONTROL_0, 0, 0),
821
822SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &linput_mux),
823SND_SOC_DAPM_MUX("Left Input Inverting Mux", SND_SOC_NOPM, 0, 0,
824 &linput_inv_mux),
825SND_SOC_DAPM_MUX("Left Input Mode Mux", SND_SOC_NOPM, 0, 0, &linput_mode_mux),
826
827SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &rinput_mux),
828SND_SOC_DAPM_MUX("Right Input Inverting Mux", SND_SOC_NOPM, 0, 0,
829 &rinput_inv_mux),
830SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
831
832SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
833SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
834
835SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0),
836SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0),
837
838SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0),
839SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0),
840
841SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0,
842 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
843SND_SOC_DAPM_MIXER("Right Output Mixer", WM8903_POWER_MANAGEMENT_1, 0, 0,
844 right_output_mixer, ARRAY_SIZE(right_output_mixer)),
845
846SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0,
847 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
848SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
849 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
850
851SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
852 1, 0, NULL, 0, wm8903_output_event,
853 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
854 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
855SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
856 0, 0, NULL, 0, wm8903_output_event,
857 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
858 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
859
860SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0,
861 NULL, 0, wm8903_output_event,
862 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
863 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
864SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0,
865 NULL, 0, wm8903_output_event,
866 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
867 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
868
869SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
870 NULL, 0),
871SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
872 NULL, 0),
873
874};
875
876static const struct snd_soc_dapm_route intercon[] = {
877
878 { "Left Input Mux", "IN1L", "IN1L" },
879 { "Left Input Mux", "IN2L", "IN2L" },
880 { "Left Input Mux", "IN3L", "IN3L" },
881
882 { "Left Input Inverting Mux", "IN1L", "IN1L" },
883 { "Left Input Inverting Mux", "IN2L", "IN2L" },
884 { "Left Input Inverting Mux", "IN3L", "IN3L" },
885
886 { "Right Input Mux", "IN1R", "IN1R" },
887 { "Right Input Mux", "IN2R", "IN2R" },
888 { "Right Input Mux", "IN3R", "IN3R" },
889
890 { "Right Input Inverting Mux", "IN1R", "IN1R" },
891 { "Right Input Inverting Mux", "IN2R", "IN2R" },
892 { "Right Input Inverting Mux", "IN3R", "IN3R" },
893
894 { "Left Input Mode Mux", "Single-Ended", "Left Input Inverting Mux" },
895 { "Left Input Mode Mux", "Differential Line",
896 "Left Input Mux" },
897 { "Left Input Mode Mux", "Differential Line",
898 "Left Input Inverting Mux" },
899 { "Left Input Mode Mux", "Differential Mic",
900 "Left Input Mux" },
901 { "Left Input Mode Mux", "Differential Mic",
902 "Left Input Inverting Mux" },
903
904 { "Right Input Mode Mux", "Single-Ended",
905 "Right Input Inverting Mux" },
906 { "Right Input Mode Mux", "Differential Line",
907 "Right Input Mux" },
908 { "Right Input Mode Mux", "Differential Line",
909 "Right Input Inverting Mux" },
910 { "Right Input Mode Mux", "Differential Mic",
911 "Right Input Mux" },
912 { "Right Input Mode Mux", "Differential Mic",
913 "Right Input Inverting Mux" },
914
915 { "Left Input PGA", NULL, "Left Input Mode Mux" },
916 { "Right Input PGA", NULL, "Right Input Mode Mux" },
917
918 { "ADCL", NULL, "Left Input PGA" },
919 { "ADCR", NULL, "Right Input PGA" },
920
921 { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" },
922 { "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" },
923 { "Left Output Mixer", "DACL Switch", "DACL" },
924 { "Left Output Mixer", "DACR Switch", "DACR" },
925
926 { "Right Output Mixer", "Left Bypass Switch", "Left Input PGA" },
927 { "Right Output Mixer", "Right Bypass Switch", "Right Input PGA" },
928 { "Right Output Mixer", "DACL Switch", "DACL" },
929 { "Right Output Mixer", "DACR Switch", "DACR" },
930
931 { "Left Speaker Mixer", "Left Bypass Switch", "Left Input PGA" },
932 { "Left Speaker Mixer", "Right Bypass Switch", "Right Input PGA" },
933 { "Left Speaker Mixer", "DACL Switch", "DACL" },
934 { "Left Speaker Mixer", "DACR Switch", "DACR" },
935
936 { "Right Speaker Mixer", "Left Bypass Switch", "Left Input PGA" },
937 { "Right Speaker Mixer", "Right Bypass Switch", "Right Input PGA" },
938 { "Right Speaker Mixer", "DACL Switch", "DACL" },
939 { "Right Speaker Mixer", "DACR Switch", "DACR" },
940
941 { "Left Line Output PGA", NULL, "Left Output Mixer" },
942 { "Right Line Output PGA", NULL, "Right Output Mixer" },
943
944 { "Left Headphone Output PGA", NULL, "Left Output Mixer" },
945 { "Right Headphone Output PGA", NULL, "Right Output Mixer" },
946
947 { "Left Speaker PGA", NULL, "Left Speaker Mixer" },
948 { "Right Speaker PGA", NULL, "Right Speaker Mixer" },
949
950 { "HPOUTL", NULL, "Left Headphone Output PGA" },
951 { "HPOUTR", NULL, "Right Headphone Output PGA" },
952
953 { "LINEOUTL", NULL, "Left Line Output PGA" },
954 { "LINEOUTR", NULL, "Right Line Output PGA" },
955
956 { "LOP", NULL, "Left Speaker PGA" },
957 { "LON", NULL, "Left Speaker PGA" },
958
959 { "ROP", NULL, "Right Speaker PGA" },
960 { "RON", NULL, "Right Speaker PGA" },
961};
962
963static int wm8903_add_widgets(struct snd_soc_codec *codec)
964{
965 snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets,
966 ARRAY_SIZE(wm8903_dapm_widgets));
967
968 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
969
970 snd_soc_dapm_new_widgets(codec);
971
972 return 0;
973}
974
975static int wm8903_set_bias_level(struct snd_soc_codec *codec,
976 enum snd_soc_bias_level level)
977{
978 struct i2c_client *i2c = codec->control_data;
979 u16 reg, reg2;
980
981 switch (level) {
982 case SND_SOC_BIAS_ON:
983 case SND_SOC_BIAS_PREPARE:
984 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0);
985 reg &= ~(WM8903_VMID_RES_MASK);
986 reg |= WM8903_VMID_RES_50K;
987 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg);
988 break;
989
990 case SND_SOC_BIAS_STANDBY:
991 if (codec->bias_level == SND_SOC_BIAS_OFF) {
992 wm8903_run_sequence(codec, 0);
993 wm8903_sync_reg_cache(codec, codec->reg_cache);
994
995 /* Enable low impedence charge pump output */
996 reg = wm8903_read(codec,
997 WM8903_CONTROL_INTERFACE_TEST_1);
998 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
999 reg | WM8903_TEST_KEY);
1000 reg2 = wm8903_read(codec, WM8903_CHARGE_PUMP_TEST_1);
1001 wm8903_write(codec, WM8903_CHARGE_PUMP_TEST_1,
1002 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
1003 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
1004 reg);
1005
1006 /* By default no bypass paths are enabled so
1007 * enable Class W support.
1008 */
1009 dev_dbg(&i2c->dev, "Enabling Class W\n");
1010 wm8903_write(codec, WM8903_CLASS_W_0, reg |
1011 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
1012 }
1013
1014 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0);
1015 reg &= ~(WM8903_VMID_RES_MASK);
1016 reg |= WM8903_VMID_RES_250K;
1017 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg);
1018 break;
1019
1020 case SND_SOC_BIAS_OFF:
1021 wm8903_run_sequence(codec, 32);
1022 break;
1023 }
1024
1025 codec->bias_level = level;
1026
1027 return 0;
1028}
1029
1030static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1031 int clk_id, unsigned int freq, int dir)
1032{
1033 struct snd_soc_codec *codec = codec_dai->codec;
1034 struct wm8903_priv *wm8903 = codec->private_data;
1035
1036 wm8903->sysclk = freq;
1037
1038 return 0;
1039}
1040
1041static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
1042 unsigned int fmt)
1043{
1044 struct snd_soc_codec *codec = codec_dai->codec;
1045 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1);
1046
1047 aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK |
1048 WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV);
1049
1050 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1051 case SND_SOC_DAIFMT_CBS_CFS:
1052 break;
1053 case SND_SOC_DAIFMT_CBS_CFM:
1054 aif1 |= WM8903_LRCLK_DIR;
1055 break;
1056 case SND_SOC_DAIFMT_CBM_CFM:
1057 aif1 |= WM8903_LRCLK_DIR | WM8903_BCLK_DIR;
1058 break;
1059 case SND_SOC_DAIFMT_CBM_CFS:
1060 aif1 |= WM8903_BCLK_DIR;
1061 break;
1062 default:
1063 return -EINVAL;
1064 }
1065
1066 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1067 case SND_SOC_DAIFMT_DSP_A:
1068 aif1 |= 0x3;
1069 break;
1070 case SND_SOC_DAIFMT_DSP_B:
1071 aif1 |= 0x3 | WM8903_AIF_LRCLK_INV;
1072 break;
1073 case SND_SOC_DAIFMT_I2S:
1074 aif1 |= 0x2;
1075 break;
1076 case SND_SOC_DAIFMT_RIGHT_J:
1077 aif1 |= 0x1;
1078 break;
1079 case SND_SOC_DAIFMT_LEFT_J:
1080 break;
1081 default:
1082 return -EINVAL;
1083 }
1084
1085 /* Clock inversion */
1086 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1087 case SND_SOC_DAIFMT_DSP_A:
1088 case SND_SOC_DAIFMT_DSP_B:
1089 /* frame inversion not valid for DSP modes */
1090 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1091 case SND_SOC_DAIFMT_NB_NF:
1092 break;
1093 case SND_SOC_DAIFMT_IB_NF:
1094 aif1 |= WM8903_AIF_BCLK_INV;
1095 break;
1096 default:
1097 return -EINVAL;
1098 }
1099 break;
1100 case SND_SOC_DAIFMT_I2S:
1101 case SND_SOC_DAIFMT_RIGHT_J:
1102 case SND_SOC_DAIFMT_LEFT_J:
1103 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1104 case SND_SOC_DAIFMT_NB_NF:
1105 break;
1106 case SND_SOC_DAIFMT_IB_IF:
1107 aif1 |= WM8903_AIF_BCLK_INV | WM8903_AIF_LRCLK_INV;
1108 break;
1109 case SND_SOC_DAIFMT_IB_NF:
1110 aif1 |= WM8903_AIF_BCLK_INV;
1111 break;
1112 case SND_SOC_DAIFMT_NB_IF:
1113 aif1 |= WM8903_AIF_LRCLK_INV;
1114 break;
1115 default:
1116 return -EINVAL;
1117 }
1118 break;
1119 default:
1120 return -EINVAL;
1121 }
1122
1123 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1124
1125 return 0;
1126}
1127
1128static int wm8903_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1129{
1130 struct snd_soc_codec *codec = codec_dai->codec;
1131 u16 reg;
1132
1133 reg = wm8903_read(codec, WM8903_DAC_DIGITAL_1);
1134
1135 if (mute)
1136 reg |= WM8903_DAC_MUTE;
1137 else
1138 reg &= ~WM8903_DAC_MUTE;
1139
1140 wm8903_write(codec, WM8903_DAC_DIGITAL_1, reg);
1141
1142 return 0;
1143}
1144
1145/* Lookup table for CLK_SYS/fs ratio. 256fs or more is recommended
1146 * for optimal performance so we list the lower rates first and match
1147 * on the last match we find. */
1148static struct {
1149 int div;
1150 int rate;
1151 int mode;
1152 int mclk_div;
1153} clk_sys_ratios[] = {
1154 { 64, 0x0, 0x0, 1 },
1155 { 68, 0x0, 0x1, 1 },
1156 { 125, 0x0, 0x2, 1 },
1157 { 128, 0x1, 0x0, 1 },
1158 { 136, 0x1, 0x1, 1 },
1159 { 192, 0x2, 0x0, 1 },
1160 { 204, 0x2, 0x1, 1 },
1161
1162 { 64, 0x0, 0x0, 2 },
1163 { 68, 0x0, 0x1, 2 },
1164 { 125, 0x0, 0x2, 2 },
1165 { 128, 0x1, 0x0, 2 },
1166 { 136, 0x1, 0x1, 2 },
1167 { 192, 0x2, 0x0, 2 },
1168 { 204, 0x2, 0x1, 2 },
1169
1170 { 250, 0x2, 0x2, 1 },
1171 { 256, 0x3, 0x0, 1 },
1172 { 272, 0x3, 0x1, 1 },
1173 { 384, 0x4, 0x0, 1 },
1174 { 408, 0x4, 0x1, 1 },
1175 { 375, 0x4, 0x2, 1 },
1176 { 512, 0x5, 0x0, 1 },
1177 { 544, 0x5, 0x1, 1 },
1178 { 500, 0x5, 0x2, 1 },
1179 { 768, 0x6, 0x0, 1 },
1180 { 816, 0x6, 0x1, 1 },
1181 { 750, 0x6, 0x2, 1 },
1182 { 1024, 0x7, 0x0, 1 },
1183 { 1088, 0x7, 0x1, 1 },
1184 { 1000, 0x7, 0x2, 1 },
1185 { 1408, 0x8, 0x0, 1 },
1186 { 1496, 0x8, 0x1, 1 },
1187 { 1536, 0x9, 0x0, 1 },
1188 { 1632, 0x9, 0x1, 1 },
1189 { 1500, 0x9, 0x2, 1 },
1190
1191 { 250, 0x2, 0x2, 2 },
1192 { 256, 0x3, 0x0, 2 },
1193 { 272, 0x3, 0x1, 2 },
1194 { 384, 0x4, 0x0, 2 },
1195 { 408, 0x4, 0x1, 2 },
1196 { 375, 0x4, 0x2, 2 },
1197 { 512, 0x5, 0x0, 2 },
1198 { 544, 0x5, 0x1, 2 },
1199 { 500, 0x5, 0x2, 2 },
1200 { 768, 0x6, 0x0, 2 },
1201 { 816, 0x6, 0x1, 2 },
1202 { 750, 0x6, 0x2, 2 },
1203 { 1024, 0x7, 0x0, 2 },
1204 { 1088, 0x7, 0x1, 2 },
1205 { 1000, 0x7, 0x2, 2 },
1206 { 1408, 0x8, 0x0, 2 },
1207 { 1496, 0x8, 0x1, 2 },
1208 { 1536, 0x9, 0x0, 2 },
1209 { 1632, 0x9, 0x1, 2 },
1210 { 1500, 0x9, 0x2, 2 },
1211};
1212
1213/* CLK_SYS/BCLK ratios - multiplied by 10 due to .5s */
1214static struct {
1215 int ratio;
1216 int div;
1217} bclk_divs[] = {
1218 { 10, 0 },
1219 { 15, 1 },
1220 { 20, 2 },
1221 { 30, 3 },
1222 { 40, 4 },
1223 { 50, 5 },
1224 { 55, 6 },
1225 { 60, 7 },
1226 { 80, 8 },
1227 { 100, 9 },
1228 { 110, 10 },
1229 { 120, 11 },
1230 { 160, 12 },
1231 { 200, 13 },
1232 { 220, 14 },
1233 { 240, 15 },
1234 { 250, 16 },
1235 { 300, 17 },
1236 { 320, 18 },
1237 { 440, 19 },
1238 { 480, 20 },
1239};
1240
1241/* Sample rates for DSP */
1242static struct {
1243 int rate;
1244 int value;
1245} sample_rates[] = {
1246 { 8000, 0 },
1247 { 11025, 1 },
1248 { 12000, 2 },
1249 { 16000, 3 },
1250 { 22050, 4 },
1251 { 24000, 5 },
1252 { 32000, 6 },
1253 { 44100, 7 },
1254 { 48000, 8 },
1255 { 88200, 9 },
1256 { 96000, 10 },
1257 { 0, 0 },
1258};
1259
1260static int wm8903_startup(struct snd_pcm_substream *substream)
1261{
1262 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1263 struct snd_soc_device *socdev = rtd->socdev;
1264 struct snd_soc_codec *codec = socdev->codec;
1265 struct wm8903_priv *wm8903 = codec->private_data;
1266 struct i2c_client *i2c = codec->control_data;
1267 struct snd_pcm_runtime *master_runtime;
1268
1269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1270 wm8903->playback_active++;
1271 else
1272 wm8903->capture_active++;
1273
1274 /* The DAI has shared clocks so if we already have a playback or
1275 * capture going then constrain this substream to match it.
1276 */
1277 if (wm8903->master_substream) {
1278 master_runtime = wm8903->master_substream->runtime;
1279
1280 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
1281 master_runtime->sample_bits,
1282 master_runtime->rate);
1283
1284 snd_pcm_hw_constraint_minmax(substream->runtime,
1285 SNDRV_PCM_HW_PARAM_RATE,
1286 master_runtime->rate,
1287 master_runtime->rate);
1288
1289 snd_pcm_hw_constraint_minmax(substream->runtime,
1290 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1291 master_runtime->sample_bits,
1292 master_runtime->sample_bits);
1293
1294 wm8903->slave_substream = substream;
1295 } else
1296 wm8903->master_substream = substream;
1297
1298 return 0;
1299}
1300
1301static void wm8903_shutdown(struct snd_pcm_substream *substream)
1302{
1303 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1304 struct snd_soc_device *socdev = rtd->socdev;
1305 struct snd_soc_codec *codec = socdev->codec;
1306 struct wm8903_priv *wm8903 = codec->private_data;
1307
1308 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1309 wm8903->playback_active--;
1310 else
1311 wm8903->capture_active--;
1312
1313 if (wm8903->master_substream == substream)
1314 wm8903->master_substream = wm8903->slave_substream;
1315
1316 wm8903->slave_substream = NULL;
1317}
1318
1319static int wm8903_hw_params(struct snd_pcm_substream *substream,
1320 struct snd_pcm_hw_params *params)
1321{
1322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1323 struct snd_soc_device *socdev = rtd->socdev;
1324 struct snd_soc_codec *codec = socdev->codec;
1325 struct wm8903_priv *wm8903 = codec->private_data;
1326 struct i2c_client *i2c = codec->control_data;
1327 int fs = params_rate(params);
1328 int bclk;
1329 int bclk_div;
1330 int i;
1331 int dsp_config;
1332 int clk_config;
1333 int best_val;
1334 int cur_val;
1335 int clk_sys;
1336
1337 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1);
1338 u16 aif2 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_2);
1339 u16 aif3 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_3);
1340 u16 clock0 = wm8903_read(codec, WM8903_CLOCK_RATES_0);
1341 u16 clock1 = wm8903_read(codec, WM8903_CLOCK_RATES_1);
1342
1343 if (substream == wm8903->slave_substream) {
1344 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
1345 return 0;
1346 }
1347
1348 /* Configure sample rate logic for DSP - choose nearest rate */
1349 dsp_config = 0;
1350 best_val = abs(sample_rates[dsp_config].rate - fs);
1351 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1352 cur_val = abs(sample_rates[i].rate - fs);
1353 if (cur_val <= best_val) {
1354 dsp_config = i;
1355 best_val = cur_val;
1356 }
1357 }
1358
1359 /* Constraints should stop us hitting this but let's make sure */
1360 if (wm8903->capture_active)
1361 switch (sample_rates[dsp_config].rate) {
1362 case 88200:
1363 case 96000:
1364 dev_err(&i2c->dev, "%dHz unsupported by ADC\n",
1365 fs);
1366 return -EINVAL;
1367
1368 default:
1369 break;
1370 }
1371
1372 dev_dbg(&i2c->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1373 clock1 &= ~WM8903_SAMPLE_RATE_MASK;
1374 clock1 |= sample_rates[dsp_config].value;
1375
1376 aif1 &= ~WM8903_AIF_WL_MASK;
1377 bclk = 2 * fs;
1378 switch (params_format(params)) {
1379 case SNDRV_PCM_FORMAT_S16_LE:
1380 bclk *= 16;
1381 break;
1382 case SNDRV_PCM_FORMAT_S20_3LE:
1383 bclk *= 20;
1384 aif1 |= 0x4;
1385 break;
1386 case SNDRV_PCM_FORMAT_S24_LE:
1387 bclk *= 24;
1388 aif1 |= 0x8;
1389 break;
1390 case SNDRV_PCM_FORMAT_S32_LE:
1391 bclk *= 32;
1392 aif1 |= 0xc;
1393 break;
1394 default:
1395 return -EINVAL;
1396 }
1397
1398 dev_dbg(&i2c->dev, "MCLK = %dHz, target sample rate = %dHz\n",
1399 wm8903->sysclk, fs);
1400
1401 /* We may not have an MCLK which allows us to generate exactly
1402 * the clock we want, particularly with USB derived inputs, so
1403 * approximate.
1404 */
1405 clk_config = 0;
1406 best_val = abs((wm8903->sysclk /
1407 (clk_sys_ratios[0].mclk_div *
1408 clk_sys_ratios[0].div)) - fs);
1409 for (i = 1; i < ARRAY_SIZE(clk_sys_ratios); i++) {
1410 cur_val = abs((wm8903->sysclk /
1411 (clk_sys_ratios[i].mclk_div *
1412 clk_sys_ratios[i].div)) - fs);
1413
1414 if (cur_val <= best_val) {
1415 clk_config = i;
1416 best_val = cur_val;
1417 }
1418 }
1419
1420 if (clk_sys_ratios[clk_config].mclk_div == 2) {
1421 clock0 |= WM8903_MCLKDIV2;
1422 clk_sys = wm8903->sysclk / 2;
1423 } else {
1424 clock0 &= ~WM8903_MCLKDIV2;
1425 clk_sys = wm8903->sysclk;
1426 }
1427
1428 clock1 &= ~(WM8903_CLK_SYS_RATE_MASK |
1429 WM8903_CLK_SYS_MODE_MASK);
1430 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
1431 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
1432
1433 dev_dbg(&i2c->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
1434 clk_sys_ratios[clk_config].rate,
1435 clk_sys_ratios[clk_config].mode,
1436 clk_sys_ratios[clk_config].div);
1437
1438 dev_dbg(&i2c->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
1439
1440 /* We may not get quite the right frequency if using
1441 * approximate clocks so look for the closest match that is
1442 * higher than the target (we need to ensure that there enough
1443 * BCLKs to clock out the samples).
1444 */
1445 bclk_div = 0;
1446 best_val = ((clk_sys * 10) / bclk_divs[0].ratio) - bclk;
1447 i = 1;
1448 while (i < ARRAY_SIZE(bclk_divs)) {
1449 cur_val = ((clk_sys * 10) / bclk_divs[i].ratio) - bclk;
1450 if (cur_val < 0) /* BCLK table is sorted */
1451 break;
1452 bclk_div = i;
1453 best_val = cur_val;
1454 i++;
1455 }
1456
1457 aif2 &= ~WM8903_BCLK_DIV_MASK;
1458 aif3 &= ~WM8903_LRCLK_RATE_MASK;
1459
1460 dev_dbg(&i2c->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
1461 bclk_divs[bclk_div].ratio / 10, bclk,
1462 (clk_sys * 10) / bclk_divs[bclk_div].ratio);
1463
1464 aif2 |= bclk_divs[bclk_div].div;
1465 aif3 |= bclk / fs;
1466
1467 wm8903_write(codec, WM8903_CLOCK_RATES_0, clock0);
1468 wm8903_write(codec, WM8903_CLOCK_RATES_1, clock1);
1469 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1470 wm8903_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
1471 wm8903_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
1472
1473 return 0;
1474}
1475
1476#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
1477 SNDRV_PCM_RATE_11025 | \
1478 SNDRV_PCM_RATE_16000 | \
1479 SNDRV_PCM_RATE_22050 | \
1480 SNDRV_PCM_RATE_32000 | \
1481 SNDRV_PCM_RATE_44100 | \
1482 SNDRV_PCM_RATE_48000 | \
1483 SNDRV_PCM_RATE_88200 | \
1484 SNDRV_PCM_RATE_96000)
1485
1486#define WM8903_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
1487 SNDRV_PCM_RATE_11025 | \
1488 SNDRV_PCM_RATE_16000 | \
1489 SNDRV_PCM_RATE_22050 | \
1490 SNDRV_PCM_RATE_32000 | \
1491 SNDRV_PCM_RATE_44100 | \
1492 SNDRV_PCM_RATE_48000)
1493
1494#define WM8903_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1495 SNDRV_PCM_FMTBIT_S20_3LE |\
1496 SNDRV_PCM_FMTBIT_S24_LE)
1497
1498struct snd_soc_dai wm8903_dai = {
1499 .name = "WM8903",
1500 .playback = {
1501 .stream_name = "Playback",
1502 .channels_min = 2,
1503 .channels_max = 2,
1504 .rates = WM8903_PLAYBACK_RATES,
1505 .formats = WM8903_FORMATS,
1506 },
1507 .capture = {
1508 .stream_name = "Capture",
1509 .channels_min = 2,
1510 .channels_max = 2,
1511 .rates = WM8903_CAPTURE_RATES,
1512 .formats = WM8903_FORMATS,
1513 },
1514 .ops = {
1515 .startup = wm8903_startup,
1516 .shutdown = wm8903_shutdown,
1517 .hw_params = wm8903_hw_params,
1518 },
1519 .dai_ops = {
1520 .digital_mute = wm8903_digital_mute,
1521 .set_fmt = wm8903_set_dai_fmt,
1522 .set_sysclk = wm8903_set_dai_sysclk
1523 }
1524};
1525EXPORT_SYMBOL_GPL(wm8903_dai);
1526
1527static int wm8903_suspend(struct platform_device *pdev, pm_message_t state)
1528{
1529 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1530 struct snd_soc_codec *codec = socdev->codec;
1531
1532 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1533
1534 return 0;
1535}
1536
1537static int wm8903_resume(struct platform_device *pdev)
1538{
1539 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1540 struct snd_soc_codec *codec = socdev->codec;
1541 struct i2c_client *i2c = codec->control_data;
1542 int i;
1543 u16 *reg_cache = codec->reg_cache;
1544 u16 *tmp_cache = kmemdup(codec->reg_cache, sizeof(wm8903_reg_defaults),
1545 GFP_KERNEL);
1546
1547 /* Bring the codec back up to standby first to minimise pop/clicks */
1548 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1549 wm8903_set_bias_level(codec, codec->suspend_bias_level);
1550
1551 /* Sync back everything else */
1552 if (tmp_cache) {
1553 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
1554 if (tmp_cache[i] != reg_cache[i])
1555 wm8903_write(codec, i, tmp_cache[i]);
1556 } else {
1557 dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
1558 }
1559
1560 return 0;
1561}
1562
1563/*
1564 * initialise the WM8903 driver
1565 * register the mixer and dsp interfaces with the kernel
1566 */
1567static int wm8903_init(struct snd_soc_device *socdev)
1568{
1569 struct snd_soc_codec *codec = socdev->codec;
1570 struct i2c_client *i2c = codec->control_data;
1571 int ret = 0;
1572 u16 val;
1573
1574 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
1575 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1576 dev_err(&i2c->dev,
1577 "Device with ID register %x is not a WM8903\n", val);
1578 return -ENODEV;
1579 }
1580
1581 codec->name = "WM8903";
1582 codec->owner = THIS_MODULE;
1583 codec->read = wm8903_read;
1584 codec->write = wm8903_write;
1585 codec->bias_level = SND_SOC_BIAS_OFF;
1586 codec->set_bias_level = wm8903_set_bias_level;
1587 codec->dai = &wm8903_dai;
1588 codec->num_dai = 1;
1589 codec->reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults);
1590 codec->reg_cache = kmemdup(wm8903_reg_defaults,
1591 sizeof(wm8903_reg_defaults),
1592 GFP_KERNEL);
1593 if (codec->reg_cache == NULL) {
1594 dev_err(&i2c->dev, "Failed to allocate register cache\n");
1595 return -ENOMEM;
1596 }
1597
1598 val = wm8903_read(codec, WM8903_REVISION_NUMBER);
1599 dev_info(&i2c->dev, "WM8903 revision %d\n",
1600 val & WM8903_CHIP_REV_MASK);
1601
1602 wm8903_reset(codec);
1603
1604 /* register pcms */
1605 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1606 if (ret < 0) {
1607 dev_err(&i2c->dev, "failed to create pcms\n");
1608 goto pcm_err;
1609 }
1610
1611 /* SYSCLK is required for pretty much anything */
1612 wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
1613
1614 /* power on device */
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1616
1617 /* Latch volume update bits */
1618 val = wm8903_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
1619 val |= WM8903_ADCVU;
1620 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
1621 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
1622
1623 val = wm8903_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
1624 val |= WM8903_DACVU;
1625 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
1626 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
1627
1628 val = wm8903_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
1629 val |= WM8903_HPOUTVU;
1630 wm8903_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
1631 wm8903_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
1632
1633 val = wm8903_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
1634 val |= WM8903_LINEOUTVU;
1635 wm8903_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
1636 wm8903_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
1637
1638 val = wm8903_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
1639 val |= WM8903_SPKVU;
1640 wm8903_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
1641 wm8903_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1642
1643 /* Enable DAC soft mute by default */
1644 val = wm8903_read(codec, WM8903_DAC_DIGITAL_1);
1645 val |= WM8903_DAC_MUTEMODE;
1646 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
1647
1648 wm8903_add_controls(codec);
1649 wm8903_add_widgets(codec);
1650 ret = snd_soc_register_card(socdev);
1651 if (ret < 0) {
1652 dev_err(&i2c->dev, "wm8903: failed to register card\n");
1653 goto card_err;
1654 }
1655
1656 return ret;
1657
1658card_err:
1659 snd_soc_free_pcms(socdev);
1660 snd_soc_dapm_free(socdev);
1661pcm_err:
1662 kfree(codec->reg_cache);
1663 return ret;
1664}
1665
1666static struct snd_soc_device *wm8903_socdev;
1667
1668static int wm8903_i2c_probe(struct i2c_client *i2c,
1669 const struct i2c_device_id *id)
1670{
1671 struct snd_soc_device *socdev = wm8903_socdev;
1672 struct snd_soc_codec *codec = socdev->codec;
1673 int ret;
1674
1675 i2c_set_clientdata(i2c, codec);
1676 codec->control_data = i2c;
1677
1678 ret = wm8903_init(socdev);
1679 if (ret < 0)
1680 dev_err(&i2c->dev, "Device initialisation failed\n");
1681
1682 return ret;
1683}
1684
1685static int wm8903_i2c_remove(struct i2c_client *client)
1686{
1687 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1688 kfree(codec->reg_cache);
1689 return 0;
1690}
1691
1692/* i2c codec control layer */
1693static const struct i2c_device_id wm8903_i2c_id[] = {
1694 { "wm8903", 0 },
1695 { }
1696};
1697MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1698
1699static struct i2c_driver wm8903_i2c_driver = {
1700 .driver = {
1701 .name = "WM8903",
1702 .owner = THIS_MODULE,
1703 },
1704 .probe = wm8903_i2c_probe,
1705 .remove = wm8903_i2c_remove,
1706 .id_table = wm8903_i2c_id,
1707};
1708
1709static int wm8903_probe(struct platform_device *pdev)
1710{
1711 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1712 struct wm8903_setup_data *setup;
1713 struct snd_soc_codec *codec;
1714 struct wm8903_priv *wm8903;
1715 struct i2c_board_info board_info;
1716 struct i2c_adapter *adapter;
1717 struct i2c_client *i2c_client;
1718 int ret = 0;
1719
1720 setup = socdev->codec_data;
1721
1722 if (!setup->i2c_address) {
1723 dev_err(&pdev->dev, "No codec address provided\n");
1724 return -ENODEV;
1725 }
1726
1727 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1728 if (codec == NULL)
1729 return -ENOMEM;
1730
1731 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1732 if (wm8903 == NULL) {
1733 ret = -ENOMEM;
1734 goto err_codec;
1735 }
1736
1737 codec->private_data = wm8903;
1738 socdev->codec = codec;
1739 mutex_init(&codec->mutex);
1740 INIT_LIST_HEAD(&codec->dapm_widgets);
1741 INIT_LIST_HEAD(&codec->dapm_paths);
1742
1743 wm8903_socdev = socdev;
1744
1745 codec->hw_write = (hw_write_t)i2c_master_send;
1746 ret = i2c_add_driver(&wm8903_i2c_driver);
1747 if (ret != 0) {
1748 dev_err(&pdev->dev, "can't add i2c driver\n");
1749 goto err_priv;
1750 } else {
1751 memset(&board_info, 0, sizeof(board_info));
1752 strlcpy(board_info.type, "wm8903", I2C_NAME_SIZE);
1753 board_info.addr = setup->i2c_address;
1754
1755 adapter = i2c_get_adapter(setup->i2c_bus);
1756 if (!adapter) {
1757 dev_err(&pdev->dev, "Can't get I2C bus %d\n",
1758 setup->i2c_bus);
1759 ret = -ENODEV;
1760 goto err_adapter;
1761 }
1762
1763 i2c_client = i2c_new_device(adapter, &board_info);
1764 i2c_put_adapter(adapter);
1765 if (i2c_client == NULL) {
1766 dev_err(&pdev->dev,
1767 "I2C driver registration failed\n");
1768 ret = -ENODEV;
1769 goto err_adapter;
1770 }
1771 }
1772
1773 return ret;
1774
1775err_adapter:
1776 i2c_del_driver(&wm8903_i2c_driver);
1777err_priv:
1778 kfree(codec->private_data);
1779err_codec:
1780 kfree(codec);
1781 return ret;
1782}
1783
1784/* power down chip */
1785static int wm8903_remove(struct platform_device *pdev)
1786{
1787 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1788 struct snd_soc_codec *codec = socdev->codec;
1789
1790 if (codec->control_data)
1791 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1792
1793 snd_soc_free_pcms(socdev);
1794 snd_soc_dapm_free(socdev);
1795 i2c_unregister_device(socdev->codec->control_data);
1796 i2c_del_driver(&wm8903_i2c_driver);
1797 kfree(codec->private_data);
1798 kfree(codec);
1799
1800 return 0;
1801}
1802
1803struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1804 .probe = wm8903_probe,
1805 .remove = wm8903_remove,
1806 .suspend = wm8903_suspend,
1807 .resume = wm8903_resume,
1808};
1809EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1810
1811MODULE_DESCRIPTION("ASoC WM8903 driver");
1812MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
1813MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
new file mode 100644
index 000000000000..cec622f2f660
--- /dev/null
+++ b/sound/soc/codecs/wm8903.h
@@ -0,0 +1,1463 @@
1/*
2 * wm8903.h - WM8903 audio codec interface
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.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#ifndef _WM8903_H
14#define _WM8903_H
15
16#include <linux/i2c.h>
17
18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20
21struct wm8903_setup_data {
22 int i2c_bus;
23 int i2c_address;
24};
25
26#define WM8903_MCLK_DIV_2 1
27#define WM8903_CLK_SYS 2
28#define WM8903_BCLK 3
29#define WM8903_LRCLK 4
30
31/*
32 * Register values.
33 */
34#define WM8903_SW_RESET_AND_ID 0x00
35#define WM8903_REVISION_NUMBER 0x01
36#define WM8903_BIAS_CONTROL_0 0x04
37#define WM8903_VMID_CONTROL_0 0x05
38#define WM8903_MIC_BIAS_CONTROL_0 0x06
39#define WM8903_ANALOGUE_DAC_0 0x08
40#define WM8903_ANALOGUE_ADC_0 0x0A
41#define WM8903_POWER_MANAGEMENT_0 0x0C
42#define WM8903_POWER_MANAGEMENT_1 0x0D
43#define WM8903_POWER_MANAGEMENT_2 0x0E
44#define WM8903_POWER_MANAGEMENT_3 0x0F
45#define WM8903_POWER_MANAGEMENT_4 0x10
46#define WM8903_POWER_MANAGEMENT_5 0x11
47#define WM8903_POWER_MANAGEMENT_6 0x12
48#define WM8903_CLOCK_RATES_0 0x14
49#define WM8903_CLOCK_RATES_1 0x15
50#define WM8903_CLOCK_RATES_2 0x16
51#define WM8903_AUDIO_INTERFACE_0 0x18
52#define WM8903_AUDIO_INTERFACE_1 0x19
53#define WM8903_AUDIO_INTERFACE_2 0x1A
54#define WM8903_AUDIO_INTERFACE_3 0x1B
55#define WM8903_DAC_DIGITAL_VOLUME_LEFT 0x1E
56#define WM8903_DAC_DIGITAL_VOLUME_RIGHT 0x1F
57#define WM8903_DAC_DIGITAL_0 0x20
58#define WM8903_DAC_DIGITAL_1 0x21
59#define WM8903_ADC_DIGITAL_VOLUME_LEFT 0x24
60#define WM8903_ADC_DIGITAL_VOLUME_RIGHT 0x25
61#define WM8903_ADC_DIGITAL_0 0x26
62#define WM8903_DIGITAL_MICROPHONE_0 0x27
63#define WM8903_DRC_0 0x28
64#define WM8903_DRC_1 0x29
65#define WM8903_DRC_2 0x2A
66#define WM8903_DRC_3 0x2B
67#define WM8903_ANALOGUE_LEFT_INPUT_0 0x2C
68#define WM8903_ANALOGUE_RIGHT_INPUT_0 0x2D
69#define WM8903_ANALOGUE_LEFT_INPUT_1 0x2E
70#define WM8903_ANALOGUE_RIGHT_INPUT_1 0x2F
71#define WM8903_ANALOGUE_LEFT_MIX_0 0x32
72#define WM8903_ANALOGUE_RIGHT_MIX_0 0x33
73#define WM8903_ANALOGUE_SPK_MIX_LEFT_0 0x34
74#define WM8903_ANALOGUE_SPK_MIX_LEFT_1 0x35
75#define WM8903_ANALOGUE_SPK_MIX_RIGHT_0 0x36
76#define WM8903_ANALOGUE_SPK_MIX_RIGHT_1 0x37
77#define WM8903_ANALOGUE_OUT1_LEFT 0x39
78#define WM8903_ANALOGUE_OUT1_RIGHT 0x3A
79#define WM8903_ANALOGUE_OUT2_LEFT 0x3B
80#define WM8903_ANALOGUE_OUT2_RIGHT 0x3C
81#define WM8903_ANALOGUE_OUT3_LEFT 0x3E
82#define WM8903_ANALOGUE_OUT3_RIGHT 0x3F
83#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41
84#define WM8903_DC_SERVO_0 0x43
85#define WM8903_DC_SERVO_2 0x45
86#define WM8903_ANALOGUE_HP_0 0x5A
87#define WM8903_ANALOGUE_LINEOUT_0 0x5E
88#define WM8903_CHARGE_PUMP_0 0x62
89#define WM8903_CLASS_W_0 0x68
90#define WM8903_WRITE_SEQUENCER_0 0x6C
91#define WM8903_WRITE_SEQUENCER_1 0x6D
92#define WM8903_WRITE_SEQUENCER_2 0x6E
93#define WM8903_WRITE_SEQUENCER_3 0x6F
94#define WM8903_WRITE_SEQUENCER_4 0x70
95#define WM8903_CONTROL_INTERFACE 0x72
96#define WM8903_GPIO_CONTROL_1 0x74
97#define WM8903_GPIO_CONTROL_2 0x75
98#define WM8903_GPIO_CONTROL_3 0x76
99#define WM8903_GPIO_CONTROL_4 0x77
100#define WM8903_GPIO_CONTROL_5 0x78
101#define WM8903_INTERRUPT_STATUS_1 0x79
102#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A
103#define WM8903_INTERRUPT_POLARITY_1 0x7B
104#define WM8903_INTERRUPT_CONTROL 0x7E
105#define WM8903_CONTROL_INTERFACE_TEST_1 0x81
106#define WM8903_CHARGE_PUMP_TEST_1 0x95
107#define WM8903_CLOCK_RATE_TEST_4 0xA4
108#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC
109
110#define WM8903_REGISTER_COUNT 75
111#define WM8903_MAX_REGISTER 0xAC
112
113/*
114 * Field Definitions.
115 */
116
117/*
118 * R0 (0x00) - SW Reset and ID
119 */
120#define WM8903_SW_RESET_DEV_ID1_MASK 0xFFFF /* SW_RESET_DEV_ID1 - [15:0] */
121#define WM8903_SW_RESET_DEV_ID1_SHIFT 0 /* SW_RESET_DEV_ID1 - [15:0] */
122#define WM8903_SW_RESET_DEV_ID1_WIDTH 16 /* SW_RESET_DEV_ID1 - [15:0] */
123
124/*
125 * R1 (0x01) - Revision Number
126 */
127#define WM8903_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
128#define WM8903_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
129#define WM8903_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
130
131/*
132 * R4 (0x04) - Bias Control 0
133 */
134#define WM8903_POBCTRL 0x0010 /* POBCTRL */
135#define WM8903_POBCTRL_MASK 0x0010 /* POBCTRL */
136#define WM8903_POBCTRL_SHIFT 4 /* POBCTRL */
137#define WM8903_POBCTRL_WIDTH 1 /* POBCTRL */
138#define WM8903_ISEL_MASK 0x000C /* ISEL - [3:2] */
139#define WM8903_ISEL_SHIFT 2 /* ISEL - [3:2] */
140#define WM8903_ISEL_WIDTH 2 /* ISEL - [3:2] */
141#define WM8903_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
142#define WM8903_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
143#define WM8903_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
144#define WM8903_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
145#define WM8903_BIAS_ENA 0x0001 /* BIAS_ENA */
146#define WM8903_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
147#define WM8903_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
148#define WM8903_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
149
150/*
151 * R5 (0x05) - VMID Control 0
152 */
153#define WM8903_VMID_TIE_ENA 0x0080 /* VMID_TIE_ENA */
154#define WM8903_VMID_TIE_ENA_MASK 0x0080 /* VMID_TIE_ENA */
155#define WM8903_VMID_TIE_ENA_SHIFT 7 /* VMID_TIE_ENA */
156#define WM8903_VMID_TIE_ENA_WIDTH 1 /* VMID_TIE_ENA */
157#define WM8903_BUFIO_ENA 0x0040 /* BUFIO_ENA */
158#define WM8903_BUFIO_ENA_MASK 0x0040 /* BUFIO_ENA */
159#define WM8903_BUFIO_ENA_SHIFT 6 /* BUFIO_ENA */
160#define WM8903_BUFIO_ENA_WIDTH 1 /* BUFIO_ENA */
161#define WM8903_VMID_IO_ENA 0x0020 /* VMID_IO_ENA */
162#define WM8903_VMID_IO_ENA_MASK 0x0020 /* VMID_IO_ENA */
163#define WM8903_VMID_IO_ENA_SHIFT 5 /* VMID_IO_ENA */
164#define WM8903_VMID_IO_ENA_WIDTH 1 /* VMID_IO_ENA */
165#define WM8903_VMID_SOFT_MASK 0x0018 /* VMID_SOFT - [4:3] */
166#define WM8903_VMID_SOFT_SHIFT 3 /* VMID_SOFT - [4:3] */
167#define WM8903_VMID_SOFT_WIDTH 2 /* VMID_SOFT - [4:3] */
168#define WM8903_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
169#define WM8903_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
170#define WM8903_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
171#define WM8903_VMID_BUF_ENA 0x0001 /* VMID_BUF_ENA */
172#define WM8903_VMID_BUF_ENA_MASK 0x0001 /* VMID_BUF_ENA */
173#define WM8903_VMID_BUF_ENA_SHIFT 0 /* VMID_BUF_ENA */
174#define WM8903_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
175
176#define WM8903_VMID_RES_50K 2
177#define WM8903_VMID_RES_250K 3
178#define WM8903_VMID_RES_5K 4
179
180/*
181 * R6 (0x06) - Mic Bias Control 0
182 */
183#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */
184#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */
185#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */
186#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
187#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
188#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
189#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
190#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
191#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
192#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
193#define WM8903_MICDET_ENA 0x0002 /* MICDET_ENA */
194#define WM8903_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
195#define WM8903_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
196#define WM8903_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
197#define WM8903_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
198#define WM8903_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
199#define WM8903_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
200#define WM8903_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
201
202/*
203 * R8 (0x08) - Analogue DAC 0
204 */
205#define WM8903_DACBIAS_SEL_MASK 0x0018 /* DACBIAS_SEL - [4:3] */
206#define WM8903_DACBIAS_SEL_SHIFT 3 /* DACBIAS_SEL - [4:3] */
207#define WM8903_DACBIAS_SEL_WIDTH 2 /* DACBIAS_SEL - [4:3] */
208#define WM8903_DACVMID_BIAS_SEL_MASK 0x0006 /* DACVMID_BIAS_SEL - [2:1] */
209#define WM8903_DACVMID_BIAS_SEL_SHIFT 1 /* DACVMID_BIAS_SEL - [2:1] */
210#define WM8903_DACVMID_BIAS_SEL_WIDTH 2 /* DACVMID_BIAS_SEL - [2:1] */
211
212/*
213 * R10 (0x0A) - Analogue ADC 0
214 */
215#define WM8903_ADC_OSR128 0x0001 /* ADC_OSR128 */
216#define WM8903_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
217#define WM8903_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
218#define WM8903_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
219
220/*
221 * R12 (0x0C) - Power Management 0
222 */
223#define WM8903_INL_ENA 0x0002 /* INL_ENA */
224#define WM8903_INL_ENA_MASK 0x0002 /* INL_ENA */
225#define WM8903_INL_ENA_SHIFT 1 /* INL_ENA */
226#define WM8903_INL_ENA_WIDTH 1 /* INL_ENA */
227#define WM8903_INR_ENA 0x0001 /* INR_ENA */
228#define WM8903_INR_ENA_MASK 0x0001 /* INR_ENA */
229#define WM8903_INR_ENA_SHIFT 0 /* INR_ENA */
230#define WM8903_INR_ENA_WIDTH 1 /* INR_ENA */
231
232/*
233 * R13 (0x0D) - Power Management 1
234 */
235#define WM8903_MIXOUTL_ENA 0x0002 /* MIXOUTL_ENA */
236#define WM8903_MIXOUTL_ENA_MASK 0x0002 /* MIXOUTL_ENA */
237#define WM8903_MIXOUTL_ENA_SHIFT 1 /* MIXOUTL_ENA */
238#define WM8903_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
239#define WM8903_MIXOUTR_ENA 0x0001 /* MIXOUTR_ENA */
240#define WM8903_MIXOUTR_ENA_MASK 0x0001 /* MIXOUTR_ENA */
241#define WM8903_MIXOUTR_ENA_SHIFT 0 /* MIXOUTR_ENA */
242#define WM8903_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
243
244/*
245 * R14 (0x0E) - Power Management 2
246 */
247#define WM8903_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
248#define WM8903_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
249#define WM8903_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
250#define WM8903_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
251#define WM8903_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
252#define WM8903_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
253#define WM8903_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
254#define WM8903_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
255
256/*
257 * R15 (0x0F) - Power Management 3
258 */
259#define WM8903_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
260#define WM8903_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
261#define WM8903_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
262#define WM8903_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
263#define WM8903_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
264#define WM8903_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
265#define WM8903_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
266#define WM8903_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
267
268/*
269 * R16 (0x10) - Power Management 4
270 */
271#define WM8903_MIXSPKL_ENA 0x0002 /* MIXSPKL_ENA */
272#define WM8903_MIXSPKL_ENA_MASK 0x0002 /* MIXSPKL_ENA */
273#define WM8903_MIXSPKL_ENA_SHIFT 1 /* MIXSPKL_ENA */
274#define WM8903_MIXSPKL_ENA_WIDTH 1 /* MIXSPKL_ENA */
275#define WM8903_MIXSPKR_ENA 0x0001 /* MIXSPKR_ENA */
276#define WM8903_MIXSPKR_ENA_MASK 0x0001 /* MIXSPKR_ENA */
277#define WM8903_MIXSPKR_ENA_SHIFT 0 /* MIXSPKR_ENA */
278#define WM8903_MIXSPKR_ENA_WIDTH 1 /* MIXSPKR_ENA */
279
280/*
281 * R17 (0x11) - Power Management 5
282 */
283#define WM8903_SPKL_ENA 0x0002 /* SPKL_ENA */
284#define WM8903_SPKL_ENA_MASK 0x0002 /* SPKL_ENA */
285#define WM8903_SPKL_ENA_SHIFT 1 /* SPKL_ENA */
286#define WM8903_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
287#define WM8903_SPKR_ENA 0x0001 /* SPKR_ENA */
288#define WM8903_SPKR_ENA_MASK 0x0001 /* SPKR_ENA */
289#define WM8903_SPKR_ENA_SHIFT 0 /* SPKR_ENA */
290#define WM8903_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
291
292/*
293 * R18 (0x12) - Power Management 6
294 */
295#define WM8903_DACL_ENA 0x0008 /* DACL_ENA */
296#define WM8903_DACL_ENA_MASK 0x0008 /* DACL_ENA */
297#define WM8903_DACL_ENA_SHIFT 3 /* DACL_ENA */
298#define WM8903_DACL_ENA_WIDTH 1 /* DACL_ENA */
299#define WM8903_DACR_ENA 0x0004 /* DACR_ENA */
300#define WM8903_DACR_ENA_MASK 0x0004 /* DACR_ENA */
301#define WM8903_DACR_ENA_SHIFT 2 /* DACR_ENA */
302#define WM8903_DACR_ENA_WIDTH 1 /* DACR_ENA */
303#define WM8903_ADCL_ENA 0x0002 /* ADCL_ENA */
304#define WM8903_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
305#define WM8903_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
306#define WM8903_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
307#define WM8903_ADCR_ENA 0x0001 /* ADCR_ENA */
308#define WM8903_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
309#define WM8903_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
310#define WM8903_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
311
312/*
313 * R20 (0x14) - Clock Rates 0
314 */
315#define WM8903_MCLKDIV2 0x0001 /* MCLKDIV2 */
316#define WM8903_MCLKDIV2_MASK 0x0001 /* MCLKDIV2 */
317#define WM8903_MCLKDIV2_SHIFT 0 /* MCLKDIV2 */
318#define WM8903_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
319
320/*
321 * R21 (0x15) - Clock Rates 1
322 */
323#define WM8903_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
324#define WM8903_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
325#define WM8903_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
326#define WM8903_CLK_SYS_MODE_MASK 0x0300 /* CLK_SYS_MODE - [9:8] */
327#define WM8903_CLK_SYS_MODE_SHIFT 8 /* CLK_SYS_MODE - [9:8] */
328#define WM8903_CLK_SYS_MODE_WIDTH 2 /* CLK_SYS_MODE - [9:8] */
329#define WM8903_SAMPLE_RATE_MASK 0x000F /* SAMPLE_RATE - [3:0] */
330#define WM8903_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [3:0] */
331#define WM8903_SAMPLE_RATE_WIDTH 4 /* SAMPLE_RATE - [3:0] */
332
333/*
334 * R22 (0x16) - Clock Rates 2
335 */
336#define WM8903_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
337#define WM8903_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
338#define WM8903_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
339#define WM8903_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
340#define WM8903_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
341#define WM8903_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
342#define WM8903_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
343#define WM8903_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
344#define WM8903_TO_ENA 0x0001 /* TO_ENA */
345#define WM8903_TO_ENA_MASK 0x0001 /* TO_ENA */
346#define WM8903_TO_ENA_SHIFT 0 /* TO_ENA */
347#define WM8903_TO_ENA_WIDTH 1 /* TO_ENA */
348
349/*
350 * R24 (0x18) - Audio Interface 0
351 */
352#define WM8903_DACL_DATINV 0x1000 /* DACL_DATINV */
353#define WM8903_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
354#define WM8903_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
355#define WM8903_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
356#define WM8903_DACR_DATINV 0x0800 /* DACR_DATINV */
357#define WM8903_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
358#define WM8903_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
359#define WM8903_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
360#define WM8903_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
361#define WM8903_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
362#define WM8903_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
363#define WM8903_LOOPBACK 0x0100 /* LOOPBACK */
364#define WM8903_LOOPBACK_MASK 0x0100 /* LOOPBACK */
365#define WM8903_LOOPBACK_SHIFT 8 /* LOOPBACK */
366#define WM8903_LOOPBACK_WIDTH 1 /* LOOPBACK */
367#define WM8903_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
368#define WM8903_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
369#define WM8903_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
370#define WM8903_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
371#define WM8903_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
372#define WM8903_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
373#define WM8903_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
374#define WM8903_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
375#define WM8903_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
376#define WM8903_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
377#define WM8903_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
378#define WM8903_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
379#define WM8903_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
380#define WM8903_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
381#define WM8903_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
382#define WM8903_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
383#define WM8903_ADC_COMP 0x0008 /* ADC_COMP */
384#define WM8903_ADC_COMP_MASK 0x0008 /* ADC_COMP */
385#define WM8903_ADC_COMP_SHIFT 3 /* ADC_COMP */
386#define WM8903_ADC_COMP_WIDTH 1 /* ADC_COMP */
387#define WM8903_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
388#define WM8903_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
389#define WM8903_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
390#define WM8903_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
391#define WM8903_DAC_COMP 0x0002 /* DAC_COMP */
392#define WM8903_DAC_COMP_MASK 0x0002 /* DAC_COMP */
393#define WM8903_DAC_COMP_SHIFT 1 /* DAC_COMP */
394#define WM8903_DAC_COMP_WIDTH 1 /* DAC_COMP */
395#define WM8903_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
396#define WM8903_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
397#define WM8903_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
398#define WM8903_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
399
400/*
401 * R25 (0x19) - Audio Interface 1
402 */
403#define WM8903_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
404#define WM8903_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
405#define WM8903_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
406#define WM8903_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
407#define WM8903_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
408#define WM8903_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
409#define WM8903_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
410#define WM8903_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
411#define WM8903_AIFADC_TDM 0x0800 /* AIFADC_TDM */
412#define WM8903_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
413#define WM8903_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
414#define WM8903_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
415#define WM8903_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
416#define WM8903_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
417#define WM8903_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
418#define WM8903_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
419#define WM8903_LRCLK_DIR 0x0200 /* LRCLK_DIR */
420#define WM8903_LRCLK_DIR_MASK 0x0200 /* LRCLK_DIR */
421#define WM8903_LRCLK_DIR_SHIFT 9 /* LRCLK_DIR */
422#define WM8903_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
423#define WM8903_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
424#define WM8903_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
425#define WM8903_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
426#define WM8903_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
427#define WM8903_BCLK_DIR 0x0040 /* BCLK_DIR */
428#define WM8903_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
429#define WM8903_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
430#define WM8903_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
431#define WM8903_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
432#define WM8903_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
433#define WM8903_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
434#define WM8903_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
435#define WM8903_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
436#define WM8903_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
437#define WM8903_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
438#define WM8903_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
439#define WM8903_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
440#define WM8903_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
441
442/*
443 * R26 (0x1A) - Audio Interface 2
444 */
445#define WM8903_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
446#define WM8903_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
447#define WM8903_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
448
449/*
450 * R27 (0x1B) - Audio Interface 3
451 */
452#define WM8903_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
453#define WM8903_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
454#define WM8903_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
455
456/*
457 * R30 (0x1E) - DAC Digital Volume Left
458 */
459#define WM8903_DACVU 0x0100 /* DACVU */
460#define WM8903_DACVU_MASK 0x0100 /* DACVU */
461#define WM8903_DACVU_SHIFT 8 /* DACVU */
462#define WM8903_DACVU_WIDTH 1 /* DACVU */
463#define WM8903_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
464#define WM8903_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
465#define WM8903_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
466
467/*
468 * R31 (0x1F) - DAC Digital Volume Right
469 */
470#define WM8903_DACVU 0x0100 /* DACVU */
471#define WM8903_DACVU_MASK 0x0100 /* DACVU */
472#define WM8903_DACVU_SHIFT 8 /* DACVU */
473#define WM8903_DACVU_WIDTH 1 /* DACVU */
474#define WM8903_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
475#define WM8903_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
476#define WM8903_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
477
478/*
479 * R32 (0x20) - DAC Digital 0
480 */
481#define WM8903_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
482#define WM8903_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
483#define WM8903_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
484#define WM8903_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
485#define WM8903_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
486#define WM8903_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
487#define WM8903_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
488#define WM8903_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
489#define WM8903_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
490#define WM8903_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
491#define WM8903_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
492#define WM8903_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
493
494/*
495 * R33 (0x21) - DAC Digital 1
496 */
497#define WM8903_DAC_MONO 0x1000 /* DAC_MONO */
498#define WM8903_DAC_MONO_MASK 0x1000 /* DAC_MONO */
499#define WM8903_DAC_MONO_SHIFT 12 /* DAC_MONO */
500#define WM8903_DAC_MONO_WIDTH 1 /* DAC_MONO */
501#define WM8903_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
502#define WM8903_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
503#define WM8903_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
504#define WM8903_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
505#define WM8903_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
506#define WM8903_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
507#define WM8903_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
508#define WM8903_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
509#define WM8903_DAC_MUTEMODE 0x0200 /* DAC_MUTEMODE */
510#define WM8903_DAC_MUTEMODE_MASK 0x0200 /* DAC_MUTEMODE */
511#define WM8903_DAC_MUTEMODE_SHIFT 9 /* DAC_MUTEMODE */
512#define WM8903_DAC_MUTEMODE_WIDTH 1 /* DAC_MUTEMODE */
513#define WM8903_DAC_MUTE 0x0008 /* DAC_MUTE */
514#define WM8903_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
515#define WM8903_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
516#define WM8903_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
517#define WM8903_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
518#define WM8903_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
519#define WM8903_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
520
521/*
522 * R36 (0x24) - ADC Digital Volume Left
523 */
524#define WM8903_ADCVU 0x0100 /* ADCVU */
525#define WM8903_ADCVU_MASK 0x0100 /* ADCVU */
526#define WM8903_ADCVU_SHIFT 8 /* ADCVU */
527#define WM8903_ADCVU_WIDTH 1 /* ADCVU */
528#define WM8903_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
529#define WM8903_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
530#define WM8903_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
531
532/*
533 * R37 (0x25) - ADC Digital Volume Right
534 */
535#define WM8903_ADCVU 0x0100 /* ADCVU */
536#define WM8903_ADCVU_MASK 0x0100 /* ADCVU */
537#define WM8903_ADCVU_SHIFT 8 /* ADCVU */
538#define WM8903_ADCVU_WIDTH 1 /* ADCVU */
539#define WM8903_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
540#define WM8903_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
541#define WM8903_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
542
543/*
544 * R38 (0x26) - ADC Digital 0
545 */
546#define WM8903_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
547#define WM8903_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
548#define WM8903_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
549#define WM8903_ADC_HPF_ENA 0x0010 /* ADC_HPF_ENA */
550#define WM8903_ADC_HPF_ENA_MASK 0x0010 /* ADC_HPF_ENA */
551#define WM8903_ADC_HPF_ENA_SHIFT 4 /* ADC_HPF_ENA */
552#define WM8903_ADC_HPF_ENA_WIDTH 1 /* ADC_HPF_ENA */
553#define WM8903_ADCL_DATINV 0x0002 /* ADCL_DATINV */
554#define WM8903_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
555#define WM8903_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
556#define WM8903_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
557#define WM8903_ADCR_DATINV 0x0001 /* ADCR_DATINV */
558#define WM8903_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
559#define WM8903_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
560#define WM8903_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
561
562/*
563 * R39 (0x27) - Digital Microphone 0
564 */
565#define WM8903_DIGMIC_MODE_SEL 0x0100 /* DIGMIC_MODE_SEL */
566#define WM8903_DIGMIC_MODE_SEL_MASK 0x0100 /* DIGMIC_MODE_SEL */
567#define WM8903_DIGMIC_MODE_SEL_SHIFT 8 /* DIGMIC_MODE_SEL */
568#define WM8903_DIGMIC_MODE_SEL_WIDTH 1 /* DIGMIC_MODE_SEL */
569#define WM8903_DIGMIC_CLK_SEL_L_MASK 0x00C0 /* DIGMIC_CLK_SEL_L - [7:6] */
570#define WM8903_DIGMIC_CLK_SEL_L_SHIFT 6 /* DIGMIC_CLK_SEL_L - [7:6] */
571#define WM8903_DIGMIC_CLK_SEL_L_WIDTH 2 /* DIGMIC_CLK_SEL_L - [7:6] */
572#define WM8903_DIGMIC_CLK_SEL_R_MASK 0x0030 /* DIGMIC_CLK_SEL_R - [5:4] */
573#define WM8903_DIGMIC_CLK_SEL_R_SHIFT 4 /* DIGMIC_CLK_SEL_R - [5:4] */
574#define WM8903_DIGMIC_CLK_SEL_R_WIDTH 2 /* DIGMIC_CLK_SEL_R - [5:4] */
575#define WM8903_DIGMIC_CLK_SEL_RT_MASK 0x000C /* DIGMIC_CLK_SEL_RT - [3:2] */
576#define WM8903_DIGMIC_CLK_SEL_RT_SHIFT 2 /* DIGMIC_CLK_SEL_RT - [3:2] */
577#define WM8903_DIGMIC_CLK_SEL_RT_WIDTH 2 /* DIGMIC_CLK_SEL_RT - [3:2] */
578#define WM8903_DIGMIC_CLK_SEL_MASK 0x0003 /* DIGMIC_CLK_SEL - [1:0] */
579#define WM8903_DIGMIC_CLK_SEL_SHIFT 0 /* DIGMIC_CLK_SEL - [1:0] */
580#define WM8903_DIGMIC_CLK_SEL_WIDTH 2 /* DIGMIC_CLK_SEL - [1:0] */
581
582/*
583 * R40 (0x28) - DRC 0
584 */
585#define WM8903_DRC_ENA 0x8000 /* DRC_ENA */
586#define WM8903_DRC_ENA_MASK 0x8000 /* DRC_ENA */
587#define WM8903_DRC_ENA_SHIFT 15 /* DRC_ENA */
588#define WM8903_DRC_ENA_WIDTH 1 /* DRC_ENA */
589#define WM8903_DRC_THRESH_HYST_MASK 0x1800 /* DRC_THRESH_HYST - [12:11] */
590#define WM8903_DRC_THRESH_HYST_SHIFT 11 /* DRC_THRESH_HYST - [12:11] */
591#define WM8903_DRC_THRESH_HYST_WIDTH 2 /* DRC_THRESH_HYST - [12:11] */
592#define WM8903_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
593#define WM8903_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
594#define WM8903_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
595#define WM8903_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
596#define WM8903_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
597#define WM8903_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
598#define WM8903_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
599#define WM8903_DRC_SMOOTH_ENA 0x0008 /* DRC_SMOOTH_ENA */
600#define WM8903_DRC_SMOOTH_ENA_MASK 0x0008 /* DRC_SMOOTH_ENA */
601#define WM8903_DRC_SMOOTH_ENA_SHIFT 3 /* DRC_SMOOTH_ENA */
602#define WM8903_DRC_SMOOTH_ENA_WIDTH 1 /* DRC_SMOOTH_ENA */
603#define WM8903_DRC_QR_ENA 0x0004 /* DRC_QR_ENA */
604#define WM8903_DRC_QR_ENA_MASK 0x0004 /* DRC_QR_ENA */
605#define WM8903_DRC_QR_ENA_SHIFT 2 /* DRC_QR_ENA */
606#define WM8903_DRC_QR_ENA_WIDTH 1 /* DRC_QR_ENA */
607#define WM8903_DRC_ANTICLIP_ENA 0x0002 /* DRC_ANTICLIP_ENA */
608#define WM8903_DRC_ANTICLIP_ENA_MASK 0x0002 /* DRC_ANTICLIP_ENA */
609#define WM8903_DRC_ANTICLIP_ENA_SHIFT 1 /* DRC_ANTICLIP_ENA */
610#define WM8903_DRC_ANTICLIP_ENA_WIDTH 1 /* DRC_ANTICLIP_ENA */
611#define WM8903_DRC_HYST_ENA 0x0001 /* DRC_HYST_ENA */
612#define WM8903_DRC_HYST_ENA_MASK 0x0001 /* DRC_HYST_ENA */
613#define WM8903_DRC_HYST_ENA_SHIFT 0 /* DRC_HYST_ENA */
614#define WM8903_DRC_HYST_ENA_WIDTH 1 /* DRC_HYST_ENA */
615
616/*
617 * R41 (0x29) - DRC 1
618 */
619#define WM8903_DRC_ATTACK_RATE_MASK 0xF000 /* DRC_ATTACK_RATE - [15:12] */
620#define WM8903_DRC_ATTACK_RATE_SHIFT 12 /* DRC_ATTACK_RATE - [15:12] */
621#define WM8903_DRC_ATTACK_RATE_WIDTH 4 /* DRC_ATTACK_RATE - [15:12] */
622#define WM8903_DRC_DECAY_RATE_MASK 0x0F00 /* DRC_DECAY_RATE - [11:8] */
623#define WM8903_DRC_DECAY_RATE_SHIFT 8 /* DRC_DECAY_RATE - [11:8] */
624#define WM8903_DRC_DECAY_RATE_WIDTH 4 /* DRC_DECAY_RATE - [11:8] */
625#define WM8903_DRC_THRESH_QR_MASK 0x00C0 /* DRC_THRESH_QR - [7:6] */
626#define WM8903_DRC_THRESH_QR_SHIFT 6 /* DRC_THRESH_QR - [7:6] */
627#define WM8903_DRC_THRESH_QR_WIDTH 2 /* DRC_THRESH_QR - [7:6] */
628#define WM8903_DRC_RATE_QR_MASK 0x0030 /* DRC_RATE_QR - [5:4] */
629#define WM8903_DRC_RATE_QR_SHIFT 4 /* DRC_RATE_QR - [5:4] */
630#define WM8903_DRC_RATE_QR_WIDTH 2 /* DRC_RATE_QR - [5:4] */
631#define WM8903_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
632#define WM8903_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
633#define WM8903_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
634#define WM8903_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
635#define WM8903_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
636#define WM8903_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
637
638/*
639 * R42 (0x2A) - DRC 2
640 */
641#define WM8903_DRC_R0_SLOPE_COMP_MASK 0x0038 /* DRC_R0_SLOPE_COMP - [5:3] */
642#define WM8903_DRC_R0_SLOPE_COMP_SHIFT 3 /* DRC_R0_SLOPE_COMP - [5:3] */
643#define WM8903_DRC_R0_SLOPE_COMP_WIDTH 3 /* DRC_R0_SLOPE_COMP - [5:3] */
644#define WM8903_DRC_R1_SLOPE_COMP_MASK 0x0007 /* DRC_R1_SLOPE_COMP - [2:0] */
645#define WM8903_DRC_R1_SLOPE_COMP_SHIFT 0 /* DRC_R1_SLOPE_COMP - [2:0] */
646#define WM8903_DRC_R1_SLOPE_COMP_WIDTH 3 /* DRC_R1_SLOPE_COMP - [2:0] */
647
648/*
649 * R43 (0x2B) - DRC 3
650 */
651#define WM8903_DRC_THRESH_COMP_MASK 0x07E0 /* DRC_THRESH_COMP - [10:5] */
652#define WM8903_DRC_THRESH_COMP_SHIFT 5 /* DRC_THRESH_COMP - [10:5] */
653#define WM8903_DRC_THRESH_COMP_WIDTH 6 /* DRC_THRESH_COMP - [10:5] */
654#define WM8903_DRC_AMP_COMP_MASK 0x001F /* DRC_AMP_COMP - [4:0] */
655#define WM8903_DRC_AMP_COMP_SHIFT 0 /* DRC_AMP_COMP - [4:0] */
656#define WM8903_DRC_AMP_COMP_WIDTH 5 /* DRC_AMP_COMP - [4:0] */
657
658/*
659 * R44 (0x2C) - Analogue Left Input 0
660 */
661#define WM8903_LINMUTE 0x0080 /* LINMUTE */
662#define WM8903_LINMUTE_MASK 0x0080 /* LINMUTE */
663#define WM8903_LINMUTE_SHIFT 7 /* LINMUTE */
664#define WM8903_LINMUTE_WIDTH 1 /* LINMUTE */
665#define WM8903_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
666#define WM8903_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
667#define WM8903_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
668
669/*
670 * R45 (0x2D) - Analogue Right Input 0
671 */
672#define WM8903_RINMUTE 0x0080 /* RINMUTE */
673#define WM8903_RINMUTE_MASK 0x0080 /* RINMUTE */
674#define WM8903_RINMUTE_SHIFT 7 /* RINMUTE */
675#define WM8903_RINMUTE_WIDTH 1 /* RINMUTE */
676#define WM8903_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
677#define WM8903_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
678#define WM8903_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
679
680/*
681 * R46 (0x2E) - Analogue Left Input 1
682 */
683#define WM8903_INL_CM_ENA 0x0040 /* INL_CM_ENA */
684#define WM8903_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
685#define WM8903_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
686#define WM8903_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
687#define WM8903_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
688#define WM8903_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
689#define WM8903_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
690#define WM8903_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
691#define WM8903_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
692#define WM8903_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
693#define WM8903_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
694#define WM8903_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
695#define WM8903_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
696
697/*
698 * R47 (0x2F) - Analogue Right Input 1
699 */
700#define WM8903_INR_CM_ENA 0x0040 /* INR_CM_ENA */
701#define WM8903_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
702#define WM8903_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
703#define WM8903_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
704#define WM8903_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
705#define WM8903_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
706#define WM8903_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
707#define WM8903_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
708#define WM8903_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
709#define WM8903_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
710#define WM8903_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
711#define WM8903_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
712#define WM8903_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
713
714/*
715 * R50 (0x32) - Analogue Left Mix 0
716 */
717#define WM8903_DACL_TO_MIXOUTL 0x0008 /* DACL_TO_MIXOUTL */
718#define WM8903_DACL_TO_MIXOUTL_MASK 0x0008 /* DACL_TO_MIXOUTL */
719#define WM8903_DACL_TO_MIXOUTL_SHIFT 3 /* DACL_TO_MIXOUTL */
720#define WM8903_DACL_TO_MIXOUTL_WIDTH 1 /* DACL_TO_MIXOUTL */
721#define WM8903_DACR_TO_MIXOUTL 0x0004 /* DACR_TO_MIXOUTL */
722#define WM8903_DACR_TO_MIXOUTL_MASK 0x0004 /* DACR_TO_MIXOUTL */
723#define WM8903_DACR_TO_MIXOUTL_SHIFT 2 /* DACR_TO_MIXOUTL */
724#define WM8903_DACR_TO_MIXOUTL_WIDTH 1 /* DACR_TO_MIXOUTL */
725#define WM8903_BYPASSL_TO_MIXOUTL 0x0002 /* BYPASSL_TO_MIXOUTL */
726#define WM8903_BYPASSL_TO_MIXOUTL_MASK 0x0002 /* BYPASSL_TO_MIXOUTL */
727#define WM8903_BYPASSL_TO_MIXOUTL_SHIFT 1 /* BYPASSL_TO_MIXOUTL */
728#define WM8903_BYPASSL_TO_MIXOUTL_WIDTH 1 /* BYPASSL_TO_MIXOUTL */
729#define WM8903_BYPASSR_TO_MIXOUTL 0x0001 /* BYPASSR_TO_MIXOUTL */
730#define WM8903_BYPASSR_TO_MIXOUTL_MASK 0x0001 /* BYPASSR_TO_MIXOUTL */
731#define WM8903_BYPASSR_TO_MIXOUTL_SHIFT 0 /* BYPASSR_TO_MIXOUTL */
732#define WM8903_BYPASSR_TO_MIXOUTL_WIDTH 1 /* BYPASSR_TO_MIXOUTL */
733
734/*
735 * R51 (0x33) - Analogue Right Mix 0
736 */
737#define WM8903_DACL_TO_MIXOUTR 0x0008 /* DACL_TO_MIXOUTR */
738#define WM8903_DACL_TO_MIXOUTR_MASK 0x0008 /* DACL_TO_MIXOUTR */
739#define WM8903_DACL_TO_MIXOUTR_SHIFT 3 /* DACL_TO_MIXOUTR */
740#define WM8903_DACL_TO_MIXOUTR_WIDTH 1 /* DACL_TO_MIXOUTR */
741#define WM8903_DACR_TO_MIXOUTR 0x0004 /* DACR_TO_MIXOUTR */
742#define WM8903_DACR_TO_MIXOUTR_MASK 0x0004 /* DACR_TO_MIXOUTR */
743#define WM8903_DACR_TO_MIXOUTR_SHIFT 2 /* DACR_TO_MIXOUTR */
744#define WM8903_DACR_TO_MIXOUTR_WIDTH 1 /* DACR_TO_MIXOUTR */
745#define WM8903_BYPASSL_TO_MIXOUTR 0x0002 /* BYPASSL_TO_MIXOUTR */
746#define WM8903_BYPASSL_TO_MIXOUTR_MASK 0x0002 /* BYPASSL_TO_MIXOUTR */
747#define WM8903_BYPASSL_TO_MIXOUTR_SHIFT 1 /* BYPASSL_TO_MIXOUTR */
748#define WM8903_BYPASSL_TO_MIXOUTR_WIDTH 1 /* BYPASSL_TO_MIXOUTR */
749#define WM8903_BYPASSR_TO_MIXOUTR 0x0001 /* BYPASSR_TO_MIXOUTR */
750#define WM8903_BYPASSR_TO_MIXOUTR_MASK 0x0001 /* BYPASSR_TO_MIXOUTR */
751#define WM8903_BYPASSR_TO_MIXOUTR_SHIFT 0 /* BYPASSR_TO_MIXOUTR */
752#define WM8903_BYPASSR_TO_MIXOUTR_WIDTH 1 /* BYPASSR_TO_MIXOUTR */
753
754/*
755 * R52 (0x34) - Analogue Spk Mix Left 0
756 */
757#define WM8903_DACL_TO_MIXSPKL 0x0008 /* DACL_TO_MIXSPKL */
758#define WM8903_DACL_TO_MIXSPKL_MASK 0x0008 /* DACL_TO_MIXSPKL */
759#define WM8903_DACL_TO_MIXSPKL_SHIFT 3 /* DACL_TO_MIXSPKL */
760#define WM8903_DACL_TO_MIXSPKL_WIDTH 1 /* DACL_TO_MIXSPKL */
761#define WM8903_DACR_TO_MIXSPKL 0x0004 /* DACR_TO_MIXSPKL */
762#define WM8903_DACR_TO_MIXSPKL_MASK 0x0004 /* DACR_TO_MIXSPKL */
763#define WM8903_DACR_TO_MIXSPKL_SHIFT 2 /* DACR_TO_MIXSPKL */
764#define WM8903_DACR_TO_MIXSPKL_WIDTH 1 /* DACR_TO_MIXSPKL */
765#define WM8903_BYPASSL_TO_MIXSPKL 0x0002 /* BYPASSL_TO_MIXSPKL */
766#define WM8903_BYPASSL_TO_MIXSPKL_MASK 0x0002 /* BYPASSL_TO_MIXSPKL */
767#define WM8903_BYPASSL_TO_MIXSPKL_SHIFT 1 /* BYPASSL_TO_MIXSPKL */
768#define WM8903_BYPASSL_TO_MIXSPKL_WIDTH 1 /* BYPASSL_TO_MIXSPKL */
769#define WM8903_BYPASSR_TO_MIXSPKL 0x0001 /* BYPASSR_TO_MIXSPKL */
770#define WM8903_BYPASSR_TO_MIXSPKL_MASK 0x0001 /* BYPASSR_TO_MIXSPKL */
771#define WM8903_BYPASSR_TO_MIXSPKL_SHIFT 0 /* BYPASSR_TO_MIXSPKL */
772#define WM8903_BYPASSR_TO_MIXSPKL_WIDTH 1 /* BYPASSR_TO_MIXSPKL */
773
774/*
775 * R53 (0x35) - Analogue Spk Mix Left 1
776 */
777#define WM8903_DACL_MIXSPKL_VOL 0x0008 /* DACL_MIXSPKL_VOL */
778#define WM8903_DACL_MIXSPKL_VOL_MASK 0x0008 /* DACL_MIXSPKL_VOL */
779#define WM8903_DACL_MIXSPKL_VOL_SHIFT 3 /* DACL_MIXSPKL_VOL */
780#define WM8903_DACL_MIXSPKL_VOL_WIDTH 1 /* DACL_MIXSPKL_VOL */
781#define WM8903_DACR_MIXSPKL_VOL 0x0004 /* DACR_MIXSPKL_VOL */
782#define WM8903_DACR_MIXSPKL_VOL_MASK 0x0004 /* DACR_MIXSPKL_VOL */
783#define WM8903_DACR_MIXSPKL_VOL_SHIFT 2 /* DACR_MIXSPKL_VOL */
784#define WM8903_DACR_MIXSPKL_VOL_WIDTH 1 /* DACR_MIXSPKL_VOL */
785#define WM8903_BYPASSL_MIXSPKL_VOL 0x0002 /* BYPASSL_MIXSPKL_VOL */
786#define WM8903_BYPASSL_MIXSPKL_VOL_MASK 0x0002 /* BYPASSL_MIXSPKL_VOL */
787#define WM8903_BYPASSL_MIXSPKL_VOL_SHIFT 1 /* BYPASSL_MIXSPKL_VOL */
788#define WM8903_BYPASSL_MIXSPKL_VOL_WIDTH 1 /* BYPASSL_MIXSPKL_VOL */
789#define WM8903_BYPASSR_MIXSPKL_VOL 0x0001 /* BYPASSR_MIXSPKL_VOL */
790#define WM8903_BYPASSR_MIXSPKL_VOL_MASK 0x0001 /* BYPASSR_MIXSPKL_VOL */
791#define WM8903_BYPASSR_MIXSPKL_VOL_SHIFT 0 /* BYPASSR_MIXSPKL_VOL */
792#define WM8903_BYPASSR_MIXSPKL_VOL_WIDTH 1 /* BYPASSR_MIXSPKL_VOL */
793
794/*
795 * R54 (0x36) - Analogue Spk Mix Right 0
796 */
797#define WM8903_DACL_TO_MIXSPKR 0x0008 /* DACL_TO_MIXSPKR */
798#define WM8903_DACL_TO_MIXSPKR_MASK 0x0008 /* DACL_TO_MIXSPKR */
799#define WM8903_DACL_TO_MIXSPKR_SHIFT 3 /* DACL_TO_MIXSPKR */
800#define WM8903_DACL_TO_MIXSPKR_WIDTH 1 /* DACL_TO_MIXSPKR */
801#define WM8903_DACR_TO_MIXSPKR 0x0004 /* DACR_TO_MIXSPKR */
802#define WM8903_DACR_TO_MIXSPKR_MASK 0x0004 /* DACR_TO_MIXSPKR */
803#define WM8903_DACR_TO_MIXSPKR_SHIFT 2 /* DACR_TO_MIXSPKR */
804#define WM8903_DACR_TO_MIXSPKR_WIDTH 1 /* DACR_TO_MIXSPKR */
805#define WM8903_BYPASSL_TO_MIXSPKR 0x0002 /* BYPASSL_TO_MIXSPKR */
806#define WM8903_BYPASSL_TO_MIXSPKR_MASK 0x0002 /* BYPASSL_TO_MIXSPKR */
807#define WM8903_BYPASSL_TO_MIXSPKR_SHIFT 1 /* BYPASSL_TO_MIXSPKR */
808#define WM8903_BYPASSL_TO_MIXSPKR_WIDTH 1 /* BYPASSL_TO_MIXSPKR */
809#define WM8903_BYPASSR_TO_MIXSPKR 0x0001 /* BYPASSR_TO_MIXSPKR */
810#define WM8903_BYPASSR_TO_MIXSPKR_MASK 0x0001 /* BYPASSR_TO_MIXSPKR */
811#define WM8903_BYPASSR_TO_MIXSPKR_SHIFT 0 /* BYPASSR_TO_MIXSPKR */
812#define WM8903_BYPASSR_TO_MIXSPKR_WIDTH 1 /* BYPASSR_TO_MIXSPKR */
813
814/*
815 * R55 (0x37) - Analogue Spk Mix Right 1
816 */
817#define WM8903_DACL_MIXSPKR_VOL 0x0008 /* DACL_MIXSPKR_VOL */
818#define WM8903_DACL_MIXSPKR_VOL_MASK 0x0008 /* DACL_MIXSPKR_VOL */
819#define WM8903_DACL_MIXSPKR_VOL_SHIFT 3 /* DACL_MIXSPKR_VOL */
820#define WM8903_DACL_MIXSPKR_VOL_WIDTH 1 /* DACL_MIXSPKR_VOL */
821#define WM8903_DACR_MIXSPKR_VOL 0x0004 /* DACR_MIXSPKR_VOL */
822#define WM8903_DACR_MIXSPKR_VOL_MASK 0x0004 /* DACR_MIXSPKR_VOL */
823#define WM8903_DACR_MIXSPKR_VOL_SHIFT 2 /* DACR_MIXSPKR_VOL */
824#define WM8903_DACR_MIXSPKR_VOL_WIDTH 1 /* DACR_MIXSPKR_VOL */
825#define WM8903_BYPASSL_MIXSPKR_VOL 0x0002 /* BYPASSL_MIXSPKR_VOL */
826#define WM8903_BYPASSL_MIXSPKR_VOL_MASK 0x0002 /* BYPASSL_MIXSPKR_VOL */
827#define WM8903_BYPASSL_MIXSPKR_VOL_SHIFT 1 /* BYPASSL_MIXSPKR_VOL */
828#define WM8903_BYPASSL_MIXSPKR_VOL_WIDTH 1 /* BYPASSL_MIXSPKR_VOL */
829#define WM8903_BYPASSR_MIXSPKR_VOL 0x0001 /* BYPASSR_MIXSPKR_VOL */
830#define WM8903_BYPASSR_MIXSPKR_VOL_MASK 0x0001 /* BYPASSR_MIXSPKR_VOL */
831#define WM8903_BYPASSR_MIXSPKR_VOL_SHIFT 0 /* BYPASSR_MIXSPKR_VOL */
832#define WM8903_BYPASSR_MIXSPKR_VOL_WIDTH 1 /* BYPASSR_MIXSPKR_VOL */
833
834/*
835 * R57 (0x39) - Analogue OUT1 Left
836 */
837#define WM8903_HPL_MUTE 0x0100 /* HPL_MUTE */
838#define WM8903_HPL_MUTE_MASK 0x0100 /* HPL_MUTE */
839#define WM8903_HPL_MUTE_SHIFT 8 /* HPL_MUTE */
840#define WM8903_HPL_MUTE_WIDTH 1 /* HPL_MUTE */
841#define WM8903_HPOUTVU 0x0080 /* HPOUTVU */
842#define WM8903_HPOUTVU_MASK 0x0080 /* HPOUTVU */
843#define WM8903_HPOUTVU_SHIFT 7 /* HPOUTVU */
844#define WM8903_HPOUTVU_WIDTH 1 /* HPOUTVU */
845#define WM8903_HPOUTLZC 0x0040 /* HPOUTLZC */
846#define WM8903_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
847#define WM8903_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
848#define WM8903_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
849#define WM8903_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
850#define WM8903_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
851#define WM8903_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
852
853/*
854 * R58 (0x3A) - Analogue OUT1 Right
855 */
856#define WM8903_HPR_MUTE 0x0100 /* HPR_MUTE */
857#define WM8903_HPR_MUTE_MASK 0x0100 /* HPR_MUTE */
858#define WM8903_HPR_MUTE_SHIFT 8 /* HPR_MUTE */
859#define WM8903_HPR_MUTE_WIDTH 1 /* HPR_MUTE */
860#define WM8903_HPOUTVU 0x0080 /* HPOUTVU */
861#define WM8903_HPOUTVU_MASK 0x0080 /* HPOUTVU */
862#define WM8903_HPOUTVU_SHIFT 7 /* HPOUTVU */
863#define WM8903_HPOUTVU_WIDTH 1 /* HPOUTVU */
864#define WM8903_HPOUTRZC 0x0040 /* HPOUTRZC */
865#define WM8903_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
866#define WM8903_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
867#define WM8903_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
868#define WM8903_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
869#define WM8903_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
870#define WM8903_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
871
872/*
873 * R59 (0x3B) - Analogue OUT2 Left
874 */
875#define WM8903_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
876#define WM8903_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
877#define WM8903_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
878#define WM8903_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
879#define WM8903_LINEOUTVU 0x0080 /* LINEOUTVU */
880#define WM8903_LINEOUTVU_MASK 0x0080 /* LINEOUTVU */
881#define WM8903_LINEOUTVU_SHIFT 7 /* LINEOUTVU */
882#define WM8903_LINEOUTVU_WIDTH 1 /* LINEOUTVU */
883#define WM8903_LINEOUTLZC 0x0040 /* LINEOUTLZC */
884#define WM8903_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
885#define WM8903_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
886#define WM8903_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
887#define WM8903_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
888#define WM8903_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
889#define WM8903_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
890
891/*
892 * R60 (0x3C) - Analogue OUT2 Right
893 */
894#define WM8903_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
895#define WM8903_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
896#define WM8903_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
897#define WM8903_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
898#define WM8903_LINEOUTVU 0x0080 /* LINEOUTVU */
899#define WM8903_LINEOUTVU_MASK 0x0080 /* LINEOUTVU */
900#define WM8903_LINEOUTVU_SHIFT 7 /* LINEOUTVU */
901#define WM8903_LINEOUTVU_WIDTH 1 /* LINEOUTVU */
902#define WM8903_LINEOUTRZC 0x0040 /* LINEOUTRZC */
903#define WM8903_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
904#define WM8903_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
905#define WM8903_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
906#define WM8903_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
907#define WM8903_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
908#define WM8903_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
909
910/*
911 * R62 (0x3E) - Analogue OUT3 Left
912 */
913#define WM8903_SPKL_MUTE 0x0100 /* SPKL_MUTE */
914#define WM8903_SPKL_MUTE_MASK 0x0100 /* SPKL_MUTE */
915#define WM8903_SPKL_MUTE_SHIFT 8 /* SPKL_MUTE */
916#define WM8903_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
917#define WM8903_SPKVU 0x0080 /* SPKVU */
918#define WM8903_SPKVU_MASK 0x0080 /* SPKVU */
919#define WM8903_SPKVU_SHIFT 7 /* SPKVU */
920#define WM8903_SPKVU_WIDTH 1 /* SPKVU */
921#define WM8903_SPKLZC 0x0040 /* SPKLZC */
922#define WM8903_SPKLZC_MASK 0x0040 /* SPKLZC */
923#define WM8903_SPKLZC_SHIFT 6 /* SPKLZC */
924#define WM8903_SPKLZC_WIDTH 1 /* SPKLZC */
925#define WM8903_SPKL_VOL_MASK 0x003F /* SPKL_VOL - [5:0] */
926#define WM8903_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [5:0] */
927#define WM8903_SPKL_VOL_WIDTH 6 /* SPKL_VOL - [5:0] */
928
929/*
930 * R63 (0x3F) - Analogue OUT3 Right
931 */
932#define WM8903_SPKR_MUTE 0x0100 /* SPKR_MUTE */
933#define WM8903_SPKR_MUTE_MASK 0x0100 /* SPKR_MUTE */
934#define WM8903_SPKR_MUTE_SHIFT 8 /* SPKR_MUTE */
935#define WM8903_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
936#define WM8903_SPKVU 0x0080 /* SPKVU */
937#define WM8903_SPKVU_MASK 0x0080 /* SPKVU */
938#define WM8903_SPKVU_SHIFT 7 /* SPKVU */
939#define WM8903_SPKVU_WIDTH 1 /* SPKVU */
940#define WM8903_SPKRZC 0x0040 /* SPKRZC */
941#define WM8903_SPKRZC_MASK 0x0040 /* SPKRZC */
942#define WM8903_SPKRZC_SHIFT 6 /* SPKRZC */
943#define WM8903_SPKRZC_WIDTH 1 /* SPKRZC */
944#define WM8903_SPKR_VOL_MASK 0x003F /* SPKR_VOL - [5:0] */
945#define WM8903_SPKR_VOL_SHIFT 0 /* SPKR_VOL - [5:0] */
946#define WM8903_SPKR_VOL_WIDTH 6 /* SPKR_VOL - [5:0] */
947
948/*
949 * R65 (0x41) - Analogue SPK Output Control 0
950 */
951#define WM8903_SPK_DISCHARGE 0x0002 /* SPK_DISCHARGE */
952#define WM8903_SPK_DISCHARGE_MASK 0x0002 /* SPK_DISCHARGE */
953#define WM8903_SPK_DISCHARGE_SHIFT 1 /* SPK_DISCHARGE */
954#define WM8903_SPK_DISCHARGE_WIDTH 1 /* SPK_DISCHARGE */
955#define WM8903_VROI 0x0001 /* VROI */
956#define WM8903_VROI_MASK 0x0001 /* VROI */
957#define WM8903_VROI_SHIFT 0 /* VROI */
958#define WM8903_VROI_WIDTH 1 /* VROI */
959
960/*
961 * R67 (0x43) - DC Servo 0
962 */
963#define WM8903_DCS_MASTER_ENA 0x0010 /* DCS_MASTER_ENA */
964#define WM8903_DCS_MASTER_ENA_MASK 0x0010 /* DCS_MASTER_ENA */
965#define WM8903_DCS_MASTER_ENA_SHIFT 4 /* DCS_MASTER_ENA */
966#define WM8903_DCS_MASTER_ENA_WIDTH 1 /* DCS_MASTER_ENA */
967#define WM8903_DCS_ENA_MASK 0x000F /* DCS_ENA - [3:0] */
968#define WM8903_DCS_ENA_SHIFT 0 /* DCS_ENA - [3:0] */
969#define WM8903_DCS_ENA_WIDTH 4 /* DCS_ENA - [3:0] */
970
971/*
972 * R69 (0x45) - DC Servo 2
973 */
974#define WM8903_DCS_MODE_MASK 0x0003 /* DCS_MODE - [1:0] */
975#define WM8903_DCS_MODE_SHIFT 0 /* DCS_MODE - [1:0] */
976#define WM8903_DCS_MODE_WIDTH 2 /* DCS_MODE - [1:0] */
977
978/*
979 * R90 (0x5A) - Analogue HP 0
980 */
981#define WM8903_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
982#define WM8903_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
983#define WM8903_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
984#define WM8903_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
985#define WM8903_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
986#define WM8903_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
987#define WM8903_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
988#define WM8903_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
989#define WM8903_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
990#define WM8903_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
991#define WM8903_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
992#define WM8903_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
993#define WM8903_HPL_ENA 0x0010 /* HPL_ENA */
994#define WM8903_HPL_ENA_MASK 0x0010 /* HPL_ENA */
995#define WM8903_HPL_ENA_SHIFT 4 /* HPL_ENA */
996#define WM8903_HPL_ENA_WIDTH 1 /* HPL_ENA */
997#define WM8903_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
998#define WM8903_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
999#define WM8903_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
1000#define WM8903_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
1001#define WM8903_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
1002#define WM8903_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
1003#define WM8903_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
1004#define WM8903_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
1005#define WM8903_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
1006#define WM8903_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
1007#define WM8903_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
1008#define WM8903_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
1009#define WM8903_HPR_ENA 0x0001 /* HPR_ENA */
1010#define WM8903_HPR_ENA_MASK 0x0001 /* HPR_ENA */
1011#define WM8903_HPR_ENA_SHIFT 0 /* HPR_ENA */
1012#define WM8903_HPR_ENA_WIDTH 1 /* HPR_ENA */
1013
1014/*
1015 * R94 (0x5E) - Analogue Lineout 0
1016 */
1017#define WM8903_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
1018#define WM8903_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
1019#define WM8903_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
1020#define WM8903_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
1021#define WM8903_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
1022#define WM8903_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
1023#define WM8903_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
1024#define WM8903_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
1025#define WM8903_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
1026#define WM8903_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
1027#define WM8903_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
1028#define WM8903_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
1029#define WM8903_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
1030#define WM8903_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
1031#define WM8903_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
1032#define WM8903_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
1033#define WM8903_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
1034#define WM8903_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
1035#define WM8903_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
1036#define WM8903_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
1037#define WM8903_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
1038#define WM8903_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
1039#define WM8903_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
1040#define WM8903_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
1041#define WM8903_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
1042#define WM8903_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
1043#define WM8903_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
1044#define WM8903_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
1045#define WM8903_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
1046#define WM8903_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
1047#define WM8903_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
1048#define WM8903_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
1049
1050/*
1051 * R98 (0x62) - Charge Pump 0
1052 */
1053#define WM8903_CP_ENA 0x0001 /* CP_ENA */
1054#define WM8903_CP_ENA_MASK 0x0001 /* CP_ENA */
1055#define WM8903_CP_ENA_SHIFT 0 /* CP_ENA */
1056#define WM8903_CP_ENA_WIDTH 1 /* CP_ENA */
1057
1058/*
1059 * R104 (0x68) - Class W 0
1060 */
1061#define WM8903_CP_DYN_FREQ 0x0002 /* CP_DYN_FREQ */
1062#define WM8903_CP_DYN_FREQ_MASK 0x0002 /* CP_DYN_FREQ */
1063#define WM8903_CP_DYN_FREQ_SHIFT 1 /* CP_DYN_FREQ */
1064#define WM8903_CP_DYN_FREQ_WIDTH 1 /* CP_DYN_FREQ */
1065#define WM8903_CP_DYN_V 0x0001 /* CP_DYN_V */
1066#define WM8903_CP_DYN_V_MASK 0x0001 /* CP_DYN_V */
1067#define WM8903_CP_DYN_V_SHIFT 0 /* CP_DYN_V */
1068#define WM8903_CP_DYN_V_WIDTH 1 /* CP_DYN_V */
1069
1070/*
1071 * R108 (0x6C) - Write Sequencer 0
1072 */
1073#define WM8903_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1074#define WM8903_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1075#define WM8903_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1076#define WM8903_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1077#define WM8903_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1078#define WM8903_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1079#define WM8903_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1080
1081/*
1082 * R109 (0x6D) - Write Sequencer 1
1083 */
1084#define WM8903_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1085#define WM8903_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1086#define WM8903_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1087#define WM8903_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1088#define WM8903_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1089#define WM8903_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1090#define WM8903_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1091#define WM8903_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1092#define WM8903_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1093
1094/*
1095 * R110 (0x6E) - Write Sequencer 2
1096 */
1097#define WM8903_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1098#define WM8903_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1099#define WM8903_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1100#define WM8903_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1101#define WM8903_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1102#define WM8903_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1103#define WM8903_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1104#define WM8903_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1105#define WM8903_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1106#define WM8903_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1107
1108/*
1109 * R111 (0x6F) - Write Sequencer 3
1110 */
1111#define WM8903_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1112#define WM8903_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1113#define WM8903_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1114#define WM8903_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1115#define WM8903_WSEQ_START 0x0100 /* WSEQ_START */
1116#define WM8903_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1117#define WM8903_WSEQ_START_SHIFT 8 /* WSEQ_START */
1118#define WM8903_WSEQ_START_WIDTH 1 /* WSEQ_START */
1119#define WM8903_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1120#define WM8903_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1121#define WM8903_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1122
1123/*
1124 * R112 (0x70) - Write Sequencer 4
1125 */
1126#define WM8903_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
1127#define WM8903_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
1128#define WM8903_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
1129#define WM8903_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1130#define WM8903_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1131#define WM8903_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1132#define WM8903_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1133
1134/*
1135 * R114 (0x72) - Control Interface
1136 */
1137#define WM8903_MASK_WRITE_ENA 0x0001 /* MASK_WRITE_ENA */
1138#define WM8903_MASK_WRITE_ENA_MASK 0x0001 /* MASK_WRITE_ENA */
1139#define WM8903_MASK_WRITE_ENA_SHIFT 0 /* MASK_WRITE_ENA */
1140#define WM8903_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
1141
1142/*
1143 * R116 (0x74) - GPIO Control 1
1144 */
1145#define WM8903_GP1_FN_MASK 0x1F00 /* GP1_FN - [12:8] */
1146#define WM8903_GP1_FN_SHIFT 8 /* GP1_FN - [12:8] */
1147#define WM8903_GP1_FN_WIDTH 5 /* GP1_FN - [12:8] */
1148#define WM8903_GP1_DIR 0x0080 /* GP1_DIR */
1149#define WM8903_GP1_DIR_MASK 0x0080 /* GP1_DIR */
1150#define WM8903_GP1_DIR_SHIFT 7 /* GP1_DIR */
1151#define WM8903_GP1_DIR_WIDTH 1 /* GP1_DIR */
1152#define WM8903_GP1_OP_CFG 0x0040 /* GP1_OP_CFG */
1153#define WM8903_GP1_OP_CFG_MASK 0x0040 /* GP1_OP_CFG */
1154#define WM8903_GP1_OP_CFG_SHIFT 6 /* GP1_OP_CFG */
1155#define WM8903_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
1156#define WM8903_GP1_IP_CFG 0x0020 /* GP1_IP_CFG */
1157#define WM8903_GP1_IP_CFG_MASK 0x0020 /* GP1_IP_CFG */
1158#define WM8903_GP1_IP_CFG_SHIFT 5 /* GP1_IP_CFG */
1159#define WM8903_GP1_IP_CFG_WIDTH 1 /* GP1_IP_CFG */
1160#define WM8903_GP1_LVL 0x0010 /* GP1_LVL */
1161#define WM8903_GP1_LVL_MASK 0x0010 /* GP1_LVL */
1162#define WM8903_GP1_LVL_SHIFT 4 /* GP1_LVL */
1163#define WM8903_GP1_LVL_WIDTH 1 /* GP1_LVL */
1164#define WM8903_GP1_PD 0x0008 /* GP1_PD */
1165#define WM8903_GP1_PD_MASK 0x0008 /* GP1_PD */
1166#define WM8903_GP1_PD_SHIFT 3 /* GP1_PD */
1167#define WM8903_GP1_PD_WIDTH 1 /* GP1_PD */
1168#define WM8903_GP1_PU 0x0004 /* GP1_PU */
1169#define WM8903_GP1_PU_MASK 0x0004 /* GP1_PU */
1170#define WM8903_GP1_PU_SHIFT 2 /* GP1_PU */
1171#define WM8903_GP1_PU_WIDTH 1 /* GP1_PU */
1172#define WM8903_GP1_INTMODE 0x0002 /* GP1_INTMODE */
1173#define WM8903_GP1_INTMODE_MASK 0x0002 /* GP1_INTMODE */
1174#define WM8903_GP1_INTMODE_SHIFT 1 /* GP1_INTMODE */
1175#define WM8903_GP1_INTMODE_WIDTH 1 /* GP1_INTMODE */
1176#define WM8903_GP1_DB 0x0001 /* GP1_DB */
1177#define WM8903_GP1_DB_MASK 0x0001 /* GP1_DB */
1178#define WM8903_GP1_DB_SHIFT 0 /* GP1_DB */
1179#define WM8903_GP1_DB_WIDTH 1 /* GP1_DB */
1180
1181/*
1182 * R117 (0x75) - GPIO Control 2
1183 */
1184#define WM8903_GP2_FN_MASK 0x1F00 /* GP2_FN - [12:8] */
1185#define WM8903_GP2_FN_SHIFT 8 /* GP2_FN - [12:8] */
1186#define WM8903_GP2_FN_WIDTH 5 /* GP2_FN - [12:8] */
1187#define WM8903_GP2_DIR 0x0080 /* GP2_DIR */
1188#define WM8903_GP2_DIR_MASK 0x0080 /* GP2_DIR */
1189#define WM8903_GP2_DIR_SHIFT 7 /* GP2_DIR */
1190#define WM8903_GP2_DIR_WIDTH 1 /* GP2_DIR */
1191#define WM8903_GP2_OP_CFG 0x0040 /* GP2_OP_CFG */
1192#define WM8903_GP2_OP_CFG_MASK 0x0040 /* GP2_OP_CFG */
1193#define WM8903_GP2_OP_CFG_SHIFT 6 /* GP2_OP_CFG */
1194#define WM8903_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
1195#define WM8903_GP2_IP_CFG 0x0020 /* GP2_IP_CFG */
1196#define WM8903_GP2_IP_CFG_MASK 0x0020 /* GP2_IP_CFG */
1197#define WM8903_GP2_IP_CFG_SHIFT 5 /* GP2_IP_CFG */
1198#define WM8903_GP2_IP_CFG_WIDTH 1 /* GP2_IP_CFG */
1199#define WM8903_GP2_LVL 0x0010 /* GP2_LVL */
1200#define WM8903_GP2_LVL_MASK 0x0010 /* GP2_LVL */
1201#define WM8903_GP2_LVL_SHIFT 4 /* GP2_LVL */
1202#define WM8903_GP2_LVL_WIDTH 1 /* GP2_LVL */
1203#define WM8903_GP2_PD 0x0008 /* GP2_PD */
1204#define WM8903_GP2_PD_MASK 0x0008 /* GP2_PD */
1205#define WM8903_GP2_PD_SHIFT 3 /* GP2_PD */
1206#define WM8903_GP2_PD_WIDTH 1 /* GP2_PD */
1207#define WM8903_GP2_PU 0x0004 /* GP2_PU */
1208#define WM8903_GP2_PU_MASK 0x0004 /* GP2_PU */
1209#define WM8903_GP2_PU_SHIFT 2 /* GP2_PU */
1210#define WM8903_GP2_PU_WIDTH 1 /* GP2_PU */
1211#define WM8903_GP2_INTMODE 0x0002 /* GP2_INTMODE */
1212#define WM8903_GP2_INTMODE_MASK 0x0002 /* GP2_INTMODE */
1213#define WM8903_GP2_INTMODE_SHIFT 1 /* GP2_INTMODE */
1214#define WM8903_GP2_INTMODE_WIDTH 1 /* GP2_INTMODE */
1215#define WM8903_GP2_DB 0x0001 /* GP2_DB */
1216#define WM8903_GP2_DB_MASK 0x0001 /* GP2_DB */
1217#define WM8903_GP2_DB_SHIFT 0 /* GP2_DB */
1218#define WM8903_GP2_DB_WIDTH 1 /* GP2_DB */
1219
1220/*
1221 * R118 (0x76) - GPIO Control 3
1222 */
1223#define WM8903_GP3_FN_MASK 0x1F00 /* GP3_FN - [12:8] */
1224#define WM8903_GP3_FN_SHIFT 8 /* GP3_FN - [12:8] */
1225#define WM8903_GP3_FN_WIDTH 5 /* GP3_FN - [12:8] */
1226#define WM8903_GP3_DIR 0x0080 /* GP3_DIR */
1227#define WM8903_GP3_DIR_MASK 0x0080 /* GP3_DIR */
1228#define WM8903_GP3_DIR_SHIFT 7 /* GP3_DIR */
1229#define WM8903_GP3_DIR_WIDTH 1 /* GP3_DIR */
1230#define WM8903_GP3_OP_CFG 0x0040 /* GP3_OP_CFG */
1231#define WM8903_GP3_OP_CFG_MASK 0x0040 /* GP3_OP_CFG */
1232#define WM8903_GP3_OP_CFG_SHIFT 6 /* GP3_OP_CFG */
1233#define WM8903_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
1234#define WM8903_GP3_IP_CFG 0x0020 /* GP3_IP_CFG */
1235#define WM8903_GP3_IP_CFG_MASK 0x0020 /* GP3_IP_CFG */
1236#define WM8903_GP3_IP_CFG_SHIFT 5 /* GP3_IP_CFG */
1237#define WM8903_GP3_IP_CFG_WIDTH 1 /* GP3_IP_CFG */
1238#define WM8903_GP3_LVL 0x0010 /* GP3_LVL */
1239#define WM8903_GP3_LVL_MASK 0x0010 /* GP3_LVL */
1240#define WM8903_GP3_LVL_SHIFT 4 /* GP3_LVL */
1241#define WM8903_GP3_LVL_WIDTH 1 /* GP3_LVL */
1242#define WM8903_GP3_PD 0x0008 /* GP3_PD */
1243#define WM8903_GP3_PD_MASK 0x0008 /* GP3_PD */
1244#define WM8903_GP3_PD_SHIFT 3 /* GP3_PD */
1245#define WM8903_GP3_PD_WIDTH 1 /* GP3_PD */
1246#define WM8903_GP3_PU 0x0004 /* GP3_PU */
1247#define WM8903_GP3_PU_MASK 0x0004 /* GP3_PU */
1248#define WM8903_GP3_PU_SHIFT 2 /* GP3_PU */
1249#define WM8903_GP3_PU_WIDTH 1 /* GP3_PU */
1250#define WM8903_GP3_INTMODE 0x0002 /* GP3_INTMODE */
1251#define WM8903_GP3_INTMODE_MASK 0x0002 /* GP3_INTMODE */
1252#define WM8903_GP3_INTMODE_SHIFT 1 /* GP3_INTMODE */
1253#define WM8903_GP3_INTMODE_WIDTH 1 /* GP3_INTMODE */
1254#define WM8903_GP3_DB 0x0001 /* GP3_DB */
1255#define WM8903_GP3_DB_MASK 0x0001 /* GP3_DB */
1256#define WM8903_GP3_DB_SHIFT 0 /* GP3_DB */
1257#define WM8903_GP3_DB_WIDTH 1 /* GP3_DB */
1258
1259/*
1260 * R119 (0x77) - GPIO Control 4
1261 */
1262#define WM8903_GP4_FN_MASK 0x1F00 /* GP4_FN - [12:8] */
1263#define WM8903_GP4_FN_SHIFT 8 /* GP4_FN - [12:8] */
1264#define WM8903_GP4_FN_WIDTH 5 /* GP4_FN - [12:8] */
1265#define WM8903_GP4_DIR 0x0080 /* GP4_DIR */
1266#define WM8903_GP4_DIR_MASK 0x0080 /* GP4_DIR */
1267#define WM8903_GP4_DIR_SHIFT 7 /* GP4_DIR */
1268#define WM8903_GP4_DIR_WIDTH 1 /* GP4_DIR */
1269#define WM8903_GP4_OP_CFG 0x0040 /* GP4_OP_CFG */
1270#define WM8903_GP4_OP_CFG_MASK 0x0040 /* GP4_OP_CFG */
1271#define WM8903_GP4_OP_CFG_SHIFT 6 /* GP4_OP_CFG */
1272#define WM8903_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
1273#define WM8903_GP4_IP_CFG 0x0020 /* GP4_IP_CFG */
1274#define WM8903_GP4_IP_CFG_MASK 0x0020 /* GP4_IP_CFG */
1275#define WM8903_GP4_IP_CFG_SHIFT 5 /* GP4_IP_CFG */
1276#define WM8903_GP4_IP_CFG_WIDTH 1 /* GP4_IP_CFG */
1277#define WM8903_GP4_LVL 0x0010 /* GP4_LVL */
1278#define WM8903_GP4_LVL_MASK 0x0010 /* GP4_LVL */
1279#define WM8903_GP4_LVL_SHIFT 4 /* GP4_LVL */
1280#define WM8903_GP4_LVL_WIDTH 1 /* GP4_LVL */
1281#define WM8903_GP4_PD 0x0008 /* GP4_PD */
1282#define WM8903_GP4_PD_MASK 0x0008 /* GP4_PD */
1283#define WM8903_GP4_PD_SHIFT 3 /* GP4_PD */
1284#define WM8903_GP4_PD_WIDTH 1 /* GP4_PD */
1285#define WM8903_GP4_PU 0x0004 /* GP4_PU */
1286#define WM8903_GP4_PU_MASK 0x0004 /* GP4_PU */
1287#define WM8903_GP4_PU_SHIFT 2 /* GP4_PU */
1288#define WM8903_GP4_PU_WIDTH 1 /* GP4_PU */
1289#define WM8903_GP4_INTMODE 0x0002 /* GP4_INTMODE */
1290#define WM8903_GP4_INTMODE_MASK 0x0002 /* GP4_INTMODE */
1291#define WM8903_GP4_INTMODE_SHIFT 1 /* GP4_INTMODE */
1292#define WM8903_GP4_INTMODE_WIDTH 1 /* GP4_INTMODE */
1293#define WM8903_GP4_DB 0x0001 /* GP4_DB */
1294#define WM8903_GP4_DB_MASK 0x0001 /* GP4_DB */
1295#define WM8903_GP4_DB_SHIFT 0 /* GP4_DB */
1296#define WM8903_GP4_DB_WIDTH 1 /* GP4_DB */
1297
1298/*
1299 * R120 (0x78) - GPIO Control 5
1300 */
1301#define WM8903_GP5_FN_MASK 0x1F00 /* GP5_FN - [12:8] */
1302#define WM8903_GP5_FN_SHIFT 8 /* GP5_FN - [12:8] */
1303#define WM8903_GP5_FN_WIDTH 5 /* GP5_FN - [12:8] */
1304#define WM8903_GP5_DIR 0x0080 /* GP5_DIR */
1305#define WM8903_GP5_DIR_MASK 0x0080 /* GP5_DIR */
1306#define WM8903_GP5_DIR_SHIFT 7 /* GP5_DIR */
1307#define WM8903_GP5_DIR_WIDTH 1 /* GP5_DIR */
1308#define WM8903_GP5_OP_CFG 0x0040 /* GP5_OP_CFG */
1309#define WM8903_GP5_OP_CFG_MASK 0x0040 /* GP5_OP_CFG */
1310#define WM8903_GP5_OP_CFG_SHIFT 6 /* GP5_OP_CFG */
1311#define WM8903_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
1312#define WM8903_GP5_IP_CFG 0x0020 /* GP5_IP_CFG */
1313#define WM8903_GP5_IP_CFG_MASK 0x0020 /* GP5_IP_CFG */
1314#define WM8903_GP5_IP_CFG_SHIFT 5 /* GP5_IP_CFG */
1315#define WM8903_GP5_IP_CFG_WIDTH 1 /* GP5_IP_CFG */
1316#define WM8903_GP5_LVL 0x0010 /* GP5_LVL */
1317#define WM8903_GP5_LVL_MASK 0x0010 /* GP5_LVL */
1318#define WM8903_GP5_LVL_SHIFT 4 /* GP5_LVL */
1319#define WM8903_GP5_LVL_WIDTH 1 /* GP5_LVL */
1320#define WM8903_GP5_PD 0x0008 /* GP5_PD */
1321#define WM8903_GP5_PD_MASK 0x0008 /* GP5_PD */
1322#define WM8903_GP5_PD_SHIFT 3 /* GP5_PD */
1323#define WM8903_GP5_PD_WIDTH 1 /* GP5_PD */
1324#define WM8903_GP5_PU 0x0004 /* GP5_PU */
1325#define WM8903_GP5_PU_MASK 0x0004 /* GP5_PU */
1326#define WM8903_GP5_PU_SHIFT 2 /* GP5_PU */
1327#define WM8903_GP5_PU_WIDTH 1 /* GP5_PU */
1328#define WM8903_GP5_INTMODE 0x0002 /* GP5_INTMODE */
1329#define WM8903_GP5_INTMODE_MASK 0x0002 /* GP5_INTMODE */
1330#define WM8903_GP5_INTMODE_SHIFT 1 /* GP5_INTMODE */
1331#define WM8903_GP5_INTMODE_WIDTH 1 /* GP5_INTMODE */
1332#define WM8903_GP5_DB 0x0001 /* GP5_DB */
1333#define WM8903_GP5_DB_MASK 0x0001 /* GP5_DB */
1334#define WM8903_GP5_DB_SHIFT 0 /* GP5_DB */
1335#define WM8903_GP5_DB_WIDTH 1 /* GP5_DB */
1336
1337/*
1338 * R121 (0x79) - Interrupt Status 1
1339 */
1340#define WM8903_MICSHRT_EINT 0x8000 /* MICSHRT_EINT */
1341#define WM8903_MICSHRT_EINT_MASK 0x8000 /* MICSHRT_EINT */
1342#define WM8903_MICSHRT_EINT_SHIFT 15 /* MICSHRT_EINT */
1343#define WM8903_MICSHRT_EINT_WIDTH 1 /* MICSHRT_EINT */
1344#define WM8903_MICDET_EINT 0x4000 /* MICDET_EINT */
1345#define WM8903_MICDET_EINT_MASK 0x4000 /* MICDET_EINT */
1346#define WM8903_MICDET_EINT_SHIFT 14 /* MICDET_EINT */
1347#define WM8903_MICDET_EINT_WIDTH 1 /* MICDET_EINT */
1348#define WM8903_WSEQ_BUSY_EINT 0x2000 /* WSEQ_BUSY_EINT */
1349#define WM8903_WSEQ_BUSY_EINT_MASK 0x2000 /* WSEQ_BUSY_EINT */
1350#define WM8903_WSEQ_BUSY_EINT_SHIFT 13 /* WSEQ_BUSY_EINT */
1351#define WM8903_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */
1352#define WM8903_GP5_EINT 0x0010 /* GP5_EINT */
1353#define WM8903_GP5_EINT_MASK 0x0010 /* GP5_EINT */
1354#define WM8903_GP5_EINT_SHIFT 4 /* GP5_EINT */
1355#define WM8903_GP5_EINT_WIDTH 1 /* GP5_EINT */
1356#define WM8903_GP4_EINT 0x0008 /* GP4_EINT */
1357#define WM8903_GP4_EINT_MASK 0x0008 /* GP4_EINT */
1358#define WM8903_GP4_EINT_SHIFT 3 /* GP4_EINT */
1359#define WM8903_GP4_EINT_WIDTH 1 /* GP4_EINT */
1360#define WM8903_GP3_EINT 0x0004 /* GP3_EINT */
1361#define WM8903_GP3_EINT_MASK 0x0004 /* GP3_EINT */
1362#define WM8903_GP3_EINT_SHIFT 2 /* GP3_EINT */
1363#define WM8903_GP3_EINT_WIDTH 1 /* GP3_EINT */
1364#define WM8903_GP2_EINT 0x0002 /* GP2_EINT */
1365#define WM8903_GP2_EINT_MASK 0x0002 /* GP2_EINT */
1366#define WM8903_GP2_EINT_SHIFT 1 /* GP2_EINT */
1367#define WM8903_GP2_EINT_WIDTH 1 /* GP2_EINT */
1368#define WM8903_GP1_EINT 0x0001 /* GP1_EINT */
1369#define WM8903_GP1_EINT_MASK 0x0001 /* GP1_EINT */
1370#define WM8903_GP1_EINT_SHIFT 0 /* GP1_EINT */
1371#define WM8903_GP1_EINT_WIDTH 1 /* GP1_EINT */
1372
1373/*
1374 * R122 (0x7A) - Interrupt Status 1 Mask
1375 */
1376#define WM8903_IM_MICSHRT_EINT 0x8000 /* IM_MICSHRT_EINT */
1377#define WM8903_IM_MICSHRT_EINT_MASK 0x8000 /* IM_MICSHRT_EINT */
1378#define WM8903_IM_MICSHRT_EINT_SHIFT 15 /* IM_MICSHRT_EINT */
1379#define WM8903_IM_MICSHRT_EINT_WIDTH 1 /* IM_MICSHRT_EINT */
1380#define WM8903_IM_MICDET_EINT 0x4000 /* IM_MICDET_EINT */
1381#define WM8903_IM_MICDET_EINT_MASK 0x4000 /* IM_MICDET_EINT */
1382#define WM8903_IM_MICDET_EINT_SHIFT 14 /* IM_MICDET_EINT */
1383#define WM8903_IM_MICDET_EINT_WIDTH 1 /* IM_MICDET_EINT */
1384#define WM8903_IM_WSEQ_BUSY_EINT 0x2000 /* IM_WSEQ_BUSY_EINT */
1385#define WM8903_IM_WSEQ_BUSY_EINT_MASK 0x2000 /* IM_WSEQ_BUSY_EINT */
1386#define WM8903_IM_WSEQ_BUSY_EINT_SHIFT 13 /* IM_WSEQ_BUSY_EINT */
1387#define WM8903_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */
1388#define WM8903_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
1389#define WM8903_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
1390#define WM8903_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
1391#define WM8903_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
1392#define WM8903_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
1393#define WM8903_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
1394#define WM8903_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
1395#define WM8903_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
1396#define WM8903_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
1397#define WM8903_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
1398#define WM8903_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
1399#define WM8903_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
1400#define WM8903_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
1401#define WM8903_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
1402#define WM8903_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
1403#define WM8903_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
1404#define WM8903_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
1405#define WM8903_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
1406#define WM8903_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
1407#define WM8903_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
1408
1409/*
1410 * R123 (0x7B) - Interrupt Polarity 1
1411 */
1412#define WM8903_MICSHRT_INV 0x8000 /* MICSHRT_INV */
1413#define WM8903_MICSHRT_INV_MASK 0x8000 /* MICSHRT_INV */
1414#define WM8903_MICSHRT_INV_SHIFT 15 /* MICSHRT_INV */
1415#define WM8903_MICSHRT_INV_WIDTH 1 /* MICSHRT_INV */
1416#define WM8903_MICDET_INV 0x4000 /* MICDET_INV */
1417#define WM8903_MICDET_INV_MASK 0x4000 /* MICDET_INV */
1418#define WM8903_MICDET_INV_SHIFT 14 /* MICDET_INV */
1419#define WM8903_MICDET_INV_WIDTH 1 /* MICDET_INV */
1420
1421/*
1422 * R126 (0x7E) - Interrupt Control
1423 */
1424#define WM8903_IRQ_POL 0x0001 /* IRQ_POL */
1425#define WM8903_IRQ_POL_MASK 0x0001 /* IRQ_POL */
1426#define WM8903_IRQ_POL_SHIFT 0 /* IRQ_POL */
1427#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */
1428
1429/*
1430 * R129 (0x81) - Control Interface Test 1
1431 */
1432#define WM8903_USER_KEY 0x0002 /* USER_KEY */
1433#define WM8903_USER_KEY_MASK 0x0002 /* USER_KEY */
1434#define WM8903_USER_KEY_SHIFT 1 /* USER_KEY */
1435#define WM8903_USER_KEY_WIDTH 1 /* USER_KEY */
1436#define WM8903_TEST_KEY 0x0001 /* TEST_KEY */
1437#define WM8903_TEST_KEY_MASK 0x0001 /* TEST_KEY */
1438#define WM8903_TEST_KEY_SHIFT 0 /* TEST_KEY */
1439#define WM8903_TEST_KEY_WIDTH 1 /* TEST_KEY */
1440
1441/*
1442 * R149 (0x95) - Charge Pump Test 1
1443 */
1444#define WM8903_CP_SW_KELVIN_MODE_MASK 0x0006 /* CP_SW_KELVIN_MODE - [2:1] */
1445#define WM8903_CP_SW_KELVIN_MODE_SHIFT 1 /* CP_SW_KELVIN_MODE - [2:1] */
1446#define WM8903_CP_SW_KELVIN_MODE_WIDTH 2 /* CP_SW_KELVIN_MODE - [2:1] */
1447
1448/*
1449 * R164 (0xA4) - Clock Rate Test 4
1450 */
1451#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */
1452#define WM8903_ADC_DIG_MIC_MASK 0x0200 /* ADC_DIG_MIC */
1453#define WM8903_ADC_DIG_MIC_SHIFT 9 /* ADC_DIG_MIC */
1454#define WM8903_ADC_DIG_MIC_WIDTH 1 /* ADC_DIG_MIC */
1455
1456/*
1457 * R172 (0xAC) - Analogue Output Bias 0
1458 */
1459#define WM8903_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
1460#define WM8903_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
1461#define WM8903_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
1462
1463#endif
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
new file mode 100644
index 000000000000..f41a578ddd4f
--- /dev/null
+++ b/sound/soc/codecs/wm8971.c
@@ -0,0 +1,941 @@
1/*
2 * wm8971.c -- WM8971 ALSA SoC Audio driver
3 *
4 * Copyright 2005 Lab126, Inc.
5 *
6 * Author: Kenneth Kiraly <kiraly@lab126.com>
7 *
8 * Based on wm8753.c by Liam Girdwood
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/module.h>
17#include <linux/moduleparam.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/i2c.h>
22#include <linux/platform_device.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
30#include "wm8971.h"
31
32#define WM8971_VERSION "0.9"
33
34#define WM8971_REG_COUNT 43
35
36static struct workqueue_struct *wm8971_workq = NULL;
37
38/* codec private data */
39struct wm8971_priv {
40 unsigned int sysclk;
41};
42
43/*
44 * wm8971 register cache
45 * We can't read the WM8971 register space when we
46 * are using 2 wire for device control, so we cache them instead.
47 */
48static const u16 wm8971_reg[] = {
49 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */
50 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */
51 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */
52 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */
53 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */
54 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */
55 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
56 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
57 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */
58 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */
59 0x0079, 0x0079, 0x0079, /* 40 */
60};
61
62static inline unsigned int wm8971_read_reg_cache(struct snd_soc_codec *codec,
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
101/* WM8971 Controls */
102static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
103static const char *wm8971_bass_filter[] = { "130Hz @ 48kHz",
104 "200Hz @ 48kHz" };
105static const char *wm8971_treble[] = { "8kHz", "4kHz" };
106static const char *wm8971_alc_func[] = { "Off", "Right", "Left", "Stereo" };
107static const char *wm8971_ng_type[] = { "Constant PGA Gain",
108 "Mute ADC Output" };
109static const char *wm8971_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
110static const char *wm8971_mono_mux[] = {"Stereo", "Mono (Left)",
111 "Mono (Right)", "Digital Mono"};
112static const char *wm8971_dac_phase[] = { "Non Inverted", "Inverted" };
113static const char *wm8971_lline_mux[] = {"Line", "NC", "NC", "PGA",
114 "Differential"};
115static const char *wm8971_rline_mux[] = {"Line", "Mic", "NC", "PGA",
116 "Differential"};
117static const char *wm8971_lpga_sel[] = {"Line", "NC", "NC", "Differential"};
118static const char *wm8971_rpga_sel[] = {"Line", "Mic", "NC", "Differential"};
119static const char *wm8971_adcpol[] = {"Normal", "L Invert", "R Invert",
120 "L + R Invert"};
121
122static const struct soc_enum wm8971_enum[] = {
123 SOC_ENUM_SINGLE(WM8971_BASS, 7, 2, wm8971_bass), /* 0 */
124 SOC_ENUM_SINGLE(WM8971_BASS, 6, 2, wm8971_bass_filter),
125 SOC_ENUM_SINGLE(WM8971_TREBLE, 6, 2, wm8971_treble),
126 SOC_ENUM_SINGLE(WM8971_ALC1, 7, 4, wm8971_alc_func),
127 SOC_ENUM_SINGLE(WM8971_NGATE, 1, 2, wm8971_ng_type), /* 4 */
128 SOC_ENUM_SINGLE(WM8971_ADCDAC, 1, 4, wm8971_deemp),
129 SOC_ENUM_SINGLE(WM8971_ADCTL1, 4, 4, wm8971_mono_mux),
130 SOC_ENUM_SINGLE(WM8971_ADCTL1, 1, 2, wm8971_dac_phase),
131 SOC_ENUM_SINGLE(WM8971_LOUTM1, 0, 5, wm8971_lline_mux), /* 8 */
132 SOC_ENUM_SINGLE(WM8971_ROUTM1, 0, 5, wm8971_rline_mux),
133 SOC_ENUM_SINGLE(WM8971_LADCIN, 6, 4, wm8971_lpga_sel),
134 SOC_ENUM_SINGLE(WM8971_RADCIN, 6, 4, wm8971_rpga_sel),
135 SOC_ENUM_SINGLE(WM8971_ADCDAC, 5, 4, wm8971_adcpol), /* 12 */
136 SOC_ENUM_SINGLE(WM8971_ADCIN, 6, 4, wm8971_mono_mux),
137};
138
139static const struct snd_kcontrol_new wm8971_snd_controls[] = {
140 SOC_DOUBLE_R("Capture Volume", WM8971_LINVOL, WM8971_RINVOL, 0, 63, 0),
141 SOC_DOUBLE_R("Capture ZC Switch", WM8971_LINVOL, WM8971_RINVOL,
142 6, 1, 0),
143 SOC_DOUBLE_R("Capture Switch", WM8971_LINVOL, WM8971_RINVOL, 7, 1, 1),
144
145 SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8971_LOUT1V,
146 WM8971_ROUT1V, 7, 1, 0),
147 SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8971_LOUT2V,
148 WM8971_ROUT2V, 7, 1, 0),
149 SOC_SINGLE("Mono Playback ZC Switch", WM8971_MOUTV, 7, 1, 0),
150
151 SOC_DOUBLE_R("PCM Volume", WM8971_LDAC, WM8971_RDAC, 0, 255, 0),
152
153 SOC_DOUBLE_R("Bypass Left Playback Volume", WM8971_LOUTM1,
154 WM8971_LOUTM2, 4, 7, 1),
155 SOC_DOUBLE_R("Bypass Right Playback Volume", WM8971_ROUTM1,
156 WM8971_ROUTM2, 4, 7, 1),
157 SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8971_MOUTM1,
158 WM8971_MOUTM2, 4, 7, 1),
159
160 SOC_DOUBLE_R("Headphone Playback Volume", WM8971_LOUT1V,
161 WM8971_ROUT1V, 0, 127, 0),
162 SOC_DOUBLE_R("Speaker Playback Volume", WM8971_LOUT2V,
163 WM8971_ROUT2V, 0, 127, 0),
164
165 SOC_ENUM("Bass Boost", wm8971_enum[0]),
166 SOC_ENUM("Bass Filter", wm8971_enum[1]),
167 SOC_SINGLE("Bass Volume", WM8971_BASS, 0, 7, 1),
168
169 SOC_SINGLE("Treble Volume", WM8971_TREBLE, 0, 7, 0),
170 SOC_ENUM("Treble Cut-off", wm8971_enum[2]),
171
172 SOC_SINGLE("Capture Filter Switch", WM8971_ADCDAC, 0, 1, 1),
173
174 SOC_SINGLE("ALC Target Volume", WM8971_ALC1, 0, 7, 0),
175 SOC_SINGLE("ALC Max Volume", WM8971_ALC1, 4, 7, 0),
176
177 SOC_SINGLE("ALC Capture Target Volume", WM8971_ALC1, 0, 7, 0),
178 SOC_SINGLE("ALC Capture Max Volume", WM8971_ALC1, 4, 7, 0),
179 SOC_ENUM("ALC Capture Function", wm8971_enum[3]),
180 SOC_SINGLE("ALC Capture ZC Switch", WM8971_ALC2, 7, 1, 0),
181 SOC_SINGLE("ALC Capture Hold Time", WM8971_ALC2, 0, 15, 0),
182 SOC_SINGLE("ALC Capture Decay Time", WM8971_ALC3, 4, 15, 0),
183 SOC_SINGLE("ALC Capture Attack Time", WM8971_ALC3, 0, 15, 0),
184 SOC_SINGLE("ALC Capture NG Threshold", WM8971_NGATE, 3, 31, 0),
185 SOC_ENUM("ALC Capture NG Type", wm8971_enum[4]),
186 SOC_SINGLE("ALC Capture NG Switch", WM8971_NGATE, 0, 1, 0),
187
188 SOC_SINGLE("Capture 6dB Attenuate", WM8971_ADCDAC, 8, 1, 0),
189 SOC_SINGLE("Playback 6dB Attenuate", WM8971_ADCDAC, 7, 1, 0),
190
191 SOC_ENUM("Playback De-emphasis", wm8971_enum[5]),
192 SOC_ENUM("Playback Function", wm8971_enum[6]),
193 SOC_ENUM("Playback Phase", wm8971_enum[7]),
194
195 SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0),
196};
197
198/* add non-DAPM controls */
199static int wm8971_add_controls(struct snd_soc_codec *codec)
200{
201 int err, i;
202
203 for (i = 0; i < ARRAY_SIZE(wm8971_snd_controls); i++) {
204 err = snd_ctl_add(codec->card,
205 snd_soc_cnew(&wm8971_snd_controls[i],
206 codec, NULL));
207 if (err < 0)
208 return err;
209 }
210 return 0;
211}
212
213/*
214 * DAPM Controls
215 */
216
217/* Left Mixer */
218static const struct snd_kcontrol_new wm8971_left_mixer_controls[] = {
219SOC_DAPM_SINGLE("Playback Switch", WM8971_LOUTM1, 8, 1, 0),
220SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_LOUTM1, 7, 1, 0),
221SOC_DAPM_SINGLE("Right Playback Switch", WM8971_LOUTM2, 8, 1, 0),
222SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_LOUTM2, 7, 1, 0),
223};
224
225/* Right Mixer */
226static const struct snd_kcontrol_new wm8971_right_mixer_controls[] = {
227SOC_DAPM_SINGLE("Left Playback Switch", WM8971_ROUTM1, 8, 1, 0),
228SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_ROUTM1, 7, 1, 0),
229SOC_DAPM_SINGLE("Playback Switch", WM8971_ROUTM2, 8, 1, 0),
230SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_ROUTM2, 7, 1, 0),
231};
232
233/* Mono Mixer */
234static const struct snd_kcontrol_new wm8971_mono_mixer_controls[] = {
235SOC_DAPM_SINGLE("Left Playback Switch", WM8971_MOUTM1, 8, 1, 0),
236SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_MOUTM1, 7, 1, 0),
237SOC_DAPM_SINGLE("Right Playback Switch", WM8971_MOUTM2, 8, 1, 0),
238SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_MOUTM2, 7, 1, 0),
239};
240
241/* Left Line Mux */
242static const struct snd_kcontrol_new wm8971_left_line_controls =
243SOC_DAPM_ENUM("Route", wm8971_enum[8]);
244
245/* Right Line Mux */
246static const struct snd_kcontrol_new wm8971_right_line_controls =
247SOC_DAPM_ENUM("Route", wm8971_enum[9]);
248
249/* Left PGA Mux */
250static const struct snd_kcontrol_new wm8971_left_pga_controls =
251SOC_DAPM_ENUM("Route", wm8971_enum[10]);
252
253/* Right PGA Mux */
254static const struct snd_kcontrol_new wm8971_right_pga_controls =
255SOC_DAPM_ENUM("Route", wm8971_enum[11]);
256
257/* Mono ADC Mux */
258static const struct snd_kcontrol_new wm8971_monomux_controls =
259SOC_DAPM_ENUM("Route", wm8971_enum[13]);
260
261static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
262 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
263 &wm8971_left_mixer_controls[0],
264 ARRAY_SIZE(wm8971_left_mixer_controls)),
265 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
266 &wm8971_right_mixer_controls[0],
267 ARRAY_SIZE(wm8971_right_mixer_controls)),
268 SND_SOC_DAPM_MIXER("Mono Mixer", WM8971_PWR2, 2, 0,
269 &wm8971_mono_mixer_controls[0],
270 ARRAY_SIZE(wm8971_mono_mixer_controls)),
271
272 SND_SOC_DAPM_PGA("Right Out 2", WM8971_PWR2, 3, 0, NULL, 0),
273 SND_SOC_DAPM_PGA("Left Out 2", WM8971_PWR2, 4, 0, NULL, 0),
274 SND_SOC_DAPM_PGA("Right Out 1", WM8971_PWR2, 5, 0, NULL, 0),
275 SND_SOC_DAPM_PGA("Left Out 1", WM8971_PWR2, 6, 0, NULL, 0),
276 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8971_PWR2, 7, 0),
277 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8971_PWR2, 8, 0),
278 SND_SOC_DAPM_PGA("Mono Out 1", WM8971_PWR2, 2, 0, NULL, 0),
279
280 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8971_PWR1, 1, 0),
281 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8971_PWR1, 2, 0),
282 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8971_PWR1, 3, 0),
283
284 SND_SOC_DAPM_MUX("Left PGA Mux", WM8971_PWR1, 5, 0,
285 &wm8971_left_pga_controls),
286 SND_SOC_DAPM_MUX("Right PGA Mux", WM8971_PWR1, 4, 0,
287 &wm8971_right_pga_controls),
288 SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
289 &wm8971_left_line_controls),
290 SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
291 &wm8971_right_line_controls),
292
293 SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
294 &wm8971_monomux_controls),
295 SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
296 &wm8971_monomux_controls),
297
298 SND_SOC_DAPM_OUTPUT("LOUT1"),
299 SND_SOC_DAPM_OUTPUT("ROUT1"),
300 SND_SOC_DAPM_OUTPUT("LOUT2"),
301 SND_SOC_DAPM_OUTPUT("ROUT2"),
302 SND_SOC_DAPM_OUTPUT("MONO"),
303
304 SND_SOC_DAPM_INPUT("LINPUT1"),
305 SND_SOC_DAPM_INPUT("RINPUT1"),
306 SND_SOC_DAPM_INPUT("MIC"),
307};
308
309static const struct snd_soc_dapm_route audio_map[] = {
310 /* left mixer */
311 {"Left Mixer", "Playback Switch", "Left DAC"},
312 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
313 {"Left Mixer", "Right Playback Switch", "Right DAC"},
314 {"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
315
316 /* right mixer */
317 {"Right Mixer", "Left Playback Switch", "Left DAC"},
318 {"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
319 {"Right Mixer", "Playback Switch", "Right DAC"},
320 {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
321
322 /* left out 1 */
323 {"Left Out 1", NULL, "Left Mixer"},
324 {"LOUT1", NULL, "Left Out 1"},
325
326 /* left out 2 */
327 {"Left Out 2", NULL, "Left Mixer"},
328 {"LOUT2", NULL, "Left Out 2"},
329
330 /* right out 1 */
331 {"Right Out 1", NULL, "Right Mixer"},
332 {"ROUT1", NULL, "Right Out 1"},
333
334 /* right out 2 */
335 {"Right Out 2", NULL, "Right Mixer"},
336 {"ROUT2", NULL, "Right Out 2"},
337
338 /* mono mixer */
339 {"Mono Mixer", "Left Playback Switch", "Left DAC"},
340 {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
341 {"Mono Mixer", "Right Playback Switch", "Right DAC"},
342 {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
343
344 /* mono out */
345 {"Mono Out", NULL, "Mono Mixer"},
346 {"MONO1", NULL, "Mono Out"},
347
348 /* Left Line Mux */
349 {"Left Line Mux", "Line", "LINPUT1"},
350 {"Left Line Mux", "PGA", "Left PGA Mux"},
351 {"Left Line Mux", "Differential", "Differential Mux"},
352
353 /* Right Line Mux */
354 {"Right Line Mux", "Line", "RINPUT1"},
355 {"Right Line Mux", "Mic", "MIC"},
356 {"Right Line Mux", "PGA", "Right PGA Mux"},
357 {"Right Line Mux", "Differential", "Differential Mux"},
358
359 /* Left PGA Mux */
360 {"Left PGA Mux", "Line", "LINPUT1"},
361 {"Left PGA Mux", "Differential", "Differential Mux"},
362
363 /* Right PGA Mux */
364 {"Right PGA Mux", "Line", "RINPUT1"},
365 {"Right PGA Mux", "Differential", "Differential Mux"},
366
367 /* Differential Mux */
368 {"Differential Mux", "Line", "LINPUT1"},
369 {"Differential Mux", "Line", "RINPUT1"},
370
371 /* Left ADC Mux */
372 {"Left ADC Mux", "Stereo", "Left PGA Mux"},
373 {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
374 {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
375
376 /* Right ADC Mux */
377 {"Right ADC Mux", "Stereo", "Right PGA Mux"},
378 {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
379 {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
380
381 /* ADC */
382 {"Left ADC", NULL, "Left ADC Mux"},
383 {"Right ADC", NULL, "Right ADC Mux"},
384};
385
386static int wm8971_add_widgets(struct snd_soc_codec *codec)
387{
388 snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets,
389 ARRAY_SIZE(wm8971_dapm_widgets));
390
391 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
392
393 snd_soc_dapm_new_widgets(codec);
394
395 return 0;
396}
397
398struct _coeff_div {
399 u32 mclk;
400 u32 rate;
401 u16 fs;
402 u8 sr:5;
403 u8 usb:1;
404};
405
406/* codec hifi mclk clock divider coefficients */
407static const struct _coeff_div coeff_div[] = {
408 /* 8k */
409 {12288000, 8000, 1536, 0x6, 0x0},
410 {11289600, 8000, 1408, 0x16, 0x0},
411 {18432000, 8000, 2304, 0x7, 0x0},
412 {16934400, 8000, 2112, 0x17, 0x0},
413 {12000000, 8000, 1500, 0x6, 0x1},
414
415 /* 11.025k */
416 {11289600, 11025, 1024, 0x18, 0x0},
417 {16934400, 11025, 1536, 0x19, 0x0},
418 {12000000, 11025, 1088, 0x19, 0x1},
419
420 /* 16k */
421 {12288000, 16000, 768, 0xa, 0x0},
422 {18432000, 16000, 1152, 0xb, 0x0},
423 {12000000, 16000, 750, 0xa, 0x1},
424
425 /* 22.05k */
426 {11289600, 22050, 512, 0x1a, 0x0},
427 {16934400, 22050, 768, 0x1b, 0x0},
428 {12000000, 22050, 544, 0x1b, 0x1},
429
430 /* 32k */
431 {12288000, 32000, 384, 0xc, 0x0},
432 {18432000, 32000, 576, 0xd, 0x0},
433 {12000000, 32000, 375, 0xa, 0x1},
434
435 /* 44.1k */
436 {11289600, 44100, 256, 0x10, 0x0},
437 {16934400, 44100, 384, 0x11, 0x0},
438 {12000000, 44100, 272, 0x11, 0x1},
439
440 /* 48k */
441 {12288000, 48000, 256, 0x0, 0x0},
442 {18432000, 48000, 384, 0x1, 0x0},
443 {12000000, 48000, 250, 0x0, 0x1},
444
445 /* 88.2k */
446 {11289600, 88200, 128, 0x1e, 0x0},
447 {16934400, 88200, 192, 0x1f, 0x0},
448 {12000000, 88200, 136, 0x1f, 0x1},
449
450 /* 96k */
451 {12288000, 96000, 128, 0xe, 0x0},
452 {18432000, 96000, 192, 0xf, 0x0},
453 {12000000, 96000, 125, 0xe, 0x1},
454};
455
456static int get_coeff(int mclk, int rate)
457{
458 int i;
459
460 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
461 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
462 return i;
463 }
464 return -EINVAL;
465}
466
467static int wm8971_set_dai_sysclk(struct snd_soc_dai *codec_dai,
468 int clk_id, unsigned int freq, int dir)
469{
470 struct snd_soc_codec *codec = codec_dai->codec;
471 struct wm8971_priv *wm8971 = codec->private_data;
472
473 switch (freq) {
474 case 11289600:
475 case 12000000:
476 case 12288000:
477 case 16934400:
478 case 18432000:
479 wm8971->sysclk = freq;
480 return 0;
481 }
482 return -EINVAL;
483}
484
485static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
486 unsigned int fmt)
487{
488 struct snd_soc_codec *codec = codec_dai->codec;
489 u16 iface = 0;
490
491 /* set master/slave audio interface */
492 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
493 case SND_SOC_DAIFMT_CBM_CFM:
494 iface = 0x0040;
495 break;
496 case SND_SOC_DAIFMT_CBS_CFS:
497 break;
498 default:
499 return -EINVAL;
500 }
501
502 /* interface format */
503 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
504 case SND_SOC_DAIFMT_I2S:
505 iface |= 0x0002;
506 break;
507 case SND_SOC_DAIFMT_RIGHT_J:
508 break;
509 case SND_SOC_DAIFMT_LEFT_J:
510 iface |= 0x0001;
511 break;
512 case SND_SOC_DAIFMT_DSP_A:
513 iface |= 0x0003;
514 break;
515 case SND_SOC_DAIFMT_DSP_B:
516 iface |= 0x0013;
517 break;
518 default:
519 return -EINVAL;
520 }
521
522 /* clock inversion */
523 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
524 case SND_SOC_DAIFMT_NB_NF:
525 break;
526 case SND_SOC_DAIFMT_IB_IF:
527 iface |= 0x0090;
528 break;
529 case SND_SOC_DAIFMT_IB_NF:
530 iface |= 0x0080;
531 break;
532 case SND_SOC_DAIFMT_NB_IF:
533 iface |= 0x0010;
534 break;
535 default:
536 return -EINVAL;
537 }
538
539 wm8971_write(codec, WM8971_IFACE, iface);
540 return 0;
541}
542
543static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
544 struct snd_pcm_hw_params *params)
545{
546 struct snd_soc_pcm_runtime *rtd = substream->private_data;
547 struct snd_soc_device *socdev = rtd->socdev;
548 struct snd_soc_codec *codec = socdev->codec;
549 struct wm8971_priv *wm8971 = codec->private_data;
550 u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3;
551 u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0;
552 int coeff = get_coeff(wm8971->sysclk, params_rate(params));
553
554 /* bit size */
555 switch (params_format(params)) {
556 case SNDRV_PCM_FORMAT_S16_LE:
557 break;
558 case SNDRV_PCM_FORMAT_S20_3LE:
559 iface |= 0x0004;
560 break;
561 case SNDRV_PCM_FORMAT_S24_LE:
562 iface |= 0x0008;
563 break;
564 case SNDRV_PCM_FORMAT_S32_LE:
565 iface |= 0x000c;
566 break;
567 }
568
569 /* set iface & srate */
570 wm8971_write(codec, WM8971_IFACE, iface);
571 if (coeff >= 0)
572 wm8971_write(codec, WM8971_SRATE, srate |
573 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
574
575 return 0;
576}
577
578static int wm8971_mute(struct snd_soc_dai *dai, int mute)
579{
580 struct snd_soc_codec *codec = dai->codec;
581 u16 mute_reg = wm8971_read_reg_cache(codec, WM8971_ADCDAC) & 0xfff7;
582
583 if (mute)
584 wm8971_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
585 else
586 wm8971_write(codec, WM8971_ADCDAC, mute_reg);
587 return 0;
588}
589
590static int wm8971_set_bias_level(struct snd_soc_codec *codec,
591 enum snd_soc_bias_level level)
592{
593 u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
594
595 switch (level) {
596 case SND_SOC_BIAS_ON:
597 /* set vmid to 50k and unmute dac */
598 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
599 break;
600 case SND_SOC_BIAS_PREPARE:
601 break;
602 case SND_SOC_BIAS_STANDBY:
603 /* mute dac and set vmid to 500k, enable VREF */
604 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
605 break;
606 case SND_SOC_BIAS_OFF:
607 wm8971_write(codec, WM8971_PWR1, 0x0001);
608 break;
609 }
610 codec->bias_level = level;
611 return 0;
612}
613
614#define WM8971_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
615 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
616 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
617
618#define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
619 SNDRV_PCM_FMTBIT_S24_LE)
620
621struct snd_soc_dai wm8971_dai = {
622 .name = "WM8971",
623 .playback = {
624 .stream_name = "Playback",
625 .channels_min = 1,
626 .channels_max = 2,
627 .rates = WM8971_RATES,
628 .formats = WM8971_FORMATS,},
629 .capture = {
630 .stream_name = "Capture",
631 .channels_min = 1,
632 .channels_max = 2,
633 .rates = WM8971_RATES,
634 .formats = WM8971_FORMATS,},
635 .ops = {
636 .hw_params = wm8971_pcm_hw_params,
637 },
638 .dai_ops = {
639 .digital_mute = wm8971_mute,
640 .set_fmt = wm8971_set_dai_fmt,
641 .set_sysclk = wm8971_set_dai_sysclk,
642 },
643};
644EXPORT_SYMBOL_GPL(wm8971_dai);
645
646static void wm8971_work(struct work_struct *work)
647{
648 struct snd_soc_codec *codec =
649 container_of(work, struct snd_soc_codec, delayed_work.work);
650 wm8971_set_bias_level(codec, codec->bias_level);
651}
652
653static int wm8971_suspend(struct platform_device *pdev, pm_message_t state)
654{
655 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
656 struct snd_soc_codec *codec = socdev->codec;
657
658 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
659 return 0;
660}
661
662static int wm8971_resume(struct platform_device *pdev)
663{
664 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
665 struct snd_soc_codec *codec = socdev->codec;
666 int i;
667 u8 data[2];
668 u16 *cache = codec->reg_cache;
669 u16 reg;
670
671 /* Sync reg_cache with the hardware */
672 for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) {
673 if (i + 1 == WM8971_RESET)
674 continue;
675 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
676 data[1] = cache[i] & 0x00ff;
677 codec->hw_write(codec->control_data, data, 2);
678 }
679
680 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
681
682 /* charge wm8971 caps */
683 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
684 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
685 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0);
686 codec->bias_level = SND_SOC_BIAS_ON;
687 queue_delayed_work(wm8971_workq, &codec->delayed_work,
688 msecs_to_jiffies(1000));
689 }
690
691 return 0;
692}
693
694static int wm8971_init(struct snd_soc_device *socdev)
695{
696 struct snd_soc_codec *codec = socdev->codec;
697 int reg, ret = 0;
698
699 codec->name = "WM8971";
700 codec->owner = THIS_MODULE;
701 codec->read = wm8971_read_reg_cache;
702 codec->write = wm8971_write;
703 codec->set_bias_level = wm8971_set_bias_level;
704 codec->dai = &wm8971_dai;
705 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
706 codec->num_dai = 1;
707 codec->reg_cache = kmemdup(wm8971_reg, sizeof(wm8971_reg), GFP_KERNEL);
708
709 if (codec->reg_cache == NULL)
710 return -ENOMEM;
711
712 wm8971_reset(codec);
713
714 /* register pcms */
715 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
716 if (ret < 0) {
717 printk(KERN_ERR "wm8971: failed to create pcms\n");
718 goto pcm_err;
719 }
720
721 /* charge output caps - set vmid to 5k for quick power up */
722 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
723 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0);
724 codec->bias_level = SND_SOC_BIAS_STANDBY;
725 queue_delayed_work(wm8971_workq, &codec->delayed_work,
726 msecs_to_jiffies(1000));
727
728 /* set the update bits */
729 reg = wm8971_read_reg_cache(codec, WM8971_LDAC);
730 wm8971_write(codec, WM8971_LDAC, reg | 0x0100);
731 reg = wm8971_read_reg_cache(codec, WM8971_RDAC);
732 wm8971_write(codec, WM8971_RDAC, reg | 0x0100);
733
734 reg = wm8971_read_reg_cache(codec, WM8971_LOUT1V);
735 wm8971_write(codec, WM8971_LOUT1V, reg | 0x0100);
736 reg = wm8971_read_reg_cache(codec, WM8971_ROUT1V);
737 wm8971_write(codec, WM8971_ROUT1V, reg | 0x0100);
738
739 reg = wm8971_read_reg_cache(codec, WM8971_LOUT2V);
740 wm8971_write(codec, WM8971_LOUT2V, reg | 0x0100);
741 reg = wm8971_read_reg_cache(codec, WM8971_ROUT2V);
742 wm8971_write(codec, WM8971_ROUT2V, reg | 0x0100);
743
744 reg = wm8971_read_reg_cache(codec, WM8971_LINVOL);
745 wm8971_write(codec, WM8971_LINVOL, reg | 0x0100);
746 reg = wm8971_read_reg_cache(codec, WM8971_RINVOL);
747 wm8971_write(codec, WM8971_RINVOL, reg | 0x0100);
748
749 wm8971_add_controls(codec);
750 wm8971_add_widgets(codec);
751 ret = snd_soc_register_card(socdev);
752 if (ret < 0) {
753 printk(KERN_ERR "wm8971: failed to register card\n");
754 goto card_err;
755 }
756 return ret;
757
758card_err:
759 snd_soc_free_pcms(socdev);
760 snd_soc_dapm_free(socdev);
761pcm_err:
762 kfree(codec->reg_cache);
763 return ret;
764}
765
766/* If the i2c layer weren't so broken, we could pass this kind of data
767 around */
768static struct snd_soc_device *wm8971_socdev;
769
770#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
771
772static int wm8971_i2c_probe(struct i2c_client *i2c,
773 const struct i2c_device_id *id)
774{
775 struct snd_soc_device *socdev = wm8971_socdev;
776 struct snd_soc_codec *codec = socdev->codec;
777 int ret;
778
779 i2c_set_clientdata(i2c, codec);
780
781 codec->control_data = i2c;
782
783 ret = wm8971_init(socdev);
784 if (ret < 0)
785 pr_err("failed to initialise WM8971\n");
786
787 return ret;
788}
789
790static int wm8971_i2c_remove(struct i2c_client *client)
791{
792 struct snd_soc_codec *codec = i2c_get_clientdata(client);
793 kfree(codec->reg_cache);
794 return 0;
795}
796
797static const struct i2c_device_id wm8971_i2c_id[] = {
798 { "wm8971", 0 },
799 { }
800};
801MODULE_DEVICE_TABLE(i2c, wm8971_i2c_id);
802
803static struct i2c_driver wm8971_i2c_driver = {
804 .driver = {
805 .name = "WM8971 I2C Codec",
806 .owner = THIS_MODULE,
807 },
808 .probe = wm8971_i2c_probe,
809 .remove = wm8971_i2c_remove,
810 .id_table = wm8971_i2c_id,
811};
812
813static int wm8971_add_i2c_device(struct platform_device *pdev,
814 const struct wm8971_setup_data *setup)
815{
816 struct i2c_board_info info;
817 struct i2c_adapter *adapter;
818 struct i2c_client *client;
819 int ret;
820
821 ret = i2c_add_driver(&wm8971_i2c_driver);
822 if (ret != 0) {
823 dev_err(&pdev->dev, "can't add i2c driver\n");
824 return ret;
825 }
826
827 memset(&info, 0, sizeof(struct i2c_board_info));
828 info.addr = setup->i2c_address;
829 strlcpy(info.type, "wm8971", I2C_NAME_SIZE);
830
831 adapter = i2c_get_adapter(setup->i2c_bus);
832 if (!adapter) {
833 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
834 setup->i2c_bus);
835 goto err_driver;
836 }
837
838 client = i2c_new_device(adapter, &info);
839 i2c_put_adapter(adapter);
840 if (!client) {
841 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
842 (unsigned int)info.addr);
843 goto err_driver;
844 }
845
846 return 0;
847
848err_driver:
849 i2c_del_driver(&wm8971_i2c_driver);
850 return -ENODEV;
851}
852
853#endif
854
855static int wm8971_probe(struct platform_device *pdev)
856{
857 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
858 struct wm8971_setup_data *setup;
859 struct snd_soc_codec *codec;
860 struct wm8971_priv *wm8971;
861 int ret = 0;
862
863 pr_info("WM8971 Audio Codec %s", WM8971_VERSION);
864
865 setup = socdev->codec_data;
866 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
867 if (codec == NULL)
868 return -ENOMEM;
869
870 wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
871 if (wm8971 == NULL) {
872 kfree(codec);
873 return -ENOMEM;
874 }
875
876 codec->private_data = wm8971;
877 socdev->codec = codec;
878 mutex_init(&codec->mutex);
879 INIT_LIST_HEAD(&codec->dapm_widgets);
880 INIT_LIST_HEAD(&codec->dapm_paths);
881 wm8971_socdev = socdev;
882
883 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
884 wm8971_workq = create_workqueue("wm8971");
885 if (wm8971_workq == NULL) {
886 kfree(codec->private_data);
887 kfree(codec);
888 return -ENOMEM;
889 }
890
891#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
892 if (setup->i2c_address) {
893 codec->hw_write = (hw_write_t)i2c_master_send;
894 ret = wm8971_add_i2c_device(pdev, setup);
895 }
896#endif
897 /* Add other interfaces here */
898
899 if (ret != 0) {
900 destroy_workqueue(wm8971_workq);
901 kfree(codec->private_data);
902 kfree(codec);
903 }
904
905 return ret;
906}
907
908/* power down chip */
909static int wm8971_remove(struct platform_device *pdev)
910{
911 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
912 struct snd_soc_codec *codec = socdev->codec;
913
914 if (codec->control_data)
915 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
916 if (wm8971_workq)
917 destroy_workqueue(wm8971_workq);
918 snd_soc_free_pcms(socdev);
919 snd_soc_dapm_free(socdev);
920#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
921 i2c_unregister_device(codec->control_data);
922 i2c_del_driver(&wm8971_i2c_driver);
923#endif
924 kfree(codec->private_data);
925 kfree(codec);
926
927 return 0;
928}
929
930struct snd_soc_codec_device soc_codec_dev_wm8971 = {
931 .probe = wm8971_probe,
932 .remove = wm8971_remove,
933 .suspend = wm8971_suspend,
934 .resume = wm8971_resume,
935};
936
937EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
938
939MODULE_DESCRIPTION("ASoC WM8971 driver");
940MODULE_AUTHOR("Lab126");
941MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8971.h b/sound/soc/codecs/wm8971.h
new file mode 100644
index 000000000000..ef4f08f9f344
--- /dev/null
+++ b/sound/soc/codecs/wm8971.h
@@ -0,0 +1,64 @@
1/*
2 * wm8971.h -- audio driver for WM8971
3 *
4 * Copyright 2005 Lab126, Inc.
5 *
6 * Author: Kenneth Kiraly <kiraly@lab126.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef _WM8971_H
16#define _WM8971_H
17
18#define WM8971_LINVOL 0x00
19#define WM8971_RINVOL 0x01
20#define WM8971_LOUT1V 0x02
21#define WM8971_ROUT1V 0x03
22#define WM8971_ADCDAC 0x05
23#define WM8971_IFACE 0x07
24#define WM8971_SRATE 0x08
25#define WM8971_LDAC 0x0a
26#define WM8971_RDAC 0x0b
27#define WM8971_BASS 0x0c
28#define WM8971_TREBLE 0x0d
29#define WM8971_RESET 0x0f
30#define WM8971_ALC1 0x11
31#define WM8971_ALC2 0x12
32#define WM8971_ALC3 0x13
33#define WM8971_NGATE 0x14
34#define WM8971_LADC 0x15
35#define WM8971_RADC 0x16
36#define WM8971_ADCTL1 0x17
37#define WM8971_ADCTL2 0x18
38#define WM8971_PWR1 0x19
39#define WM8971_PWR2 0x1a
40#define WM8971_ADCTL3 0x1b
41#define WM8971_ADCIN 0x1f
42#define WM8971_LADCIN 0x20
43#define WM8971_RADCIN 0x21
44#define WM8971_LOUTM1 0x22
45#define WM8971_LOUTM2 0x23
46#define WM8971_ROUTM1 0x24
47#define WM8971_ROUTM2 0x25
48#define WM8971_MOUTM1 0x26
49#define WM8971_MOUTM2 0x27
50#define WM8971_LOUT2V 0x28
51#define WM8971_ROUT2V 0x29
52#define WM8971_MOUTV 0x2A
53
54#define WM8971_SYSCLK 0
55
56struct wm8971_setup_data {
57 int i2c_bus;
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8971_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8971;
63
64#endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index dd995ef448b4..572d22b0880b 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -30,7 +30,6 @@
30 30
31#include "wm8990.h" 31#include "wm8990.h"
32 32
33#define AUDIO_NAME "wm8990"
34#define WM8990_VERSION "0.2" 33#define WM8990_VERSION "0.2"
35 34
36/* codec private data */ 35/* codec private data */
@@ -1477,81 +1476,86 @@ static struct snd_soc_device *wm8990_socdev;
1477 * low = 0x34 1476 * low = 0x34
1478 * high = 0x36 1477 * high = 0x36
1479 */ 1478 */
1480static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1481 1479
1482/* Magic definition of all other variables and things */ 1480static int wm8990_i2c_probe(struct i2c_client *i2c,
1483I2C_CLIENT_INSMOD; 1481 const struct i2c_device_id *id)
1484
1485static struct i2c_driver wm8990_i2c_driver;
1486static struct i2c_client client_template;
1487
1488static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1489{ 1482{
1490 struct snd_soc_device *socdev = wm8990_socdev; 1483 struct snd_soc_device *socdev = wm8990_socdev;
1491 struct wm8990_setup_data *setup = socdev->codec_data;
1492 struct snd_soc_codec *codec = socdev->codec; 1484 struct snd_soc_codec *codec = socdev->codec;
1493 struct i2c_client *i2c;
1494 int ret; 1485 int ret;
1495 1486
1496 if (addr != setup->i2c_address)
1497 return -ENODEV;
1498
1499 client_template.adapter = adap;
1500 client_template.addr = addr;
1501
1502 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1503 if (i2c == NULL)
1504 return -ENOMEM;
1505
1506 i2c_set_clientdata(i2c, codec); 1487 i2c_set_clientdata(i2c, codec);
1507 codec->control_data = i2c; 1488 codec->control_data = i2c;
1508 1489
1509 ret = i2c_attach_client(i2c);
1510 if (ret < 0) {
1511 pr_err("failed to attach codec at addr %x\n", addr);
1512 goto err;
1513 }
1514
1515 ret = wm8990_init(socdev); 1490 ret = wm8990_init(socdev);
1516 if (ret < 0) { 1491 if (ret < 0)
1517 pr_err("failed to initialise WM8990\n"); 1492 pr_err("failed to initialise WM8990\n");
1518 goto err;
1519 }
1520 return ret;
1521 1493
1522err:
1523 kfree(i2c);
1524 return ret; 1494 return ret;
1525} 1495}
1526 1496
1527static int wm8990_i2c_detach(struct i2c_client *client) 1497static int wm8990_i2c_remove(struct i2c_client *client)
1528{ 1498{
1529 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1499 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1530 i2c_detach_client(client);
1531 kfree(codec->reg_cache); 1500 kfree(codec->reg_cache);
1532 kfree(client);
1533 return 0; 1501 return 0;
1534} 1502}
1535 1503
1536static int wm8990_i2c_attach(struct i2c_adapter *adap) 1504static const struct i2c_device_id wm8990_i2c_id[] = {
1537{ 1505 { "wm8990", 0 },
1538 return i2c_probe(adap, &addr_data, wm8990_codec_probe); 1506 { }
1539} 1507};
1508MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id);
1540 1509
1541static struct i2c_driver wm8990_i2c_driver = { 1510static struct i2c_driver wm8990_i2c_driver = {
1542 .driver = { 1511 .driver = {
1543 .name = "WM8990 I2C Codec", 1512 .name = "WM8990 I2C Codec",
1544 .owner = THIS_MODULE, 1513 .owner = THIS_MODULE,
1545 }, 1514 },
1546 .attach_adapter = wm8990_i2c_attach, 1515 .probe = wm8990_i2c_probe,
1547 .detach_client = wm8990_i2c_detach, 1516 .remove = wm8990_i2c_remove,
1548 .command = NULL, 1517 .id_table = wm8990_i2c_id,
1549}; 1518};
1550 1519
1551static struct i2c_client client_template = { 1520static int wm8990_add_i2c_device(struct platform_device *pdev,
1552 .name = "WM8990", 1521 const struct wm8990_setup_data *setup)
1553 .driver = &wm8990_i2c_driver, 1522{
1554}; 1523 struct i2c_board_info info;
1524 struct i2c_adapter *adapter;
1525 struct i2c_client *client;
1526 int ret;
1527
1528 ret = i2c_add_driver(&wm8990_i2c_driver);
1529 if (ret != 0) {
1530 dev_err(&pdev->dev, "can't add i2c driver\n");
1531 return ret;
1532 }
1533
1534 memset(&info, 0, sizeof(struct i2c_board_info));
1535 info.addr = setup->i2c_address;
1536 strlcpy(info.type, "wm8990", I2C_NAME_SIZE);
1537
1538 adapter = i2c_get_adapter(setup->i2c_bus);
1539 if (!adapter) {
1540 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1541 setup->i2c_bus);
1542 goto err_driver;
1543 }
1544
1545 client = i2c_new_device(adapter, &info);
1546 i2c_put_adapter(adapter);
1547 if (!client) {
1548 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1549 (unsigned int)info.addr);
1550 goto err_driver;
1551 }
1552
1553 return 0;
1554
1555err_driver:
1556 i2c_del_driver(&wm8990_i2c_driver);
1557 return -ENODEV;
1558}
1555#endif 1559#endif
1556 1560
1557static int wm8990_probe(struct platform_device *pdev) 1561static int wm8990_probe(struct platform_device *pdev)
@@ -1560,7 +1564,7 @@ static int wm8990_probe(struct platform_device *pdev)
1560 struct wm8990_setup_data *setup; 1564 struct wm8990_setup_data *setup;
1561 struct snd_soc_codec *codec; 1565 struct snd_soc_codec *codec;
1562 struct wm8990_priv *wm8990; 1566 struct wm8990_priv *wm8990;
1563 int ret = 0; 1567 int ret;
1564 1568
1565 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION); 1569 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION);
1566 1570
@@ -1582,16 +1586,13 @@ static int wm8990_probe(struct platform_device *pdev)
1582 INIT_LIST_HEAD(&codec->dapm_paths); 1586 INIT_LIST_HEAD(&codec->dapm_paths);
1583 wm8990_socdev = socdev; 1587 wm8990_socdev = socdev;
1584 1588
1589 ret = -ENODEV;
1590
1585#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1591#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1586 if (setup->i2c_address) { 1592 if (setup->i2c_address) {
1587 normal_i2c[0] = setup->i2c_address;
1588 codec->hw_write = (hw_write_t)i2c_master_send; 1593 codec->hw_write = (hw_write_t)i2c_master_send;
1589 ret = i2c_add_driver(&wm8990_i2c_driver); 1594 ret = wm8990_add_i2c_device(pdev, setup);
1590 if (ret != 0)
1591 printk(KERN_ERR "can't add i2c driver");
1592 } 1595 }
1593#else
1594 /* Add other interfaces here */
1595#endif 1596#endif
1596 1597
1597 if (ret != 0) { 1598 if (ret != 0) {
@@ -1612,6 +1613,7 @@ static int wm8990_remove(struct platform_device *pdev)
1612 snd_soc_free_pcms(socdev); 1613 snd_soc_free_pcms(socdev);
1613 snd_soc_dapm_free(socdev); 1614 snd_soc_dapm_free(socdev);
1614#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1615#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1616 i2c_unregister_device(codec->control_data);
1615 i2c_del_driver(&wm8990_i2c_driver); 1617 i2c_del_driver(&wm8990_i2c_driver);
1616#endif 1618#endif
1617 kfree(codec->private_data); 1619 kfree(codec->private_data);
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 0a08325d5443..0e192f3b0788 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -827,6 +827,7 @@
827#define WM8990_AINRMUX_PWR_BIT 3 827#define WM8990_AINRMUX_PWR_BIT 3
828 828
829struct wm8990_setup_data { 829struct wm8990_setup_data {
830 unsigned i2c_bus;
830 unsigned short i2c_address; 831 unsigned short i2c_address;
831}; 832};
832 833
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 2f1c91b1d556..ffb471e420e2 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -2,8 +2,7 @@
2 * wm9712.c -- ALSA Soc WM9712 codec support 2 * wm9712.c -- ALSA Soc WM9712 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 38d1fe0971fc..aba402b3c999 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -2,8 +2,7 @@
2 * wm9713.c -- ALSA Soc WM9713 codec support 2 * wm9713.c -- ALSA Soc WM9713 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -419,8 +418,12 @@ SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
419SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 418SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
420SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1), 419SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1),
421SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1), 420SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
422SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", AC97_EXTENDED_MID, 5, 1), 421SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
423SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", AC97_EXTENDED_MID, 4, 1), 422SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
423SND_SOC_DAPM_ADC("Left HiFi ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0),
424SND_SOC_DAPM_ADC("Right HiFi ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0),
425SND_SOC_DAPM_ADC("Left Voice ADC", "Left Voice Capture", SND_SOC_NOPM, 0, 0),
426SND_SOC_DAPM_ADC("Right Voice ADC", "Right Voice Capture", SND_SOC_NOPM, 0, 0),
424SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0), 427SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0),
425SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0), 428SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0),
426SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0), 429SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0),
@@ -583,9 +586,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
583 586
584 /* left ADC */ 587 /* left ADC */
585 {"Left ADC", NULL, "Left Capture Source"}, 588 {"Left ADC", NULL, "Left Capture Source"},
589 {"Left Voice ADC", NULL, "Left ADC"},
590 {"Left HiFi ADC", NULL, "Left ADC"},
586 591
587 /* right ADC */ 592 /* right ADC */
588 {"Right ADC", NULL, "Right Capture Source"}, 593 {"Right ADC", NULL, "Right Capture Source"},
594 {"Right Voice ADC", NULL, "Right ADC"},
595 {"Right HiFi ADC", NULL, "Right ADC"},
589 596
590 /* mic */ 597 /* mic */
591 {"Mic A Pre Amp", NULL, "Mic A Source"}, 598 {"Mic A Pre Amp", NULL, "Mic A Source"},
@@ -949,17 +956,17 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
949 956
950static void wm9713_voiceshutdown(struct snd_pcm_substream *substream) 957static void wm9713_voiceshutdown(struct snd_pcm_substream *substream)
951{ 958{
952 struct snd_soc_pcm_runtime *rtd = substream->private_data; 959 struct snd_soc_pcm_runtime *rtd = substream->private_data;
953 struct snd_soc_device *socdev = rtd->socdev; 960 struct snd_soc_device *socdev = rtd->socdev;
954 struct snd_soc_codec *codec = socdev->codec; 961 struct snd_soc_codec *codec = socdev->codec;
955 u16 status; 962 u16 status;
956 963
957 /* Gracefully shut down the voice interface. */ 964 /* Gracefully shut down the voice interface. */
958 status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000; 965 status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
959 ac97_write(codec, AC97_HANDSET_RATE, 0x0280); 966 ac97_write(codec, AC97_HANDSET_RATE, 0x0280);
960 schedule_timeout_interruptible(msecs_to_jiffies(1)); 967 schedule_timeout_interruptible(msecs_to_jiffies(1));
961 ac97_write(codec, AC97_HANDSET_RATE, 0x0F80); 968 ac97_write(codec, AC97_HANDSET_RATE, 0x0F80);
962 ac97_write(codec, AC97_EXTENDED_MID, status); 969 ac97_write(codec, AC97_EXTENDED_MID, status);
963} 970}
964 971
965static int ac97_hifi_prepare(struct snd_pcm_substream *substream) 972static int ac97_hifi_prepare(struct snd_pcm_substream *substream)