aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-08-16 00:32:24 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-08-16 00:32:24 -0400
commitbbcf6e8b66ab2fb5ddab4d0fe40c2e6a5ebe5301 (patch)
tree071fa9f86dc04a16570be367d04cff3b00c694ad /sound/soc/codecs
parent57682827b9a5edb52e33af0be9082b51bffcd5c7 (diff)
parentda5cabf80e2433131bf0ed8993abc0f7ea618c73 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: arch/sh/include/asm/Kbuild drivers/Makefile Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig20
-rw-r--r--sound/soc/codecs/Makefile6
-rw-r--r--sound/soc/codecs/ad1836.c1
-rw-r--r--sound/soc/codecs/ad193x.c41
-rw-r--r--sound/soc/codecs/ad193x.h5
-rw-r--r--sound/soc/codecs/ad1980.c10
-rw-r--r--sound/soc/codecs/ad1980.h6
-rw-r--r--sound/soc/codecs/ak4642.c36
-rw-r--r--sound/soc/codecs/cs42l51.c763
-rw-r--r--sound/soc/codecs/cs42l51.h163
-rw-r--r--sound/soc/codecs/da7210.c48
-rw-r--r--sound/soc/codecs/jz4740.c511
-rw-r--r--sound/soc/codecs/jz4740.h20
-rw-r--r--sound/soc/codecs/spdif_transciever.c94
-rw-r--r--sound/soc/codecs/spdif_transciever.h1
-rw-r--r--sound/soc/codecs/tlv320aic23.c7
-rw-r--r--sound/soc/codecs/tlv320dac33.c180
-rw-r--r--sound/soc/codecs/twl4030.c388
-rw-r--r--sound/soc/codecs/twl4030.h4
-rw-r--r--sound/soc/codecs/twl6040.c58
-rw-r--r--sound/soc/codecs/uda134x.c64
-rw-r--r--sound/soc/codecs/uda134x.h5
-rw-r--r--sound/soc/codecs/wm2000.c2
-rw-r--r--sound/soc/codecs/wm8523.c10
-rw-r--r--sound/soc/codecs/wm8580.c6
-rw-r--r--sound/soc/codecs/wm8711.c3
-rw-r--r--sound/soc/codecs/wm8741.c579
-rw-r--r--sound/soc/codecs/wm8741.h214
-rw-r--r--sound/soc/codecs/wm8750.c11
-rw-r--r--sound/soc/codecs/wm8904.c13
-rw-r--r--sound/soc/codecs/wm8940.c7
-rw-r--r--sound/soc/codecs/wm8955.c10
-rw-r--r--sound/soc/codecs/wm8960.c99
-rw-r--r--sound/soc/codecs/wm8961.c9
-rw-r--r--sound/soc/codecs/wm8974.c3
-rw-r--r--sound/soc/codecs/wm8978.c10
-rw-r--r--sound/soc/codecs/wm8990.c4
-rw-r--r--sound/soc/codecs/wm8994.c98
-rw-r--r--sound/soc/codecs/wm8994.h3
-rw-r--r--sound/soc/codecs/wm9081.c11
-rw-r--r--sound/soc/codecs/wm_hubs.c2
41 files changed, 3155 insertions, 370 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 5da30eb6ad00..83f5c67d3c41 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -22,9 +22,11 @@ config SND_SOC_ALL_CODECS
22 select SND_SOC_AK4642 if I2C 22 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C 23 select SND_SOC_AK4671 if I2C
24 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 24 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
25 select SND_SOC_CS42L51 if I2C
25 select SND_SOC_CS4270 if I2C 26 select SND_SOC_CS4270 if I2C
26 select SND_SOC_MAX9877 if I2C
27 select SND_SOC_DA7210 if I2C 27 select SND_SOC_DA7210 if I2C
28 select SND_SOC_JZ4740 if SOC_JZ4740
29 select SND_SOC_MAX9877 if I2C
28 select SND_SOC_PCM3008 30 select SND_SOC_PCM3008
29 select SND_SOC_SPDIF 31 select SND_SOC_SPDIF
30 select SND_SOC_SSM2602 if I2C 32 select SND_SOC_SSM2602 if I2C
@@ -48,6 +50,7 @@ config SND_SOC_ALL_CODECS
48 select SND_SOC_WM8727 50 select SND_SOC_WM8727
49 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 51 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
50 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 52 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
53 select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI
51 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 54 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
52 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI 55 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
53 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 56 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
@@ -120,13 +123,13 @@ config SND_SOC_AK4671
120config SND_SOC_CQ0093VC 123config SND_SOC_CQ0093VC
121 tristate 124 tristate
122 125
126config SND_SOC_CS42L51
127 tristate
128
123# Cirrus Logic CS4270 Codec 129# Cirrus Logic CS4270 Codec
124config SND_SOC_CS4270 130config SND_SOC_CS4270
125 tristate 131 tristate
126 132
127config SND_SOC_DA7210
128 tristate
129
130# Cirrus Logic CS4270 Codec VD = 3.3V Errata 133# Cirrus Logic CS4270 Codec VD = 3.3V Errata
131# Select if you are affected by the errata where the part will not function 134# Select if you are affected by the errata where the part will not function
132# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will 135# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
@@ -138,9 +141,15 @@ config SND_SOC_CS4270_VD33_ERRATA
138config SND_SOC_CX20442 141config SND_SOC_CX20442
139 tristate 142 tristate
140 143
144config SND_SOC_JZ4740_CODEC
145 tristate
146
141config SND_SOC_L3 147config SND_SOC_L3
142 tristate 148 tristate
143 149
150config SND_SOC_DA7210
151 tristate
152
144config SND_SOC_PCM3008 153config SND_SOC_PCM3008
145 tristate 154 tristate
146 155
@@ -206,6 +215,9 @@ config SND_SOC_WM8728
206config SND_SOC_WM8731 215config SND_SOC_WM8731
207 tristate 216 tristate
208 217
218config SND_SOC_WM8741
219 tristate
220
209config SND_SOC_WM8750 221config SND_SOC_WM8750
210 tristate 222 tristate
211 223
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 91429eab0707..53524095759c 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -9,6 +9,7 @@ snd-soc-ak4535-objs := ak4535.o
9snd-soc-ak4642-objs := ak4642.o 9snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o 10snd-soc-ak4671-objs := ak4671.o
11snd-soc-cq93vc-objs := cq93vc.o 11snd-soc-cq93vc-objs := cq93vc.o
12snd-soc-cs42l51-objs := cs42l51.o
12snd-soc-cs4270-objs := cs4270.o 13snd-soc-cs4270-objs := cs4270.o
13snd-soc-cx20442-objs := cx20442.o 14snd-soc-cx20442-objs := cx20442.o
14snd-soc-da7210-objs := da7210.o 15snd-soc-da7210-objs := da7210.o
@@ -34,6 +35,7 @@ snd-soc-wm8711-objs := wm8711.o
34snd-soc-wm8727-objs := wm8727.o 35snd-soc-wm8727-objs := wm8727.o
35snd-soc-wm8728-objs := wm8728.o 36snd-soc-wm8728-objs := wm8728.o
36snd-soc-wm8731-objs := wm8731.o 37snd-soc-wm8731-objs := wm8731.o
38snd-soc-wm8741-objs := wm8741.o
37snd-soc-wm8750-objs := wm8750.o 39snd-soc-wm8750-objs := wm8750.o
38snd-soc-wm8753-objs := wm8753.o 40snd-soc-wm8753-objs := wm8753.o
39snd-soc-wm8776-objs := wm8776.o 41snd-soc-wm8776-objs := wm8776.o
@@ -56,6 +58,7 @@ snd-soc-wm9705-objs := wm9705.o
56snd-soc-wm9712-objs := wm9712.o 58snd-soc-wm9712-objs := wm9712.o
57snd-soc-wm9713-objs := wm9713.o 59snd-soc-wm9713-objs := wm9713.o
58snd-soc-wm-hubs-objs := wm_hubs.o 60snd-soc-wm-hubs-objs := wm_hubs.o
61snd-soc-jz4740-codec-objs := jz4740.o
59 62
60# Amp 63# Amp
61snd-soc-max9877-objs := max9877.o 64snd-soc-max9877-objs := max9877.o
@@ -74,10 +77,12 @@ obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
74obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 77obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
75obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 78obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
76obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 79obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
80obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
77obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 81obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
78obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 82obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
79obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 83obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
80obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 84obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
85obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
81obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 86obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
82obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 87obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
83obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 88obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
@@ -99,6 +104,7 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
99obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o 104obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
100obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 105obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
101obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 106obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
107obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o
102obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 108obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
103obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 109obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
104obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 110obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 217538423225..a01006c8c606 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -272,6 +272,7 @@ static int ad1836_register(struct ad1836_priv *ad1836)
272 272
273 if (ad1836_codec) { 273 if (ad1836_codec) {
274 dev_err(codec->dev, "Another ad1836 is registered\n"); 274 dev_err(codec->dev, "Another ad1836 is registered\n");
275 kfree(ad1836);
275 return -EINVAL; 276 return -EINVAL;
276 } 277 }
277 278
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index c8ca1142b2f4..1def75e4862f 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -24,6 +24,7 @@
24 24
25/* codec private data */ 25/* codec private data */
26struct ad193x_priv { 26struct ad193x_priv {
27 unsigned int sysclk;
27 struct snd_soc_codec codec; 28 struct snd_soc_codec codec;
28 u8 reg_cache[AD193X_NUM_REGS]; 29 u8 reg_cache[AD193X_NUM_REGS];
29}; 30};
@@ -251,15 +252,32 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
251 return 0; 252 return 0;
252} 253}
253 254
255static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
256 int clk_id, unsigned int freq, int dir)
257{
258 struct snd_soc_codec *codec = codec_dai->codec;
259 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
260 switch (freq) {
261 case 12288000:
262 case 18432000:
263 case 24576000:
264 case 36864000:
265 ad193x->sysclk = freq;
266 return 0;
267 }
268 return -EINVAL;
269}
270
254static int ad193x_hw_params(struct snd_pcm_substream *substream, 271static int ad193x_hw_params(struct snd_pcm_substream *substream,
255 struct snd_pcm_hw_params *params, 272 struct snd_pcm_hw_params *params,
256 struct snd_soc_dai *dai) 273 struct snd_soc_dai *dai)
257{ 274{
258 int word_len = 0, reg = 0; 275 int word_len = 0, reg = 0, master_rate = 0;
259 276
260 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
261 struct snd_soc_device *socdev = rtd->socdev; 278 struct snd_soc_device *socdev = rtd->socdev;
262 struct snd_soc_codec *codec = socdev->card->codec; 279 struct snd_soc_codec *codec = socdev->card->codec;
280 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
263 281
264 /* bit size */ 282 /* bit size */
265 switch (params_format(params)) { 283 switch (params_format(params)) {
@@ -275,6 +293,25 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
275 break; 293 break;
276 } 294 }
277 295
296 switch (ad193x->sysclk) {
297 case 12288000:
298 master_rate = AD193X_PLL_INPUT_256;
299 break;
300 case 18432000:
301 master_rate = AD193X_PLL_INPUT_384;
302 break;
303 case 24576000:
304 master_rate = AD193X_PLL_INPUT_512;
305 break;
306 case 36864000:
307 master_rate = AD193X_PLL_INPUT_768;
308 break;
309 }
310
311 reg = snd_soc_read(codec, AD193X_PLL_CLK_CTRL0);
312 reg = (reg & AD193X_PLL_INPUT_MASK) | master_rate;
313 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
314
278 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 315 reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
279 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len; 316 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len;
280 snd_soc_write(codec, AD193X_DAC_CTRL2, reg); 317 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
@@ -348,6 +385,7 @@ static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
348 /* pll input: mclki/xi */ 385 /* pll input: mclki/xi */
349 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ 386 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
350 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04); 387 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
388 ad193x->sysclk = 12288000;
351 389
352 ret = snd_soc_register_codec(codec); 390 ret = snd_soc_register_codec(codec);
353 if (ret != 0) { 391 if (ret != 0) {
@@ -383,6 +421,7 @@ static struct snd_soc_dai_ops ad193x_dai_ops = {
383 .hw_params = ad193x_hw_params, 421 .hw_params = ad193x_hw_params,
384 .digital_mute = ad193x_mute, 422 .digital_mute = ad193x_mute,
385 .set_tdm_slot = ad193x_set_tdm_slot, 423 .set_tdm_slot = ad193x_set_tdm_slot,
424 .set_sysclk = ad193x_set_dai_sysclk,
386 .set_fmt = ad193x_set_dai_fmt, 425 .set_fmt = ad193x_set_dai_fmt,
387}; 426};
388 427
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index a03c880d52f9..654ba64ae04c 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -11,6 +11,11 @@
11 11
12#define AD193X_PLL_CLK_CTRL0 0x800 12#define AD193X_PLL_CLK_CTRL0 0x800
13#define AD193X_PLL_POWERDOWN 0x01 13#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_INPUT_MASK (~0x6)
15#define AD193X_PLL_INPUT_256 (0 << 1)
16#define AD193X_PLL_INPUT_384 (1 << 1)
17#define AD193X_PLL_INPUT_512 (2 << 1)
18#define AD193X_PLL_INPUT_768 (3 << 1)
14#define AD193X_PLL_CLK_CTRL1 0x801 19#define AD193X_PLL_CLK_CTRL1 0x801
15#define AD193X_DAC_CTRL0 0x802 20#define AD193X_DAC_CTRL0 0x802
16#define AD193X_DAC_POWERDOWN 0x01 21#define AD193X_DAC_POWERDOWN 0x01
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 042072738cdc..70cfaec3be2c 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -11,6 +11,14 @@
11 * option) any later version. 11 * option) any later version.
12 */ 12 */
13 13
14/*
15 * WARNING:
16 *
17 * Because Analog Devices Inc. discontinued the ad1980 sound chip since
18 * Sep. 2009, this ad1980 driver is not maintained, tested and supported
19 * by ADI now.
20 */
21
14#include <linux/init.h> 22#include <linux/init.h>
15#include <linux/slab.h> 23#include <linux/slab.h>
16#include <linux/module.h> 24#include <linux/module.h>
@@ -298,6 +306,6 @@ struct snd_soc_codec_device soc_codec_dev_ad1980 = {
298}; 306};
299EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980); 307EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980);
300 308
301MODULE_DESCRIPTION("ASoC ad1980 driver"); 309MODULE_DESCRIPTION("ASoC ad1980 driver (Obsolete)");
302MODULE_AUTHOR("Roy Huang, Cliff Cai"); 310MODULE_AUTHOR("Roy Huang, Cliff Cai");
303MODULE_LICENSE("GPL"); 311MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h
index db6c8500d66b..538f37c90806 100644
--- a/sound/soc/codecs/ad1980.h
+++ b/sound/soc/codecs/ad1980.h
@@ -1,5 +1,11 @@
1/* 1/*
2 * ad1980.h -- ad1980 Soc Audio driver 2 * ad1980.h -- ad1980 Soc Audio driver
3 *
4 * WARNING:
5 *
6 * Because Analog Devices Inc. discontinued the ad1980 sound chip since
7 * Sep. 2009, this ad1980 driver is not maintained, tested and supported
8 * by ADI now.
3 */ 9 */
4 10
5#ifndef _AD1980_H 11#ifndef _AD1980_H
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 7528a54102b5..3d7dc55305ec 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -22,20 +22,13 @@
22 * AK4643 is tested. 22 * AK4643 is tested.
23 */ 23 */
24 24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h> 25#include <linux/delay.h>
29#include <linux/pm.h>
30#include <linux/i2c.h> 26#include <linux/i2c.h>
31#include <linux/platform_device.h> 27#include <linux/platform_device.h>
32#include <linux/slab.h> 28#include <linux/slab.h>
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37#include <sound/soc-dapm.h> 29#include <sound/soc-dapm.h>
38#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/tlv.h>
39 32
40#include "ak4642.h" 33#include "ak4642.h"
41 34
@@ -111,6 +104,23 @@
111 104
112struct snd_soc_codec_device soc_codec_dev_ak4642; 105struct snd_soc_codec_device soc_codec_dev_ak4642;
113 106
107/*
108 * Playback Volume (table 39)
109 *
110 * max : 0x00 : +12.0 dB
111 * ( 0.5 dB step )
112 * min : 0xFE : -115.0 dB
113 * mute: 0xFF
114 */
115static const DECLARE_TLV_DB_SCALE(out_tlv, -11500, 50, 1);
116
117static const struct snd_kcontrol_new ak4642_snd_controls[] = {
118
119 SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
120 0, 0xFF, 1, out_tlv),
121};
122
123
114/* codec private data */ 124/* codec private data */
115struct ak4642_priv { 125struct ak4642_priv {
116 struct snd_soc_codec codec; 126 struct snd_soc_codec codec;
@@ -204,7 +214,6 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
204 * 214 *
205 * PLL, Master Mode 215 * PLL, Master Mode
206 * Audio I/F Format :MSB justified (ADC & DAC) 216 * Audio I/F Format :MSB justified (ADC & DAC)
207 * Digital Volume: -8dB
208 * Bass Boost Level : Middle 217 * Bass Boost Level : Middle
209 * 218 *
210 * This operation came from example code of 219 * This operation came from example code of
@@ -214,8 +223,6 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
214 ak4642_write(codec, 0x0e, 0x19); 223 ak4642_write(codec, 0x0e, 0x19);
215 ak4642_write(codec, 0x09, 0x91); 224 ak4642_write(codec, 0x09, 0x91);
216 ak4642_write(codec, 0x0c, 0x91); 225 ak4642_write(codec, 0x0c, 0x91);
217 ak4642_write(codec, 0x0a, 0x28);
218 ak4642_write(codec, 0x0d, 0x28);
219 ak4642_write(codec, 0x00, 0x64); 226 ak4642_write(codec, 0x00, 0x64);
220 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); 227 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
221 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN); 228 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
@@ -491,8 +498,10 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
491 codec->control_data = i2c; 498 codec->control_data = i2c;
492 499
493 ret = ak4642_init(ak4642); 500 ret = ak4642_init(ak4642);
494 if (ret < 0) 501 if (ret < 0) {
495 printk(KERN_ERR "failed to initialise AK4642\n"); 502 printk(KERN_ERR "failed to initialise AK4642\n");
503 kfree(ak4642);
504 }
496 505
497 return ret; 506 return ret;
498} 507}
@@ -548,6 +557,9 @@ static int ak4642_probe(struct platform_device *pdev)
548 goto pcm_err; 557 goto pcm_err;
549 } 558 }
550 559
560 snd_soc_add_controls(ak4642_codec, ak4642_snd_controls,
561 ARRAY_SIZE(ak4642_snd_controls));
562
551 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 563 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
552 return ret; 564 return ret;
553 565
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
new file mode 100644
index 000000000000..dd9b8550c402
--- /dev/null
+++ b/sound/soc/codecs/cs42l51.c
@@ -0,0 +1,763 @@
1/*
2 * cs42l51.c
3 *
4 * ASoC Driver for Cirrus Logic CS42L51 codecs
5 *
6 * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>
7 *
8 * Based on cs4270.c - Copyright (c) Freescale Semiconductor
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * For now:
20 * - Only I2C is support. Not SPI
21 * - master mode *NOT* supported
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/slab.h>
27#include <sound/core.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/tlv.h>
31#include <sound/initval.h>
32#include <sound/pcm_params.h>
33#include <sound/pcm.h>
34#include <linux/i2c.h>
35
36#include "cs42l51.h"
37
38enum master_slave_mode {
39 MODE_SLAVE,
40 MODE_SLAVE_AUTO,
41 MODE_MASTER,
42};
43
44struct cs42l51_private {
45 unsigned int mclk;
46 unsigned int audio_mode; /* The mode (I2S or left-justified) */
47 enum master_slave_mode func;
48 struct snd_soc_codec codec;
49 u8 reg_cache[CS42L51_NUMREGS];
50};
51
52static struct snd_soc_codec *cs42l51_codec;
53
54#define CS42L51_FORMATS ( \
55 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
56 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
57 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
58 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
59
60static int cs42l51_fill_cache(struct snd_soc_codec *codec)
61{
62 u8 *cache = codec->reg_cache + 1;
63 struct i2c_client *i2c_client = codec->control_data;
64 s32 length;
65
66 length = i2c_smbus_read_i2c_block_data(i2c_client,
67 CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
68 if (length != CS42L51_NUMREGS) {
69 dev_err(&i2c_client->dev,
70 "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
71 i2c_client->addr, length, CS42L51_NUMREGS);
72 return -EIO;
73 }
74
75 return 0;
76}
77
78static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
79 const struct i2c_device_id *id)
80{
81 struct snd_soc_codec *codec;
82 struct cs42l51_private *cs42l51;
83 int ret = 0;
84 int reg;
85
86 if (cs42l51_codec)
87 return -EBUSY;
88
89 /* Verify that we have a CS42L51 */
90 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
91 if (ret < 0) {
92 dev_err(&i2c_client->dev, "failed to read I2C\n");
93 goto error;
94 }
95
96 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
97 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
98 dev_err(&i2c_client->dev, "Invalid chip id\n");
99 ret = -ENODEV;
100 goto error;
101 }
102
103 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
104 ret & 7);
105
106 cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
107 if (!cs42l51) {
108 dev_err(&i2c_client->dev, "could not allocate codec\n");
109 return -ENOMEM;
110 }
111 codec = &cs42l51->codec;
112
113 mutex_init(&codec->mutex);
114 INIT_LIST_HEAD(&codec->dapm_widgets);
115 INIT_LIST_HEAD(&codec->dapm_paths);
116
117 codec->dev = &i2c_client->dev;
118 codec->name = "CS42L51";
119 codec->owner = THIS_MODULE;
120 codec->dai = &cs42l51_dai;
121 codec->num_dai = 1;
122 snd_soc_codec_set_drvdata(codec, cs42l51);
123
124 codec->control_data = i2c_client;
125 codec->reg_cache = cs42l51->reg_cache;
126 codec->reg_cache_size = CS42L51_NUMREGS;
127 i2c_set_clientdata(i2c_client, codec);
128
129 ret = cs42l51_fill_cache(codec);
130 if (ret < 0) {
131 dev_err(&i2c_client->dev, "failed to fill register cache\n");
132 goto error_alloc;
133 }
134
135 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
136 if (ret < 0) {
137 dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
138 goto error_alloc;
139 }
140
141 /*
142 * DAC configuration
143 * - Use signal processor
144 * - auto mute
145 * - vol changes immediate
146 * - no de-emphasize
147 */
148 reg = CS42L51_DAC_CTL_DATA_SEL(1)
149 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
150 ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
151 if (ret < 0)
152 goto error_alloc;
153
154 cs42l51_dai.dev = codec->dev;
155 cs42l51_codec = codec;
156
157 ret = snd_soc_register_codec(codec);
158 if (ret != 0) {
159 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
160 goto error_alloc;
161 }
162
163 ret = snd_soc_register_dai(&cs42l51_dai);
164 if (ret < 0) {
165 dev_err(&i2c_client->dev, "failed to register DAIe\n");
166 goto error_reg;
167 }
168
169 return 0;
170
171error_reg:
172 snd_soc_unregister_codec(codec);
173error_alloc:
174 kfree(cs42l51);
175error:
176 return ret;
177}
178
179static int cs42l51_i2c_remove(struct i2c_client *client)
180{
181 struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
182 snd_soc_unregister_dai(&cs42l51_dai);
183 snd_soc_unregister_codec(cs42l51_codec);
184 cs42l51_codec = NULL;
185 kfree(cs42l51);
186 return 0;
187}
188
189
190static const struct i2c_device_id cs42l51_id[] = {
191 {"cs42l51", 0},
192 {}
193};
194MODULE_DEVICE_TABLE(i2c, cs42l51_id);
195
196static struct i2c_driver cs42l51_i2c_driver = {
197 .driver = {
198 .name = "CS42L51 I2C",
199 .owner = THIS_MODULE,
200 },
201 .id_table = cs42l51_id,
202 .probe = cs42l51_i2c_probe,
203 .remove = cs42l51_i2c_remove,
204};
205
206static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol)
208{
209 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
210 unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;
211
212 switch (value) {
213 default:
214 case 0:
215 ucontrol->value.integer.value[0] = 0;
216 break;
217 /* same value : (L+R)/2 and (R+L)/2 */
218 case 1:
219 case 2:
220 ucontrol->value.integer.value[0] = 1;
221 break;
222 case 3:
223 ucontrol->value.integer.value[0] = 2;
224 break;
225 }
226
227 return 0;
228}
229
230#define CHAN_MIX_NORMAL 0x00
231#define CHAN_MIX_BOTH 0x55
232#define CHAN_MIX_SWAP 0xFF
233
234static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
235 struct snd_ctl_elem_value *ucontrol)
236{
237 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
238 unsigned char val;
239
240 switch (ucontrol->value.integer.value[0]) {
241 default:
242 case 0:
243 val = CHAN_MIX_NORMAL;
244 break;
245 case 1:
246 val = CHAN_MIX_BOTH;
247 break;
248 case 2:
249 val = CHAN_MIX_SWAP;
250 break;
251 }
252
253 snd_soc_write(codec, CS42L51_PCM_MIXER, val);
254
255 return 1;
256}
257
258static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0);
259static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
260/* This is a lie. after -102 db, it stays at -102 */
261/* maybe a range would be better */
262static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0);
263
264static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);
265static const char *chan_mix[] = {
266 "L R",
267 "L+R",
268 "R L",
269};
270
271static const struct soc_enum cs42l51_chan_mix =
272 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chan_mix), chan_mix);
273
274static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
275 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
276 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
277 7, 0xffffff99, 0x18, adc_pcm_tlv),
278 SOC_DOUBLE_R("PCM Playback Switch",
279 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
280 SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
281 CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,
282 8, 0xffffff19, 0x18, aout_tlv),
283 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
284 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
285 7, 0xffffff99, 0x18, adc_pcm_tlv),
286 SOC_DOUBLE_R("ADC Mixer Switch",
287 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
288 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
289 SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
290 SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
291 SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0),
292 SOC_DOUBLE_TLV("Mic Boost Volume",
293 CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv),
294 SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv),
295 SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv),
296 SOC_ENUM_EXT("PCM channel mixer",
297 cs42l51_chan_mix,
298 cs42l51_get_chan_mix, cs42l51_set_chan_mix),
299};
300
301/*
302 * to power down, one must:
303 * 1.) Enable the PDN bit
304 * 2.) enable power-down for the select channels
305 * 3.) disable the PDN bit.
306 */
307static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
308 struct snd_kcontrol *kcontrol, int event)
309{
310 unsigned long value;
311
312 value = snd_soc_read(w->codec, CS42L51_POWER_CTL1);
313 value &= ~CS42L51_POWER_CTL1_PDN;
314
315 switch (event) {
316 case SND_SOC_DAPM_PRE_PMD:
317 value |= CS42L51_POWER_CTL1_PDN;
318 break;
319 default:
320 case SND_SOC_DAPM_POST_PMD:
321 break;
322 }
323 snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
324 CS42L51_POWER_CTL1_PDN, value);
325
326 return 0;
327}
328
329static const char *cs42l51_dac_names[] = {"Direct PCM",
330 "DSP PCM", "ADC"};
331static const struct soc_enum cs42l51_dac_mux_enum =
332 SOC_ENUM_SINGLE(CS42L51_DAC_CTL, 6, 3, cs42l51_dac_names);
333static const struct snd_kcontrol_new cs42l51_dac_mux_controls =
334 SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum);
335
336static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left",
337 "MIC Left", "MIC+preamp Left"};
338static const struct soc_enum cs42l51_adcl_mux_enum =
339 SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 4, 4, cs42l51_adcl_names);
340static const struct snd_kcontrol_new cs42l51_adcl_mux_controls =
341 SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum);
342
343static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right",
344 "MIC Right", "MIC+preamp Right"};
345static const struct soc_enum cs42l51_adcr_mux_enum =
346 SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 6, 4, cs42l51_adcr_names);
347static const struct snd_kcontrol_new cs42l51_adcr_mux_controls =
348 SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum);
349
350static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {
351 SND_SOC_DAPM_MICBIAS("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1),
352 SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0,
353 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
354 SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0,
355 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
356 SND_SOC_DAPM_ADC_E("Left ADC", "Left HiFi Capture",
357 CS42L51_POWER_CTL1, 1, 1,
358 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
359 SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture",
360 CS42L51_POWER_CTL1, 2, 1,
361 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
362 SND_SOC_DAPM_DAC_E("Left DAC", "Left HiFi Playback",
363 CS42L51_POWER_CTL1, 5, 1,
364 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
365 SND_SOC_DAPM_DAC_E("Right DAC", "Right HiFi Playback",
366 CS42L51_POWER_CTL1, 6, 1,
367 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
368
369 /* analog/mic */
370 SND_SOC_DAPM_INPUT("AIN1L"),
371 SND_SOC_DAPM_INPUT("AIN1R"),
372 SND_SOC_DAPM_INPUT("AIN2L"),
373 SND_SOC_DAPM_INPUT("AIN2R"),
374 SND_SOC_DAPM_INPUT("MICL"),
375 SND_SOC_DAPM_INPUT("MICR"),
376
377 SND_SOC_DAPM_MIXER("Mic Preamp Left",
378 CS42L51_MIC_POWER_CTL, 2, 1, NULL, 0),
379 SND_SOC_DAPM_MIXER("Mic Preamp Right",
380 CS42L51_MIC_POWER_CTL, 3, 1, NULL, 0),
381
382 /* HP */
383 SND_SOC_DAPM_OUTPUT("HPL"),
384 SND_SOC_DAPM_OUTPUT("HPR"),
385
386 /* mux */
387 SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0,
388 &cs42l51_dac_mux_controls),
389 SND_SOC_DAPM_MUX("PGA-ADC Mux Left", SND_SOC_NOPM, 0, 0,
390 &cs42l51_adcl_mux_controls),
391 SND_SOC_DAPM_MUX("PGA-ADC Mux Right", SND_SOC_NOPM, 0, 0,
392 &cs42l51_adcr_mux_controls),
393};
394
395static const struct snd_soc_dapm_route cs42l51_routes[] = {
396 {"HPL", NULL, "Left DAC"},
397 {"HPR", NULL, "Right DAC"},
398
399 {"Left ADC", NULL, "Left PGA"},
400 {"Right ADC", NULL, "Right PGA"},
401
402 {"Mic Preamp Left", NULL, "MICL"},
403 {"Mic Preamp Right", NULL, "MICR"},
404
405 {"PGA-ADC Mux Left", "AIN1 Left", "AIN1L" },
406 {"PGA-ADC Mux Left", "AIN2 Left", "AIN2L" },
407 {"PGA-ADC Mux Left", "MIC Left", "MICL" },
408 {"PGA-ADC Mux Left", "MIC+preamp Left", "Mic Preamp Left" },
409 {"PGA-ADC Mux Right", "AIN1 Right", "AIN1R" },
410 {"PGA-ADC Mux Right", "AIN2 Right", "AIN2R" },
411 {"PGA-ADC Mux Right", "MIC Right", "MICR" },
412 {"PGA-ADC Mux Right", "MIC+preamp Right", "Mic Preamp Right" },
413
414 {"Left PGA", NULL, "PGA-ADC Mux Left"},
415 {"Right PGA", NULL, "PGA-ADC Mux Right"},
416};
417
418static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
419 unsigned int format)
420{
421 struct snd_soc_codec *codec = codec_dai->codec;
422 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
423 int ret = 0;
424
425 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
426 case SND_SOC_DAIFMT_I2S:
427 case SND_SOC_DAIFMT_LEFT_J:
428 case SND_SOC_DAIFMT_RIGHT_J:
429 cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
430 break;
431 default:
432 dev_err(codec->dev, "invalid DAI format\n");
433 ret = -EINVAL;
434 }
435
436 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
437 case SND_SOC_DAIFMT_CBM_CFM:
438 cs42l51->func = MODE_MASTER;
439 break;
440 case SND_SOC_DAIFMT_CBS_CFS:
441 cs42l51->func = MODE_SLAVE_AUTO;
442 break;
443 default:
444 ret = -EINVAL;
445 break;
446 }
447
448 return ret;
449}
450
451struct cs42l51_ratios {
452 unsigned int ratio;
453 unsigned char speed_mode;
454 unsigned char mclk;
455};
456
457static struct cs42l51_ratios slave_ratios[] = {
458 { 512, CS42L51_QSM_MODE, 0 }, { 768, CS42L51_QSM_MODE, 0 },
459 { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
460 { 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 },
461 { 256, CS42L51_HSM_MODE, 0 }, { 384, CS42L51_HSM_MODE, 0 },
462 { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 },
463 { 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 },
464 { 128, CS42L51_SSM_MODE, 0 }, { 192, CS42L51_SSM_MODE, 0 },
465 { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 },
466 { 512, CS42L51_SSM_MODE, 0 }, { 768, CS42L51_SSM_MODE, 0 },
467 { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 },
468 { 256, CS42L51_DSM_MODE, 0 }, { 384, CS42L51_DSM_MODE, 0 },
469};
470
471static struct cs42l51_ratios slave_auto_ratios[] = {
472 { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
473 { 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 },
474 { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 },
475 { 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 },
476 { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 },
477 { 512, CS42L51_SSM_MODE, 1 }, { 768, CS42L51_SSM_MODE, 1 },
478 { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 },
479 { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 },
480};
481
482static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
483 int clk_id, unsigned int freq, int dir)
484{
485 struct snd_soc_codec *codec = codec_dai->codec;
486 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
487 struct cs42l51_ratios *ratios = NULL;
488 int nr_ratios = 0;
489 unsigned int rates = 0;
490 unsigned int rate_min = -1;
491 unsigned int rate_max = 0;
492 int i;
493
494 cs42l51->mclk = freq;
495
496 switch (cs42l51->func) {
497 case MODE_MASTER:
498 return -EINVAL;
499 case MODE_SLAVE:
500 ratios = slave_ratios;
501 nr_ratios = ARRAY_SIZE(slave_ratios);
502 break;
503 case MODE_SLAVE_AUTO:
504 ratios = slave_auto_ratios;
505 nr_ratios = ARRAY_SIZE(slave_auto_ratios);
506 break;
507 }
508
509 for (i = 0; i < nr_ratios; i++) {
510 unsigned int rate = freq / ratios[i].ratio;
511 rates |= snd_pcm_rate_to_rate_bit(rate);
512 if (rate < rate_min)
513 rate_min = rate;
514 if (rate > rate_max)
515 rate_max = rate;
516 }
517 rates &= ~SNDRV_PCM_RATE_KNOT;
518
519 if (!rates) {
520 dev_err(codec->dev, "could not find a valid sample rate\n");
521 return -EINVAL;
522 }
523
524 codec_dai->playback.rates = rates;
525 codec_dai->playback.rate_min = rate_min;
526 codec_dai->playback.rate_max = rate_max;
527
528 codec_dai->capture.rates = rates;
529 codec_dai->capture.rate_min = rate_min;
530 codec_dai->capture.rate_max = rate_max;
531
532 return 0;
533}
534
535static int cs42l51_hw_params(struct snd_pcm_substream *substream,
536 struct snd_pcm_hw_params *params,
537 struct snd_soc_dai *dai)
538{
539 struct snd_soc_pcm_runtime *rtd = substream->private_data;
540 struct snd_soc_device *socdev = rtd->socdev;
541 struct snd_soc_codec *codec = socdev->card->codec;
542 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
543 int ret;
544 unsigned int i;
545 unsigned int rate;
546 unsigned int ratio;
547 struct cs42l51_ratios *ratios = NULL;
548 int nr_ratios = 0;
549 int intf_ctl, power_ctl, fmt;
550
551 switch (cs42l51->func) {
552 case MODE_MASTER:
553 return -EINVAL;
554 case MODE_SLAVE:
555 ratios = slave_ratios;
556 nr_ratios = ARRAY_SIZE(slave_ratios);
557 break;
558 case MODE_SLAVE_AUTO:
559 ratios = slave_auto_ratios;
560 nr_ratios = ARRAY_SIZE(slave_auto_ratios);
561 break;
562 }
563
564 /* Figure out which MCLK/LRCK ratio to use */
565 rate = params_rate(params); /* Sampling rate, in Hz */
566 ratio = cs42l51->mclk / rate; /* MCLK/LRCK ratio */
567 for (i = 0; i < nr_ratios; i++) {
568 if (ratios[i].ratio == ratio)
569 break;
570 }
571
572 if (i == nr_ratios) {
573 /* We did not find a matching ratio */
574 dev_err(codec->dev, "could not find matching ratio\n");
575 return -EINVAL;
576 }
577
578 intf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL);
579 power_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL);
580
581 intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
582 | CS42L51_INTF_CTL_DAC_FORMAT(7));
583 power_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3)
584 | CS42L51_MIC_POWER_CTL_MCLK_DIV2);
585
586 switch (cs42l51->func) {
587 case MODE_MASTER:
588 intf_ctl |= CS42L51_INTF_CTL_MASTER;
589 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
590 break;
591 case MODE_SLAVE:
592 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
593 break;
594 case MODE_SLAVE_AUTO:
595 power_ctl |= CS42L51_MIC_POWER_CTL_AUTO;
596 break;
597 }
598
599 switch (cs42l51->audio_mode) {
600 case SND_SOC_DAIFMT_I2S:
601 intf_ctl |= CS42L51_INTF_CTL_ADC_I2S;
602 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S);
603 break;
604 case SND_SOC_DAIFMT_LEFT_J:
605 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);
606 break;
607 case SND_SOC_DAIFMT_RIGHT_J:
608 switch (params_format(params)) {
609 case SNDRV_PCM_FORMAT_S16_LE:
610 case SNDRV_PCM_FORMAT_S16_BE:
611 fmt = CS42L51_DAC_DIF_RJ16;
612 break;
613 case SNDRV_PCM_FORMAT_S18_3LE:
614 case SNDRV_PCM_FORMAT_S18_3BE:
615 fmt = CS42L51_DAC_DIF_RJ18;
616 break;
617 case SNDRV_PCM_FORMAT_S20_3LE:
618 case SNDRV_PCM_FORMAT_S20_3BE:
619 fmt = CS42L51_DAC_DIF_RJ20;
620 break;
621 case SNDRV_PCM_FORMAT_S24_LE:
622 case SNDRV_PCM_FORMAT_S24_BE:
623 fmt = CS42L51_DAC_DIF_RJ24;
624 break;
625 default:
626 dev_err(codec->dev, "unknown format\n");
627 return -EINVAL;
628 }
629 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);
630 break;
631 default:
632 dev_err(codec->dev, "unknown format\n");
633 return -EINVAL;
634 }
635
636 if (ratios[i].mclk)
637 power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;
638
639 ret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl);
640 if (ret < 0)
641 return ret;
642
643 ret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl);
644 if (ret < 0)
645 return ret;
646
647 return 0;
648}
649
650static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
651{
652 struct snd_soc_codec *codec = dai->codec;
653 int reg;
654 int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
655
656 reg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL);
657
658 if (mute)
659 reg |= mask;
660 else
661 reg &= ~mask;
662
663 return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
664}
665
666static struct snd_soc_dai_ops cs42l51_dai_ops = {
667 .hw_params = cs42l51_hw_params,
668 .set_sysclk = cs42l51_set_dai_sysclk,
669 .set_fmt = cs42l51_set_dai_fmt,
670 .digital_mute = cs42l51_dai_mute,
671};
672
673struct snd_soc_dai cs42l51_dai = {
674 .name = "CS42L51 HiFi",
675 .playback = {
676 .stream_name = "Playback",
677 .channels_min = 1,
678 .channels_max = 2,
679 .rates = SNDRV_PCM_RATE_8000_96000,
680 .formats = CS42L51_FORMATS,
681 },
682 .capture = {
683 .stream_name = "Capture",
684 .channels_min = 1,
685 .channels_max = 2,
686 .rates = SNDRV_PCM_RATE_8000_96000,
687 .formats = CS42L51_FORMATS,
688 },
689 .ops = &cs42l51_dai_ops,
690};
691EXPORT_SYMBOL_GPL(cs42l51_dai);
692
693
694static int cs42l51_probe(struct platform_device *pdev)
695{
696 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
697 struct snd_soc_codec *codec;
698 int ret = 0;
699
700 if (!cs42l51_codec) {
701 dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
702 return -EINVAL;
703 }
704
705 socdev->card->codec = cs42l51_codec;
706 codec = socdev->card->codec;
707
708 /* Register PCMs */
709 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
710 if (ret < 0) {
711 dev_err(&pdev->dev, "failed to create PCMs\n");
712 return ret;
713 }
714
715 snd_soc_add_controls(codec, cs42l51_snd_controls,
716 ARRAY_SIZE(cs42l51_snd_controls));
717 snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
718 ARRAY_SIZE(cs42l51_dapm_widgets));
719 snd_soc_dapm_add_routes(codec, cs42l51_routes,
720 ARRAY_SIZE(cs42l51_routes));
721
722 return 0;
723}
724
725
726static int cs42l51_remove(struct platform_device *pdev)
727{
728 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
729
730 snd_soc_free_pcms(socdev);
731 snd_soc_dapm_free(socdev);
732
733 return 0;
734}
735
736struct snd_soc_codec_device soc_codec_device_cs42l51 = {
737 .probe = cs42l51_probe,
738 .remove = cs42l51_remove
739};
740EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
741
742static int __init cs42l51_init(void)
743{
744 int ret;
745
746 ret = i2c_add_driver(&cs42l51_i2c_driver);
747 if (ret != 0) {
748 printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
749 return ret;
750 }
751 return 0;
752}
753module_init(cs42l51_init);
754
755static void __exit cs42l51_exit(void)
756{
757 i2c_del_driver(&cs42l51_i2c_driver);
758}
759module_exit(cs42l51_exit);
760
761MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>");
762MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
763MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h
new file mode 100644
index 000000000000..8f0bd9786ad2
--- /dev/null
+++ b/sound/soc/codecs/cs42l51.h
@@ -0,0 +1,163 @@
1/*
2 * cs42l51.h
3 *
4 * ASoC Driver for Cirrus Logic CS42L51 codecs
5 *
6 * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18#ifndef _CS42L51_H
19#define _CS42L51_H
20
21#define CS42L51_CHIP_ID 0x1B
22#define CS42L51_CHIP_REV_A 0x00
23#define CS42L51_CHIP_REV_B 0x01
24
25#define CS42L51_CHIP_REV_ID 0x01
26#define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b))
27
28#define CS42L51_POWER_CTL1 0x02
29#define CS42L51_POWER_CTL1_PDN_DACB (1<<6)
30#define CS42L51_POWER_CTL1_PDN_DACA (1<<5)
31#define CS42L51_POWER_CTL1_PDN_PGAB (1<<4)
32#define CS42L51_POWER_CTL1_PDN_PGAA (1<<3)
33#define CS42L51_POWER_CTL1_PDN_ADCB (1<<2)
34#define CS42L51_POWER_CTL1_PDN_ADCA (1<<1)
35#define CS42L51_POWER_CTL1_PDN (1<<0)
36
37#define CS42L51_MIC_POWER_CTL 0x03
38#define CS42L51_MIC_POWER_CTL_AUTO (1<<7)
39#define CS42L51_MIC_POWER_CTL_SPEED(x) (((x)&3)<<5)
40#define CS42L51_QSM_MODE 3
41#define CS42L51_HSM_MODE 2
42#define CS42L51_SSM_MODE 1
43#define CS42L51_DSM_MODE 0
44#define CS42L51_MIC_POWER_CTL_3ST_SP (1<<4)
45#define CS42L51_MIC_POWER_CTL_PDN_MICB (1<<3)
46#define CS42L51_MIC_POWER_CTL_PDN_MICA (1<<2)
47#define CS42L51_MIC_POWER_CTL_PDN_BIAS (1<<1)
48#define CS42L51_MIC_POWER_CTL_MCLK_DIV2 (1<<0)
49
50#define CS42L51_INTF_CTL 0x04
51#define CS42L51_INTF_CTL_LOOPBACK (1<<7)
52#define CS42L51_INTF_CTL_MASTER (1<<6)
53#define CS42L51_INTF_CTL_DAC_FORMAT(x) (((x)&7)<<3)
54#define CS42L51_DAC_DIF_LJ24 0x00
55#define CS42L51_DAC_DIF_I2S 0x01
56#define CS42L51_DAC_DIF_RJ24 0x02
57#define CS42L51_DAC_DIF_RJ20 0x03
58#define CS42L51_DAC_DIF_RJ18 0x04
59#define CS42L51_DAC_DIF_RJ16 0x05
60#define CS42L51_INTF_CTL_ADC_I2S (1<<2)
61#define CS42L51_INTF_CTL_DIGMIX (1<<1)
62#define CS42L51_INTF_CTL_MICMIX (1<<0)
63
64#define CS42L51_MIC_CTL 0x05
65#define CS42L51_MIC_CTL_ADC_SNGVOL (1<<7)
66#define CS42L51_MIC_CTL_ADCD_DBOOST (1<<6)
67#define CS42L51_MIC_CTL_ADCA_DBOOST (1<<5)
68#define CS42L51_MIC_CTL_MICBIAS_SEL (1<<4)
69#define CS42L51_MIC_CTL_MICBIAS_LVL(x) (((x)&3)<<2)
70#define CS42L51_MIC_CTL_MICB_BOOST (1<<1)
71#define CS42L51_MIC_CTL_MICA_BOOST (1<<0)
72
73#define CS42L51_ADC_CTL 0x06
74#define CS42L51_ADC_CTL_ADCB_HPFEN (1<<7)
75#define CS42L51_ADC_CTL_ADCB_HPFRZ (1<<6)
76#define CS42L51_ADC_CTL_ADCA_HPFEN (1<<5)
77#define CS42L51_ADC_CTL_ADCA_HPFRZ (1<<4)
78#define CS42L51_ADC_CTL_SOFTB (1<<3)
79#define CS42L51_ADC_CTL_ZCROSSB (1<<2)
80#define CS42L51_ADC_CTL_SOFTA (1<<1)
81#define CS42L51_ADC_CTL_ZCROSSA (1<<0)
82
83#define CS42L51_ADC_INPUT 0x07
84#define CS42L51_ADC_INPUT_AINB_MUX(x) (((x)&3)<<6)
85#define CS42L51_ADC_INPUT_AINA_MUX(x) (((x)&3)<<4)
86#define CS42L51_ADC_INPUT_INV_ADCB (1<<3)
87#define CS42L51_ADC_INPUT_INV_ADCA (1<<2)
88#define CS42L51_ADC_INPUT_ADCB_MUTE (1<<1)
89#define CS42L51_ADC_INPUT_ADCA_MUTE (1<<0)
90
91#define CS42L51_DAC_OUT_CTL 0x08
92#define CS42L51_DAC_OUT_CTL_HP_GAIN(x) (((x)&7)<<5)
93#define CS42L51_DAC_OUT_CTL_DAC_SNGVOL (1<<4)
94#define CS42L51_DAC_OUT_CTL_INV_PCMB (1<<3)
95#define CS42L51_DAC_OUT_CTL_INV_PCMA (1<<2)
96#define CS42L51_DAC_OUT_CTL_DACB_MUTE (1<<1)
97#define CS42L51_DAC_OUT_CTL_DACA_MUTE (1<<0)
98
99#define CS42L51_DAC_CTL 0x09
100#define CS42L51_DAC_CTL_DATA_SEL(x) (((x)&3)<<6)
101#define CS42L51_DAC_CTL_FREEZE (1<<5)
102#define CS42L51_DAC_CTL_DEEMPH (1<<3)
103#define CS42L51_DAC_CTL_AMUTE (1<<2)
104#define CS42L51_DAC_CTL_DACSZ(x) (((x)&3)<<0)
105
106#define CS42L51_ALC_PGA_CTL 0x0A
107#define CS42L51_ALC_PGB_CTL 0x0B
108#define CS42L51_ALC_PGX_ALCX_SRDIS (1<<7)
109#define CS42L51_ALC_PGX_ALCX_ZCDIS (1<<6)
110#define CS42L51_ALC_PGX_PGX_VOL(x) (((x)&0x1f)<<0)
111
112#define CS42L51_ADCA_ATT 0x0C
113#define CS42L51_ADCB_ATT 0x0D
114
115#define CS42L51_ADCA_VOL 0x0E
116#define CS42L51_ADCB_VOL 0x0F
117#define CS42L51_PCMA_VOL 0x10
118#define CS42L51_PCMB_VOL 0x11
119#define CS42L51_MIX_MUTE_ADCMIX (1<<7)
120#define CS42L51_MIX_VOLUME(x) (((x)&0x7f)<<0)
121
122#define CS42L51_BEEP_FREQ 0x12
123#define CS42L51_BEEP_VOL 0x13
124#define CS42L51_BEEP_CONF 0x14
125
126#define CS42L51_TONE_CTL 0x15
127#define CS42L51_TONE_CTL_TREB(x) (((x)&0xf)<<4)
128#define CS42L51_TONE_CTL_BASS(x) (((x)&0xf)<<0)
129
130#define CS42L51_AOUTA_VOL 0x16
131#define CS42L51_AOUTB_VOL 0x17
132#define CS42L51_PCM_MIXER 0x18
133#define CS42L51_LIMIT_THRES_DIS 0x19
134#define CS42L51_LIMIT_REL 0x1A
135#define CS42L51_LIMIT_ATT 0x1B
136#define CS42L51_ALC_EN 0x1C
137#define CS42L51_ALC_REL 0x1D
138#define CS42L51_ALC_THRES 0x1E
139#define CS42L51_NOISE_CONF 0x1F
140
141#define CS42L51_STATUS 0x20
142#define CS42L51_STATUS_SP_CLKERR (1<<6)
143#define CS42L51_STATUS_SPEA_OVFL (1<<5)
144#define CS42L51_STATUS_SPEB_OVFL (1<<4)
145#define CS42L51_STATUS_PCMA_OVFL (1<<3)
146#define CS42L51_STATUS_PCMB_OVFL (1<<2)
147#define CS42L51_STATUS_ADCA_OVFL (1<<1)
148#define CS42L51_STATUS_ADCB_OVFL (1<<0)
149
150#define CS42L51_CHARGE_FREQ 0x21
151
152#define CS42L51_FIRSTREG 0x01
153/*
154 * Hack: with register 0x21, it makes 33 registers. Looks like someone in the
155 * i2c layer doesn't like i2c smbus block read of 33 regs. Workaround by using
156 * 32 regs
157 */
158#define CS42L51_LASTREG 0x20
159#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
160
161extern struct snd_soc_dai cs42l51_dai;
162extern struct snd_soc_codec_device soc_codec_device_cs42l51;
163#endif
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 75af2d6e0e78..3c51d6a57523 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -15,23 +15,15 @@
15 * option) any later version. 15 * option) any later version.
16 */ 16 */
17 17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/delay.h> 18#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h> 19#include <linux/i2c.h>
25#include <linux/platform_device.h> 20#include <linux/platform_device.h>
26#include <linux/slab.h> 21#include <linux/slab.h>
27#include <sound/core.h>
28#include <sound/pcm.h> 22#include <sound/pcm.h>
29#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
32#include <sound/tlv.h>
33#include <sound/initval.h> 25#include <sound/initval.h>
34#include <asm/div64.h> 26#include <sound/tlv.h>
35 27
36#include "da7210.h" 28#include "da7210.h"
37 29
@@ -145,6 +137,29 @@
145 137
146#define DA7210_VERSION "0.0.1" 138#define DA7210_VERSION "0.0.1"
147 139
140/*
141 * Playback Volume
142 *
143 * max : 0x3F (+15.0 dB)
144 * (1.5 dB step)
145 * min : 0x11 (-54.0 dB)
146 * mute : 0x10
147 * reserved : 0x00 - 0x0F
148 *
149 * ** FIXME **
150 *
151 * Reserved area are considered as "mute".
152 * -> min = -79.5 dB
153 */
154static const DECLARE_TLV_DB_SCALE(hp_out_tlv, -7950, 150, 1);
155
156static const struct snd_kcontrol_new da7210_snd_controls[] = {
157
158 SOC_DOUBLE_R_TLV("HeadPhone Playback Volume",
159 DA7210_HP_L_VOL, DA7210_HP_R_VOL,
160 0, 0x3F, 0, hp_out_tlv),
161};
162
148/* Codec private data */ 163/* Codec private data */
149struct da7210_priv { 164struct da7210_priv {
150 struct snd_soc_codec codec; 165 struct snd_soc_codec codec;
@@ -227,10 +242,6 @@ static int da7210_startup(struct snd_pcm_substream *substream,
227 struct snd_soc_codec *codec = dai->codec; 242 struct snd_soc_codec *codec = dai->codec;
228 243
229 if (is_play) { 244 if (is_play) {
230 /* PlayBack Volume 40 */
231 snd_soc_update_bits(codec, DA7210_HP_L_VOL, 0x3F, 40);
232 snd_soc_update_bits(codec, DA7210_HP_R_VOL, 0x3F, 40);
233
234 /* Enable Out */ 245 /* Enable Out */
235 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10); 246 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
236 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10); 247 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
@@ -488,7 +499,7 @@ static int da7210_init(struct da7210_priv *da7210)
488 ret = snd_soc_register_dai(&da7210_dai); 499 ret = snd_soc_register_dai(&da7210_dai);
489 if (ret) { 500 if (ret) {
490 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 501 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
491 goto init_err; 502 goto codec_err;
492 } 503 }
493 504
494 /* FIXME 505 /* FIXME
@@ -574,6 +585,8 @@ static int da7210_init(struct da7210_priv *da7210)
574 585
575 return ret; 586 return ret;
576 587
588codec_err:
589 snd_soc_unregister_codec(codec);
577init_err: 590init_err:
578 kfree(codec->reg_cache); 591 kfree(codec->reg_cache);
579 codec->reg_cache = NULL; 592 codec->reg_cache = NULL;
@@ -601,8 +614,10 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
601 codec->control_data = i2c; 614 codec->control_data = i2c;
602 615
603 ret = da7210_init(da7210); 616 ret = da7210_init(da7210);
604 if (ret < 0) 617 if (ret < 0) {
605 pr_err("Failed to initialise da7210 audio codec\n"); 618 pr_err("Failed to initialise da7210 audio codec\n");
619 kfree(da7210);
620 }
606 621
607 return ret; 622 return ret;
608} 623}
@@ -656,6 +671,9 @@ static int da7210_probe(struct platform_device *pdev)
656 if (ret < 0) 671 if (ret < 0)
657 goto pcm_err; 672 goto pcm_err;
658 673
674 snd_soc_add_controls(da7210_codec, da7210_snd_controls,
675 ARRAY_SIZE(da7210_snd_controls));
676
659 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); 677 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
660 678
661pcm_err: 679pcm_err:
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
new file mode 100644
index 000000000000..66557de1e4fe
--- /dev/null
+++ b/sound/soc/codecs/jz4740.c
@@ -0,0 +1,511 @@
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
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 * You should have received a copy of the GNU General Public License along
9 * with this program; if not, write to the Free Software Foundation, Inc.,
10 * 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/platform_device.h>
17#include <linux/slab.h>
18
19#include <linux/delay.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/initval.h>
25#include <sound/soc-dapm.h>
26#include <sound/soc.h>
27
28#define JZ4740_REG_CODEC_1 0x0
29#define JZ4740_REG_CODEC_2 0x1
30
31#define JZ4740_CODEC_1_LINE_ENABLE BIT(29)
32#define JZ4740_CODEC_1_MIC_ENABLE BIT(28)
33#define JZ4740_CODEC_1_SW1_ENABLE BIT(27)
34#define JZ4740_CODEC_1_ADC_ENABLE BIT(26)
35#define JZ4740_CODEC_1_SW2_ENABLE BIT(25)
36#define JZ4740_CODEC_1_DAC_ENABLE BIT(24)
37#define JZ4740_CODEC_1_VREF_DISABLE BIT(20)
38#define JZ4740_CODEC_1_VREF_AMP_DISABLE BIT(19)
39#define JZ4740_CODEC_1_VREF_PULLDOWN BIT(18)
40#define JZ4740_CODEC_1_VREF_LOW_CURRENT BIT(17)
41#define JZ4740_CODEC_1_VREF_HIGH_CURRENT BIT(16)
42#define JZ4740_CODEC_1_HEADPHONE_DISABLE BIT(14)
43#define JZ4740_CODEC_1_HEADPHONE_AMP_CHANGE_ANY BIT(13)
44#define JZ4740_CODEC_1_HEADPHONE_CHARGE BIT(12)
45#define JZ4740_CODEC_1_HEADPHONE_PULLDOWN (BIT(11) | BIT(10))
46#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M BIT(9)
47#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN BIT(8)
48#define JZ4740_CODEC_1_SUSPEND BIT(1)
49#define JZ4740_CODEC_1_RESET BIT(0)
50
51#define JZ4740_CODEC_1_LINE_ENABLE_OFFSET 29
52#define JZ4740_CODEC_1_MIC_ENABLE_OFFSET 28
53#define JZ4740_CODEC_1_SW1_ENABLE_OFFSET 27
54#define JZ4740_CODEC_1_ADC_ENABLE_OFFSET 26
55#define JZ4740_CODEC_1_SW2_ENABLE_OFFSET 25
56#define JZ4740_CODEC_1_DAC_ENABLE_OFFSET 24
57#define JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET 14
58#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN_OFFSET 8
59
60#define JZ4740_CODEC_2_INPUT_VOLUME_MASK 0x1f0000
61#define JZ4740_CODEC_2_SAMPLE_RATE_MASK 0x000f00
62#define JZ4740_CODEC_2_MIC_BOOST_GAIN_MASK 0x000030
63#define JZ4740_CODEC_2_HEADPHONE_VOLUME_MASK 0x000003
64
65#define JZ4740_CODEC_2_INPUT_VOLUME_OFFSET 16
66#define JZ4740_CODEC_2_SAMPLE_RATE_OFFSET 8
67#define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4
68#define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0
69
70static const uint32_t jz4740_codec_regs[] = {
71 0x021b2302, 0x00170803,
72};
73
74struct jz4740_codec {
75 void __iomem *base;
76 struct resource *mem;
77
78 uint32_t reg_cache[2];
79 struct snd_soc_codec codec;
80};
81
82static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec)
83{
84 return container_of(codec, struct jz4740_codec, codec);
85}
86
87static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
88 unsigned int reg)
89{
90 struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
91 return readl(jz4740_codec->base + (reg << 2));
92}
93
94static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
95 unsigned int val)
96{
97 struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
98
99 jz4740_codec->reg_cache[reg] = val;
100 writel(val, jz4740_codec->base + (reg << 2));
101
102 return 0;
103}
104
105static const struct snd_kcontrol_new jz4740_codec_controls[] = {
106 SOC_SINGLE("Master Playback Volume", JZ4740_REG_CODEC_2,
107 JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0),
108 SOC_SINGLE("Master Capture Volume", JZ4740_REG_CODEC_2,
109 JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0),
110 SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1,
111 JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1),
112 SOC_SINGLE("Mic Capture Volume", JZ4740_REG_CODEC_2,
113 JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0),
114};
115
116static const struct snd_kcontrol_new jz4740_codec_output_controls[] = {
117 SOC_DAPM_SINGLE("Bypass Switch", JZ4740_REG_CODEC_1,
118 JZ4740_CODEC_1_SW1_ENABLE_OFFSET, 1, 0),
119 SOC_DAPM_SINGLE("DAC Switch", JZ4740_REG_CODEC_1,
120 JZ4740_CODEC_1_SW2_ENABLE_OFFSET, 1, 0),
121};
122
123static const struct snd_kcontrol_new jz4740_codec_input_controls[] = {
124 SOC_DAPM_SINGLE("Line Capture Switch", JZ4740_REG_CODEC_1,
125 JZ4740_CODEC_1_LINE_ENABLE_OFFSET, 1, 0),
126 SOC_DAPM_SINGLE("Mic Capture Switch", JZ4740_REG_CODEC_1,
127 JZ4740_CODEC_1_MIC_ENABLE_OFFSET, 1, 0),
128};
129
130static const struct snd_soc_dapm_widget jz4740_codec_dapm_widgets[] = {
131 SND_SOC_DAPM_ADC("ADC", "Capture", JZ4740_REG_CODEC_1,
132 JZ4740_CODEC_1_ADC_ENABLE_OFFSET, 0),
133 SND_SOC_DAPM_DAC("DAC", "Playback", JZ4740_REG_CODEC_1,
134 JZ4740_CODEC_1_DAC_ENABLE_OFFSET, 0),
135
136 SND_SOC_DAPM_MIXER("Output Mixer", JZ4740_REG_CODEC_1,
137 JZ4740_CODEC_1_HEADPHONE_POWERDOWN_OFFSET, 1,
138 jz4740_codec_output_controls,
139 ARRAY_SIZE(jz4740_codec_output_controls)),
140
141 SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
142 jz4740_codec_input_controls,
143 ARRAY_SIZE(jz4740_codec_input_controls)),
144 SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
145
146 SND_SOC_DAPM_OUTPUT("LOUT"),
147 SND_SOC_DAPM_OUTPUT("ROUT"),
148
149 SND_SOC_DAPM_INPUT("MIC"),
150 SND_SOC_DAPM_INPUT("LIN"),
151 SND_SOC_DAPM_INPUT("RIN"),
152};
153
154static const struct snd_soc_dapm_route jz4740_codec_dapm_routes[] = {
155 {"Line Input", NULL, "LIN"},
156 {"Line Input", NULL, "RIN"},
157
158 {"Input Mixer", "Line Capture Switch", "Line Input"},
159 {"Input Mixer", "Mic Capture Switch", "MIC"},
160
161 {"ADC", NULL, "Input Mixer"},
162
163 {"Output Mixer", "Bypass Switch", "Input Mixer"},
164 {"Output Mixer", "DAC Switch", "DAC"},
165
166 {"LOUT", NULL, "Output Mixer"},
167 {"ROUT", NULL, "Output Mixer"},
168};
169
170static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
171 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
172{
173 uint32_t val;
174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_device *socdev = rtd->socdev;
176 struct snd_soc_codec *codec = socdev->card->codec;
177
178 switch (params_rate(params)) {
179 case 8000:
180 val = 0;
181 break;
182 case 11025:
183 val = 1;
184 break;
185 case 12000:
186 val = 2;
187 break;
188 case 16000:
189 val = 3;
190 break;
191 case 22050:
192 val = 4;
193 break;
194 case 24000:
195 val = 5;
196 break;
197 case 32000:
198 val = 6;
199 break;
200 case 44100:
201 val = 7;
202 break;
203 case 48000:
204 val = 8;
205 break;
206 default:
207 return -EINVAL;
208 }
209
210 val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET;
211
212 snd_soc_update_bits(codec, JZ4740_REG_CODEC_2,
213 JZ4740_CODEC_2_SAMPLE_RATE_MASK, val);
214
215 return 0;
216}
217
218static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
219 .hw_params = jz4740_codec_hw_params,
220};
221
222struct snd_soc_dai jz4740_codec_dai = {
223 .name = "jz4740",
224 .playback = {
225 .stream_name = "Playback",
226 .channels_min = 2,
227 .channels_max = 2,
228 .rates = SNDRV_PCM_RATE_8000_48000,
229 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
230 },
231 .capture = {
232 .stream_name = "Capture",
233 .channels_min = 2,
234 .channels_max = 2,
235 .rates = SNDRV_PCM_RATE_8000_48000,
236 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
237 },
238 .ops = &jz4740_codec_dai_ops,
239 .symmetric_rates = 1,
240};
241EXPORT_SYMBOL_GPL(jz4740_codec_dai);
242
243static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
244{
245 int i;
246 uint32_t *cache = codec->reg_cache;
247
248 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
249 JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET);
250 udelay(2);
251
252 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
253 JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0);
254
255 for (i = 0; i < ARRAY_SIZE(jz4740_codec_regs); ++i)
256 jz4740_codec_write(codec, i, cache[i]);
257}
258
259static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
260 enum snd_soc_bias_level level)
261{
262 unsigned int mask;
263 unsigned int value;
264
265 switch (level) {
266 case SND_SOC_BIAS_ON:
267 break;
268 case SND_SOC_BIAS_PREPARE:
269 mask = JZ4740_CODEC_1_VREF_DISABLE |
270 JZ4740_CODEC_1_VREF_AMP_DISABLE |
271 JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
272 value = 0;
273
274 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
275 break;
276 case SND_SOC_BIAS_STANDBY:
277 /* The only way to clear the suspend flag is to reset the codec */
278 if (codec->bias_level == SND_SOC_BIAS_OFF)
279 jz4740_codec_wakeup(codec);
280
281 mask = JZ4740_CODEC_1_VREF_DISABLE |
282 JZ4740_CODEC_1_VREF_AMP_DISABLE |
283 JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
284 value = JZ4740_CODEC_1_VREF_DISABLE |
285 JZ4740_CODEC_1_VREF_AMP_DISABLE |
286 JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
287
288 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
289 break;
290 case SND_SOC_BIAS_OFF:
291 mask = JZ4740_CODEC_1_SUSPEND;
292 value = JZ4740_CODEC_1_SUSPEND;
293
294 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
295 break;
296 default:
297 break;
298 }
299
300 codec->bias_level = level;
301
302 return 0;
303}
304
305static struct snd_soc_codec *jz4740_codec_codec;
306
307static int jz4740_codec_dev_probe(struct platform_device *pdev)
308{
309 int ret;
310 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
311 struct snd_soc_codec *codec = jz4740_codec_codec;
312
313 BUG_ON(!codec);
314
315 socdev->card->codec = codec;
316
317 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
318 if (ret) {
319 dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret);
320 return ret;
321 }
322
323 snd_soc_add_controls(codec, jz4740_codec_controls,
324 ARRAY_SIZE(jz4740_codec_controls));
325
326 snd_soc_dapm_new_controls(codec, jz4740_codec_dapm_widgets,
327 ARRAY_SIZE(jz4740_codec_dapm_widgets));
328
329 snd_soc_dapm_add_routes(codec, jz4740_codec_dapm_routes,
330 ARRAY_SIZE(jz4740_codec_dapm_routes));
331
332 snd_soc_dapm_new_widgets(codec);
333
334 return 0;
335}
336
337static int jz4740_codec_dev_remove(struct platform_device *pdev)
338{
339 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
340
341 snd_soc_free_pcms(socdev);
342 snd_soc_dapm_free(socdev);
343
344 return 0;
345}
346
347#ifdef CONFIG_PM_SLEEP
348
349static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state)
350{
351 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
352 struct snd_soc_codec *codec = socdev->card->codec;
353
354 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
355}
356
357static int jz4740_codec_resume(struct platform_device *pdev)
358{
359 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
360 struct snd_soc_codec *codec = socdev->card->codec;
361
362 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
363}
364
365#else
366#define jz4740_codec_suspend NULL
367#define jz4740_codec_resume NULL
368#endif
369
370struct snd_soc_codec_device soc_codec_dev_jz4740_codec = {
371 .probe = jz4740_codec_dev_probe,
372 .remove = jz4740_codec_dev_remove,
373 .suspend = jz4740_codec_suspend,
374 .resume = jz4740_codec_resume,
375};
376EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec);
377
378static int __devinit jz4740_codec_probe(struct platform_device *pdev)
379{
380 int ret;
381 struct jz4740_codec *jz4740_codec;
382 struct snd_soc_codec *codec;
383 struct resource *mem;
384
385 jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL);
386 if (!jz4740_codec)
387 return -ENOMEM;
388
389 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
390 if (!mem) {
391 dev_err(&pdev->dev, "Failed to get mmio memory resource\n");
392 ret = -ENOENT;
393 goto err_free_codec;
394 }
395
396 mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
397 if (!mem) {
398 dev_err(&pdev->dev, "Failed to request mmio memory region\n");
399 ret = -EBUSY;
400 goto err_free_codec;
401 }
402
403 jz4740_codec->base = ioremap(mem->start, resource_size(mem));
404 if (!jz4740_codec->base) {
405 dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
406 ret = -EBUSY;
407 goto err_release_mem_region;
408 }
409 jz4740_codec->mem = mem;
410
411 jz4740_codec_dai.dev = &pdev->dev;
412
413 codec = &jz4740_codec->codec;
414
415 codec->dev = &pdev->dev;
416 codec->name = "jz4740";
417 codec->owner = THIS_MODULE;
418
419 codec->read = jz4740_codec_read;
420 codec->write = jz4740_codec_write;
421 codec->set_bias_level = jz4740_codec_set_bias_level;
422 codec->bias_level = SND_SOC_BIAS_OFF;
423
424 codec->dai = &jz4740_codec_dai;
425 codec->num_dai = 1;
426
427 codec->reg_cache = jz4740_codec->reg_cache;
428 codec->reg_cache_size = 2;
429 memcpy(codec->reg_cache, jz4740_codec_regs, sizeof(jz4740_codec_regs));
430
431 mutex_init(&codec->mutex);
432 INIT_LIST_HEAD(&codec->dapm_widgets);
433 INIT_LIST_HEAD(&codec->dapm_paths);
434
435 jz4740_codec_codec = codec;
436
437 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
438 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
439
440 platform_set_drvdata(pdev, jz4740_codec);
441
442 ret = snd_soc_register_codec(codec);
443 if (ret) {
444 dev_err(&pdev->dev, "Failed to register codec\n");
445 goto err_iounmap;
446 }
447
448 ret = snd_soc_register_dai(&jz4740_codec_dai);
449 if (ret) {
450 dev_err(&pdev->dev, "Failed to register codec dai\n");
451 goto err_unregister_codec;
452 }
453
454 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
455
456 return 0;
457
458err_unregister_codec:
459 snd_soc_unregister_codec(codec);
460err_iounmap:
461 iounmap(jz4740_codec->base);
462err_release_mem_region:
463 release_mem_region(mem->start, resource_size(mem));
464err_free_codec:
465 kfree(jz4740_codec);
466
467 return ret;
468}
469
470static int __devexit jz4740_codec_remove(struct platform_device *pdev)
471{
472 struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
473 struct resource *mem = jz4740_codec->mem;
474
475 snd_soc_unregister_dai(&jz4740_codec_dai);
476 snd_soc_unregister_codec(&jz4740_codec->codec);
477
478 iounmap(jz4740_codec->base);
479 release_mem_region(mem->start, resource_size(mem));
480
481 platform_set_drvdata(pdev, NULL);
482 kfree(jz4740_codec);
483
484 return 0;
485}
486
487static struct platform_driver jz4740_codec_driver = {
488 .probe = jz4740_codec_probe,
489 .remove = __devexit_p(jz4740_codec_remove),
490 .driver = {
491 .name = "jz4740-codec",
492 .owner = THIS_MODULE,
493 },
494};
495
496static int __init jz4740_codec_init(void)
497{
498 return platform_driver_register(&jz4740_codec_driver);
499}
500module_init(jz4740_codec_init);
501
502static void __exit jz4740_codec_exit(void)
503{
504 platform_driver_unregister(&jz4740_codec_driver);
505}
506module_exit(jz4740_codec_exit);
507
508MODULE_DESCRIPTION("JZ4740 SoC internal codec driver");
509MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
510MODULE_LICENSE("GPL v2");
511MODULE_ALIAS("platform:jz4740-codec");
diff --git a/sound/soc/codecs/jz4740.h b/sound/soc/codecs/jz4740.h
new file mode 100644
index 000000000000..b5a0691be763
--- /dev/null
+++ b/sound/soc/codecs/jz4740.h
@@ -0,0 +1,20 @@
1/*
2 * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
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 * You should have received a copy of the GNU General Public License along
9 * with this program; if not, write to the Free Software Foundation, Inc.,
10 * 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 */
13
14#ifndef __SND_SOC_CODECS_JZ4740_CODEC_H__
15#define __SND_SOC_CODECS_JZ4740_CODEC_H__
16
17extern struct snd_soc_dai jz4740_codec_dai;
18extern struct snd_soc_codec_device soc_codec_dev_jz4740_codec;
19
20#endif
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index a63191141052..9119836051a4 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -16,8 +16,10 @@
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
19#include <linux/slab.h>
19#include <sound/soc.h> 20#include <sound/soc.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h>
21 23
22#include "spdif_transciever.h" 24#include "spdif_transciever.h"
23 25
@@ -26,6 +28,48 @@ MODULE_LICENSE("GPL");
26#define STUB_RATES SNDRV_PCM_RATE_8000_96000 28#define STUB_RATES SNDRV_PCM_RATE_8000_96000
27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE 29#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
28 30
31static struct snd_soc_codec *spdif_dit_codec;
32
33static int spdif_dit_codec_probe(struct platform_device *pdev)
34{
35 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
36 struct snd_soc_codec *codec;
37 int ret;
38
39 if (spdif_dit_codec == NULL) {
40 dev_err(&pdev->dev, "Codec device not registered\n");
41 return -ENODEV;
42 }
43
44 socdev->card->codec = spdif_dit_codec;
45 codec = spdif_dit_codec;
46
47 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
48 if (ret < 0) {
49 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
50 goto err_create_pcms;
51 }
52
53 return 0;
54
55err_create_pcms:
56 return ret;
57}
58
59static int spdif_dit_codec_remove(struct platform_device *pdev)
60{
61 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
62
63 snd_soc_free_pcms(socdev);
64
65 return 0;
66}
67
68struct snd_soc_codec_device soc_codec_dev_spdif_dit = {
69 .probe = spdif_dit_codec_probe,
70 .remove = spdif_dit_codec_remove,
71}; EXPORT_SYMBOL_GPL(soc_codec_dev_spdif_dit);
72
29struct snd_soc_dai dit_stub_dai = { 73struct snd_soc_dai dit_stub_dai = {
30 .name = "DIT", 74 .name = "DIT",
31 .playback = { 75 .playback = {
@@ -40,13 +84,61 @@ EXPORT_SYMBOL_GPL(dit_stub_dai);
40 84
41static int spdif_dit_probe(struct platform_device *pdev) 85static int spdif_dit_probe(struct platform_device *pdev)
42{ 86{
87 struct snd_soc_codec *codec;
88 int ret;
89
90 if (spdif_dit_codec) {
91 dev_err(&pdev->dev, "Another Codec is registered\n");
92 ret = -EINVAL;
93 goto err_reg_codec;
94 }
95
96 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
97 if (codec == NULL)
98 return -ENOMEM;
99
100 codec->dev = &pdev->dev;
101
102 mutex_init(&codec->mutex);
103
104 INIT_LIST_HEAD(&codec->dapm_widgets);
105 INIT_LIST_HEAD(&codec->dapm_paths);
106
107 codec->name = "spdif-dit";
108 codec->owner = THIS_MODULE;
109 codec->dai = &dit_stub_dai;
110 codec->num_dai = 1;
111
112 spdif_dit_codec = codec;
113
114 ret = snd_soc_register_codec(codec);
115 if (ret < 0) {
116 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
117 goto err_reg_codec;
118 }
119
43 dit_stub_dai.dev = &pdev->dev; 120 dit_stub_dai.dev = &pdev->dev;
44 return snd_soc_register_dai(&dit_stub_dai); 121 ret = snd_soc_register_dai(&dit_stub_dai);
122 if (ret < 0) {
123 dev_err(codec->dev, "Failed to register dai: %d\n", ret);
124 goto err_reg_dai;
125 }
126
127 return 0;
128
129err_reg_dai:
130 snd_soc_unregister_codec(codec);
131err_reg_codec:
132 kfree(spdif_dit_codec);
133 return ret;
45} 134}
46 135
47static int spdif_dit_remove(struct platform_device *pdev) 136static int spdif_dit_remove(struct platform_device *pdev)
48{ 137{
49 snd_soc_unregister_dai(&dit_stub_dai); 138 snd_soc_unregister_dai(&dit_stub_dai);
139 snd_soc_unregister_codec(spdif_dit_codec);
140 kfree(spdif_dit_codec);
141 spdif_dit_codec = NULL;
50 return 0; 142 return 0;
51} 143}
52 144
diff --git a/sound/soc/codecs/spdif_transciever.h b/sound/soc/codecs/spdif_transciever.h
index 296f2eb6c4ef..1e102124f546 100644
--- a/sound/soc/codecs/spdif_transciever.h
+++ b/sound/soc/codecs/spdif_transciever.h
@@ -12,6 +12,7 @@
12#ifndef CODEC_STUBS_H 12#ifndef CODEC_STUBS_H
13#define CODEC_STUBS_H 13#define CODEC_STUBS_H
14 14
15extern struct snd_soc_codec_device soc_codec_dev_spdif_dit;
15extern struct snd_soc_dai dit_stub_dai; 16extern struct snd_soc_dai dit_stub_dai;
16 17
17#endif /* CODEC_STUBS_H */ 18#endif /* CODEC_STUBS_H */
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index b0bae3508b29..0a4b0fef3355 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -560,13 +560,16 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
560 switch (level) { 560 switch (level) {
561 case SND_SOC_BIAS_ON: 561 case SND_SOC_BIAS_ON:
562 /* vref/mid, osc on, dac unmute */ 562 /* vref/mid, osc on, dac unmute */
563 reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
564 TLV320AIC23_DAC_OFF);
563 tlv320aic23_write(codec, TLV320AIC23_PWR, reg); 565 tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
564 break; 566 break;
565 case SND_SOC_BIAS_PREPARE: 567 case SND_SOC_BIAS_PREPARE:
566 break; 568 break;
567 case SND_SOC_BIAS_STANDBY: 569 case SND_SOC_BIAS_STANDBY:
568 /* everything off except vref/vmid, */ 570 /* everything off except vref/vmid, */
569 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040); 571 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | \
572 TLV320AIC23_CLK_OFF);
570 break; 573 break;
571 case SND_SOC_BIAS_OFF: 574 case SND_SOC_BIAS_OFF:
572 /* everything off, dac mute, inactive */ 575 /* everything off, dac mute, inactive */
@@ -615,7 +618,6 @@ static int tlv320aic23_suspend(struct platform_device *pdev,
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 618 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
616 struct snd_soc_codec *codec = socdev->card->codec; 619 struct snd_soc_codec *codec = socdev->card->codec;
617 620
618 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
619 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 621 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
620 622
621 return 0; 623 return 0;
@@ -632,7 +634,6 @@ static int tlv320aic23_resume(struct platform_device *pdev)
632 u16 val = tlv320aic23_read_reg_cache(codec, reg); 634 u16 val = tlv320aic23_read_reg_cache(codec, reg);
633 tlv320aic23_write(codec, reg, val); 635 tlv320aic23_write(codec, reg, val);
634 } 636 }
635
636 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 637 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
637 638
638 return 0; 639 return 0;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 65adc77eada1..8651b01ed223 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -49,8 +49,6 @@
49 49
50#define NSAMPLE_MAX 5700 50#define NSAMPLE_MAX 5700
51 51
52#define LATENCY_TIME_MS 20
53
54#define MODE7_LTHR 10 52#define MODE7_LTHR 10
55#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10) 53#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10)
56 54
@@ -62,6 +60,9 @@
62#define US_TO_SAMPLES(rate, us) \ 60#define US_TO_SAMPLES(rate, us) \
63 (rate / (1000000 / us)) 61 (rate / (1000000 / us))
64 62
63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
64 ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate)))
65
65static void dac33_calculate_times(struct snd_pcm_substream *substream); 66static void dac33_calculate_times(struct snd_pcm_substream *substream);
66static int dac33_prepare_chip(struct snd_pcm_substream *substream); 67static int dac33_prepare_chip(struct snd_pcm_substream *substream);
67 68
@@ -107,6 +108,10 @@ struct tlv320dac33_priv {
107 * this */ 108 * this */
108 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ 109 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
109 unsigned int nsample; /* burst read amount from host */ 110 unsigned int nsample; /* burst read amount from host */
111 int mode1_latency; /* latency caused by the i2c writes in
112 * us */
113 int auto_fifo_config; /* Configure the FIFO based on the
114 * period size */
110 u8 burst_bclkdiv; /* BCLK divider value in burst mode */ 115 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
111 unsigned int burst_rate; /* Interface speed in Burst modes */ 116 unsigned int burst_rate; /* Interface speed in Burst modes */
112 117
@@ -120,6 +125,8 @@ struct tlv320dac33_priv {
120 * samples */ 125 * samples */
121 unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */ 126 unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */
122 127
128 unsigned int uthr;
129
123 enum dac33_state state; 130 enum dac33_state state;
124}; 131};
125 132
@@ -442,6 +449,39 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
442 return ret; 449 return ret;
443} 450}
444 451
452static int dac33_get_uthr(struct snd_kcontrol *kcontrol,
453 struct snd_ctl_elem_value *ucontrol)
454{
455 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
456 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
457
458 ucontrol->value.integer.value[0] = dac33->uthr;
459
460 return 0;
461}
462
463static int dac33_set_uthr(struct snd_kcontrol *kcontrol,
464 struct snd_ctl_elem_value *ucontrol)
465{
466 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
467 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
468 int ret = 0;
469
470 if (dac33->substream)
471 return -EBUSY;
472
473 if (dac33->uthr == ucontrol->value.integer.value[0])
474 return 0;
475
476 if (ucontrol->value.integer.value[0] < (MODE7_LTHR + 10) ||
477 ucontrol->value.integer.value[0] > MODE7_UTHR)
478 ret = -EINVAL;
479 else
480 dac33->uthr = ucontrol->value.integer.value[0];
481
482 return ret;
483}
484
445static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, 485static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol) 486 struct snd_ctl_elem_value *ucontrol)
447{ 487{
@@ -503,13 +543,18 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = {
503 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1), 543 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
504}; 544};
505 545
506static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = { 546static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
507 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
508 dac33_get_nsample, dac33_set_nsample),
509 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum, 547 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
510 dac33_get_fifo_mode, dac33_set_fifo_mode), 548 dac33_get_fifo_mode, dac33_set_fifo_mode),
511}; 549};
512 550
551static const struct snd_kcontrol_new dac33_fifo_snd_controls[] = {
552 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
553 dac33_get_nsample, dac33_set_nsample),
554 SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0,
555 dac33_get_uthr, dac33_set_uthr),
556};
557
513/* Analog bypass */ 558/* Analog bypass */
514static const struct snd_kcontrol_new dac33_dapm_abypassl_control = 559static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
515 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1); 560 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
@@ -612,7 +657,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
612 switch (dac33->fifo_mode) { 657 switch (dac33->fifo_mode) {
613 case DAC33_FIFO_MODE1: 658 case DAC33_FIFO_MODE1:
614 dac33_write16(codec, DAC33_NSAMPLE_MSB, 659 dac33_write16(codec, DAC33_NSAMPLE_MSB,
615 DAC33_THRREG(dac33->nsample + dac33->alarm_threshold)); 660 DAC33_THRREG(dac33->nsample));
616 661
617 /* Take the timestamps */ 662 /* Take the timestamps */
618 spin_lock_irq(&dac33->lock); 663 spin_lock_irq(&dac33->lock);
@@ -761,6 +806,10 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
761 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 806 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
762 807
763 dac33->substream = NULL; 808 dac33->substream = NULL;
809
810 /* Reset the nSample restrictions */
811 dac33->nsample_min = 0;
812 dac33->nsample_max = NSAMPLE_MAX;
764} 813}
765 814
766static int dac33_hw_params(struct snd_pcm_substream *substream, 815static int dac33_hw_params(struct snd_pcm_substream *substream,
@@ -985,7 +1034,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
985 * Configure the threshold levels, and leave 10 sample space 1034 * Configure the threshold levels, and leave 10 sample space
986 * at the bottom, and also at the top of the FIFO 1035 * at the bottom, and also at the top of the FIFO
987 */ 1036 */
988 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(MODE7_UTHR)); 1037 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
989 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR)); 1038 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR));
990 break; 1039 break;
991 default: 1040 default:
@@ -1003,57 +1052,71 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1003 struct snd_soc_device *socdev = rtd->socdev; 1052 struct snd_soc_device *socdev = rtd->socdev;
1004 struct snd_soc_codec *codec = socdev->card->codec; 1053 struct snd_soc_codec *codec = socdev->card->codec;
1005 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1054 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1055 unsigned int period_size = substream->runtime->period_size;
1056 unsigned int rate = substream->runtime->rate;
1006 unsigned int nsample_limit; 1057 unsigned int nsample_limit;
1007 1058
1008 /* In bypass mode we don't need to calculate */ 1059 /* In bypass mode we don't need to calculate */
1009 if (!dac33->fifo_mode) 1060 if (!dac33->fifo_mode)
1010 return; 1061 return;
1011 1062
1012 /* Number of samples (16bit, stereo) in one period */
1013 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
1014
1015 /* Number of samples (16bit, stereo) in ALSA buffer */
1016 dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
1017 /* Subtract one period from the total */
1018 dac33->nsample_max -= dac33->nsample_min;
1019
1020 /* Number of samples for LATENCY_TIME_MS / 2 */
1021 dac33->alarm_threshold = substream->runtime->rate /
1022 (1000 / (LATENCY_TIME_MS / 2));
1023
1024 /* Find and fix up the lowest nsmaple limit */
1025 nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
1026
1027 if (dac33->nsample_min < nsample_limit)
1028 dac33->nsample_min = nsample_limit;
1029
1030 if (dac33->nsample < dac33->nsample_min)
1031 dac33->nsample = dac33->nsample_min;
1032
1033 /*
1034 * Find and fix up the highest nsmaple limit
1035 * In order to not overflow the DAC33 buffer substract the
1036 * alarm_threshold value from the size of the DAC33 buffer
1037 */
1038 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
1039
1040 if (dac33->nsample_max > nsample_limit)
1041 dac33->nsample_max = nsample_limit;
1042
1043 if (dac33->nsample > dac33->nsample_max)
1044 dac33->nsample = dac33->nsample_max;
1045
1046 switch (dac33->fifo_mode) { 1063 switch (dac33->fifo_mode) {
1047 case DAC33_FIFO_MODE1: 1064 case DAC33_FIFO_MODE1:
1065 /* Number of samples under i2c latency */
1066 dac33->alarm_threshold = US_TO_SAMPLES(rate,
1067 dac33->mode1_latency);
1068 if (dac33->auto_fifo_config) {
1069 if (period_size <= dac33->alarm_threshold)
1070 /*
1071 * Configure nSamaple to number of periods,
1072 * which covers the latency requironment.
1073 */
1074 dac33->nsample = period_size *
1075 ((dac33->alarm_threshold / period_size) +
1076 (dac33->alarm_threshold % period_size ?
1077 1 : 0));
1078 else
1079 dac33->nsample = period_size;
1080 } else {
1081 /* nSample time shall not be shorter than i2c latency */
1082 dac33->nsample_min = dac33->alarm_threshold;
1083 /*
1084 * nSample should not be bigger than alsa buffer minus
1085 * size of one period to avoid overruns
1086 */
1087 dac33->nsample_max = substream->runtime->buffer_size -
1088 period_size;
1089 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
1090 dac33->alarm_threshold;
1091 if (dac33->nsample_max > nsample_limit)
1092 dac33->nsample_max = nsample_limit;
1093
1094 /* Correct the nSample if it is outside of the ranges */
1095 if (dac33->nsample < dac33->nsample_min)
1096 dac33->nsample = dac33->nsample_min;
1097 if (dac33->nsample > dac33->nsample_max)
1098 dac33->nsample = dac33->nsample_max;
1099 }
1100
1048 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, 1101 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
1049 dac33->nsample); 1102 dac33->nsample);
1050 dac33->t_stamp1 = 0; 1103 dac33->t_stamp1 = 0;
1051 dac33->t_stamp2 = 0; 1104 dac33->t_stamp2 = 0;
1052 break; 1105 break;
1053 case DAC33_FIFO_MODE7: 1106 case DAC33_FIFO_MODE7:
1107 if (dac33->auto_fifo_config) {
1108 dac33->uthr = UTHR_FROM_PERIOD_SIZE(
1109 period_size,
1110 rate,
1111 dac33->burst_rate) + 9;
1112 if (dac33->uthr > MODE7_UTHR)
1113 dac33->uthr = MODE7_UTHR;
1114 if (dac33->uthr < (MODE7_LTHR + 10))
1115 dac33->uthr = (MODE7_LTHR + 10);
1116 }
1054 dac33->mode7_us_to_lthr = 1117 dac33->mode7_us_to_lthr =
1055 SAMPLES_TO_US(substream->runtime->rate, 1118 SAMPLES_TO_US(substream->runtime->rate,
1056 MODE7_UTHR - MODE7_LTHR + 1); 1119 dac33->uthr - MODE7_LTHR + 1);
1057 dac33->t_stamp1 = 0; 1120 dac33->t_stamp1 = 0;
1058 break; 1121 break;
1059 default: 1122 default:
@@ -1104,7 +1167,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1104 struct snd_soc_codec *codec = socdev->card->codec; 1167 struct snd_soc_codec *codec = socdev->card->codec;
1105 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1168 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1106 unsigned long long t0, t1, t_now; 1169 unsigned long long t0, t1, t_now;
1107 unsigned int time_delta; 1170 unsigned int time_delta, uthr;
1108 int samples_out, samples_in, samples; 1171 int samples_out, samples_in, samples;
1109 snd_pcm_sframes_t delay = 0; 1172 snd_pcm_sframes_t delay = 0;
1110 1173
@@ -1182,6 +1245,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1182 case DAC33_FIFO_MODE7: 1245 case DAC33_FIFO_MODE7:
1183 spin_lock(&dac33->lock); 1246 spin_lock(&dac33->lock);
1184 t0 = dac33->t_stamp1; 1247 t0 = dac33->t_stamp1;
1248 uthr = dac33->uthr;
1185 spin_unlock(&dac33->lock); 1249 spin_unlock(&dac33->lock);
1186 t_now = ktime_to_us(ktime_get()); 1250 t_now = ktime_to_us(ktime_get());
1187 1251
@@ -1194,7 +1258,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1194 * Either the timestamps are messed or equal. Report 1258 * Either the timestamps are messed or equal. Report
1195 * maximum delay 1259 * maximum delay
1196 */ 1260 */
1197 delay = MODE7_UTHR; 1261 delay = uthr;
1198 goto out; 1262 goto out;
1199 } 1263 }
1200 1264
@@ -1208,8 +1272,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
1208 substream->runtime->rate, 1272 substream->runtime->rate,
1209 time_delta); 1273 time_delta);
1210 1274
1211 if (likely(MODE7_UTHR > samples_out)) 1275 if (likely(uthr > samples_out))
1212 delay = MODE7_UTHR - samples_out; 1276 delay = uthr - samples_out;
1213 else 1277 else
1214 delay = 0; 1278 delay = 0;
1215 } else { 1279 } else {
@@ -1227,8 +1291,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
1227 time_delta); 1291 time_delta);
1228 delay = MODE7_LTHR + samples_in - samples_out; 1292 delay = MODE7_LTHR + samples_in - samples_out;
1229 1293
1230 if (unlikely(delay > MODE7_UTHR)) 1294 if (unlikely(delay > uthr))
1231 delay = MODE7_UTHR; 1295 delay = uthr;
1232 } 1296 }
1233 break; 1297 break;
1234 default: 1298 default:
@@ -1347,10 +1411,15 @@ static int dac33_soc_probe(struct platform_device *pdev)
1347 1411
1348 snd_soc_add_controls(codec, dac33_snd_controls, 1412 snd_soc_add_controls(codec, dac33_snd_controls,
1349 ARRAY_SIZE(dac33_snd_controls)); 1413 ARRAY_SIZE(dac33_snd_controls));
1350 /* Only add the nSample controls, if we have valid IRQ number */ 1414 /* Only add the FIFO controls, if we have valid IRQ number */
1351 if (dac33->irq >= 0) 1415 if (dac33->irq >= 0) {
1352 snd_soc_add_controls(codec, dac33_nsample_snd_controls, 1416 snd_soc_add_controls(codec, dac33_mode_snd_controls,
1353 ARRAY_SIZE(dac33_nsample_snd_controls)); 1417 ARRAY_SIZE(dac33_mode_snd_controls));
1418 /* FIFO usage controls only, if autoio config is not selected */
1419 if (!dac33->auto_fifo_config)
1420 snd_soc_add_controls(codec, dac33_fifo_snd_controls,
1421 ARRAY_SIZE(dac33_fifo_snd_controls));
1422 }
1354 1423
1355 dac33_add_widgets(codec); 1424 dac33_add_widgets(codec);
1356 1425
@@ -1481,9 +1550,14 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1481 /* Pre calculate the burst rate */ 1550 /* Pre calculate the burst rate */
1482 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32; 1551 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
1483 dac33->keep_bclk = pdata->keep_bclk; 1552 dac33->keep_bclk = pdata->keep_bclk;
1553 dac33->auto_fifo_config = pdata->auto_fifo_config;
1554 dac33->mode1_latency = pdata->mode1_latency;
1555 if (!dac33->mode1_latency)
1556 dac33->mode1_latency = 10000; /* 10ms */
1484 dac33->irq = client->irq; 1557 dac33->irq = client->irq;
1485 dac33->nsample = NSAMPLE_MAX; 1558 dac33->nsample = NSAMPLE_MAX;
1486 dac33->nsample_max = NSAMPLE_MAX; 1559 dac33->nsample_max = NSAMPLE_MAX;
1560 dac33->uthr = MODE7_UTHR;
1487 /* Disable FIFO use by default */ 1561 /* Disable FIFO use by default */
1488 dac33->fifo_mode = DAC33_FIFO_BYPASS; 1562 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1489 1563
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index b4fcdb01fc49..7b618bbff884 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -43,37 +43,37 @@
43 */ 43 */
44static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { 44static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
45 0x00, /* this register not used */ 45 0x00, /* this register not used */
46 0x91, /* REG_CODEC_MODE (0x1) */ 46 0x00, /* REG_CODEC_MODE (0x1) */
47 0xc3, /* REG_OPTION (0x2) */ 47 0x00, /* REG_OPTION (0x2) */
48 0x00, /* REG_UNKNOWN (0x3) */ 48 0x00, /* REG_UNKNOWN (0x3) */
49 0x00, /* REG_MICBIAS_CTL (0x4) */ 49 0x00, /* REG_MICBIAS_CTL (0x4) */
50 0x20, /* REG_ANAMICL (0x5) */ 50 0x00, /* REG_ANAMICL (0x5) */
51 0x00, /* REG_ANAMICR (0x6) */ 51 0x00, /* REG_ANAMICR (0x6) */
52 0x00, /* REG_AVADC_CTL (0x7) */ 52 0x00, /* REG_AVADC_CTL (0x7) */
53 0x00, /* REG_ADCMICSEL (0x8) */ 53 0x00, /* REG_ADCMICSEL (0x8) */
54 0x00, /* REG_DIGMIXING (0x9) */ 54 0x00, /* REG_DIGMIXING (0x9) */
55 0x0c, /* REG_ATXL1PGA (0xA) */ 55 0x0f, /* REG_ATXL1PGA (0xA) */
56 0x0c, /* REG_ATXR1PGA (0xB) */ 56 0x0f, /* REG_ATXR1PGA (0xB) */
57 0x00, /* REG_AVTXL2PGA (0xC) */ 57 0x0f, /* REG_AVTXL2PGA (0xC) */
58 0x00, /* REG_AVTXR2PGA (0xD) */ 58 0x0f, /* REG_AVTXR2PGA (0xD) */
59 0x00, /* REG_AUDIO_IF (0xE) */ 59 0x00, /* REG_AUDIO_IF (0xE) */
60 0x00, /* REG_VOICE_IF (0xF) */ 60 0x00, /* REG_VOICE_IF (0xF) */
61 0x00, /* REG_ARXR1PGA (0x10) */ 61 0x3f, /* REG_ARXR1PGA (0x10) */
62 0x00, /* REG_ARXL1PGA (0x11) */ 62 0x3f, /* REG_ARXL1PGA (0x11) */
63 0x6c, /* REG_ARXR2PGA (0x12) */ 63 0x3f, /* REG_ARXR2PGA (0x12) */
64 0x6c, /* REG_ARXL2PGA (0x13) */ 64 0x3f, /* REG_ARXL2PGA (0x13) */
65 0x00, /* REG_VRXPGA (0x14) */ 65 0x25, /* REG_VRXPGA (0x14) */
66 0x00, /* REG_VSTPGA (0x15) */ 66 0x00, /* REG_VSTPGA (0x15) */
67 0x00, /* REG_VRX2ARXPGA (0x16) */ 67 0x00, /* REG_VRX2ARXPGA (0x16) */
68 0x00, /* REG_AVDAC_CTL (0x17) */ 68 0x00, /* REG_AVDAC_CTL (0x17) */
69 0x00, /* REG_ARX2VTXPGA (0x18) */ 69 0x00, /* REG_ARX2VTXPGA (0x18) */
70 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ 70 0x32, /* REG_ARXL1_APGA_CTL (0x19) */
71 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ 71 0x32, /* REG_ARXR1_APGA_CTL (0x1A) */
72 0x4a, /* REG_ARXL2_APGA_CTL (0x1B) */ 72 0x32, /* REG_ARXL2_APGA_CTL (0x1B) */
73 0x4a, /* REG_ARXR2_APGA_CTL (0x1C) */ 73 0x32, /* REG_ARXR2_APGA_CTL (0x1C) */
74 0x00, /* REG_ATX2ARXPGA (0x1D) */ 74 0x00, /* REG_ATX2ARXPGA (0x1D) */
75 0x00, /* REG_BT_IF (0x1E) */ 75 0x00, /* REG_BT_IF (0x1E) */
76 0x00, /* REG_BTPGA (0x1F) */ 76 0x55, /* REG_BTPGA (0x1F) */
77 0x00, /* REG_BTSTPGA (0x20) */ 77 0x00, /* REG_BTSTPGA (0x20) */
78 0x00, /* REG_EAR_CTL (0x21) */ 78 0x00, /* REG_EAR_CTL (0x21) */
79 0x00, /* REG_HS_SEL (0x22) */ 79 0x00, /* REG_HS_SEL (0x22) */
@@ -85,32 +85,32 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
85 0x00, /* REG_PRECKR_CTL (0x28) */ 85 0x00, /* REG_PRECKR_CTL (0x28) */
86 0x00, /* REG_HFL_CTL (0x29) */ 86 0x00, /* REG_HFL_CTL (0x29) */
87 0x00, /* REG_HFR_CTL (0x2A) */ 87 0x00, /* REG_HFR_CTL (0x2A) */
88 0x00, /* REG_ALC_CTL (0x2B) */ 88 0x05, /* REG_ALC_CTL (0x2B) */
89 0x00, /* REG_ALC_SET1 (0x2C) */ 89 0x00, /* REG_ALC_SET1 (0x2C) */
90 0x00, /* REG_ALC_SET2 (0x2D) */ 90 0x00, /* REG_ALC_SET2 (0x2D) */
91 0x00, /* REG_BOOST_CTL (0x2E) */ 91 0x00, /* REG_BOOST_CTL (0x2E) */
92 0x00, /* REG_SOFTVOL_CTL (0x2F) */ 92 0x00, /* REG_SOFTVOL_CTL (0x2F) */
93 0x00, /* REG_DTMF_FREQSEL (0x30) */ 93 0x13, /* REG_DTMF_FREQSEL (0x30) */
94 0x00, /* REG_DTMF_TONEXT1H (0x31) */ 94 0x00, /* REG_DTMF_TONEXT1H (0x31) */
95 0x00, /* REG_DTMF_TONEXT1L (0x32) */ 95 0x00, /* REG_DTMF_TONEXT1L (0x32) */
96 0x00, /* REG_DTMF_TONEXT2H (0x33) */ 96 0x00, /* REG_DTMF_TONEXT2H (0x33) */
97 0x00, /* REG_DTMF_TONEXT2L (0x34) */ 97 0x00, /* REG_DTMF_TONEXT2L (0x34) */
98 0x00, /* REG_DTMF_TONOFF (0x35) */ 98 0x79, /* REG_DTMF_TONOFF (0x35) */
99 0x00, /* REG_DTMF_WANONOFF (0x36) */ 99 0x11, /* REG_DTMF_WANONOFF (0x36) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ 100 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ 101 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
102 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ 102 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
103 0x06, /* REG_APLL_CTL (0x3A) */ 103 0x06, /* REG_APLL_CTL (0x3A) */
104 0x00, /* REG_DTMF_CTL (0x3B) */ 104 0x00, /* REG_DTMF_CTL (0x3B) */
105 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ 105 0x44, /* REG_DTMF_PGA_CTL2 (0x3C) */
106 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ 106 0x69, /* REG_DTMF_PGA_CTL1 (0x3D) */
107 0x00, /* REG_MISC_SET_1 (0x3E) */ 107 0x00, /* REG_MISC_SET_1 (0x3E) */
108 0x00, /* REG_PCMBTMUX (0x3F) */ 108 0x00, /* REG_PCMBTMUX (0x3F) */
109 0x00, /* not used (0x40) */ 109 0x00, /* not used (0x40) */
110 0x00, /* not used (0x41) */ 110 0x00, /* not used (0x41) */
111 0x00, /* not used (0x42) */ 111 0x00, /* not used (0x42) */
112 0x00, /* REG_RX_PATH_SEL (0x43) */ 112 0x00, /* REG_RX_PATH_SEL (0x43) */
113 0x00, /* REG_VDL_APGA_CTL (0x44) */ 113 0x32, /* REG_VDL_APGA_CTL (0x44) */
114 0x00, /* REG_VIBRA_CTL (0x45) */ 114 0x00, /* REG_VIBRA_CTL (0x45) */
115 0x00, /* REG_VIBRA_SET (0x46) */ 115 0x00, /* REG_VIBRA_SET (0x46) */
116 0x00, /* REG_VIBRA_PWM_SET (0x47) */ 116 0x00, /* REG_VIBRA_PWM_SET (0x47) */
@@ -143,6 +143,9 @@ struct twl4030_priv {
143 u8 earpiece_enabled; 143 u8 earpiece_enabled;
144 u8 predrivel_enabled, predriver_enabled; 144 u8 predrivel_enabled, predriver_enabled;
145 u8 carkitl_enabled, carkitr_enabled; 145 u8 carkitl_enabled, carkitr_enabled;
146
147 /* Delay needed after enabling the digimic interface */
148 unsigned int digimic_delay;
146}; 149};
147 150
148/* 151/*
@@ -244,58 +247,95 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
244 udelay(10); 247 udelay(10);
245} 248}
246 249
247static void twl4030_init_chip(struct snd_soc_codec *codec) 250static inline void twl4030_check_defaults(struct snd_soc_codec *codec)
248{ 251{
249 u8 *cache = codec->reg_cache; 252 int i, difference = 0;
250 int i; 253 u8 val;
254
255 dev_dbg(codec->dev, "Checking TWL audio default configuration\n");
256 for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) {
257 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i);
258 if (val != twl4030_reg[i]) {
259 difference++;
260 dev_dbg(codec->dev,
261 "Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n",
262 i, val, twl4030_reg[i]);
263 }
264 }
265 dev_dbg(codec->dev, "Found %d non maching registers. %s\n",
266 difference, difference ? "Not OK" : "OK");
267}
251 268
252 /* clear CODECPDZ prior to setting register defaults */ 269static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
253 twl4030_codec_enable(codec, 0); 270{
271 int i;
254 272
255 /* set all audio section registers to reasonable defaults */ 273 /* set all audio section registers to reasonable defaults */
256 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) 274 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
257 if (i != TWL4030_REG_APLL_CTL) 275 if (i != TWL4030_REG_APLL_CTL)
258 twl4030_write(codec, i, cache[i]); 276 twl4030_write(codec, i, twl4030_reg[i]);
259 277
260} 278}
261 279
262static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) 280static void twl4030_init_chip(struct platform_device *pdev)
263{ 281{
282 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
283 struct twl4030_setup_data *setup = socdev->codec_data;
284 struct snd_soc_codec *codec = socdev->card->codec;
264 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
265 int status = -1; 286 u8 reg, byte;
287 int i = 0;
266 288
267 if (enable) { 289 /* Check defaults, if instructed before anything else */
268 twl4030->apll_enabled++; 290 if (setup && setup->check_defaults)
269 if (twl4030->apll_enabled == 1) 291 twl4030_check_defaults(codec);
270 status = twl4030_codec_enable_resource(
271 TWL4030_CODEC_RES_APLL);
272 } else {
273 twl4030->apll_enabled--;
274 if (!twl4030->apll_enabled)
275 status = twl4030_codec_disable_resource(
276 TWL4030_CODEC_RES_APLL);
277 }
278 292
279 if (status >= 0) 293 /* Reset registers, if no setup data or if instructed to do so */
280 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); 294 if (!setup || (setup && setup->reset_registers))
281} 295 twl4030_reset_registers(codec);
282 296
283static void twl4030_power_up(struct snd_soc_codec *codec) 297 /* Refresh APLL_CTL register from HW */
284{ 298 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 299 TWL4030_REG_APLL_CTL);
286 u8 anamicl, regmisc1, byte; 300 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte);
287 int i = 0; 301
302 /* anti-pop when changing analog gain */
303 reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
304 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
305 reg | TWL4030_SMOOTH_ANAVOL_EN);
288 306
289 if (twl4030->codec_powered) 307 twl4030_write(codec, TWL4030_REG_OPTION,
308 TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
309 TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
310
311 /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */
312 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
313
314 /* Machine dependent setup */
315 if (!setup)
290 return; 316 return;
291 317
292 /* set CODECPDZ to turn on codec */ 318 twl4030->digimic_delay = setup->digimic_delay;
293 twl4030_codec_enable(codec, 1); 319
320 /* Configuration for headset ramp delay from setup data */
321 if (setup->sysclk != twl4030->sysclk)
322 dev_warn(codec->dev,
323 "Mismatch in APLL mclk: %u (configured: %u)\n",
324 setup->sysclk, twl4030->sysclk);
325
326 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
327 reg &= ~TWL4030_RAMP_DELAY;
328 reg |= (setup->ramp_delay_value << 2);
329 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
294 330
295 /* initiate offset cancellation */ 331 /* initiate offset cancellation */
296 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); 332 twl4030_codec_enable(codec, 1);
333
334 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
335 reg &= ~TWL4030_OFFSET_CNCL_SEL;
336 reg |= setup->offset_cncl_path;
297 twl4030_write(codec, TWL4030_REG_ANAMICL, 337 twl4030_write(codec, TWL4030_REG_ANAMICL,
298 anamicl | TWL4030_CNCL_OFFSET_START); 338 reg | TWL4030_CNCL_OFFSET_START);
299 339
300 /* wait for offset cancellation to complete */ 340 /* wait for offset cancellation to complete */
301 do { 341 do {
@@ -310,23 +350,28 @@ static void twl4030_power_up(struct snd_soc_codec *codec)
310 /* Make sure that the reg_cache has the same value as the HW */ 350 /* Make sure that the reg_cache has the same value as the HW */
311 twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte); 351 twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte);
312 352
313 /* anti-pop when changing analog gain */
314 regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
315 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
316 regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
317
318 /* toggle CODECPDZ as per TRM */
319 twl4030_codec_enable(codec, 0); 353 twl4030_codec_enable(codec, 0);
320 twl4030_codec_enable(codec, 1);
321} 354}
322 355
323/* 356static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
324 * Unconditional power down
325 */
326static void twl4030_power_down(struct snd_soc_codec *codec)
327{ 357{
328 /* power down */ 358 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
329 twl4030_codec_enable(codec, 0); 359 int status = -1;
360
361 if (enable) {
362 twl4030->apll_enabled++;
363 if (twl4030->apll_enabled == 1)
364 status = twl4030_codec_enable_resource(
365 TWL4030_CODEC_RES_APLL);
366 } else {
367 twl4030->apll_enabled--;
368 if (!twl4030->apll_enabled)
369 status = twl4030_codec_disable_resource(
370 TWL4030_CODEC_RES_APLL);
371 }
372
373 if (status >= 0)
374 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
330} 375}
331 376
332/* Earpiece */ 377/* Earpiece */
@@ -500,10 +545,11 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
500static const struct snd_kcontrol_new twl4030_dapm_abypassv_control = 545static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
501 SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0); 546 SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
502 547
503/* Digital bypass gain, 0 mutes the bypass */ 548/* Digital bypass gain, mute instead of -30dB */
504static const unsigned int twl4030_dapm_dbypass_tlv[] = { 549static const unsigned int twl4030_dapm_dbypass_tlv[] = {
505 TLV_DB_RANGE_HEAD(2), 550 TLV_DB_RANGE_HEAD(3),
506 0, 3, TLV_DB_SCALE_ITEM(-2400, 0, 1), 551 0, 1, TLV_DB_SCALE_ITEM(-3000, 600, 1),
552 2, 3, TLV_DB_SCALE_ITEM(-2400, 0, 0),
507 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0), 553 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0),
508}; 554};
509 555
@@ -531,36 +577,6 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
531 TWL4030_REG_VSTPGA, 0, 0x29, 0, 577 TWL4030_REG_VSTPGA, 0, 0x29, 0,
532 twl4030_dapm_dbypassv_tlv); 578 twl4030_dapm_dbypassv_tlv);
533 579
534static int micpath_event(struct snd_soc_dapm_widget *w,
535 struct snd_kcontrol *kcontrol, int event)
536{
537 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
538 unsigned char adcmicsel, micbias_ctl;
539
540 adcmicsel = twl4030_read_reg_cache(w->codec, TWL4030_REG_ADCMICSEL);
541 micbias_ctl = twl4030_read_reg_cache(w->codec, TWL4030_REG_MICBIAS_CTL);
542 /* Prepare the bits for the given TX path:
543 * shift_l == 0: TX1 microphone path
544 * shift_l == 2: TX2 microphone path */
545 if (e->shift_l) {
546 /* TX2 microphone path */
547 if (adcmicsel & TWL4030_TX2IN_SEL)
548 micbias_ctl |= TWL4030_MICBIAS2_CTL; /* digimic */
549 else
550 micbias_ctl &= ~TWL4030_MICBIAS2_CTL;
551 } else {
552 /* TX1 microphone path */
553 if (adcmicsel & TWL4030_TX1IN_SEL)
554 micbias_ctl |= TWL4030_MICBIAS1_CTL; /* digimic */
555 else
556 micbias_ctl &= ~TWL4030_MICBIAS1_CTL;
557 }
558
559 twl4030_write(w->codec, TWL4030_REG_MICBIAS_CTL, micbias_ctl);
560
561 return 0;
562}
563
564/* 580/*
565 * Output PGA builder: 581 * Output PGA builder:
566 * Handle the muting and unmuting of the given output (turning off the 582 * Handle the muting and unmuting of the given output (turning off the
@@ -814,6 +830,16 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
814 return 0; 830 return 0;
815} 831}
816 832
833static int digimic_event(struct snd_soc_dapm_widget *w,
834 struct snd_kcontrol *kcontrol, int event)
835{
836 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
837
838 if (twl4030->digimic_delay)
839 mdelay(twl4030->digimic_delay);
840 return 0;
841}
842
817/* 843/*
818 * Some of the gain controls in TWL (mostly those which are associated with 844 * Some of the gain controls in TWL (mostly those which are associated with
819 * the outputs) are implemented in an interesting way: 845 * the outputs) are implemented in an interesting way:
@@ -1374,14 +1400,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1374 /* Analog/Digital mic path selection. 1400 /* Analog/Digital mic path selection.
1375 TX1 Left/Right: either analog Left/Right or Digimic0 1401 TX1 Left/Right: either analog Left/Right or Digimic0
1376 TX2 Left/Right: either analog Left/Right or Digimic1 */ 1402 TX2 Left/Right: either analog Left/Right or Digimic1 */
1377 SND_SOC_DAPM_MUX_E("TX1 Capture Route", SND_SOC_NOPM, 0, 0, 1403 SND_SOC_DAPM_MUX("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
1378 &twl4030_dapm_micpathtx1_control, micpath_event, 1404 &twl4030_dapm_micpathtx1_control),
1379 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD| 1405 SND_SOC_DAPM_MUX("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
1380 SND_SOC_DAPM_POST_REG), 1406 &twl4030_dapm_micpathtx2_control),
1381 SND_SOC_DAPM_MUX_E("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
1382 &twl4030_dapm_micpathtx2_control, micpath_event,
1383 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
1384 SND_SOC_DAPM_POST_REG),
1385 1407
1386 /* Analog input mixers for the capture amplifiers */ 1408 /* Analog input mixers for the capture amplifiers */
1387 SND_SOC_DAPM_MIXER("Analog Left", 1409 SND_SOC_DAPM_MIXER("Analog Left",
@@ -1398,10 +1420,17 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1398 SND_SOC_DAPM_PGA("ADC Physical Right", 1420 SND_SOC_DAPM_PGA("ADC Physical Right",
1399 TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0), 1421 TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0),
1400 1422
1401 SND_SOC_DAPM_PGA("Digimic0 Enable", 1423 SND_SOC_DAPM_PGA_E("Digimic0 Enable",
1402 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0), 1424 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0,
1403 SND_SOC_DAPM_PGA("Digimic1 Enable", 1425 digimic_event, SND_SOC_DAPM_POST_PMU),
1404 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0), 1426 SND_SOC_DAPM_PGA_E("Digimic1 Enable",
1427 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0,
1428 digimic_event, SND_SOC_DAPM_POST_PMU),
1429
1430 SND_SOC_DAPM_SUPPLY("micbias1 select", TWL4030_REG_MICBIAS_CTL, 5, 0,
1431 NULL, 0),
1432 SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0,
1433 NULL, 0),
1405 1434
1406 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), 1435 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
1407 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), 1436 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
@@ -1419,8 +1448,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1419 /* Supply for the digital part (APLL) */ 1448 /* Supply for the digital part (APLL) */
1420 {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, 1449 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1421 1450
1422 {"Digital R1 Playback Mixer", NULL, "AIF Enable"}, 1451 {"DAC Left1", NULL, "AIF Enable"},
1423 {"Digital L1 Playback Mixer", NULL, "AIF Enable"}, 1452 {"DAC Right1", NULL, "AIF Enable"},
1453 {"DAC Left2", NULL, "AIF Enable"},
1454 {"DAC Right1", NULL, "AIF Enable"},
1455
1424 {"Digital R2 Playback Mixer", NULL, "AIF Enable"}, 1456 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1425 {"Digital L2 Playback Mixer", NULL, "AIF Enable"}, 1457 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1426 1458
@@ -1491,10 +1523,10 @@ static const struct snd_soc_dapm_route intercon[] = {
1491 1523
1492 /* outputs */ 1524 /* outputs */
1493 /* Must be always connected (for AIF and APLL) */ 1525 /* Must be always connected (for AIF and APLL) */
1494 {"Virtual HiFi OUT", NULL, "Digital L1 Playback Mixer"}, 1526 {"Virtual HiFi OUT", NULL, "DAC Left1"},
1495 {"Virtual HiFi OUT", NULL, "Digital R1 Playback Mixer"}, 1527 {"Virtual HiFi OUT", NULL, "DAC Right1"},
1496 {"Virtual HiFi OUT", NULL, "Digital L2 Playback Mixer"}, 1528 {"Virtual HiFi OUT", NULL, "DAC Left2"},
1497 {"Virtual HiFi OUT", NULL, "Digital R2 Playback Mixer"}, 1529 {"Virtual HiFi OUT", NULL, "DAC Right2"},
1498 /* Must be always connected (for APLL) */ 1530 /* Must be always connected (for APLL) */
1499 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"}, 1531 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"},
1500 /* Physical outputs */ 1532 /* Physical outputs */
@@ -1531,6 +1563,9 @@ static const struct snd_soc_dapm_route intercon[] = {
1531 {"Digimic0 Enable", NULL, "DIGIMIC0"}, 1563 {"Digimic0 Enable", NULL, "DIGIMIC0"},
1532 {"Digimic1 Enable", NULL, "DIGIMIC1"}, 1564 {"Digimic1 Enable", NULL, "DIGIMIC1"},
1533 1565
1566 {"DIGIMIC0", NULL, "micbias1 select"},
1567 {"DIGIMIC1", NULL, "micbias2 select"},
1568
1534 /* TX1 Left capture path */ 1569 /* TX1 Left capture path */
1535 {"TX1 Capture Route", "Analog", "ADC Physical Left"}, 1570 {"TX1 Capture Route", "Analog", "ADC Physical Left"},
1536 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, 1571 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
@@ -1605,10 +1640,10 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1605 break; 1640 break;
1606 case SND_SOC_BIAS_STANDBY: 1641 case SND_SOC_BIAS_STANDBY:
1607 if (codec->bias_level == SND_SOC_BIAS_OFF) 1642 if (codec->bias_level == SND_SOC_BIAS_OFF)
1608 twl4030_power_up(codec); 1643 twl4030_codec_enable(codec, 1);
1609 break; 1644 break;
1610 case SND_SOC_BIAS_OFF: 1645 case SND_SOC_BIAS_OFF:
1611 twl4030_power_down(codec); 1646 twl4030_codec_enable(codec, 0);
1612 break; 1647 break;
1613 } 1648 }
1614 codec->bias_level = level; 1649 codec->bias_level = level;
@@ -1794,13 +1829,6 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1794 return -EINVAL; 1829 return -EINVAL;
1795 } 1830 }
1796 1831
1797 if (mode != old_mode) {
1798 /* change rate and set CODECPDZ */
1799 twl4030_codec_enable(codec, 0);
1800 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1801 twl4030_codec_enable(codec, 1);
1802 }
1803
1804 /* sample size */ 1832 /* sample size */
1805 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); 1833 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1806 format = old_format; 1834 format = old_format;
@@ -1818,16 +1846,20 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1818 return -EINVAL; 1846 return -EINVAL;
1819 } 1847 }
1820 1848
1821 if (format != old_format) { 1849 if (format != old_format || mode != old_mode) {
1822 1850 if (twl4030->codec_powered) {
1823 /* clear CODECPDZ before changing format (codec requirement) */ 1851 /*
1824 twl4030_codec_enable(codec, 0); 1852 * If the codec is powered, than we need to toggle the
1825 1853 * codec power.
1826 /* change format */ 1854 */
1827 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); 1855 twl4030_codec_enable(codec, 0);
1828 1856 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1829 /* set CODECPDZ afterwards */ 1857 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1830 twl4030_codec_enable(codec, 1); 1858 twl4030_codec_enable(codec, 1);
1859 } else {
1860 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1861 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1862 }
1831 } 1863 }
1832 1864
1833 /* Store the important parameters for the DAI configuration and set 1865 /* Store the important parameters for the DAI configuration and set
@@ -1877,6 +1909,7 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1877 unsigned int fmt) 1909 unsigned int fmt)
1878{ 1910{
1879 struct snd_soc_codec *codec = codec_dai->codec; 1911 struct snd_soc_codec *codec = codec_dai->codec;
1912 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1880 u8 old_format, format; 1913 u8 old_format, format;
1881 1914
1882 /* get format */ 1915 /* get format */
@@ -1911,15 +1944,17 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1911 } 1944 }
1912 1945
1913 if (format != old_format) { 1946 if (format != old_format) {
1914 1947 if (twl4030->codec_powered) {
1915 /* clear CODECPDZ before changing format (codec requirement) */ 1948 /*
1916 twl4030_codec_enable(codec, 0); 1949 * If the codec is powered, than we need to toggle the
1917 1950 * codec power.
1918 /* change format */ 1951 */
1919 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); 1952 twl4030_codec_enable(codec, 0);
1920 1953 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1921 /* set CODECPDZ afterwards */ 1954 twl4030_codec_enable(codec, 1);
1922 twl4030_codec_enable(codec, 1); 1955 } else {
1956 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1957 }
1923 } 1958 }
1924 1959
1925 return 0; 1960 return 0;
@@ -2011,6 +2046,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2011 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2046 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2012 struct snd_soc_device *socdev = rtd->socdev; 2047 struct snd_soc_device *socdev = rtd->socdev;
2013 struct snd_soc_codec *codec = socdev->card->codec; 2048 struct snd_soc_codec *codec = socdev->card->codec;
2049 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2014 u8 old_mode, mode; 2050 u8 old_mode, mode;
2015 2051
2016 /* Enable voice digital filters */ 2052 /* Enable voice digital filters */
@@ -2035,10 +2071,17 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2035 } 2071 }
2036 2072
2037 if (mode != old_mode) { 2073 if (mode != old_mode) {
2038 /* change rate and set CODECPDZ */ 2074 if (twl4030->codec_powered) {
2039 twl4030_codec_enable(codec, 0); 2075 /*
2040 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); 2076 * If the codec is powered, than we need to toggle the
2041 twl4030_codec_enable(codec, 1); 2077 * codec power.
2078 */
2079 twl4030_codec_enable(codec, 0);
2080 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
2081 twl4030_codec_enable(codec, 1);
2082 } else {
2083 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
2084 }
2042 } 2085 }
2043 2086
2044 return 0; 2087 return 0;
@@ -2068,6 +2111,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
2068 unsigned int fmt) 2111 unsigned int fmt)
2069{ 2112{
2070 struct snd_soc_codec *codec = codec_dai->codec; 2113 struct snd_soc_codec *codec = codec_dai->codec;
2114 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2071 u8 old_format, format; 2115 u8 old_format, format;
2072 2116
2073 /* get format */ 2117 /* get format */
@@ -2099,10 +2143,17 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
2099 } 2143 }
2100 2144
2101 if (format != old_format) { 2145 if (format != old_format) {
2102 /* change format and set CODECPDZ */ 2146 if (twl4030->codec_powered) {
2103 twl4030_codec_enable(codec, 0); 2147 /*
2104 twl4030_write(codec, TWL4030_REG_VOICE_IF, format); 2148 * If the codec is powered, than we need to toggle the
2105 twl4030_codec_enable(codec, 1); 2149 * codec power.
2150 */
2151 twl4030_codec_enable(codec, 0);
2152 twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
2153 twl4030_codec_enable(codec, 1);
2154 } else {
2155 twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
2156 }
2106 } 2157 }
2107 2158
2108 return 0; 2159 return 0;
@@ -2202,31 +2253,15 @@ static struct snd_soc_codec *twl4030_codec;
2202static int twl4030_soc_probe(struct platform_device *pdev) 2253static int twl4030_soc_probe(struct platform_device *pdev)
2203{ 2254{
2204 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2205 struct twl4030_setup_data *setup = socdev->codec_data;
2206 struct snd_soc_codec *codec; 2256 struct snd_soc_codec *codec;
2207 struct twl4030_priv *twl4030;
2208 int ret; 2257 int ret;
2209 2258
2210 BUG_ON(!twl4030_codec); 2259 BUG_ON(!twl4030_codec);
2211 2260
2212 codec = twl4030_codec; 2261 codec = twl4030_codec;
2213 twl4030 = snd_soc_codec_get_drvdata(codec);
2214 socdev->card->codec = codec; 2262 socdev->card->codec = codec;
2215 2263
2216 /* Configuration for headset ramp delay from setup data */ 2264 twl4030_init_chip(pdev);
2217 if (setup) {
2218 unsigned char hs_pop;
2219
2220 if (setup->sysclk != twl4030->sysclk)
2221 dev_warn(&pdev->dev,
2222 "Mismatch in APLL mclk: %u (configured: %u)\n",
2223 setup->sysclk, twl4030->sysclk);
2224
2225 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
2226 hs_pop &= ~TWL4030_RAMP_DELAY;
2227 hs_pop |= (setup->ramp_delay_value << 2);
2228 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
2229 }
2230 2265
2231 /* register pcms */ 2266 /* register pcms */
2232 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2267 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -2247,6 +2282,8 @@ static int twl4030_soc_remove(struct platform_device *pdev)
2247 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2282 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2248 struct snd_soc_codec *codec = socdev->card->codec; 2283 struct snd_soc_codec *codec = socdev->card->codec;
2249 2284
2285 /* Reset registers to their chip default before leaving */
2286 twl4030_reset_registers(codec);
2250 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2287 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2251 snd_soc_free_pcms(socdev); 2288 snd_soc_free_pcms(socdev);
2252 snd_soc_dapm_free(socdev); 2289 snd_soc_dapm_free(socdev);
@@ -2287,6 +2324,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2287 codec->read = twl4030_read_reg_cache; 2324 codec->read = twl4030_read_reg_cache;
2288 codec->write = twl4030_write; 2325 codec->write = twl4030_write;
2289 codec->set_bias_level = twl4030_set_bias_level; 2326 codec->set_bias_level = twl4030_set_bias_level;
2327 codec->idle_bias_off = 1;
2290 codec->dai = twl4030_dai; 2328 codec->dai = twl4030_dai;
2291 codec->num_dai = ARRAY_SIZE(twl4030_dai); 2329 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2292 codec->reg_cache_size = sizeof(twl4030_reg); 2330 codec->reg_cache_size = sizeof(twl4030_reg);
@@ -2302,9 +2340,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2302 2340
2303 /* Set the defaults, and power up the codec */ 2341 /* Set the defaults, and power up the codec */
2304 twl4030->sysclk = twl4030_codec_get_mclk() / 1000; 2342 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2305 twl4030_init_chip(codec);
2306 codec->bias_level = SND_SOC_BIAS_OFF; 2343 codec->bias_level = SND_SOC_BIAS_OFF;
2307 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2308 2344
2309 ret = snd_soc_register_codec(codec); 2345 ret = snd_soc_register_codec(codec);
2310 if (ret != 0) { 2346 if (ret != 0) {
@@ -2322,7 +2358,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2322 return 0; 2358 return 0;
2323 2359
2324error_codec: 2360error_codec:
2325 twl4030_power_down(codec); 2361 twl4030_codec_enable(codec, 0);
2326 kfree(codec->reg_cache); 2362 kfree(codec->reg_cache);
2327error_cache: 2363error_cache:
2328 kfree(twl4030); 2364 kfree(twl4030);
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index f206d242ca31..6c57430f6e24 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -41,7 +41,11 @@ extern struct snd_soc_codec_device soc_codec_dev_twl4030;
41 41
42struct twl4030_setup_data { 42struct twl4030_setup_data {
43 unsigned int ramp_delay_value; 43 unsigned int ramp_delay_value;
44 unsigned int digimic_delay; /* in ms */
44 unsigned int sysclk; 45 unsigned int sysclk;
46 unsigned int offset_cncl_path;
47 unsigned int check_defaults:1;
48 unsigned int reset_registers:1;
45 unsigned int hs_extmute:1; 49 unsigned int hs_extmute:1;
46 void (*set_hs_extmute)(int mute); 50 void (*set_hs_extmute)(int mute);
47}; 51};
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index af36346ff336..64a807f1a8a1 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -360,6 +360,13 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
360 return 0; 360 return 0;
361} 361}
362 362
363static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
364 struct snd_kcontrol *kcontrol, int event)
365{
366 msleep(1);
367 return 0;
368}
369
363static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, 370static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
364 struct snd_kcontrol *kcontrol, int event) 371 struct snd_kcontrol *kcontrol, int event)
365{ 372{
@@ -371,6 +378,8 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
371 else 378 else
372 priv->non_lp--; 379 priv->non_lp--;
373 380
381 msleep(1);
382
374 return 0; 383 return 0;
375} 384}
376 385
@@ -471,20 +480,6 @@ static const struct snd_kcontrol_new hfdacl_switch_controls =
471static const struct snd_kcontrol_new hfdacr_switch_controls = 480static const struct snd_kcontrol_new hfdacr_switch_controls =
472 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0); 481 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0);
473 482
474/* Headset driver switches */
475static const struct snd_kcontrol_new hsl_driver_switch_controls =
476 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 2, 1, 0);
477
478static const struct snd_kcontrol_new hsr_driver_switch_controls =
479 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 2, 1, 0);
480
481/* Handsfree driver switches */
482static const struct snd_kcontrol_new hfl_driver_switch_controls =
483 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 4, 1, 0);
484
485static const struct snd_kcontrol_new hfr_driver_switch_controls =
486 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 4, 1, 0);
487
488static const struct snd_kcontrol_new ep_driver_switch_controls = 483static const struct snd_kcontrol_new ep_driver_switch_controls =
489 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); 484 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
490 485
@@ -548,10 +543,14 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
548 TWL6040_REG_DMICBCTL, 4, 0), 543 TWL6040_REG_DMICBCTL, 4, 0),
549 544
550 /* DACs */ 545 /* DACs */
551 SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", 546 SND_SOC_DAPM_DAC_E("HSDAC Left", "Headset Playback",
552 TWL6040_REG_HSLCTL, 0, 0), 547 TWL6040_REG_HSLCTL, 0, 0,
553 SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", 548 twl6040_hs_dac_event,
554 TWL6040_REG_HSRCTL, 0, 0), 549 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
550 SND_SOC_DAPM_DAC_E("HSDAC Right", "Headset Playback",
551 TWL6040_REG_HSRCTL, 0, 0,
552 twl6040_hs_dac_event,
553 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
555 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", 554 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback",
556 TWL6040_REG_HFLCTL, 0, 0, 555 TWL6040_REG_HFLCTL, 0, 0,
557 twl6040_power_mode_event, 556 twl6040_power_mode_event,
@@ -571,18 +570,19 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
571 SND_SOC_DAPM_SWITCH("HFDAC Right Playback", 570 SND_SOC_DAPM_SWITCH("HFDAC Right Playback",
572 SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls), 571 SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls),
573 572
574 SND_SOC_DAPM_SWITCH("Headset Left Driver", 573 /* Analog playback drivers */
575 SND_SOC_NOPM, 0, 0, &hsl_driver_switch_controls), 574 SND_SOC_DAPM_PGA_E("Handsfree Left Driver",
576 SND_SOC_DAPM_SWITCH("Headset Right Driver", 575 TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
577 SND_SOC_NOPM, 0, 0, &hsr_driver_switch_controls),
578 SND_SOC_DAPM_SWITCH_E("Handsfree Left Driver",
579 SND_SOC_NOPM, 0, 0, &hfl_driver_switch_controls,
580 twl6040_power_mode_event, 576 twl6040_power_mode_event,
581 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 577 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
582 SND_SOC_DAPM_SWITCH_E("Handsfree Right Driver", 578 SND_SOC_DAPM_PGA_E("Handsfree Right Driver",
583 SND_SOC_NOPM, 0, 0, &hfr_driver_switch_controls, 579 TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
584 twl6040_power_mode_event, 580 twl6040_power_mode_event,
585 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 581 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
582 SND_SOC_DAPM_PGA("Headset Left Driver",
583 TWL6040_REG_HSLCTL, 2, 0, NULL, 0),
584 SND_SOC_DAPM_PGA("Headset Right Driver",
585 TWL6040_REG_HSRCTL, 2, 0, NULL, 0),
586 SND_SOC_DAPM_SWITCH_E("Earphone Driver", 586 SND_SOC_DAPM_SWITCH_E("Earphone Driver",
587 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, 587 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
588 twl6040_power_mode_event, 588 twl6040_power_mode_event,
@@ -616,8 +616,8 @@ static const struct snd_soc_dapm_route intercon[] = {
616 {"HSDAC Left Playback", "Switch", "HSDAC Left"}, 616 {"HSDAC Left Playback", "Switch", "HSDAC Left"},
617 {"HSDAC Right Playback", "Switch", "HSDAC Right"}, 617 {"HSDAC Right Playback", "Switch", "HSDAC Right"},
618 618
619 {"Headset Left Driver", "Switch", "HSDAC Left Playback"}, 619 {"Headset Left Driver", NULL, "HSDAC Left Playback"},
620 {"Headset Right Driver", "Switch", "HSDAC Right Playback"}, 620 {"Headset Right Driver", NULL, "HSDAC Right Playback"},
621 621
622 {"HSOL", NULL, "Headset Left Driver"}, 622 {"HSOL", NULL, "Headset Left Driver"},
623 {"HSOR", NULL, "Headset Right Driver"}, 623 {"HSOR", NULL, "Headset Right Driver"},
@@ -928,7 +928,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
928 case 19200000: 928 case 19200000:
929 /* mclk input, pll disabled */ 929 /* mclk input, pll disabled */
930 hppllctl |= TWL6040_MCLK_19200KHZ | 930 hppllctl |= TWL6040_MCLK_19200KHZ |
931 TWL6040_HPLLSQRBP | 931 TWL6040_HPLLSQRENA |
932 TWL6040_HPLLBP; 932 TWL6040_HPLLBP;
933 break; 933 break;
934 case 26000000: 934 case 26000000:
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 28aac53c97bb..f3b4c1d6a82d 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -28,19 +28,6 @@
28#include "uda134x.h" 28#include "uda134x.h"
29 29
30 30
31#define POWER_OFF_ON_STANDBY 1
32/*
33 ALSA SOC usually puts the device in standby mode when it's not used
34 for sometime. If you define POWER_OFF_ON_STANDBY the driver will
35 turn off the ADC/DAC when this callback is invoked and turn it back
36 on when needed. Unfortunately this will result in a very light bump
37 (it can be audible only with good earphones). If this bothers you
38 just comment this line, you will have slightly higher power
39 consumption . Please note that sending the L3 command for ADC is
40 enough to make the bump, so it doesn't make difference if you
41 completely take off power from the codec.
42 */
43
44#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000 31#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
45#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ 32#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
46 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE) 33 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
@@ -58,7 +45,7 @@ static const char uda134x_reg[UDA134X_REGS_NUM] = {
58 /* Extended address registers */ 45 /* Extended address registers */
59 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 46 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
60 /* Status, data regs */ 47 /* Status, data regs */
61 0x00, 0x83, 0x00, 0x40, 0x80, 0x00, 48 0x00, 0x83, 0x00, 0x40, 0x80, 0xC0, 0x00,
62}; 49};
63 50
64/* 51/*
@@ -117,6 +104,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
117 case UDA134X_DATA000: 104 case UDA134X_DATA000:
118 case UDA134X_DATA001: 105 case UDA134X_DATA001:
119 case UDA134X_DATA010: 106 case UDA134X_DATA010:
107 case UDA134X_DATA011:
120 addr = UDA134X_DATA0_ADDR; 108 addr = UDA134X_DATA0_ADDR;
121 break; 109 break;
122 case UDA134X_DATA1: 110 case UDA134X_DATA1:
@@ -353,8 +341,22 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
353 switch (level) { 341 switch (level) {
354 case SND_SOC_BIAS_ON: 342 case SND_SOC_BIAS_ON:
355 /* ADC, DAC on */ 343 /* ADC, DAC on */
356 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1); 344 switch (pd->model) {
357 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03); 345 case UDA134X_UDA1340:
346 case UDA134X_UDA1344:
347 case UDA134X_UDA1345:
348 reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
349 uda134x_write(codec, UDA134X_DATA011, reg | 0x03);
350 break;
351 case UDA134X_UDA1341:
352 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
353 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
354 break;
355 default:
356 printk(KERN_ERR "UDA134X SoC codec: "
357 "unsupported model %d\n", pd->model);
358 return -EINVAL;
359 }
358 break; 360 break;
359 case SND_SOC_BIAS_PREPARE: 361 case SND_SOC_BIAS_PREPARE:
360 /* power on */ 362 /* power on */
@@ -367,8 +369,22 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
367 break; 369 break;
368 case SND_SOC_BIAS_STANDBY: 370 case SND_SOC_BIAS_STANDBY:
369 /* ADC, DAC power off */ 371 /* ADC, DAC power off */
370 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1); 372 switch (pd->model) {
371 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03)); 373 case UDA134X_UDA1340:
374 case UDA134X_UDA1344:
375 case UDA134X_UDA1345:
376 reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
377 uda134x_write(codec, UDA134X_DATA011, reg & ~(0x03));
378 break;
379 case UDA134X_UDA1341:
380 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
381 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
382 break;
383 default:
384 printk(KERN_ERR "UDA134X SoC codec: "
385 "unsupported model %d\n", pd->model);
386 return -EINVAL;
387 }
372 break; 388 break;
373 case SND_SOC_BIAS_OFF: 389 case SND_SOC_BIAS_OFF:
374 /* power off */ 390 /* power off */
@@ -531,9 +547,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
531 codec->num_dai = 1; 547 codec->num_dai = 1;
532 codec->read = uda134x_read_reg_cache; 548 codec->read = uda134x_read_reg_cache;
533 codec->write = uda134x_write; 549 codec->write = uda134x_write;
534#ifdef POWER_OFF_ON_STANDBY 550
535 codec->set_bias_level = uda134x_set_bias_level;
536#endif
537 INIT_LIST_HEAD(&codec->dapm_widgets); 551 INIT_LIST_HEAD(&codec->dapm_widgets);
538 INIT_LIST_HEAD(&codec->dapm_paths); 552 INIT_LIST_HEAD(&codec->dapm_paths);
539 553
@@ -544,6 +558,14 @@ static int uda134x_soc_probe(struct platform_device *pdev)
544 558
545 uda134x_reset(codec); 559 uda134x_reset(codec);
546 560
561 if (pd->is_powered_on_standby) {
562 codec->set_bias_level = NULL;
563 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
564 } else {
565 codec->set_bias_level = uda134x_set_bias_level;
566 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 }
568
547 /* register pcms */ 569 /* register pcms */
548 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 570 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
549 if (ret < 0) { 571 if (ret < 0) {
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
index 94f440490b31..205f03b3eaf8 100644
--- a/sound/soc/codecs/uda134x.h
+++ b/sound/soc/codecs/uda134x.h
@@ -23,9 +23,10 @@
23#define UDA134X_DATA000 10 23#define UDA134X_DATA000 10
24#define UDA134X_DATA001 11 24#define UDA134X_DATA001 11
25#define UDA134X_DATA010 12 25#define UDA134X_DATA010 12
26#define UDA134X_DATA1 13 26#define UDA134X_DATA011 13
27#define UDA134X_DATA1 14
27 28
28#define UDA134X_REGS_NUM 14 29#define UDA134X_REGS_NUM 15
29 30
30#define STATUS0_DAIFMT_MASK (~(7<<1)) 31#define STATUS0_DAIFMT_MASK (~(7<<1))
31#define STATUS0_SYSCLK_MASK (~(3<<4)) 32#define STATUS0_SYSCLK_MASK (~(3<<4))
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 002e289d1255..4bcd168794e1 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -795,6 +795,8 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
795 795
796 dev_set_drvdata(&i2c->dev, wm2000); 796 dev_set_drvdata(&i2c->dev, wm2000);
797 wm2000->anc_eng_ena = 1; 797 wm2000->anc_eng_ena = 1;
798 wm2000->anc_active = 1;
799 wm2000->spk_ena = 1;
798 wm2000->i2c = i2c; 800 wm2000->i2c = i2c;
799 801
800 wm2000_reset(wm2000); 802 wm2000_reset(wm2000);
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 37242a7d3077..0ad039b4adf5 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -482,7 +482,8 @@ static int wm8523_register(struct wm8523_priv *wm8523,
482 482
483 if (wm8523_codec) { 483 if (wm8523_codec) {
484 dev_err(codec->dev, "Another WM8523 is registered\n"); 484 dev_err(codec->dev, "Another WM8523 is registered\n");
485 return -EINVAL; 485 ret = -EINVAL;
486 goto err;
486 } 487 }
487 488
488 mutex_init(&codec->mutex); 489 mutex_init(&codec->mutex);
@@ -570,18 +571,19 @@ static int wm8523_register(struct wm8523_priv *wm8523,
570 ret = snd_soc_register_codec(codec); 571 ret = snd_soc_register_codec(codec);
571 if (ret != 0) { 572 if (ret != 0) {
572 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 573 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
573 return ret; 574 goto err_enable;
574 } 575 }
575 576
576 ret = snd_soc_register_dai(&wm8523_dai); 577 ret = snd_soc_register_dai(&wm8523_dai);
577 if (ret != 0) { 578 if (ret != 0) {
578 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 579 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
579 snd_soc_unregister_codec(codec); 580 goto err_codec;
580 return ret;
581 } 581 }
582 582
583 return 0; 583 return 0;
584 584
585err_codec:
586 snd_soc_unregister_codec(codec);
585err_enable: 587err_enable:
586 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 588 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
587err_get: 589err_get:
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index c3571ee5c11b..72deeabef4fe 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -269,9 +269,9 @@ SOC_DOUBLE("DAC2 Invert Switch", WM8580_DAC_CONTROL4, 2, 3, 1, 0),
269SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0), 269SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0),
270 270
271SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0), 271SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0),
272SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 0), 272SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 1),
273SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 0), 273SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 1),
274SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 0), 274SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 1),
275 275
276SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0), 276SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
277SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), 277SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index effb14eee7d4..e2dba07f0260 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -439,7 +439,8 @@ static int wm8711_register(struct wm8711_priv *wm8711,
439 439
440 if (wm8711_codec) { 440 if (wm8711_codec) {
441 dev_err(codec->dev, "Another WM8711 is registered\n"); 441 dev_err(codec->dev, "Another WM8711 is registered\n");
442 return -EINVAL; 442 ret = -EINVAL;
443 goto err;
443 } 444 }
444 445
445 mutex_init(&codec->mutex); 446 mutex_init(&codec->mutex);
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
new file mode 100644
index 000000000000..b9ea8904ad4b
--- /dev/null
+++ b/sound/soc/codecs/wm8741.c
@@ -0,0 +1,579 @@
1/*
2 * wm8741.c -- WM8741 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "wm8741.h"
32
33static struct snd_soc_codec *wm8741_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8741;
35
36#define WM8741_NUM_SUPPLIES 2
37static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
38 "AVDD",
39 "DVDD",
40};
41
42#define WM8741_NUM_RATES 4
43
44/* codec private data */
45struct wm8741_priv {
46 struct snd_soc_codec codec;
47 u16 reg_cache[WM8741_REGISTER_COUNT];
48 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
49 unsigned int sysclk;
50 unsigned int rate_constraint_list[WM8741_NUM_RATES];
51 struct snd_pcm_hw_constraint_list rate_constraint;
52};
53
54static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = {
55 0x0000, /* R0 - DACLLSB Attenuation */
56 0x0000, /* R1 - DACLMSB Attenuation */
57 0x0000, /* R2 - DACRLSB Attenuation */
58 0x0000, /* R3 - DACRMSB Attenuation */
59 0x0000, /* R4 - Volume Control */
60 0x000A, /* R5 - Format Control */
61 0x0000, /* R6 - Filter Control */
62 0x0000, /* R7 - Mode Control 1 */
63 0x0002, /* R8 - Mode Control 2 */
64 0x0000, /* R9 - Reset */
65 0x0002, /* R32 - ADDITONAL_CONTROL_1 */
66};
67
68
69static int wm8741_reset(struct snd_soc_codec *codec)
70{
71 return snd_soc_write(codec, WM8741_RESET, 0);
72}
73
74static const DECLARE_TLV_DB_SCALE(dac_tlv_fine, -12700, 13, 0);
75static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 400, 0);
76
77static const struct snd_kcontrol_new wm8741_snd_controls[] = {
78SOC_DOUBLE_R_TLV("Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,
79 WM8741_DACRLSB_ATTENUATION, 1, 255, 1, dac_tlv_fine),
80SOC_DOUBLE_R_TLV("Playback Volume", WM8741_DACLMSB_ATTENUATION,
81 WM8741_DACRMSB_ATTENUATION, 0, 511, 1, dac_tlv),
82};
83
84static const struct snd_soc_dapm_widget wm8741_dapm_widgets[] = {
85SND_SOC_DAPM_DAC("DACL", "Playback", SND_SOC_NOPM, 0, 0),
86SND_SOC_DAPM_DAC("DACR", "Playback", SND_SOC_NOPM, 0, 0),
87SND_SOC_DAPM_OUTPUT("VOUTLP"),
88SND_SOC_DAPM_OUTPUT("VOUTLN"),
89SND_SOC_DAPM_OUTPUT("VOUTRP"),
90SND_SOC_DAPM_OUTPUT("VOUTRN"),
91};
92
93static const struct snd_soc_dapm_route intercon[] = {
94 { "VOUTLP", NULL, "DACL" },
95 { "VOUTLN", NULL, "DACL" },
96 { "VOUTRP", NULL, "DACR" },
97 { "VOUTRN", NULL, "DACR" },
98};
99
100static int wm8741_add_widgets(struct snd_soc_codec *codec)
101{
102 snd_soc_dapm_new_controls(codec, wm8741_dapm_widgets,
103 ARRAY_SIZE(wm8741_dapm_widgets));
104
105 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
106
107 return 0;
108}
109
110static struct {
111 int value;
112 int ratio;
113} lrclk_ratios[WM8741_NUM_RATES] = {
114 { 1, 256 },
115 { 2, 384 },
116 { 3, 512 },
117 { 4, 768 },
118};
119
120
121static int wm8741_startup(struct snd_pcm_substream *substream,
122 struct snd_soc_dai *dai)
123{
124 struct snd_soc_codec *codec = dai->codec;
125 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
126
127 /* The set of sample rates that can be supported depends on the
128 * MCLK supplied to the CODEC - enforce this.
129 */
130 if (!wm8741->sysclk) {
131 dev_err(codec->dev,
132 "No MCLK configured, call set_sysclk() on init\n");
133 return -EINVAL;
134 }
135
136 snd_pcm_hw_constraint_list(substream->runtime, 0,
137 SNDRV_PCM_HW_PARAM_RATE,
138 &wm8741->rate_constraint);
139
140 return 0;
141}
142
143static int wm8741_hw_params(struct snd_pcm_substream *substream,
144 struct snd_pcm_hw_params *params,
145 struct snd_soc_dai *dai)
146{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_device *socdev = rtd->socdev;
149 struct snd_soc_codec *codec = socdev->card->codec;
150 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
151 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
152 int i;
153
154 /* Find a supported LRCLK ratio */
155 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
156 if (wm8741->sysclk / params_rate(params) ==
157 lrclk_ratios[i].ratio)
158 break;
159 }
160
161 /* Should never happen, should be handled by constraints */
162 if (i == ARRAY_SIZE(lrclk_ratios)) {
163 dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
164 wm8741->sysclk / params_rate(params));
165 return -EINVAL;
166 }
167
168 /* bit size */
169 switch (params_format(params)) {
170 case SNDRV_PCM_FORMAT_S16_LE:
171 break;
172 case SNDRV_PCM_FORMAT_S20_3LE:
173 iface |= 0x0001;
174 break;
175 case SNDRV_PCM_FORMAT_S24_LE:
176 iface |= 0x0002;
177 break;
178 case SNDRV_PCM_FORMAT_S32_LE:
179 iface |= 0x0003;
180 break;
181 default:
182 dev_dbg(codec->dev, "wm8741_hw_params: Unsupported bit size param = %d",
183 params_format(params));
184 return -EINVAL;
185 }
186
187 dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d",
188 params_format(params));
189
190 snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
191 return 0;
192}
193
194static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
195 int clk_id, unsigned int freq, int dir)
196{
197 struct snd_soc_codec *codec = codec_dai->codec;
198 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
199 unsigned int val;
200 int i;
201
202 dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
203
204 wm8741->sysclk = freq;
205
206 wm8741->rate_constraint.count = 0;
207
208 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
209 dev_dbg(codec->dev, "index = %d, ratio = %d, freq = %d",
210 i, lrclk_ratios[i].ratio, freq);
211
212 val = freq / lrclk_ratios[i].ratio;
213 /* Check that it's a standard rate since core can't
214 * cope with others and having the odd rates confuses
215 * constraint matching.
216 */
217 switch (val) {
218 case 32000:
219 case 44100:
220 case 48000:
221 case 64000:
222 case 88200:
223 case 96000:
224 dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
225 val);
226 wm8741->rate_constraint_list[i] = val;
227 wm8741->rate_constraint.count++;
228 break;
229 default:
230 dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
231 val);
232 }
233 }
234
235 /* Need at least one supported rate... */
236 if (wm8741->rate_constraint.count == 0)
237 return -EINVAL;
238
239 return 0;
240}
241
242static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
243 unsigned int fmt)
244{
245 struct snd_soc_codec *codec = codec_dai->codec;
246 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1C3;
247
248 /* check master/slave audio interface */
249 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
250 case SND_SOC_DAIFMT_CBS_CFS:
251 break;
252 default:
253 return -EINVAL;
254 }
255
256 /* interface format */
257 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
258 case SND_SOC_DAIFMT_I2S:
259 iface |= 0x0008;
260 break;
261 case SND_SOC_DAIFMT_RIGHT_J:
262 break;
263 case SND_SOC_DAIFMT_LEFT_J:
264 iface |= 0x0004;
265 break;
266 case SND_SOC_DAIFMT_DSP_A:
267 iface |= 0x0003;
268 break;
269 case SND_SOC_DAIFMT_DSP_B:
270 iface |= 0x0013;
271 break;
272 default:
273 return -EINVAL;
274 }
275
276 /* clock inversion */
277 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
278 case SND_SOC_DAIFMT_NB_NF:
279 break;
280 case SND_SOC_DAIFMT_IB_IF:
281 iface |= 0x0010;
282 break;
283 case SND_SOC_DAIFMT_IB_NF:
284 iface |= 0x0020;
285 break;
286 case SND_SOC_DAIFMT_NB_IF:
287 iface |= 0x0030;
288 break;
289 default:
290 return -EINVAL;
291 }
292
293
294 dev_dbg(codec->dev, "wm8741_set_dai_fmt: Format=%x, Clock Inv=%x\n",
295 fmt & SND_SOC_DAIFMT_FORMAT_MASK,
296 ((fmt & SND_SOC_DAIFMT_INV_MASK)));
297
298 snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
299 return 0;
300}
301
302#define WM8741_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
303 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
304 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
305 SNDRV_PCM_RATE_192000)
306
307#define WM8741_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
308 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
309
310static struct snd_soc_dai_ops wm8741_dai_ops = {
311 .startup = wm8741_startup,
312 .hw_params = wm8741_hw_params,
313 .set_sysclk = wm8741_set_dai_sysclk,
314 .set_fmt = wm8741_set_dai_fmt,
315};
316
317struct snd_soc_dai wm8741_dai = {
318 .name = "WM8741",
319 .playback = {
320 .stream_name = "Playback",
321 .channels_min = 2, /* Mono modes not yet supported */
322 .channels_max = 2,
323 .rates = WM8741_RATES,
324 .formats = WM8741_FORMATS,
325 },
326 .ops = &wm8741_dai_ops,
327};
328EXPORT_SYMBOL_GPL(wm8741_dai);
329
330#ifdef CONFIG_PM
331static int wm8741_resume(struct platform_device *pdev)
332{
333 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
334 struct snd_soc_codec *codec = socdev->card->codec;
335 u16 *cache = codec->reg_cache;
336 int i;
337
338 /* RESTORE REG Cache */
339 for (i = 0; i < WM8741_REGISTER_COUNT; i++) {
340 if (cache[i] == wm8741_reg_defaults[i] || WM8741_RESET == i)
341 continue;
342 snd_soc_write(codec, i, cache[i]);
343 }
344 return 0;
345}
346#else
347#define wm8741_suspend NULL
348#define wm8741_resume NULL
349#endif
350
351static int wm8741_probe(struct platform_device *pdev)
352{
353 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
354 struct snd_soc_codec *codec;
355 int ret = 0;
356
357 if (wm8741_codec == NULL) {
358 dev_err(&pdev->dev, "Codec device not registered\n");
359 return -ENODEV;
360 }
361
362 socdev->card->codec = wm8741_codec;
363 codec = wm8741_codec;
364
365 /* register pcms */
366 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
367 if (ret < 0) {
368 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
369 goto pcm_err;
370 }
371
372 snd_soc_add_controls(codec, wm8741_snd_controls,
373 ARRAY_SIZE(wm8741_snd_controls));
374 wm8741_add_widgets(codec);
375
376 return ret;
377
378pcm_err:
379 return ret;
380}
381
382static int wm8741_remove(struct platform_device *pdev)
383{
384 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
385
386 snd_soc_free_pcms(socdev);
387 snd_soc_dapm_free(socdev);
388
389 return 0;
390}
391
392struct snd_soc_codec_device soc_codec_dev_wm8741 = {
393 .probe = wm8741_probe,
394 .remove = wm8741_remove,
395 .resume = wm8741_resume,
396};
397EXPORT_SYMBOL_GPL(soc_codec_dev_wm8741);
398
399static int wm8741_register(struct wm8741_priv *wm8741,
400 enum snd_soc_control_type control)
401{
402 int ret;
403 struct snd_soc_codec *codec = &wm8741->codec;
404 int i;
405
406 if (wm8741_codec) {
407 dev_err(codec->dev, "Another WM8741 is registered\n");
408 return -EINVAL;
409 }
410
411 mutex_init(&codec->mutex);
412 INIT_LIST_HEAD(&codec->dapm_widgets);
413 INIT_LIST_HEAD(&codec->dapm_paths);
414
415 snd_soc_codec_set_drvdata(codec, wm8741);
416 codec->name = "WM8741";
417 codec->owner = THIS_MODULE;
418 codec->bias_level = SND_SOC_BIAS_OFF;
419 codec->set_bias_level = NULL;
420 codec->dai = &wm8741_dai;
421 codec->num_dai = 1;
422 codec->reg_cache_size = WM8741_REGISTER_COUNT;
423 codec->reg_cache = &wm8741->reg_cache;
424
425 wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0];
426 wm8741->rate_constraint.count =
427 ARRAY_SIZE(wm8741->rate_constraint_list);
428
429 memcpy(codec->reg_cache, wm8741_reg_defaults,
430 sizeof(wm8741->reg_cache));
431
432 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
433 if (ret != 0) {
434 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
435 goto err;
436 }
437
438 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
439 wm8741->supplies[i].supply = wm8741_supply_names[i];
440
441 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
442 wm8741->supplies);
443 if (ret != 0) {
444 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
445 goto err;
446 }
447
448 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
449 wm8741->supplies);
450 if (ret != 0) {
451 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
452 goto err_get;
453 }
454
455 ret = wm8741_reset(codec);
456 if (ret < 0) {
457 dev_err(codec->dev, "Failed to issue reset\n");
458 goto err_enable;
459 }
460
461 wm8741_dai.dev = codec->dev;
462
463 /* Change some default settings - latch VU */
464 wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
465 wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
466 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
467 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
468
469 wm8741_codec = codec;
470
471 ret = snd_soc_register_codec(codec);
472 if (ret != 0) {
473 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
474 return ret;
475 }
476
477 ret = snd_soc_register_dai(&wm8741_dai);
478 if (ret != 0) {
479 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
480 snd_soc_unregister_codec(codec);
481 return ret;
482 }
483
484 dev_dbg(codec->dev, "Successful registration\n");
485 return 0;
486
487err_enable:
488 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
489
490err_get:
491 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
492
493err:
494 kfree(wm8741);
495 return ret;
496}
497
498static void wm8741_unregister(struct wm8741_priv *wm8741)
499{
500 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
501
502 snd_soc_unregister_dai(&wm8741_dai);
503 snd_soc_unregister_codec(&wm8741->codec);
504 kfree(wm8741);
505 wm8741_codec = NULL;
506}
507
508#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
509static __devinit int wm8741_i2c_probe(struct i2c_client *i2c,
510 const struct i2c_device_id *id)
511{
512 struct wm8741_priv *wm8741;
513 struct snd_soc_codec *codec;
514
515 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
516 if (wm8741 == NULL)
517 return -ENOMEM;
518
519 codec = &wm8741->codec;
520 codec->hw_write = (hw_write_t)i2c_master_send;
521
522 i2c_set_clientdata(i2c, wm8741);
523 codec->control_data = i2c;
524
525 codec->dev = &i2c->dev;
526
527 return wm8741_register(wm8741, SND_SOC_I2C);
528}
529
530static __devexit int wm8741_i2c_remove(struct i2c_client *client)
531{
532 struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
533 wm8741_unregister(wm8741);
534 return 0;
535}
536
537static const struct i2c_device_id wm8741_i2c_id[] = {
538 { "wm8741", 0 },
539 { }
540};
541MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
542
543
544static struct i2c_driver wm8741_i2c_driver = {
545 .driver = {
546 .name = "WM8741",
547 .owner = THIS_MODULE,
548 },
549 .probe = wm8741_i2c_probe,
550 .remove = __devexit_p(wm8741_i2c_remove),
551 .id_table = wm8741_i2c_id,
552};
553#endif
554
555static int __init wm8741_modinit(void)
556{
557 int ret;
558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
559 ret = i2c_add_driver(&wm8741_i2c_driver);
560 if (ret != 0) {
561 printk(KERN_ERR "Failed to register WM8741 I2C driver: %d\n",
562 ret);
563 }
564#endif
565 return 0;
566}
567module_init(wm8741_modinit);
568
569static void __exit wm8741_exit(void)
570{
571#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
572 i2c_del_driver(&wm8741_i2c_driver);
573#endif
574}
575module_exit(wm8741_exit);
576
577MODULE_DESCRIPTION("ASoC WM8741 driver");
578MODULE_AUTHOR("Ian Lartey <ian@opensource.wolfsonmicro.com>");
579MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8741.h b/sound/soc/codecs/wm8741.h
new file mode 100644
index 000000000000..fdef6ecd1f6f
--- /dev/null
+++ b/sound/soc/codecs/wm8741.h
@@ -0,0 +1,214 @@
1/*
2 * wm8741.h -- WM8423 ASoC driver
3 *
4 * Copyright 2010 Wolfson Microelectronics, plc
5 *
6 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>
7 *
8 * Based on wm8753.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _WM8741_H
16#define _WM8741_H
17
18/*
19 * Register values.
20 */
21#define WM8741_DACLLSB_ATTENUATION 0x00
22#define WM8741_DACLMSB_ATTENUATION 0x01
23#define WM8741_DACRLSB_ATTENUATION 0x02
24#define WM8741_DACRMSB_ATTENUATION 0x03
25#define WM8741_VOLUME_CONTROL 0x04
26#define WM8741_FORMAT_CONTROL 0x05
27#define WM8741_FILTER_CONTROL 0x06
28#define WM8741_MODE_CONTROL_1 0x07
29#define WM8741_MODE_CONTROL_2 0x08
30#define WM8741_RESET 0x09
31#define WM8741_ADDITIONAL_CONTROL_1 0x20
32
33#define WM8741_REGISTER_COUNT 11
34#define WM8741_MAX_REGISTER 0x20
35
36/*
37 * Field Definitions.
38 */
39
40/*
41 * R0 (0x00) - DACLLSB_ATTENUATION
42 */
43#define WM8741_UPDATELL 0x0020 /* UPDATELL */
44#define WM8741_UPDATELL_MASK 0x0020 /* UPDATELL */
45#define WM8741_UPDATELL_SHIFT 5 /* UPDATELL */
46#define WM8741_UPDATELL_WIDTH 1 /* UPDATELL */
47#define WM8741_LAT_4_0_MASK 0x001F /* LAT[4:0] - [4:0] */
48#define WM8741_LAT_4_0_SHIFT 0 /* LAT[4:0] - [4:0] */
49#define WM8741_LAT_4_0_WIDTH 5 /* LAT[4:0] - [4:0] */
50
51/*
52 * R1 (0x01) - DACLMSB_ATTENUATION
53 */
54#define WM8741_UPDATELM 0x0020 /* UPDATELM */
55#define WM8741_UPDATELM_MASK 0x0020 /* UPDATELM */
56#define WM8741_UPDATELM_SHIFT 5 /* UPDATELM */
57#define WM8741_UPDATELM_WIDTH 1 /* UPDATELM */
58#define WM8741_LAT_9_5_0_MASK 0x001F /* LAT[9:5] - [4:0] */
59#define WM8741_LAT_9_5_0_SHIFT 0 /* LAT[9:5] - [4:0] */
60#define WM8741_LAT_9_5_0_WIDTH 5 /* LAT[9:5] - [4:0] */
61
62/*
63 * R2 (0x02) - DACRLSB_ATTENUATION
64 */
65#define WM8741_UPDATERL 0x0020 /* UPDATERL */
66#define WM8741_UPDATERL_MASK 0x0020 /* UPDATERL */
67#define WM8741_UPDATERL_SHIFT 5 /* UPDATERL */
68#define WM8741_UPDATERL_WIDTH 1 /* UPDATERL */
69#define WM8741_RAT_4_0_MASK 0x001F /* RAT[4:0] - [4:0] */
70#define WM8741_RAT_4_0_SHIFT 0 /* RAT[4:0] - [4:0] */
71#define WM8741_RAT_4_0_WIDTH 5 /* RAT[4:0] - [4:0] */
72
73/*
74 * R3 (0x03) - DACRMSB_ATTENUATION
75 */
76#define WM8741_UPDATERM 0x0020 /* UPDATERM */
77#define WM8741_UPDATERM_MASK 0x0020 /* UPDATERM */
78#define WM8741_UPDATERM_SHIFT 5 /* UPDATERM */
79#define WM8741_UPDATERM_WIDTH 1 /* UPDATERM */
80#define WM8741_RAT_9_5_0_MASK 0x001F /* RAT[9:5] - [4:0] */
81#define WM8741_RAT_9_5_0_SHIFT 0 /* RAT[9:5] - [4:0] */
82#define WM8741_RAT_9_5_0_WIDTH 5 /* RAT[9:5] - [4:0] */
83
84/*
85 * R4 (0x04) - VOLUME_CONTROL
86 */
87#define WM8741_AMUTE 0x0080 /* AMUTE */
88#define WM8741_AMUTE_MASK 0x0080 /* AMUTE */
89#define WM8741_AMUTE_SHIFT 7 /* AMUTE */
90#define WM8741_AMUTE_WIDTH 1 /* AMUTE */
91#define WM8741_ZFLAG_MASK 0x0060 /* ZFLAG - [6:5] */
92#define WM8741_ZFLAG_SHIFT 5 /* ZFLAG - [6:5] */
93#define WM8741_ZFLAG_WIDTH 2 /* ZFLAG - [6:5] */
94#define WM8741_IZD 0x0010 /* IZD */
95#define WM8741_IZD_MASK 0x0010 /* IZD */
96#define WM8741_IZD_SHIFT 4 /* IZD */
97#define WM8741_IZD_WIDTH 1 /* IZD */
98#define WM8741_SOFT 0x0008 /* SOFT MUTE */
99#define WM8741_SOFT_MASK 0x0008 /* SOFT MUTE */
100#define WM8741_SOFT_SHIFT 3 /* SOFT MUTE */
101#define WM8741_SOFT_WIDTH 1 /* SOFT MUTE */
102#define WM8741_ATC 0x0004 /* ATC */
103#define WM8741_ATC_MASK 0x0004 /* ATC */
104#define WM8741_ATC_SHIFT 2 /* ATC */
105#define WM8741_ATC_WIDTH 1 /* ATC */
106#define WM8741_ATT2DB 0x0002 /* ATT2DB */
107#define WM8741_ATT2DB_MASK 0x0002 /* ATT2DB */
108#define WM8741_ATT2DB_SHIFT 1 /* ATT2DB */
109#define WM8741_ATT2DB_WIDTH 1 /* ATT2DB */
110#define WM8741_VOL_RAMP 0x0001 /* VOL_RAMP */
111#define WM8741_VOL_RAMP_MASK 0x0001 /* VOL_RAMP */
112#define WM8741_VOL_RAMP_SHIFT 0 /* VOL_RAMP */
113#define WM8741_VOL_RAMP_WIDTH 1 /* VOL_RAMP */
114
115/*
116 * R5 (0x05) - FORMAT_CONTROL
117 */
118#define WM8741_PWDN 0x0080 /* PWDN */
119#define WM8741_PWDN_MASK 0x0080 /* PWDN */
120#define WM8741_PWDN_SHIFT 7 /* PWDN */
121#define WM8741_PWDN_WIDTH 1 /* PWDN */
122#define WM8741_REV 0x0040 /* REV */
123#define WM8741_REV_MASK 0x0040 /* REV */
124#define WM8741_REV_SHIFT 6 /* REV */
125#define WM8741_REV_WIDTH 1 /* REV */
126#define WM8741_BCP 0x0020 /* BCP */
127#define WM8741_BCP_MASK 0x0020 /* BCP */
128#define WM8741_BCP_SHIFT 5 /* BCP */
129#define WM8741_BCP_WIDTH 1 /* BCP */
130#define WM8741_LRP 0x0010 /* LRP */
131#define WM8741_LRP_MASK 0x0010 /* LRP */
132#define WM8741_LRP_SHIFT 4 /* LRP */
133#define WM8741_LRP_WIDTH 1 /* LRP */
134#define WM8741_FMT_MASK 0x000C /* FMT - [3:2] */
135#define WM8741_FMT_SHIFT 2 /* FMT - [3:2] */
136#define WM8741_FMT_WIDTH 2 /* FMT - [3:2] */
137#define WM8741_IWL_MASK 0x0003 /* IWL - [1:0] */
138#define WM8741_IWL_SHIFT 0 /* IWL - [1:0] */
139#define WM8741_IWL_WIDTH 2 /* IWL - [1:0] */
140
141/*
142 * R6 (0x06) - FILTER_CONTROL
143 */
144#define WM8741_ZFLAG_HI 0x0080 /* ZFLAG_HI */
145#define WM8741_ZFLAG_HI_MASK 0x0080 /* ZFLAG_HI */
146#define WM8741_ZFLAG_HI_SHIFT 7 /* ZFLAG_HI */
147#define WM8741_ZFLAG_HI_WIDTH 1 /* ZFLAG_HI */
148#define WM8741_DEEMPH_MASK 0x0060 /* DEEMPH - [6:5] */
149#define WM8741_DEEMPH_SHIFT 5 /* DEEMPH - [6:5] */
150#define WM8741_DEEMPH_WIDTH 2 /* DEEMPH - [6:5] */
151#define WM8741_DSDFILT_MASK 0x0018 /* DSDFILT - [4:3] */
152#define WM8741_DSDFILT_SHIFT 3 /* DSDFILT - [4:3] */
153#define WM8741_DSDFILT_WIDTH 2 /* DSDFILT - [4:3] */
154#define WM8741_FIRSEL_MASK 0x0007 /* FIRSEL - [2:0] */
155#define WM8741_FIRSEL_SHIFT 0 /* FIRSEL - [2:0] */
156#define WM8741_FIRSEL_WIDTH 3 /* FIRSEL - [2:0] */
157
158/*
159 * R7 (0x07) - MODE_CONTROL_1
160 */
161#define WM8741_MODE8X 0x0080 /* MODE8X */
162#define WM8741_MODE8X_MASK 0x0080 /* MODE8X */
163#define WM8741_MODE8X_SHIFT 7 /* MODE8X */
164#define WM8741_MODE8X_WIDTH 1 /* MODE8X */
165#define WM8741_OSR_MASK 0x0060 /* OSR - [6:5] */
166#define WM8741_OSR_SHIFT 5 /* OSR - [6:5] */
167#define WM8741_OSR_WIDTH 2 /* OSR - [6:5] */
168#define WM8741_SR_MASK 0x001C /* SR - [4:2] */
169#define WM8741_SR_SHIFT 2 /* SR - [4:2] */
170#define WM8741_SR_WIDTH 3 /* SR - [4:2] */
171#define WM8741_MODESEL_MASK 0x0003 /* MODESEL - [1:0] */
172#define WM8741_MODESEL_SHIFT 0 /* MODESEL - [1:0] */
173#define WM8741_MODESEL_WIDTH 2 /* MODESEL - [1:0] */
174
175/*
176 * R8 (0x08) - MODE_CONTROL_2
177 */
178#define WM8741_DSD_GAIN 0x0040 /* DSD_GAIN */
179#define WM8741_DSD_GAIN_MASK 0x0040 /* DSD_GAIN */
180#define WM8741_DSD_GAIN_SHIFT 6 /* DSD_GAIN */
181#define WM8741_DSD_GAIN_WIDTH 1 /* DSD_GAIN */
182#define WM8741_SDOUT 0x0020 /* SDOUT */
183#define WM8741_SDOUT_MASK 0x0020 /* SDOUT */
184#define WM8741_SDOUT_SHIFT 5 /* SDOUT */
185#define WM8741_SDOUT_WIDTH 1 /* SDOUT */
186#define WM8741_DOUT 0x0010 /* DOUT */
187#define WM8741_DOUT_MASK 0x0010 /* DOUT */
188#define WM8741_DOUT_SHIFT 4 /* DOUT */
189#define WM8741_DOUT_WIDTH 1 /* DOUT */
190#define WM8741_DIFF_MASK 0x000C /* DIFF - [3:2] */
191#define WM8741_DIFF_SHIFT 2 /* DIFF - [3:2] */
192#define WM8741_DIFF_WIDTH 2 /* DIFF - [3:2] */
193#define WM8741_DITHER_MASK 0x0003 /* DITHER - [1:0] */
194#define WM8741_DITHER_SHIFT 0 /* DITHER - [1:0] */
195#define WM8741_DITHER_WIDTH 2 /* DITHER - [1:0] */
196
197/*
198 * R32 (0x20) - ADDITONAL_CONTROL_1
199 */
200#define WM8741_DSD_LEVEL 0x0002 /* DSD_LEVEL */
201#define WM8741_DSD_LEVEL_MASK 0x0002 /* DSD_LEVEL */
202#define WM8741_DSD_LEVEL_SHIFT 1 /* DSD_LEVEL */
203#define WM8741_DSD_LEVEL_WIDTH 1 /* DSD_LEVEL */
204#define WM8741_DSD_NO_NOTCH 0x0001 /* DSD_NO_NOTCH */
205#define WM8741_DSD_NO_NOTCH_MASK 0x0001 /* DSD_NO_NOTCH */
206#define WM8741_DSD_NO_NOTCH_SHIFT 0 /* DSD_NO_NOTCH */
207#define WM8741_DSD_NO_NOTCH_WIDTH 1 /* DSD_NO_NOTCH */
208
209#define WM8741_SYSCLK 0
210
211extern struct snd_soc_dai wm8741_dai;
212extern struct snd_soc_codec_device soc_codec_dev_wm8741;
213
214#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 9407e193fcc3..e2c05e3e323a 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -884,6 +884,7 @@ static int wm8750_i2c_remove(struct i2c_client *client)
884 884
885static const struct i2c_device_id wm8750_i2c_id[] = { 885static const struct i2c_device_id wm8750_i2c_id[] = {
886 { "wm8750", 0 }, 886 { "wm8750", 0 },
887 { "wm8987", 0 }, /* WM8987 is register compatible with WM8750 */
887 { } 888 { }
888}; 889};
889MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id); 890MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
@@ -925,14 +926,22 @@ static int __devexit wm8750_spi_remove(struct spi_device *spi)
925 return 0; 926 return 0;
926} 927}
927 928
929static const struct spi_device_id wm8750_spi_id[] = {
930 { "wm8750", 0 },
931 { "wm8987", 0 },
932 { }
933};
934MODULE_DEVICE_TABLE(spi, wm8750_spi_id);
935
928static struct spi_driver wm8750_spi_driver = { 936static struct spi_driver wm8750_spi_driver = {
929 .driver = { 937 .driver = {
930 .name = "wm8750", 938 .name = "WM8750 SPI Codec",
931 .bus = &spi_bus_type, 939 .bus = &spi_bus_type,
932 .owner = THIS_MODULE, 940 .owner = THIS_MODULE,
933 }, 941 },
934 .probe = wm8750_spi_probe, 942 .probe = wm8750_spi_probe,
935 .remove = __devexit_p(wm8750_spi_remove), 943 .remove = __devexit_p(wm8750_spi_remove),
944 .id_table = wm8750_spi_id,
936}; 945};
937#endif 946#endif
938 947
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 87f14f8675fa..f7dcabf6283c 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2433,7 +2433,8 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2433 2433
2434 if (wm8904_codec) { 2434 if (wm8904_codec) {
2435 dev_err(codec->dev, "Another WM8904 is registered\n"); 2435 dev_err(codec->dev, "Another WM8904 is registered\n");
2436 return -EINVAL; 2436 ret = -EINVAL;
2437 goto err;
2437 } 2438 }
2438 2439
2439 mutex_init(&codec->mutex); 2440 mutex_init(&codec->mutex);
@@ -2462,7 +2463,8 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2462 default: 2463 default:
2463 dev_err(codec->dev, "Unknown device type %d\n", 2464 dev_err(codec->dev, "Unknown device type %d\n",
2464 wm8904->devtype); 2465 wm8904->devtype);
2465 return -EINVAL; 2466 ret = -EINVAL;
2467 goto err;
2466 } 2468 }
2467 2469
2468 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); 2470 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
@@ -2566,18 +2568,19 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2566 ret = snd_soc_register_codec(codec); 2568 ret = snd_soc_register_codec(codec);
2567 if (ret != 0) { 2569 if (ret != 0) {
2568 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 2570 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2569 return ret; 2571 goto err_enable;
2570 } 2572 }
2571 2573
2572 ret = snd_soc_register_dai(&wm8904_dai); 2574 ret = snd_soc_register_dai(&wm8904_dai);
2573 if (ret != 0) { 2575 if (ret != 0) {
2574 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 2576 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2575 snd_soc_unregister_codec(codec); 2577 goto err_codec;
2576 return ret;
2577 } 2578 }
2578 2579
2579 return 0; 2580 return 0;
2580 2581
2582err_codec:
2583 snd_soc_unregister_codec(codec);
2581err_enable: 2584err_enable:
2582 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2585 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2583err_get: 2586err_get:
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index e3c4bbfaae27..f0c11138e610 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -845,6 +845,7 @@ static void wm8940_unregister(struct wm8940_priv *wm8940)
845static int wm8940_i2c_probe(struct i2c_client *i2c, 845static int wm8940_i2c_probe(struct i2c_client *i2c,
846 const struct i2c_device_id *id) 846 const struct i2c_device_id *id)
847{ 847{
848 int ret;
848 struct wm8940_priv *wm8940; 849 struct wm8940_priv *wm8940;
849 struct snd_soc_codec *codec; 850 struct snd_soc_codec *codec;
850 851
@@ -858,7 +859,11 @@ static int wm8940_i2c_probe(struct i2c_client *i2c,
858 codec->control_data = i2c; 859 codec->control_data = i2c;
859 codec->dev = &i2c->dev; 860 codec->dev = &i2c->dev;
860 861
861 return wm8940_register(wm8940, SND_SOC_I2C); 862 ret = wm8940_register(wm8940, SND_SOC_I2C);
863 if (ret < 0)
864 kfree(wm8940);
865
866 return ret;
862} 867}
863 868
864static int __devexit wm8940_i2c_remove(struct i2c_client *client) 869static int __devexit wm8940_i2c_remove(struct i2c_client *client)
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index fedb76452f1b..5f025593d84d 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -964,7 +964,8 @@ static int wm8955_register(struct wm8955_priv *wm8955,
964 964
965 if (wm8955_codec) { 965 if (wm8955_codec) {
966 dev_err(codec->dev, "Another WM8955 is registered\n"); 966 dev_err(codec->dev, "Another WM8955 is registered\n");
967 return -EINVAL; 967 ret = -EINVAL;
968 goto err;
968 } 969 }
969 970
970 mutex_init(&codec->mutex); 971 mutex_init(&codec->mutex);
@@ -1047,18 +1048,19 @@ static int wm8955_register(struct wm8955_priv *wm8955,
1047 ret = snd_soc_register_codec(codec); 1048 ret = snd_soc_register_codec(codec);
1048 if (ret != 0) { 1049 if (ret != 0) {
1049 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1050 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1050 return ret; 1051 goto err_enable;
1051 } 1052 }
1052 1053
1053 ret = snd_soc_register_dai(&wm8955_dai); 1054 ret = snd_soc_register_dai(&wm8955_dai);
1054 if (ret != 0) { 1055 if (ret != 0) {
1055 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 1056 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1056 snd_soc_unregister_codec(codec); 1057 goto err_codec;
1057 return ret;
1058 } 1058 }
1059 1059
1060 return 0; 1060 return 0;
1061 1061
1062err_codec:
1063 snd_soc_unregister_codec(codec);
1062err_enable: 1064err_enable:
1063 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 1065 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1064err_get: 1066err_get:
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 7233cc68435a..3c6ee61f6c95 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -79,12 +79,13 @@ struct wm8960_priv {
79 struct snd_soc_dapm_widget *lout1; 79 struct snd_soc_dapm_widget *lout1;
80 struct snd_soc_dapm_widget *rout1; 80 struct snd_soc_dapm_widget *rout1;
81 struct snd_soc_dapm_widget *out3; 81 struct snd_soc_dapm_widget *out3;
82 bool deemph;
83 int playback_fs;
82}; 84};
83 85
84#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0) 86#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
85 87
86/* enumerated controls */ 88/* enumerated controls */
87static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
88static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted", 89static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
89 "Right Inverted", "Stereo Inversion"}; 90 "Right Inverted", "Stereo Inversion"};
90static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"}; 91static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"};
@@ -93,7 +94,6 @@ static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"};
93static const char *wm8960_alcmode[] = {"ALC", "Limiter"}; 94static const char *wm8960_alcmode[] = {"ALC", "Limiter"};
94 95
95static const struct soc_enum wm8960_enum[] = { 96static const struct soc_enum wm8960_enum[] = {
96 SOC_ENUM_SINGLE(WM8960_DACCTL1, 1, 4, wm8960_deemph),
97 SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity), 97 SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity),
98 SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity), 98 SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity),
99 SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff), 99 SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff),
@@ -102,6 +102,59 @@ static const struct soc_enum wm8960_enum[] = {
102 SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode), 102 SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode),
103}; 103};
104 104
105static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
106
107static int wm8960_set_deemph(struct snd_soc_codec *codec)
108{
109 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
110 int val, i, best;
111
112 /* If we're using deemphasis select the nearest available sample
113 * rate.
114 */
115 if (wm8960->deemph) {
116 best = 1;
117 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
118 if (abs(deemph_settings[i] - wm8960->playback_fs) <
119 abs(deemph_settings[best] - wm8960->playback_fs))
120 best = i;
121 }
122
123 val = best << 1;
124 } else {
125 val = 0;
126 }
127
128 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
129
130 return snd_soc_update_bits(codec, WM8960_DACCTL1,
131 0x6, val);
132}
133
134static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
135 struct snd_ctl_elem_value *ucontrol)
136{
137 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
138 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
139
140 return wm8960->deemph;
141}
142
143static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
144 struct snd_ctl_elem_value *ucontrol)
145{
146 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
147 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
148 int deemph = ucontrol->value.enumerated.item[0];
149
150 if (deemph > 1)
151 return -EINVAL;
152
153 wm8960->deemph = deemph;
154
155 return wm8960_set_deemph(codec);
156}
157
105static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0); 158static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0);
106static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); 159static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
107static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); 160static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
@@ -131,23 +184,24 @@ SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0),
131SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0), 184SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0),
132 185
133SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0), 186SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
134SOC_ENUM("ADC Polarity", wm8960_enum[1]), 187SOC_ENUM("ADC Polarity", wm8960_enum[0]),
135SOC_ENUM("Playback De-emphasis", wm8960_enum[0]),
136SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0), 188SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0),
137 189
138SOC_ENUM("DAC Polarity", wm8960_enum[2]), 190SOC_ENUM("DAC Polarity", wm8960_enum[2]),
191SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
192 wm8960_get_deemph, wm8960_put_deemph),
139 193
140SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[3]), 194SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[2]),
141SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[4]), 195SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[3]),
142SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0), 196SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0),
143SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0), 197SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0),
144 198
145SOC_ENUM("ALC Function", wm8960_enum[5]), 199SOC_ENUM("ALC Function", wm8960_enum[4]),
146SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0), 200SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0),
147SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1), 201SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1),
148SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0), 202SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0),
149SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0), 203SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0),
150SOC_ENUM("ALC Mode", wm8960_enum[6]), 204SOC_ENUM("ALC Mode", wm8960_enum[5]),
151SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0), 205SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0),
152SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0), 206SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0),
153 207
@@ -433,6 +487,21 @@ static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
433 return 0; 487 return 0;
434} 488}
435 489
490static struct {
491 int rate;
492 unsigned int val;
493} alc_rates[] = {
494 { 48000, 0 },
495 { 44100, 0 },
496 { 32000, 1 },
497 { 22050, 2 },
498 { 24000, 2 },
499 { 16000, 3 },
500 { 11250, 4 },
501 { 12000, 4 },
502 { 8000, 5 },
503};
504
436static int wm8960_hw_params(struct snd_pcm_substream *substream, 505static int wm8960_hw_params(struct snd_pcm_substream *substream,
437 struct snd_pcm_hw_params *params, 506 struct snd_pcm_hw_params *params,
438 struct snd_soc_dai *dai) 507 struct snd_soc_dai *dai)
@@ -440,7 +509,9 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
440 struct snd_soc_pcm_runtime *rtd = substream->private_data; 509 struct snd_soc_pcm_runtime *rtd = substream->private_data;
441 struct snd_soc_device *socdev = rtd->socdev; 510 struct snd_soc_device *socdev = rtd->socdev;
442 struct snd_soc_codec *codec = socdev->card->codec; 511 struct snd_soc_codec *codec = socdev->card->codec;
512 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
443 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3; 513 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
514 int i;
444 515
445 /* bit size */ 516 /* bit size */
446 switch (params_format(params)) { 517 switch (params_format(params)) {
@@ -454,6 +525,18 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
454 break; 525 break;
455 } 526 }
456 527
528 /* Update filters for the new rate */
529 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
530 wm8960->playback_fs = params_rate(params);
531 wm8960_set_deemph(codec);
532 } else {
533 for (i = 0; i < ARRAY_SIZE(alc_rates); i++)
534 if (alc_rates[i].rate == params_rate(params))
535 snd_soc_update_bits(codec,
536 WM8960_ADDCTL3, 0x7,
537 alc_rates[i].val);
538 }
539
457 /* set iface */ 540 /* set iface */
458 snd_soc_write(codec, WM8960_IFACE1, iface); 541 snd_soc_write(codec, WM8960_IFACE1, iface);
459 return 0; 542 return 0;
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 5b9a756242f1..2549d3a297ab 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1102,7 +1102,7 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1102 ret = wm8961_reset(codec); 1102 ret = wm8961_reset(codec);
1103 if (ret < 0) { 1103 if (ret < 0) {
1104 dev_err(codec->dev, "Failed to issue reset\n"); 1104 dev_err(codec->dev, "Failed to issue reset\n");
1105 return ret; 1105 goto err;
1106 } 1106 }
1107 1107
1108 /* Enable class W */ 1108 /* Enable class W */
@@ -1147,18 +1147,19 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1147 ret = snd_soc_register_codec(codec); 1147 ret = snd_soc_register_codec(codec);
1148 if (ret != 0) { 1148 if (ret != 0) {
1149 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1149 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1150 return ret; 1150 goto err;
1151 } 1151 }
1152 1152
1153 ret = snd_soc_register_dai(&wm8961_dai); 1153 ret = snd_soc_register_dai(&wm8961_dai);
1154 if (ret != 0) { 1154 if (ret != 0) {
1155 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 1155 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1156 snd_soc_unregister_codec(codec); 1156 goto err_codec;
1157 return ret;
1158 } 1157 }
1159 1158
1160 return 0; 1159 return 0;
1161 1160
1161err_codec:
1162 snd_soc_unregister_codec(codec);
1162err: 1163err:
1163 kfree(wm8961); 1164 kfree(wm8961);
1164 return ret; 1165 return ret;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index a2c4b2f37cca..1468fe10cbbe 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -670,7 +670,8 @@ static __devinit int wm8974_register(struct wm8974_priv *wm8974)
670 670
671 if (wm8974_codec) { 671 if (wm8974_codec) {
672 dev_err(codec->dev, "Another WM8974 is registered\n"); 672 dev_err(codec->dev, "Another WM8974 is registered\n");
673 return -EINVAL; 673 ret = -EINVAL;
674 goto err;
674 } 675 }
675 676
676 mutex_init(&codec->mutex); 677 mutex_init(&codec->mutex);
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 51d5f433215c..8a1ad778e7e3 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -1076,7 +1076,6 @@ static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1076err_codec: 1076err_codec:
1077 snd_soc_unregister_codec(codec); 1077 snd_soc_unregister_codec(codec);
1078err: 1078err:
1079 kfree(wm8978);
1080 return ret; 1079 return ret;
1081} 1080}
1082 1081
@@ -1085,13 +1084,13 @@ static __devexit void wm8978_unregister(struct wm8978_priv *wm8978)
1085 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF); 1084 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF);
1086 snd_soc_unregister_dai(&wm8978_dai); 1085 snd_soc_unregister_dai(&wm8978_dai);
1087 snd_soc_unregister_codec(&wm8978->codec); 1086 snd_soc_unregister_codec(&wm8978->codec);
1088 kfree(wm8978);
1089 wm8978_codec = NULL; 1087 wm8978_codec = NULL;
1090} 1088}
1091 1089
1092static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, 1090static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1093 const struct i2c_device_id *id) 1091 const struct i2c_device_id *id)
1094{ 1092{
1093 int ret;
1095 struct wm8978_priv *wm8978; 1094 struct wm8978_priv *wm8978;
1096 struct snd_soc_codec *codec; 1095 struct snd_soc_codec *codec;
1097 1096
@@ -1107,13 +1106,18 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1107 1106
1108 codec->dev = &i2c->dev; 1107 codec->dev = &i2c->dev;
1109 1108
1110 return wm8978_register(wm8978); 1109 ret = wm8978_register(wm8978);
1110 if (ret < 0)
1111 kfree(wm8978);
1112
1113 return ret;
1111} 1114}
1112 1115
1113static __devexit int wm8978_i2c_remove(struct i2c_client *client) 1116static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1114{ 1117{
1115 struct wm8978_priv *wm8978 = i2c_get_clientdata(client); 1118 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1116 wm8978_unregister(wm8978); 1119 wm8978_unregister(wm8978);
1120 kfree(wm8978);
1117 return 0; 1121 return 0;
1118} 1122}
1119 1123
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index c018772cc430..dd8d909788c1 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -30,8 +30,6 @@
30 30
31#include "wm8990.h" 31#include "wm8990.h"
32 32
33#define WM8990_VERSION "0.2"
34
35/* codec private data */ 33/* codec private data */
36struct wm8990_priv { 34struct wm8990_priv {
37 unsigned int sysclk; 35 unsigned int sysclk;
@@ -1511,8 +1509,6 @@ static int wm8990_probe(struct platform_device *pdev)
1511 struct wm8990_priv *wm8990; 1509 struct wm8990_priv *wm8990;
1512 int ret; 1510 int ret;
1513 1511
1514 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION);
1515
1516 setup = socdev->codec_data; 1512 setup = socdev->codec_data;
1517 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1513 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1518 if (codec == NULL) 1514 if (codec == NULL)
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index e84a1177f350..522249d5c2b4 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -95,6 +95,7 @@ struct wm8994_priv {
95 95
96 struct wm8994_micdet micdet[2]; 96 struct wm8994_micdet micdet[2];
97 97
98 int revision;
98 struct wm8994_pdata *pdata; 99 struct wm8994_pdata *pdata;
99}; 100};
100 101
@@ -1677,6 +1678,26 @@ static struct {
1677 1678
1678static int wm8994_readable(unsigned int reg) 1679static int wm8994_readable(unsigned int reg)
1679{ 1680{
1681 switch (reg) {
1682 case WM8994_GPIO_1:
1683 case WM8994_GPIO_2:
1684 case WM8994_GPIO_3:
1685 case WM8994_GPIO_4:
1686 case WM8994_GPIO_5:
1687 case WM8994_GPIO_6:
1688 case WM8994_GPIO_7:
1689 case WM8994_GPIO_8:
1690 case WM8994_GPIO_9:
1691 case WM8994_GPIO_10:
1692 case WM8994_GPIO_11:
1693 case WM8994_INTERRUPT_STATUS_1:
1694 case WM8994_INTERRUPT_STATUS_2:
1695 case WM8994_INTERRUPT_RAW_STATUS_2:
1696 return 1;
1697 default:
1698 break;
1699 }
1700
1680 if (reg >= ARRAY_SIZE(access_masks)) 1701 if (reg >= ARRAY_SIZE(access_masks))
1681 return 0; 1702 return 0;
1682 return access_masks[reg].readable != 0; 1703 return access_masks[reg].readable != 0;
@@ -2341,6 +2362,20 @@ SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2341 0, 1, 0), 2362 0, 1, 0),
2342}; 2363};
2343 2364
2365static const struct snd_kcontrol_new aif1adc2l_mix[] = {
2366SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING,
2367 1, 1, 0),
2368SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING,
2369 0, 1, 0),
2370};
2371
2372static const struct snd_kcontrol_new aif1adc2r_mix[] = {
2373SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING,
2374 1, 1, 0),
2375SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING,
2376 0, 1, 0),
2377};
2378
2344static const struct snd_kcontrol_new aif2dac2l_mix[] = { 2379static const struct snd_kcontrol_new aif2dac2l_mix[] = {
2345SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING, 2380SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2346 5, 1, 0), 2381 5, 1, 0),
@@ -2472,6 +2507,7 @@ static const struct snd_kcontrol_new aif3adc_mux =
2472static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { 2507static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2473SND_SOC_DAPM_INPUT("DMIC1DAT"), 2508SND_SOC_DAPM_INPUT("DMIC1DAT"),
2474SND_SOC_DAPM_INPUT("DMIC2DAT"), 2509SND_SOC_DAPM_INPUT("DMIC2DAT"),
2510SND_SOC_DAPM_INPUT("Clock"),
2475 2511
2476SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 2512SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
2477 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 2513 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -2506,6 +2542,11 @@ SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2506SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0, 2542SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
2507 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)), 2543 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
2508 2544
2545SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0,
2546 aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)),
2547SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0,
2548 aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)),
2549
2509SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0, 2550SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
2510 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)), 2551 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
2511SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0, 2552SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
@@ -2668,6 +2709,14 @@ static const struct snd_soc_dapm_route intercon[] = {
2668 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" }, 2709 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
2669 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" }, 2710 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2670 2711
2712 { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" },
2713 { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" },
2714 { "AIF1ADC2L Mixer", "AIF2 Switch", "AIF2DACL" },
2715
2716 { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" },
2717 { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" },
2718 { "AIF1ADC2R Mixer", "AIF2 Switch", "AIF2DACR" },
2719
2671 /* Pin level routing for AIF3 */ 2720 /* Pin level routing for AIF3 */
2672 { "AIF1DAC1L", NULL, "AIF1DAC Mux" }, 2721 { "AIF1DAC1L", NULL, "AIF1DAC Mux" },
2673 { "AIF1DAC1R", NULL, "AIF1DAC Mux" }, 2722 { "AIF1DAC1R", NULL, "AIF1DAC Mux" },
@@ -2946,11 +2995,14 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2946 return 0; 2995 return 0;
2947} 2996}
2948 2997
2998static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
2999
2949static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, 3000static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2950 int clk_id, unsigned int freq, int dir) 3001 int clk_id, unsigned int freq, int dir)
2951{ 3002{
2952 struct snd_soc_codec *codec = dai->codec; 3003 struct snd_soc_codec *codec = dai->codec;
2953 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3004 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3005 int i;
2954 3006
2955 switch (dai->id) { 3007 switch (dai->id) {
2956 case 1: 3008 case 1:
@@ -2988,6 +3040,25 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2988 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id); 3040 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
2989 break; 3041 break;
2990 3042
3043 case WM8994_SYSCLK_OPCLK:
3044 /* Special case - a division (times 10) is given and
3045 * no effect on main clocking.
3046 */
3047 if (freq) {
3048 for (i = 0; i < ARRAY_SIZE(opclk_divs); i++)
3049 if (opclk_divs[i] == freq)
3050 break;
3051 if (i == ARRAY_SIZE(opclk_divs))
3052 return -EINVAL;
3053 snd_soc_update_bits(codec, WM8994_CLOCKING_2,
3054 WM8994_OPCLK_DIV_MASK, i);
3055 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
3056 WM8994_OPCLK_ENA, WM8994_OPCLK_ENA);
3057 } else {
3058 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
3059 WM8994_OPCLK_ENA, 0);
3060 }
3061
2991 default: 3062 default:
2992 return -EINVAL; 3063 return -EINVAL;
2993 } 3064 }
@@ -3000,6 +3071,8 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
3000static int wm8994_set_bias_level(struct snd_soc_codec *codec, 3071static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3001 enum snd_soc_bias_level level) 3072 enum snd_soc_bias_level level)
3002{ 3073{
3074 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3075
3003 switch (level) { 3076 switch (level) {
3004 case SND_SOC_BIAS_ON: 3077 case SND_SOC_BIAS_ON:
3005 break; 3078 break;
@@ -3012,11 +3085,16 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3012 3085
3013 case SND_SOC_BIAS_STANDBY: 3086 case SND_SOC_BIAS_STANDBY:
3014 if (codec->bias_level == SND_SOC_BIAS_OFF) { 3087 if (codec->bias_level == SND_SOC_BIAS_OFF) {
3015 /* Tweak DC servo configuration for improved 3088 /* Tweak DC servo and DSP configuration for
3016 * performance. */ 3089 * improved performance. */
3017 snd_soc_write(codec, 0x102, 0x3); 3090 if (wm8994->revision < 4) {
3018 snd_soc_write(codec, 0x56, 0x3); 3091 /* Tweak DC servo and DSP configuration for
3019 snd_soc_write(codec, 0x102, 0); 3092 * improved performance. */
3093 snd_soc_write(codec, 0x102, 0x3);
3094 snd_soc_write(codec, 0x56, 0x3);
3095 snd_soc_write(codec, 0x817, 0);
3096 snd_soc_write(codec, 0x102, 0);
3097 }
3020 3098
3021 /* Discharge LINEOUT1 & 2 */ 3099 /* Discharge LINEOUT1 & 2 */
3022 snd_soc_update_bits(codec, WM8994_ANTIPOP_1, 3100 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
@@ -3849,7 +3927,6 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3849 struct wm8994_priv *wm8994; 3927 struct wm8994_priv *wm8994;
3850 struct snd_soc_codec *codec; 3928 struct snd_soc_codec *codec;
3851 int i; 3929 int i;
3852 u16 rev;
3853 3930
3854 if (wm8994_codec) { 3931 if (wm8994_codec) {
3855 dev_err(&pdev->dev, "Another WM8994 is registered\n"); 3932 dev_err(&pdev->dev, "Another WM8994 is registered\n");
@@ -3903,8 +3980,8 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3903 wm8994->reg_cache[i] = 0; 3980 wm8994->reg_cache[i] = 0;
3904 3981
3905 /* Set revision-specific configuration */ 3982 /* Set revision-specific configuration */
3906 rev = snd_soc_read(codec, WM8994_CHIP_REVISION); 3983 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
3907 switch (rev) { 3984 switch (wm8994->revision) {
3908 case 2: 3985 case 2:
3909 case 3: 3986 case 3:
3910 wm8994->hubs.dcs_codes = -5; 3987 wm8994->hubs.dcs_codes = -5;
@@ -4004,6 +4081,11 @@ static int wm8994_codec_probe(struct platform_device *pdev)
4004 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT, 4081 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
4005 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT); 4082 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
4006 4083
4084 /* Unconditionally enable AIF1 ADC TDM mode; it only affects
4085 * behaviour on idle TDM clock cycles. */
4086 snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1,
4087 WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM);
4088
4007 wm8994_update_class_w(codec); 4089 wm8994_update_class_w(codec);
4008 4090
4009 ret = snd_soc_register_codec(codec); 4091 ret = snd_soc_register_codec(codec);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 7072dc539354..2e0ca67a8df7 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -20,6 +20,9 @@ extern struct snd_soc_dai wm8994_dai[];
20#define WM8994_SYSCLK_FLL1 3 20#define WM8994_SYSCLK_FLL1 3
21#define WM8994_SYSCLK_FLL2 4 21#define WM8994_SYSCLK_FLL2 4
22 22
23/* OPCLK is also configured with set_dai_sysclk, specify division*10 as rate. */
24#define WM8994_SYSCLK_OPCLK 5
25
23#define WM8994_FLL1 1 26#define WM8994_FLL1 1
24#define WM8994_FLL2 2 27#define WM8994_FLL2 2
25 28
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 13186fb4dcb4..76b37ff6c264 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1356,7 +1356,7 @@ static int wm9081_register(struct wm9081_priv *wm9081,
1356 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); 1356 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
1357 if (ret != 0) { 1357 if (ret != 0) {
1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1359 return ret; 1359 goto err;
1360 } 1360 }
1361 1361
1362 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET); 1362 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
@@ -1369,7 +1369,7 @@ static int wm9081_register(struct wm9081_priv *wm9081,
1369 ret = wm9081_reset(codec); 1369 ret = wm9081_reset(codec);
1370 if (ret < 0) { 1370 if (ret < 0) {
1371 dev_err(codec->dev, "Failed to issue reset\n"); 1371 dev_err(codec->dev, "Failed to issue reset\n");
1372 return ret; 1372 goto err;
1373 } 1373 }
1374 1374
1375 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1375 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1388,18 +1388,19 @@ static int wm9081_register(struct wm9081_priv *wm9081,
1388 ret = snd_soc_register_codec(codec); 1388 ret = snd_soc_register_codec(codec);
1389 if (ret != 0) { 1389 if (ret != 0) {
1390 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1390 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1391 return ret; 1391 goto err;
1392 } 1392 }
1393 1393
1394 ret = snd_soc_register_dai(&wm9081_dai); 1394 ret = snd_soc_register_dai(&wm9081_dai);
1395 if (ret != 0) { 1395 if (ret != 0) {
1396 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 1396 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1397 snd_soc_unregister_codec(codec); 1397 goto err_codec;
1398 return ret;
1399 } 1398 }
1400 1399
1401 return 0; 1400 return 0;
1402 1401
1402err_codec:
1403 snd_soc_unregister_codec(codec);
1403err: 1404err:
1404 kfree(wm9081); 1405 kfree(wm9081);
1405 return ret; 1406 return ret;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 16f1a57da08a..2cb81538cd91 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -410,6 +410,8 @@ static int hp_event(struct snd_soc_dapm_widget *w,
410 WM8993_HPOUT1L_DLY | 410 WM8993_HPOUT1L_DLY |
411 WM8993_HPOUT1R_DLY, 0); 411 WM8993_HPOUT1R_DLY, 0);
412 412
413 snd_soc_write(codec, WM8993_DC_SERVO_0, 0);
414
413 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 415 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
414 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 416 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
415 0); 417 0);