aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig25
-rw-r--r--sound/soc/codecs/Makefile12
-rw-r--r--sound/soc/codecs/ac97.c3
-rw-r--r--sound/soc/codecs/ad1836.c12
-rw-r--r--sound/soc/codecs/ad1938.c12
-rw-r--r--sound/soc/codecs/ad1980.c5
-rw-r--r--sound/soc/codecs/ad73311.c8
-rw-r--r--sound/soc/codecs/ads117x.c123
-rw-r--r--sound/soc/codecs/ads117x.h13
-rw-r--r--sound/soc/codecs/ak4104.c8
-rw-r--r--sound/soc/codecs/ak4535.c9
-rw-r--r--sound/soc/codecs/ak4642.c9
-rw-r--r--sound/soc/codecs/ak4671.c815
-rw-r--r--sound/soc/codecs/ak4671.h156
-rw-r--r--sound/soc/codecs/cs4270.c28
-rw-r--r--sound/soc/codecs/cx20442.c12
-rw-r--r--sound/soc/codecs/pcm3008.c9
-rw-r--r--sound/soc/codecs/ssm2602.c9
-rw-r--r--sound/soc/codecs/stac9766.c3
-rw-r--r--sound/soc/codecs/tlv320aic23.c14
-rw-r--r--sound/soc/codecs/tlv320aic26.c11
-rw-r--r--sound/soc/codecs/tlv320aic3x.c11
-rw-r--r--sound/soc/codecs/tlv320dac33.c1229
-rw-r--r--sound/soc/codecs/tlv320dac33.h267
-rw-r--r--sound/soc/codecs/tpa6130a2.c463
-rw-r--r--sound/soc/codecs/tpa6130a2.h61
-rw-r--r--sound/soc/codecs/twl4030.c452
-rw-r--r--sound/soc/codecs/twl4030.h242
-rw-r--r--sound/soc/codecs/uda134x.c13
-rw-r--r--sound/soc/codecs/uda1380.c9
-rw-r--r--sound/soc/codecs/wm8350.c32
-rw-r--r--sound/soc/codecs/wm8400.c32
-rw-r--r--sound/soc/codecs/wm8510.c14
-rw-r--r--sound/soc/codecs/wm8523.c26
-rw-r--r--sound/soc/codecs/wm8580.c30
-rw-r--r--sound/soc/codecs/wm8711.c633
-rw-r--r--sound/soc/codecs/wm8711.h42
-rw-r--r--sound/soc/codecs/wm8727.c135
-rw-r--r--sound/soc/codecs/wm8727.h21
-rw-r--r--sound/soc/codecs/wm8728.c10
-rw-r--r--sound/soc/codecs/wm8731.c94
-rw-r--r--sound/soc/codecs/wm8750.c9
-rw-r--r--sound/soc/codecs/wm8753.c49
-rw-r--r--sound/soc/codecs/wm8776.c43
-rw-r--r--sound/soc/codecs/wm8900.c34
-rw-r--r--sound/soc/codecs/wm8903.c34
-rw-r--r--sound/soc/codecs/wm8940.c28
-rw-r--r--sound/soc/codecs/wm8960.c30
-rw-r--r--sound/soc/codecs/wm8961.c27
-rw-r--r--sound/soc/codecs/wm8971.c11
-rw-r--r--sound/soc/codecs/wm8974.c36
-rw-r--r--sound/soc/codecs/wm8988.c44
-rw-r--r--sound/soc/codecs/wm8990.c14
-rw-r--r--sound/soc/codecs/wm8993.c53
-rw-r--r--sound/soc/codecs/wm9081.c27
-rw-r--r--sound/soc/codecs/wm9705.c7
-rw-r--r--sound/soc/codecs/wm9712.c7
-rw-r--r--sound/soc/codecs/wm9713.c10
-rw-r--r--sound/soc/codecs/wm_hubs.c51
-rw-r--r--sound/soc/codecs/wm_hubs.h5
60 files changed, 4377 insertions, 1254 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0edca93af3b0..52b005f8fed4 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -15,10 +15,12 @@ config SND_SOC_ALL_CODECS
15 select SND_SOC_AD1836 if SPI_MASTER 15 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD1938 if SPI_MASTER 16 select SND_SOC_AD1938 if SPI_MASTER
17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
18 select SND_SOC_ADS117X
18 select SND_SOC_AD73311 if I2C 19 select SND_SOC_AD73311 if I2C
19 select SND_SOC_AK4104 if SPI_MASTER 20 select SND_SOC_AK4104 if SPI_MASTER
20 select SND_SOC_AK4535 if I2C 21 select SND_SOC_AK4535 if I2C
21 select SND_SOC_AK4642 if I2C 22 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C
22 select SND_SOC_CS4270 if I2C 24 select SND_SOC_CS4270 if I2C
23 select SND_SOC_MAX9877 if I2C 25 select SND_SOC_MAX9877 if I2C
24 select SND_SOC_PCM3008 26 select SND_SOC_PCM3008
@@ -28,6 +30,8 @@ config SND_SOC_ALL_CODECS
28 select SND_SOC_TLV320AIC23 if I2C 30 select SND_SOC_TLV320AIC23 if I2C
29 select SND_SOC_TLV320AIC26 if SPI_MASTER 31 select SND_SOC_TLV320AIC26 if SPI_MASTER
30 select SND_SOC_TLV320AIC3X if I2C 32 select SND_SOC_TLV320AIC3X if I2C
33 select SND_SOC_TPA6130A2 if I2C
34 select SND_SOC_TLV320DAC33 if I2C
31 select SND_SOC_TWL4030 if TWL4030_CORE 35 select SND_SOC_TWL4030 if TWL4030_CORE
32 select SND_SOC_UDA134X 36 select SND_SOC_UDA134X
33 select SND_SOC_UDA1380 if I2C 37 select SND_SOC_UDA1380 if I2C
@@ -36,6 +40,8 @@ config SND_SOC_ALL_CODECS
36 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 40 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
37 select SND_SOC_WM8523 if I2C 41 select SND_SOC_WM8523 if I2C
38 select SND_SOC_WM8580 if I2C 42 select SND_SOC_WM8580 if I2C
43 select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI
44 select SND_SOC_WM8727
39 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 45 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
40 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 46 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
41 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 47 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
@@ -86,6 +92,9 @@ config SND_SOC_AD1980
86 92
87config SND_SOC_AD73311 93config SND_SOC_AD73311
88 tristate 94 tristate
95
96config SND_SOC_ADS117X
97 tristate
89 98
90config SND_SOC_AK4104 99config SND_SOC_AK4104
91 tristate 100 tristate
@@ -96,6 +105,9 @@ config SND_SOC_AK4535
96config SND_SOC_AK4642 105config SND_SOC_AK4642
97 tristate 106 tristate
98 107
108config SND_SOC_AK4671
109 tristate
110
99# Cirrus Logic CS4270 Codec 111# Cirrus Logic CS4270 Codec
100config SND_SOC_CS4270 112config SND_SOC_CS4270
101 tristate 113 tristate
@@ -136,7 +148,11 @@ config SND_SOC_TLV320AIC26
136config SND_SOC_TLV320AIC3X 148config SND_SOC_TLV320AIC3X
137 tristate 149 tristate
138 150
151config SND_SOC_TLV320DAC33
152 tristate
153
139config SND_SOC_TWL4030 154config SND_SOC_TWL4030
155 select TWL4030_CODEC
140 tristate 156 tristate
141 157
142config SND_SOC_UDA134X 158config SND_SOC_UDA134X
@@ -160,6 +176,12 @@ config SND_SOC_WM8523
160config SND_SOC_WM8580 176config SND_SOC_WM8580
161 tristate 177 tristate
162 178
179config SND_SOC_WM8711
180 tristate
181
182config SND_SOC_WM8727
183 tristate
184
163config SND_SOC_WM8728 185config SND_SOC_WM8728
164 tristate 186 tristate
165 187
@@ -220,3 +242,6 @@ config SND_SOC_WM9713
220# Amp 242# Amp
221config SND_SOC_MAX9877 243config SND_SOC_MAX9877
222 tristate 244 tristate
245
246config SND_SOC_TPA6130A2
247 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fb4af28486ba..dbaecb133ac7 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,9 +3,11 @@ snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad1938-objs := ad1938.o 3snd-soc-ad1938-objs := ad1938.o
4snd-soc-ad1980-objs := ad1980.o 4snd-soc-ad1980-objs := ad1980.o
5snd-soc-ad73311-objs := ad73311.o 5snd-soc-ad73311-objs := ad73311.o
6snd-soc-ads117x-objs := ads117x.o
6snd-soc-ak4104-objs := ak4104.o 7snd-soc-ak4104-objs := ak4104.o
7snd-soc-ak4535-objs := ak4535.o 8snd-soc-ak4535-objs := ak4535.o
8snd-soc-ak4642-objs := ak4642.o 9snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o
9snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
10snd-soc-cx20442-objs := cx20442.o 12snd-soc-cx20442-objs := cx20442.o
11snd-soc-l3-objs := l3.o 13snd-soc-l3-objs := l3.o
@@ -16,6 +18,7 @@ snd-soc-stac9766-objs := stac9766.o
16snd-soc-tlv320aic23-objs := tlv320aic23.o 18snd-soc-tlv320aic23-objs := tlv320aic23.o
17snd-soc-tlv320aic26-objs := tlv320aic26.o 19snd-soc-tlv320aic26-objs := tlv320aic26.o
18snd-soc-tlv320aic3x-objs := tlv320aic3x.o 20snd-soc-tlv320aic3x-objs := tlv320aic3x.o
21snd-soc-tlv320dac33-objs := tlv320dac33.o
19snd-soc-twl4030-objs := twl4030.o 22snd-soc-twl4030-objs := twl4030.o
20snd-soc-uda134x-objs := uda134x.o 23snd-soc-uda134x-objs := uda134x.o
21snd-soc-uda1380-objs := uda1380.o 24snd-soc-uda1380-objs := uda1380.o
@@ -24,6 +27,8 @@ snd-soc-wm8400-objs := wm8400.o
24snd-soc-wm8510-objs := wm8510.o 27snd-soc-wm8510-objs := wm8510.o
25snd-soc-wm8523-objs := wm8523.o 28snd-soc-wm8523-objs := wm8523.o
26snd-soc-wm8580-objs := wm8580.o 29snd-soc-wm8580-objs := wm8580.o
30snd-soc-wm8711-objs := wm8711.o
31snd-soc-wm8727-objs := wm8727.o
27snd-soc-wm8728-objs := wm8728.o 32snd-soc-wm8728-objs := wm8728.o
28snd-soc-wm8731-objs := wm8731.o 33snd-soc-wm8731-objs := wm8731.o
29snd-soc-wm8750-objs := wm8750.o 34snd-soc-wm8750-objs := wm8750.o
@@ -47,15 +52,18 @@ snd-soc-wm-hubs-objs := wm_hubs.o
47 52
48# Amp 53# Amp
49snd-soc-max9877-objs := max9877.o 54snd-soc-max9877-objs := max9877.o
55snd-soc-tpa6130a2-objs := tpa6130a2.o
50 56
51obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 57obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
52obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 58obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
53obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o 59obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o
54obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 60obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
55obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 61obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
62obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
56obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 63obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
57obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 64obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
58obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 65obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
66obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
59obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 67obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
60obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 68obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
61obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 69obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
@@ -66,6 +74,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
66obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 74obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
67obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 75obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
68obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 76obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
77obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
69obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 78obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
70obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 79obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
71obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 80obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
@@ -74,6 +83,8 @@ obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
74obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 83obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
75obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o 84obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
76obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 85obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
86obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
87obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
77obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 88obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
78obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 89obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
79obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 90obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
@@ -97,3 +108,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
97 108
98# Amp 109# Amp
99obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 110obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
111obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 932299bb5d1e..69bd0acc81c8 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -117,9 +117,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
117 if (ret < 0) 117 if (ret < 0)
118 goto bus_err; 118 goto bus_err;
119 119
120 ret = snd_soc_init_card(socdev);
121 if (ret < 0)
122 goto bus_err;
123 return 0; 120 return 0;
124 121
125bus_err: 122bus_err:
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c48485f2c55d..2c18e3d1b71e 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -385,19 +385,7 @@ static int ad1836_probe(struct platform_device *pdev)
385 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, 385 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
386 ARRAY_SIZE(ad1836_dapm_widgets)); 386 ARRAY_SIZE(ad1836_dapm_widgets));
387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
388 snd_soc_dapm_new_widgets(codec);
389 388
390 ret = snd_soc_init_card(socdev);
391 if (ret < 0) {
392 dev_err(codec->dev, "failed to register card: %d\n", ret);
393 goto card_err;
394 }
395
396 return ret;
397
398card_err:
399 snd_soc_free_pcms(socdev);
400 snd_soc_dapm_free(socdev);
401pcm_err: 389pcm_err:
402 return ret; 390 return ret;
403} 391}
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index 34b30efc3cb0..5d489186c05b 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -592,21 +592,9 @@ static int ad1938_probe(struct platform_device *pdev)
592 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets, 592 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets,
593 ARRAY_SIZE(ad1938_dapm_widgets)); 593 ARRAY_SIZE(ad1938_dapm_widgets));
594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
595 snd_soc_dapm_new_widgets(codec);
596 595
597 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 596 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
598 597
599 ret = snd_soc_init_card(socdev);
600 if (ret < 0) {
601 dev_err(codec->dev, "failed to register card: %d\n", ret);
602 goto card_err;
603 }
604
605 return ret;
606
607card_err:
608 snd_soc_free_pcms(socdev);
609 snd_soc_dapm_free(socdev);
610pcm_err: 598pcm_err:
611 return ret; 599 return ret;
612} 600}
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index d7440a982d22..39c0f7584e65 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -257,11 +257,6 @@ static int ad1980_soc_probe(struct platform_device *pdev)
257 257
258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls, 258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls,
259 ARRAY_SIZE(ad1980_snd_ac97_controls)); 259 ARRAY_SIZE(ad1980_snd_ac97_controls));
260 ret = snd_soc_init_card(socdev);
261 if (ret < 0) {
262 printk(KERN_ERR "ad1980: failed to register card\n");
263 goto reset_err;
264 }
265 260
266 return 0; 261 return 0;
267 262
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index e61dac5e7b8f..d2fcc601722c 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -64,16 +64,8 @@ static int ad73311_soc_probe(struct platform_device *pdev)
64 goto pcm_err; 64 goto pcm_err;
65 } 65 }
66 66
67 ret = snd_soc_init_card(socdev);
68 if (ret < 0) {
69 printk(KERN_ERR "ad73311: failed to register card\n");
70 goto register_err;
71 }
72
73 return ret; 67 return ret;
74 68
75register_err:
76 snd_soc_free_pcms(socdev);
77pcm_err: 69pcm_err:
78 kfree(socdev->card->codec); 70 kfree(socdev->card->codec);
79 socdev->card->codec = NULL; 71 socdev->card->codec = NULL;
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
new file mode 100644
index 000000000000..cc96411ca3e6
--- /dev/null
+++ b/sound/soc/codecs/ads117x.c
@@ -0,0 +1,123 @@
1/*
2 * ads117x.c -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/device.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/initval.h>
19#include <sound/soc.h>
20
21#include "ads117x.h"
22
23#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
24
25#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
26
27struct snd_soc_dai ads117x_dai = {
28/* ADC */
29 .name = "ADS117X ADC",
30 .id = 1,
31 .capture = {
32 .stream_name = "Capture",
33 .channels_min = 1,
34 .channels_max = 32,
35 .rates = ADS117X_RATES,
36 .formats = ADS117X_FORMATS,},
37};
38EXPORT_SYMBOL_GPL(ads117x_dai);
39
40static int ads117x_probe(struct platform_device *pdev)
41{
42 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
43 struct snd_soc_codec *codec;
44 int ret;
45
46 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
47 if (codec == NULL)
48 return -ENOMEM;
49
50 socdev->card->codec = codec;
51 mutex_init(&codec->mutex);
52 INIT_LIST_HEAD(&codec->dapm_widgets);
53 INIT_LIST_HEAD(&codec->dapm_paths);
54 codec->name = "ADS117X";
55 codec->owner = THIS_MODULE;
56 codec->dai = &ads117x_dai;
57 codec->num_dai = 1;
58
59 /* register pcms */
60 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
61 if (ret < 0) {
62 printk(KERN_ERR "ads117x: failed to create pcms\n");
63 kfree(codec);
64 return ret;
65 }
66
67 return 0;
68}
69
70static int ads117x_remove(struct platform_device *pdev)
71{
72 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
73 struct snd_soc_codec *codec = socdev->card->codec;
74
75 snd_soc_free_pcms(socdev);
76 kfree(codec);
77
78 return 0;
79}
80
81struct snd_soc_codec_device soc_codec_dev_ads117x = {
82 .probe = ads117x_probe,
83 .remove = ads117x_remove,
84};
85EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
86
87static __devinit int ads117x_platform_probe(struct platform_device *pdev)
88{
89 ads117x_dai.dev = &pdev->dev;
90 return snd_soc_register_dai(&ads117x_dai);
91}
92
93static int __devexit ads117x_platform_remove(struct platform_device *pdev)
94{
95 snd_soc_unregister_dai(&ads117x_dai);
96 return 0;
97}
98
99static struct platform_driver ads117x_codec_driver = {
100 .driver = {
101 .name = "ads117x",
102 .owner = THIS_MODULE,
103 },
104
105 .probe = ads117x_platform_probe,
106 .remove = __devexit_p(ads117x_platform_remove),
107};
108
109static int __init ads117x_init(void)
110{
111 return platform_driver_register(&ads117x_codec_driver);
112}
113module_init(ads117x_init);
114
115static void __exit ads117x_exit(void)
116{
117 platform_driver_unregister(&ads117x_codec_driver);
118}
119module_exit(ads117x_exit);
120
121MODULE_DESCRIPTION("ASoC ads117x driver");
122MODULE_AUTHOR("Graeme Gregory");
123MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
new file mode 100644
index 000000000000..dbcf50ec9bd1
--- /dev/null
+++ b/sound/soc/codecs/ads117x.h
@@ -0,0 +1,13 @@
1/*
2 * ads117x.h -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12extern struct snd_soc_dai ads117x_dai;
13extern struct snd_soc_codec_device soc_codec_dev_ads117x;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 4d47bc4f7428..3a14c6fc4f5e 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -313,14 +313,6 @@ static int ak4104_probe(struct platform_device *pdev)
313 return ret; 313 return ret;
314 } 314 }
315 315
316 /* Register the socdev */
317 ret = snd_soc_init_card(socdev);
318 if (ret < 0) {
319 dev_err(codec->dev, "failed to register card\n");
320 snd_soc_free_pcms(socdev);
321 return ret;
322 }
323
324 return 0; 316 return 0;
325} 317}
326 318
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 0abec0d29a96..ff966567e2ba 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -294,7 +294,6 @@ static int ak4535_add_widgets(struct snd_soc_codec *codec)
294 294
295 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 295 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
296 296
297 snd_soc_dapm_new_widgets(codec);
298 return 0; 297 return 0;
299} 298}
300 299
@@ -485,17 +484,9 @@ static int ak4535_init(struct snd_soc_device *socdev)
485 snd_soc_add_controls(codec, ak4535_snd_controls, 484 snd_soc_add_controls(codec, ak4535_snd_controls,
486 ARRAY_SIZE(ak4535_snd_controls)); 485 ARRAY_SIZE(ak4535_snd_controls));
487 ak4535_add_widgets(codec); 486 ak4535_add_widgets(codec);
488 ret = snd_soc_init_card(socdev);
489 if (ret < 0) {
490 printk(KERN_ERR "ak4535: failed to register card\n");
491 goto card_err;
492 }
493 487
494 return ret; 488 return ret;
495 489
496card_err:
497 snd_soc_free_pcms(socdev);
498 snd_soc_dapm_free(socdev);
499pcm_err: 490pcm_err:
500 kfree(codec->reg_cache); 491 kfree(codec->reg_cache);
501 492
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index e057c7b578df..b69861d52161 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -442,18 +442,9 @@ static int ak4642_probe(struct platform_device *pdev)
442 goto pcm_err; 442 goto pcm_err;
443 } 443 }
444 444
445 ret = snd_soc_init_card(socdev);
446 if (ret < 0) {
447 printk(KERN_ERR "ak4642: failed to register card\n");
448 goto card_err;
449 }
450
451 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 445 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
452 return ret; 446 return ret;
453 447
454card_err:
455 snd_soc_free_pcms(socdev);
456 snd_soc_dapm_free(socdev);
457pcm_err: 448pcm_err:
458 return ret; 449 return ret;
459 450
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
new file mode 100644
index 000000000000..82fca284d007
--- /dev/null
+++ b/sound/soc/codecs/ak4671.c
@@ -0,0 +1,815 @@
1/*
2 * ak4671.c -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/delay.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20#include <sound/initval.h>
21#include <sound/tlv.h>
22
23#include "ak4671.h"
24
25static struct snd_soc_codec *ak4671_codec;
26
27/* codec private data */
28struct ak4671_priv {
29 struct snd_soc_codec codec;
30 u8 reg_cache[AK4671_CACHEREGNUM];
31};
32
33/* ak4671 register cache & default register settings */
34static const u8 ak4671_reg[AK4671_CACHEREGNUM] = {
35 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
36 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */
37 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */
38 0x02, /* AK4671_FORMAT_SELECT (0x03) */
39 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
40 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */
41 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
42 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
43 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
44 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
45 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
46 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
47 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
48 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
49 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
50 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
51 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
52 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
53 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
54 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
55 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
56 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
57 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */
58 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */
59 0x02, /* AK4671_MODE_CONTROL1 (0x18) */
60 0x01, /* AK4671_MODE_CONTROL2 (0x19) */
61 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
62 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
63 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
64 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
65 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
66 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
67 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
68 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
69 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */
70 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */
71 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */
72 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */
73 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */
74 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */
75 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
76 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
77 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
78 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
79 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
80 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
81 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
82 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
83 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
84 0x00, /* this register not used */
85 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */
86 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */
87 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */
88 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */
89 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */
90 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */
91 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */
92 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */
93 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */
94 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */
95 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */
96 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */
97 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */
98 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */
99 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */
100 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */
101 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */
102 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */
103 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */
104 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */
105 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */
106 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */
107 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */
108 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */
109 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */
110 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */
111 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */
112 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */
113 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */
114 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */
115 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
116 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
117 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
118 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */
119 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */
120 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */
121 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
122 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
123 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
124 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
125 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */
126};
127
128/*
129 * LOUT1/ROUT1 output volume control:
130 * from -24 to 6 dB in 6 dB steps (mute instead of -30 dB)
131 */
132static DECLARE_TLV_DB_SCALE(out1_tlv, -3000, 600, 1);
133
134/*
135 * LOUT2/ROUT2 output volume control:
136 * from -33 to 6 dB in 3 dB steps (mute instead of -33 dB)
137 */
138static DECLARE_TLV_DB_SCALE(out2_tlv, -3300, 300, 1);
139
140/*
141 * LOUT3/ROUT3 output volume control:
142 * from -6 to 3 dB in 3 dB steps
143 */
144static DECLARE_TLV_DB_SCALE(out3_tlv, -600, 300, 0);
145
146/*
147 * Mic amp gain control:
148 * from -15 to 30 dB in 3 dB steps
149 * REVISIT: The actual min value(0x01) is -12 dB and the reg value 0x00 is not
150 * available
151 */
152static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -1500, 300, 0);
153
154static const struct snd_kcontrol_new ak4671_snd_controls[] = {
155 /* Common playback gain controls */
156 SOC_SINGLE_TLV("Line Output1 Playback Volume",
157 AK4671_OUTPUT_VOLUME_CONTROL, 0, 0x6, 0, out1_tlv),
158 SOC_SINGLE_TLV("Headphone Output2 Playback Volume",
159 AK4671_OUTPUT_VOLUME_CONTROL, 4, 0xd, 0, out2_tlv),
160 SOC_SINGLE_TLV("Line Output3 Playback Volume",
161 AK4671_LOUT3_POWER_MANAGERMENT, 6, 0x3, 0, out3_tlv),
162
163 /* Common capture gain controls */
164 SOC_DOUBLE_TLV("Mic Amp Capture Volume",
165 AK4671_MIC_AMP_GAIN, 0, 4, 0xf, 0, mic_amp_tlv),
166};
167
168/* event handlers */
169static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
170 struct snd_kcontrol *kcontrol, int event)
171{
172 struct snd_soc_codec *codec = w->codec;
173 u8 reg;
174
175 switch (event) {
176 case SND_SOC_DAPM_POST_PMU:
177 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
178 reg |= AK4671_MUTEN;
179 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
180 break;
181 case SND_SOC_DAPM_PRE_PMD:
182 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
183 reg &= ~AK4671_MUTEN;
184 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
185 break;
186 }
187
188 return 0;
189}
190
191/* Output Mixers */
192static const struct snd_kcontrol_new ak4671_lout1_mixer_controls[] = {
193 SOC_DAPM_SINGLE("DACL", AK4671_LOUT1_SIGNAL_SELECT, 0, 1, 0),
194 SOC_DAPM_SINGLE("LINL1", AK4671_LOUT1_SIGNAL_SELECT, 1, 1, 0),
195 SOC_DAPM_SINGLE("LINL2", AK4671_LOUT1_SIGNAL_SELECT, 2, 1, 0),
196 SOC_DAPM_SINGLE("LINL3", AK4671_LOUT1_SIGNAL_SELECT, 3, 1, 0),
197 SOC_DAPM_SINGLE("LINL4", AK4671_LOUT1_SIGNAL_SELECT, 4, 1, 0),
198 SOC_DAPM_SINGLE("LOOPL", AK4671_LOUT1_SIGNAL_SELECT, 5, 1, 0),
199};
200
201static const struct snd_kcontrol_new ak4671_rout1_mixer_controls[] = {
202 SOC_DAPM_SINGLE("DACR", AK4671_ROUT1_SIGNAL_SELECT, 0, 1, 0),
203 SOC_DAPM_SINGLE("RINR1", AK4671_ROUT1_SIGNAL_SELECT, 1, 1, 0),
204 SOC_DAPM_SINGLE("RINR2", AK4671_ROUT1_SIGNAL_SELECT, 2, 1, 0),
205 SOC_DAPM_SINGLE("RINR3", AK4671_ROUT1_SIGNAL_SELECT, 3, 1, 0),
206 SOC_DAPM_SINGLE("RINR4", AK4671_ROUT1_SIGNAL_SELECT, 4, 1, 0),
207 SOC_DAPM_SINGLE("LOOPR", AK4671_ROUT1_SIGNAL_SELECT, 5, 1, 0),
208};
209
210static const struct snd_kcontrol_new ak4671_lout2_mixer_controls[] = {
211 SOC_DAPM_SINGLE("DACHL", AK4671_LOUT2_SIGNAL_SELECT, 0, 1, 0),
212 SOC_DAPM_SINGLE("LINH1", AK4671_LOUT2_SIGNAL_SELECT, 1, 1, 0),
213 SOC_DAPM_SINGLE("LINH2", AK4671_LOUT2_SIGNAL_SELECT, 2, 1, 0),
214 SOC_DAPM_SINGLE("LINH3", AK4671_LOUT2_SIGNAL_SELECT, 3, 1, 0),
215 SOC_DAPM_SINGLE("LINH4", AK4671_LOUT2_SIGNAL_SELECT, 4, 1, 0),
216 SOC_DAPM_SINGLE("LOOPHL", AK4671_LOUT2_SIGNAL_SELECT, 5, 1, 0),
217};
218
219static const struct snd_kcontrol_new ak4671_rout2_mixer_controls[] = {
220 SOC_DAPM_SINGLE("DACHR", AK4671_ROUT2_SIGNAL_SELECT, 0, 1, 0),
221 SOC_DAPM_SINGLE("RINH1", AK4671_ROUT2_SIGNAL_SELECT, 1, 1, 0),
222 SOC_DAPM_SINGLE("RINH2", AK4671_ROUT2_SIGNAL_SELECT, 2, 1, 0),
223 SOC_DAPM_SINGLE("RINH3", AK4671_ROUT2_SIGNAL_SELECT, 3, 1, 0),
224 SOC_DAPM_SINGLE("RINH4", AK4671_ROUT2_SIGNAL_SELECT, 4, 1, 0),
225 SOC_DAPM_SINGLE("LOOPHR", AK4671_ROUT2_SIGNAL_SELECT, 5, 1, 0),
226};
227
228static const struct snd_kcontrol_new ak4671_lout3_mixer_controls[] = {
229 SOC_DAPM_SINGLE("DACSL", AK4671_LOUT3_SIGNAL_SELECT, 0, 1, 0),
230 SOC_DAPM_SINGLE("LINS1", AK4671_LOUT3_SIGNAL_SELECT, 1, 1, 0),
231 SOC_DAPM_SINGLE("LINS2", AK4671_LOUT3_SIGNAL_SELECT, 2, 1, 0),
232 SOC_DAPM_SINGLE("LINS3", AK4671_LOUT3_SIGNAL_SELECT, 3, 1, 0),
233 SOC_DAPM_SINGLE("LINS4", AK4671_LOUT3_SIGNAL_SELECT, 4, 1, 0),
234 SOC_DAPM_SINGLE("LOOPSL", AK4671_LOUT3_SIGNAL_SELECT, 5, 1, 0),
235};
236
237static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
238 SOC_DAPM_SINGLE("DACSR", AK4671_ROUT3_SIGNAL_SELECT, 0, 1, 0),
239 SOC_DAPM_SINGLE("RINS1", AK4671_ROUT3_SIGNAL_SELECT, 1, 1, 0),
240 SOC_DAPM_SINGLE("RINS2", AK4671_ROUT3_SIGNAL_SELECT, 2, 1, 0),
241 SOC_DAPM_SINGLE("RINS3", AK4671_ROUT3_SIGNAL_SELECT, 3, 1, 0),
242 SOC_DAPM_SINGLE("RINS4", AK4671_ROUT3_SIGNAL_SELECT, 4, 1, 0),
243 SOC_DAPM_SINGLE("LOOPSR", AK4671_ROUT3_SIGNAL_SELECT, 5, 1, 0),
244};
245
246/* Input MUXs */
247static const char *ak4671_lin_mux_texts[] =
248 {"LIN1", "LIN2", "LIN3", "LIN4"};
249static const struct soc_enum ak4671_lin_mux_enum =
250 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0,
251 ARRAY_SIZE(ak4671_lin_mux_texts),
252 ak4671_lin_mux_texts);
253static const struct snd_kcontrol_new ak4671_lin_mux_control =
254 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
255
256static const char *ak4671_rin_mux_texts[] =
257 {"RIN1", "RIN2", "RIN3", "RIN4"};
258static const struct soc_enum ak4671_rin_mux_enum =
259 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2,
260 ARRAY_SIZE(ak4671_rin_mux_texts),
261 ak4671_rin_mux_texts);
262static const struct snd_kcontrol_new ak4671_rin_mux_control =
263 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
264
265static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
266 /* Inputs */
267 SND_SOC_DAPM_INPUT("LIN1"),
268 SND_SOC_DAPM_INPUT("RIN1"),
269 SND_SOC_DAPM_INPUT("LIN2"),
270 SND_SOC_DAPM_INPUT("RIN2"),
271 SND_SOC_DAPM_INPUT("LIN3"),
272 SND_SOC_DAPM_INPUT("RIN3"),
273 SND_SOC_DAPM_INPUT("LIN4"),
274 SND_SOC_DAPM_INPUT("RIN4"),
275
276 /* Outputs */
277 SND_SOC_DAPM_OUTPUT("LOUT1"),
278 SND_SOC_DAPM_OUTPUT("ROUT1"),
279 SND_SOC_DAPM_OUTPUT("LOUT2"),
280 SND_SOC_DAPM_OUTPUT("ROUT2"),
281 SND_SOC_DAPM_OUTPUT("LOUT3"),
282 SND_SOC_DAPM_OUTPUT("ROUT3"),
283
284 /* DAC */
285 SND_SOC_DAPM_DAC("DAC Left", "Left HiFi Playback",
286 AK4671_AD_DA_POWER_MANAGEMENT, 6, 0),
287 SND_SOC_DAPM_DAC("DAC Right", "Right HiFi Playback",
288 AK4671_AD_DA_POWER_MANAGEMENT, 7, 0),
289
290 /* ADC */
291 SND_SOC_DAPM_ADC("ADC Left", "Left HiFi Capture",
292 AK4671_AD_DA_POWER_MANAGEMENT, 4, 0),
293 SND_SOC_DAPM_ADC("ADC Right", "Right HiFi Capture",
294 AK4671_AD_DA_POWER_MANAGEMENT, 5, 0),
295
296 /* PGA */
297 SND_SOC_DAPM_PGA("LOUT2 Mix Amp",
298 AK4671_LOUT2_POWER_MANAGERMENT, 5, 0, NULL, 0),
299 SND_SOC_DAPM_PGA("ROUT2 Mix Amp",
300 AK4671_LOUT2_POWER_MANAGERMENT, 6, 0, NULL, 0),
301
302 SND_SOC_DAPM_PGA("LIN1 Mixing Circuit",
303 AK4671_MIXING_POWER_MANAGEMENT1, 0, 0, NULL, 0),
304 SND_SOC_DAPM_PGA("RIN1 Mixing Circuit",
305 AK4671_MIXING_POWER_MANAGEMENT1, 1, 0, NULL, 0),
306 SND_SOC_DAPM_PGA("LIN2 Mixing Circuit",
307 AK4671_MIXING_POWER_MANAGEMENT1, 2, 0, NULL, 0),
308 SND_SOC_DAPM_PGA("RIN2 Mixing Circuit",
309 AK4671_MIXING_POWER_MANAGEMENT1, 3, 0, NULL, 0),
310 SND_SOC_DAPM_PGA("LIN3 Mixing Circuit",
311 AK4671_MIXING_POWER_MANAGEMENT1, 4, 0, NULL, 0),
312 SND_SOC_DAPM_PGA("RIN3 Mixing Circuit",
313 AK4671_MIXING_POWER_MANAGEMENT1, 5, 0, NULL, 0),
314 SND_SOC_DAPM_PGA("LIN4 Mixing Circuit",
315 AK4671_MIXING_POWER_MANAGEMENT1, 6, 0, NULL, 0),
316 SND_SOC_DAPM_PGA("RIN4 Mixing Circuit",
317 AK4671_MIXING_POWER_MANAGEMENT1, 7, 0, NULL, 0),
318
319 /* Output Mixers */
320 SND_SOC_DAPM_MIXER("LOUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 0, 0,
321 &ak4671_lout1_mixer_controls[0],
322 ARRAY_SIZE(ak4671_lout1_mixer_controls)),
323 SND_SOC_DAPM_MIXER("ROUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 1, 0,
324 &ak4671_rout1_mixer_controls[0],
325 ARRAY_SIZE(ak4671_rout1_mixer_controls)),
326 SND_SOC_DAPM_MIXER_E("LOUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
327 0, 0, &ak4671_lout2_mixer_controls[0],
328 ARRAY_SIZE(ak4671_lout2_mixer_controls),
329 ak4671_out2_event,
330 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
331 SND_SOC_DAPM_MIXER_E("ROUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
332 1, 0, &ak4671_rout2_mixer_controls[0],
333 ARRAY_SIZE(ak4671_rout2_mixer_controls),
334 ak4671_out2_event,
335 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
336 SND_SOC_DAPM_MIXER("LOUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 0, 0,
337 &ak4671_lout3_mixer_controls[0],
338 ARRAY_SIZE(ak4671_lout3_mixer_controls)),
339 SND_SOC_DAPM_MIXER("ROUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 1, 0,
340 &ak4671_rout3_mixer_controls[0],
341 ARRAY_SIZE(ak4671_rout3_mixer_controls)),
342
343 /* Input MUXs */
344 SND_SOC_DAPM_MUX("LIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 2, 0,
345 &ak4671_lin_mux_control),
346 SND_SOC_DAPM_MUX("RIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 3, 0,
347 &ak4671_rin_mux_control),
348
349 /* Mic Power */
350 SND_SOC_DAPM_MICBIAS("Mic Bias", AK4671_AD_DA_POWER_MANAGEMENT, 1, 0),
351
352 /* Supply */
353 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
354};
355
356static const struct snd_soc_dapm_route intercon[] = {
357 {"DAC Left", "NULL", "PMPLL"},
358 {"DAC Right", "NULL", "PMPLL"},
359 {"ADC Left", "NULL", "PMPLL"},
360 {"ADC Right", "NULL", "PMPLL"},
361
362 /* Outputs */
363 {"LOUT1", "NULL", "LOUT1 Mixer"},
364 {"ROUT1", "NULL", "ROUT1 Mixer"},
365 {"LOUT2", "NULL", "LOUT2 Mix Amp"},
366 {"ROUT2", "NULL", "ROUT2 Mix Amp"},
367 {"LOUT3", "NULL", "LOUT3 Mixer"},
368 {"ROUT3", "NULL", "ROUT3 Mixer"},
369
370 {"LOUT1 Mixer", "DACL", "DAC Left"},
371 {"ROUT1 Mixer", "DACR", "DAC Right"},
372 {"LOUT2 Mixer", "DACHL", "DAC Left"},
373 {"ROUT2 Mixer", "DACHR", "DAC Right"},
374 {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"},
375 {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"},
376 {"LOUT3 Mixer", "DACSL", "DAC Left"},
377 {"ROUT3 Mixer", "DACSR", "DAC Right"},
378
379 /* Inputs */
380 {"LIN MUX", "LIN1", "LIN1"},
381 {"LIN MUX", "LIN2", "LIN2"},
382 {"LIN MUX", "LIN3", "LIN3"},
383 {"LIN MUX", "LIN4", "LIN4"},
384
385 {"RIN MUX", "RIN1", "RIN1"},
386 {"RIN MUX", "RIN2", "RIN2"},
387 {"RIN MUX", "RIN3", "RIN3"},
388 {"RIN MUX", "RIN4", "RIN4"},
389
390 {"LIN1", NULL, "Mic Bias"},
391 {"RIN1", NULL, "Mic Bias"},
392 {"LIN2", NULL, "Mic Bias"},
393 {"RIN2", NULL, "Mic Bias"},
394
395 {"ADC Left", "NULL", "LIN MUX"},
396 {"ADC Right", "NULL", "RIN MUX"},
397
398 /* Analog Loops */
399 {"LIN1 Mixing Circuit", "NULL", "LIN1"},
400 {"RIN1 Mixing Circuit", "NULL", "RIN1"},
401 {"LIN2 Mixing Circuit", "NULL", "LIN2"},
402 {"RIN2 Mixing Circuit", "NULL", "RIN2"},
403 {"LIN3 Mixing Circuit", "NULL", "LIN3"},
404 {"RIN3 Mixing Circuit", "NULL", "RIN3"},
405 {"LIN4 Mixing Circuit", "NULL", "LIN4"},
406 {"RIN4 Mixing Circuit", "NULL", "RIN4"},
407
408 {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
409 {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
410 {"LOUT2 Mixer", "LINH1", "LIN1 Mixing Circuit"},
411 {"ROUT2 Mixer", "RINH1", "RIN1 Mixing Circuit"},
412 {"LOUT3 Mixer", "LINS1", "LIN1 Mixing Circuit"},
413 {"ROUT3 Mixer", "RINS1", "RIN1 Mixing Circuit"},
414
415 {"LOUT1 Mixer", "LINL2", "LIN2 Mixing Circuit"},
416 {"ROUT1 Mixer", "RINR2", "RIN2 Mixing Circuit"},
417 {"LOUT2 Mixer", "LINH2", "LIN2 Mixing Circuit"},
418 {"ROUT2 Mixer", "RINH2", "RIN2 Mixing Circuit"},
419 {"LOUT3 Mixer", "LINS2", "LIN2 Mixing Circuit"},
420 {"ROUT3 Mixer", "RINS2", "RIN2 Mixing Circuit"},
421
422 {"LOUT1 Mixer", "LINL3", "LIN3 Mixing Circuit"},
423 {"ROUT1 Mixer", "RINR3", "RIN3 Mixing Circuit"},
424 {"LOUT2 Mixer", "LINH3", "LIN3 Mixing Circuit"},
425 {"ROUT2 Mixer", "RINH3", "RIN3 Mixing Circuit"},
426 {"LOUT3 Mixer", "LINS3", "LIN3 Mixing Circuit"},
427 {"ROUT3 Mixer", "RINS3", "RIN3 Mixing Circuit"},
428
429 {"LOUT1 Mixer", "LINL4", "LIN4 Mixing Circuit"},
430 {"ROUT1 Mixer", "RINR4", "RIN4 Mixing Circuit"},
431 {"LOUT2 Mixer", "LINH4", "LIN4 Mixing Circuit"},
432 {"ROUT2 Mixer", "RINH4", "RIN4 Mixing Circuit"},
433 {"LOUT3 Mixer", "LINS4", "LIN4 Mixing Circuit"},
434 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
435};
436
437static int ak4671_add_widgets(struct snd_soc_codec *codec)
438{
439 snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
440 ARRAY_SIZE(ak4671_dapm_widgets));
441
442 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
443
444 return 0;
445}
446
447static int ak4671_hw_params(struct snd_pcm_substream *substream,
448 struct snd_pcm_hw_params *params,
449 struct snd_soc_dai *dai)
450{
451 struct snd_soc_codec *codec = dai->codec;
452 u8 fs;
453
454 fs = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
455 fs &= ~AK4671_FS;
456
457 switch (params_rate(params)) {
458 case 8000:
459 fs |= AK4671_FS_8KHZ;
460 break;
461 case 12000:
462 fs |= AK4671_FS_12KHZ;
463 break;
464 case 16000:
465 fs |= AK4671_FS_16KHZ;
466 break;
467 case 24000:
468 fs |= AK4671_FS_24KHZ;
469 break;
470 case 11025:
471 fs |= AK4671_FS_11_025KHZ;
472 break;
473 case 22050:
474 fs |= AK4671_FS_22_05KHZ;
475 break;
476 case 32000:
477 fs |= AK4671_FS_32KHZ;
478 break;
479 case 44100:
480 fs |= AK4671_FS_44_1KHZ;
481 break;
482 case 48000:
483 fs |= AK4671_FS_48KHZ;
484 break;
485 default:
486 return -EINVAL;
487 }
488
489 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, fs);
490
491 return 0;
492}
493
494static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
495 unsigned int freq, int dir)
496{
497 struct snd_soc_codec *codec = dai->codec;
498 u8 pll;
499
500 pll = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
501 pll &= ~AK4671_PLL;
502
503 switch (freq) {
504 case 11289600:
505 pll |= AK4671_PLL_11_2896MHZ;
506 break;
507 case 12000000:
508 pll |= AK4671_PLL_12MHZ;
509 break;
510 case 12288000:
511 pll |= AK4671_PLL_12_288MHZ;
512 break;
513 case 13000000:
514 pll |= AK4671_PLL_13MHZ;
515 break;
516 case 13500000:
517 pll |= AK4671_PLL_13_5MHZ;
518 break;
519 case 19200000:
520 pll |= AK4671_PLL_19_2MHZ;
521 break;
522 case 24000000:
523 pll |= AK4671_PLL_24MHZ;
524 break;
525 case 26000000:
526 pll |= AK4671_PLL_26MHZ;
527 break;
528 case 27000000:
529 pll |= AK4671_PLL_27MHZ;
530 break;
531 default:
532 return -EINVAL;
533 }
534
535 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, pll);
536
537 return 0;
538}
539
540static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
541{
542 struct snd_soc_codec *codec = dai->codec;
543 u8 mode;
544 u8 format;
545
546 /* set master/slave audio interface */
547 mode = snd_soc_read(codec, AK4671_PLL_MODE_SELECT1);
548
549 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
550 case SND_SOC_DAIFMT_CBM_CFM:
551 mode |= AK4671_M_S;
552 break;
553 case SND_SOC_DAIFMT_CBM_CFS:
554 mode &= ~(AK4671_M_S);
555 break;
556 default:
557 return -EINVAL;
558 }
559
560 /* interface format */
561 format = snd_soc_read(codec, AK4671_FORMAT_SELECT);
562 format &= ~AK4671_DIF;
563
564 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
565 case SND_SOC_DAIFMT_I2S:
566 format |= AK4671_DIF_I2S_MODE;
567 break;
568 case SND_SOC_DAIFMT_LEFT_J:
569 format |= AK4671_DIF_MSB_MODE;
570 break;
571 case SND_SOC_DAIFMT_DSP_A:
572 format |= AK4671_DIF_DSP_MODE;
573 format |= AK4671_BCKP;
574 format |= AK4671_MSBS;
575 break;
576 default:
577 return -EINVAL;
578 }
579
580 /* set mode and format */
581 snd_soc_write(codec, AK4671_PLL_MODE_SELECT1, mode);
582 snd_soc_write(codec, AK4671_FORMAT_SELECT, format);
583
584 return 0;
585}
586
587static int ak4671_set_bias_level(struct snd_soc_codec *codec,
588 enum snd_soc_bias_level level)
589{
590 u8 reg;
591
592 switch (level) {
593 case SND_SOC_BIAS_ON:
594 case SND_SOC_BIAS_PREPARE:
595 case SND_SOC_BIAS_STANDBY:
596 reg = snd_soc_read(codec, AK4671_AD_DA_POWER_MANAGEMENT);
597 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT,
598 reg | AK4671_PMVCM);
599 break;
600 case SND_SOC_BIAS_OFF:
601 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
602 break;
603 }
604 codec->bias_level = level;
605 return 0;
606}
607
608#define AK4671_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
609 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
610 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
611 SNDRV_PCM_RATE_48000)
612
613#define AK4671_FORMATS SNDRV_PCM_FMTBIT_S16_LE
614
615static struct snd_soc_dai_ops ak4671_dai_ops = {
616 .hw_params = ak4671_hw_params,
617 .set_sysclk = ak4671_set_dai_sysclk,
618 .set_fmt = ak4671_set_dai_fmt,
619};
620
621struct snd_soc_dai ak4671_dai = {
622 .name = "AK4671",
623 .playback = {
624 .stream_name = "Playback",
625 .channels_min = 1,
626 .channels_max = 2,
627 .rates = AK4671_RATES,
628 .formats = AK4671_FORMATS,},
629 .capture = {
630 .stream_name = "Capture",
631 .channels_min = 1,
632 .channels_max = 2,
633 .rates = AK4671_RATES,
634 .formats = AK4671_FORMATS,},
635 .ops = &ak4671_dai_ops,
636};
637EXPORT_SYMBOL_GPL(ak4671_dai);
638
639static int ak4671_probe(struct platform_device *pdev)
640{
641 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
642 struct snd_soc_codec *codec;
643 int ret = 0;
644
645 if (ak4671_codec == NULL) {
646 dev_err(&pdev->dev, "Codec device not registered\n");
647 return -ENODEV;
648 }
649
650 socdev->card->codec = ak4671_codec;
651 codec = ak4671_codec;
652
653 /* register pcms */
654 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
655 if (ret < 0) {
656 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
657 goto pcm_err;
658 }
659
660 snd_soc_add_controls(codec, ak4671_snd_controls,
661 ARRAY_SIZE(ak4671_snd_controls));
662 ak4671_add_widgets(codec);
663
664 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
665
666 return ret;
667
668pcm_err:
669 return ret;
670}
671
672static int ak4671_remove(struct platform_device *pdev)
673{
674 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
675
676 snd_soc_free_pcms(socdev);
677 snd_soc_dapm_free(socdev);
678
679 return 0;
680}
681
682struct snd_soc_codec_device soc_codec_dev_ak4671 = {
683 .probe = ak4671_probe,
684 .remove = ak4671_remove,
685};
686EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
687
688static int ak4671_register(struct ak4671_priv *ak4671,
689 enum snd_soc_control_type control)
690{
691 int ret;
692 struct snd_soc_codec *codec = &ak4671->codec;
693
694 if (ak4671_codec) {
695 dev_err(codec->dev, "Another AK4671 is registered\n");
696 ret = -EINVAL;
697 goto err;
698 }
699
700 mutex_init(&codec->mutex);
701 INIT_LIST_HEAD(&codec->dapm_widgets);
702 INIT_LIST_HEAD(&codec->dapm_paths);
703
704 codec->private_data = ak4671;
705 codec->name = "AK4671";
706 codec->owner = THIS_MODULE;
707 codec->bias_level = SND_SOC_BIAS_OFF;
708 codec->set_bias_level = ak4671_set_bias_level;
709 codec->dai = &ak4671_dai;
710 codec->num_dai = 1;
711 codec->reg_cache_size = AK4671_CACHEREGNUM;
712 codec->reg_cache = &ak4671->reg_cache;
713
714 memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
715
716 ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
717 if (ret < 0) {
718 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
719 goto err;
720 }
721
722 ak4671_dai.dev = codec->dev;
723 ak4671_codec = codec;
724
725 ret = snd_soc_register_codec(codec);
726 if (ret != 0) {
727 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
728 goto err;
729 }
730
731 ret = snd_soc_register_dai(&ak4671_dai);
732 if (ret != 0) {
733 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
734 goto err_codec;
735 }
736
737 return 0;
738
739err_codec:
740 snd_soc_unregister_codec(codec);
741err:
742 kfree(ak4671);
743 return ret;
744}
745
746static void ak4671_unregister(struct ak4671_priv *ak4671)
747{
748 ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
749 snd_soc_unregister_dai(&ak4671_dai);
750 snd_soc_unregister_codec(&ak4671->codec);
751 kfree(ak4671);
752 ak4671_codec = NULL;
753}
754
755static int __devinit ak4671_i2c_probe(struct i2c_client *client,
756 const struct i2c_device_id *id)
757{
758 struct ak4671_priv *ak4671;
759 struct snd_soc_codec *codec;
760
761 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
762 if (ak4671 == NULL)
763 return -ENOMEM;
764
765 codec = &ak4671->codec;
766 codec->hw_write = (hw_write_t)i2c_master_send;
767
768 i2c_set_clientdata(client, ak4671);
769 codec->control_data = client;
770
771 codec->dev = &client->dev;
772
773 return ak4671_register(ak4671, SND_SOC_I2C);
774}
775
776static __devexit int ak4671_i2c_remove(struct i2c_client *client)
777{
778 struct ak4671_priv *ak4671 = i2c_get_clientdata(client);
779
780 ak4671_unregister(ak4671);
781
782 return 0;
783}
784
785static const struct i2c_device_id ak4671_i2c_id[] = {
786 { "ak4671", 0 },
787 { }
788};
789MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
790
791static struct i2c_driver ak4671_i2c_driver = {
792 .driver = {
793 .name = "ak4671",
794 .owner = THIS_MODULE,
795 },
796 .probe = ak4671_i2c_probe,
797 .remove = __devexit_p(ak4671_i2c_remove),
798 .id_table = ak4671_i2c_id,
799};
800
801static int __init ak4671_modinit(void)
802{
803 return i2c_add_driver(&ak4671_i2c_driver);
804}
805module_init(ak4671_modinit);
806
807static void __exit ak4671_exit(void)
808{
809 i2c_del_driver(&ak4671_i2c_driver);
810}
811module_exit(ak4671_exit);
812
813MODULE_DESCRIPTION("ASoC AK4671 codec driver");
814MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
815MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
new file mode 100644
index 000000000000..e2fad964e88b
--- /dev/null
+++ b/sound/soc/codecs/ak4671.h
@@ -0,0 +1,156 @@
1/*
2 * ak4671.h -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef _AK4671_H
15#define _AK4671_H
16
17#define AK4671_AD_DA_POWER_MANAGEMENT 0x00
18#define AK4671_PLL_MODE_SELECT0 0x01
19#define AK4671_PLL_MODE_SELECT1 0x02
20#define AK4671_FORMAT_SELECT 0x03
21#define AK4671_MIC_SIGNAL_SELECT 0x04
22#define AK4671_MIC_AMP_GAIN 0x05
23#define AK4671_MIXING_POWER_MANAGEMENT0 0x06
24#define AK4671_MIXING_POWER_MANAGEMENT1 0x07
25#define AK4671_OUTPUT_VOLUME_CONTROL 0x08
26#define AK4671_LOUT1_SIGNAL_SELECT 0x09
27#define AK4671_ROUT1_SIGNAL_SELECT 0x0a
28#define AK4671_LOUT2_SIGNAL_SELECT 0x0b
29#define AK4671_ROUT2_SIGNAL_SELECT 0x0c
30#define AK4671_LOUT3_SIGNAL_SELECT 0x0d
31#define AK4671_ROUT3_SIGNAL_SELECT 0x0e
32#define AK4671_LOUT1_POWER_MANAGERMENT 0x0f
33#define AK4671_LOUT2_POWER_MANAGERMENT 0x10
34#define AK4671_LOUT3_POWER_MANAGERMENT 0x11
35#define AK4671_LCH_INPUT_VOLUME_CONTROL 0x12
36#define AK4671_RCH_INPUT_VOLUME_CONTROL 0x13
37#define AK4671_ALC_REFERENCE_SELECT 0x14
38#define AK4671_DIGITAL_MIXING_CONTROL 0x15
39#define AK4671_ALC_TIMER_SELECT 0x16
40#define AK4671_ALC_MODE_CONTROL 0x17
41#define AK4671_MODE_CONTROL1 0x18
42#define AK4671_MODE_CONTROL2 0x19
43#define AK4671_LCH_OUTPUT_VOLUME_CONTROL 0x1a
44#define AK4671_RCH_OUTPUT_VOLUME_CONTROL 0x1b
45#define AK4671_SIDETONE_A_CONTROL 0x1c
46#define AK4671_DIGITAL_FILTER_SELECT 0x1d
47#define AK4671_FIL3_COEFFICIENT0 0x1e
48#define AK4671_FIL3_COEFFICIENT1 0x1f
49#define AK4671_FIL3_COEFFICIENT2 0x20
50#define AK4671_FIL3_COEFFICIENT3 0x21
51#define AK4671_EQ_COEFFICIENT0 0x22
52#define AK4671_EQ_COEFFICIENT1 0x23
53#define AK4671_EQ_COEFFICIENT2 0x24
54#define AK4671_EQ_COEFFICIENT3 0x25
55#define AK4671_EQ_COEFFICIENT4 0x26
56#define AK4671_EQ_COEFFICIENT5 0x27
57#define AK4671_FIL1_COEFFICIENT0 0x28
58#define AK4671_FIL1_COEFFICIENT1 0x29
59#define AK4671_FIL1_COEFFICIENT2 0x2a
60#define AK4671_FIL1_COEFFICIENT3 0x2b
61#define AK4671_FIL2_COEFFICIENT0 0x2c
62#define AK4671_FIL2_COEFFICIENT1 0x2d
63#define AK4671_FIL2_COEFFICIENT2 0x2e
64#define AK4671_FIL2_COEFFICIENT3 0x2f
65#define AK4671_DIGITAL_FILTER_SELECT2 0x30
66#define AK4671_E1_COEFFICIENT0 0x32
67#define AK4671_E1_COEFFICIENT1 0x33
68#define AK4671_E1_COEFFICIENT2 0x34
69#define AK4671_E1_COEFFICIENT3 0x35
70#define AK4671_E1_COEFFICIENT4 0x36
71#define AK4671_E1_COEFFICIENT5 0x37
72#define AK4671_E2_COEFFICIENT0 0x38
73#define AK4671_E2_COEFFICIENT1 0x39
74#define AK4671_E2_COEFFICIENT2 0x3a
75#define AK4671_E2_COEFFICIENT3 0x3b
76#define AK4671_E2_COEFFICIENT4 0x3c
77#define AK4671_E2_COEFFICIENT5 0x3d
78#define AK4671_E3_COEFFICIENT0 0x3e
79#define AK4671_E3_COEFFICIENT1 0x3f
80#define AK4671_E3_COEFFICIENT2 0x40
81#define AK4671_E3_COEFFICIENT3 0x41
82#define AK4671_E3_COEFFICIENT4 0x42
83#define AK4671_E3_COEFFICIENT5 0x43
84#define AK4671_E4_COEFFICIENT0 0x44
85#define AK4671_E4_COEFFICIENT1 0x45
86#define AK4671_E4_COEFFICIENT2 0x46
87#define AK4671_E4_COEFFICIENT3 0x47
88#define AK4671_E4_COEFFICIENT4 0x48
89#define AK4671_E4_COEFFICIENT5 0x49
90#define AK4671_E5_COEFFICIENT0 0x4a
91#define AK4671_E5_COEFFICIENT1 0x4b
92#define AK4671_E5_COEFFICIENT2 0x4c
93#define AK4671_E5_COEFFICIENT3 0x4d
94#define AK4671_E5_COEFFICIENT4 0x4e
95#define AK4671_E5_COEFFICIENT5 0x4f
96#define AK4671_EQ_CONTROL_250HZ_100HZ 0x50
97#define AK4671_EQ_CONTROL_3500HZ_1KHZ 0x51
98#define AK4671_EQ_CONTRO_10KHZ 0x52
99#define AK4671_PCM_IF_CONTROL0 0x53
100#define AK4671_PCM_IF_CONTROL1 0x54
101#define AK4671_PCM_IF_CONTROL2 0x55
102#define AK4671_DIGITAL_VOLUME_B_CONTROL 0x56
103#define AK4671_DIGITAL_VOLUME_C_CONTROL 0x57
104#define AK4671_SIDETONE_VOLUME_CONTROL 0x58
105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
106#define AK4671_SAR_ADC_CONTROL 0x5a
107
108#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
109
110/* Bitfield Definitions */
111
112/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
113#define AK4671_PMVCM 0x01
114
115/* AK4671_PLL_MODE_SELECT0 (0x01) Fields */
116#define AK4671_PLL 0x0f
117#define AK4671_PLL_11_2896MHZ (4 << 0)
118#define AK4671_PLL_12_288MHZ (5 << 0)
119#define AK4671_PLL_12MHZ (6 << 0)
120#define AK4671_PLL_24MHZ (7 << 0)
121#define AK4671_PLL_19_2MHZ (8 << 0)
122#define AK4671_PLL_13_5MHZ (12 << 0)
123#define AK4671_PLL_27MHZ (13 << 0)
124#define AK4671_PLL_13MHZ (14 << 0)
125#define AK4671_PLL_26MHZ (15 << 0)
126#define AK4671_FS 0xf0
127#define AK4671_FS_8KHZ (0 << 4)
128#define AK4671_FS_12KHZ (1 << 4)
129#define AK4671_FS_16KHZ (2 << 4)
130#define AK4671_FS_24KHZ (3 << 4)
131#define AK4671_FS_11_025KHZ (5 << 4)
132#define AK4671_FS_22_05KHZ (7 << 4)
133#define AK4671_FS_32KHZ (10 << 4)
134#define AK4671_FS_48KHZ (11 << 4)
135#define AK4671_FS_44_1KHZ (15 << 4)
136
137/* AK4671_PLL_MODE_SELECT1 (0x02) Fields */
138#define AK4671_PMPLL 0x01
139#define AK4671_M_S 0x02
140
141/* AK4671_FORMAT_SELECT (0x03) Fields */
142#define AK4671_DIF 0x03
143#define AK4671_DIF_DSP_MODE (0 << 0)
144#define AK4671_DIF_MSB_MODE (2 << 0)
145#define AK4671_DIF_I2S_MODE (3 << 0)
146#define AK4671_BCKP 0x04
147#define AK4671_MSBS 0x08
148#define AK4671_SDOD 0x10
149
150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
151#define AK4671_MUTEN 0x04
152
153extern struct snd_soc_dai ak4671_dai;
154extern struct snd_soc_codec_device soc_codec_dev_ak4671;
155
156#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ca1e24a8f12a..ffe122d1cd76 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -520,6 +520,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0), 520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0), 521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), 522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
523 SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
523 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), 524 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
524 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), 525 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
525 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1), 526 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
@@ -598,13 +599,6 @@ static int cs4270_probe(struct platform_device *pdev)
598 goto error_free_pcms; 599 goto error_free_pcms;
599 } 600 }
600 601
601 /* And finally, register the socdev */
602 ret = snd_soc_init_card(socdev);
603 if (ret < 0) {
604 dev_err(codec->dev, "failed to register card\n");
605 goto error_free_pcms;
606 }
607
608 return 0; 602 return 0;
609 603
610error_free_pcms: 604error_free_pcms:
@@ -802,22 +796,6 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
802 * and all registers are written back to the hardware when resuming. 796 * and all registers are written back to the hardware when resuming.
803 */ 797 */
804 798
805static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
806{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
808 struct snd_soc_codec *codec = &cs4270->codec;
809
810 return snd_soc_suspend_device(codec->dev);
811}
812
813static int cs4270_i2c_resume(struct i2c_client *client)
814{
815 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
816 struct snd_soc_codec *codec = &cs4270->codec;
817
818 return snd_soc_resume_device(codec->dev);
819}
820
821static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 799static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
822{ 800{
823 struct snd_soc_codec *codec = cs4270_codec; 801 struct snd_soc_codec *codec = cs4270_codec;
@@ -853,8 +831,6 @@ static int cs4270_soc_resume(struct platform_device *pdev)
853 return snd_soc_write(codec, CS4270_PWRCTL, reg); 831 return snd_soc_write(codec, CS4270_PWRCTL, reg);
854} 832}
855#else 833#else
856#define cs4270_i2c_suspend NULL
857#define cs4270_i2c_resume NULL
858#define cs4270_soc_suspend NULL 834#define cs4270_soc_suspend NULL
859#define cs4270_soc_resume NULL 835#define cs4270_soc_resume NULL
860#endif /* CONFIG_PM */ 836#endif /* CONFIG_PM */
@@ -873,8 +849,6 @@ static struct i2c_driver cs4270_i2c_driver = {
873 .id_table = cs4270_id, 849 .id_table = cs4270_id,
874 .probe = cs4270_i2c_probe, 850 .probe = cs4270_i2c_probe,
875 .remove = cs4270_i2c_remove, 851 .remove = cs4270_i2c_remove,
876 .suspend = cs4270_i2c_suspend,
877 .resume = cs4270_i2c_resume,
878}; 852};
879 853
880/* 854/*
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 38eac9c866e1..e000cdfec1ec 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -93,7 +93,6 @@ static int cx20442_add_widgets(struct snd_soc_codec *codec)
93 snd_soc_dapm_add_routes(codec, cx20442_audio_map, 93 snd_soc_dapm_add_routes(codec, cx20442_audio_map,
94 ARRAY_SIZE(cx20442_audio_map)); 94 ARRAY_SIZE(cx20442_audio_map));
95 95
96 snd_soc_dapm_new_widgets(codec);
97 return 0; 96 return 0;
98} 97}
99 98
@@ -355,17 +354,6 @@ static int cx20442_codec_probe(struct platform_device *pdev)
355 354
356 cx20442_add_widgets(codec); 355 cx20442_add_widgets(codec);
357 356
358 ret = snd_soc_init_card(socdev);
359 if (ret < 0) {
360 dev_err(&pdev->dev, "failed to register card\n");
361 goto card_err;
362 }
363
364 return ret;
365
366card_err:
367 snd_soc_free_pcms(socdev);
368 snd_soc_dapm_free(socdev);
369pcm_err: 357pcm_err:
370 return ret; 358 return ret;
371} 359}
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 5cda9e6b5a74..2afcd0a8669d 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -90,13 +90,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
90 goto pcm_err; 90 goto pcm_err;
91 } 91 }
92 92
93 /* Register Card. */
94 ret = snd_soc_init_card(socdev);
95 if (ret < 0) {
96 printk(KERN_ERR "pcm3008: failed to register card\n");
97 goto card_err;
98 }
99
100 /* DEM1 DEM0 DE-EMPHASIS_MODE 93 /* DEM1 DEM0 DE-EMPHASIS_MODE
101 * Low Low De-emphasis 44.1 kHz ON 94 * Low Low De-emphasis 44.1 kHz ON
102 * Low High De-emphasis OFF 95 * Low High De-emphasis OFF
@@ -136,8 +129,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
136 129
137gpio_err: 130gpio_err:
138 pcm3008_gpio_free(setup); 131 pcm3008_gpio_free(setup);
139card_err:
140 snd_soc_free_pcms(socdev);
141pcm_err: 132pcm_err:
142 kfree(socdev->card->codec); 133 kfree(socdev->card->codec);
143 134
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index c550750c79c0..d2ff1cde6883 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -210,7 +210,6 @@ static int ssm2602_add_widgets(struct snd_soc_codec *codec)
210 210
211 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn)); 211 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
212 212
213 snd_soc_dapm_new_widgets(codec);
214 return 0; 213 return 0;
215} 214}
216 215
@@ -613,17 +612,9 @@ static int ssm2602_init(struct snd_soc_device *socdev)
613 snd_soc_add_controls(codec, ssm2602_snd_controls, 612 snd_soc_add_controls(codec, ssm2602_snd_controls,
614 ARRAY_SIZE(ssm2602_snd_controls)); 613 ARRAY_SIZE(ssm2602_snd_controls));
615 ssm2602_add_widgets(codec); 614 ssm2602_add_widgets(codec);
616 ret = snd_soc_init_card(socdev);
617 if (ret < 0) {
618 pr_err("ssm2602: failed to register card\n");
619 goto card_err;
620 }
621 615
622 return ret; 616 return ret;
623 617
624card_err:
625 snd_soc_free_pcms(socdev);
626 snd_soc_dapm_free(socdev);
627pcm_err: 618pcm_err:
628 kfree(codec->reg_cache); 619 kfree(codec->reg_cache);
629 return ret; 620 return ret;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index befc6488c39a..bbc72c2ddfca 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -418,9 +418,6 @@ static int stac9766_codec_probe(struct platform_device *pdev)
418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls, 418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls,
419 ARRAY_SIZE(stac9766_snd_ac97_controls)); 419 ARRAY_SIZE(stac9766_snd_ac97_controls));
420 420
421 ret = snd_soc_init_card(socdev);
422 if (ret < 0)
423 goto reset_err;
424 return 0; 421 return 0;
425 422
426reset_err: 423reset_err:
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 35606ae60868..a9dc5fb54774 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -265,8 +265,8 @@ static const int bosr_usb_divisor_table[] = {
265#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15)) 265#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15))
266static const unsigned short sr_valid_mask[] = { 266static const unsigned short sr_valid_mask[] = {
267 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/ 267 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/
268 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
269 LOWER_GROUP, /* Usb, bosr - 0*/ 268 LOWER_GROUP, /* Usb, bosr - 0*/
269 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
270 UPPER_GROUP, /* Usb, bosr - 1*/ 270 UPPER_GROUP, /* Usb, bosr - 1*/
271}; 271};
272/* 272/*
@@ -395,7 +395,6 @@ static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
395 /* set up audio path interconnects */ 395 /* set up audio path interconnects */
396 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 396 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
397 397
398 snd_soc_dapm_new_widgets(codec);
399 return 0; 398 return 0;
400} 399}
401 400
@@ -625,11 +624,10 @@ static int tlv320aic23_resume(struct platform_device *pdev)
625{ 624{
626 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 625 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
627 struct snd_soc_codec *codec = socdev->card->codec; 626 struct snd_soc_codec *codec = socdev->card->codec;
628 int i;
629 u16 reg; 627 u16 reg;
630 628
631 /* Sync reg_cache with the hardware */ 629 /* Sync reg_cache with the hardware */
632 for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) { 630 for (reg = 0; reg < TLV320AIC23_RESET; reg++) {
633 u16 val = tlv320aic23_read_reg_cache(codec, reg); 631 u16 val = tlv320aic23_read_reg_cache(codec, reg);
634 tlv320aic23_write(codec, reg, val); 632 tlv320aic23_write(codec, reg, val);
635 } 633 }
@@ -707,17 +705,9 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
707 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 705 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
708 ARRAY_SIZE(tlv320aic23_snd_controls)); 706 ARRAY_SIZE(tlv320aic23_snd_controls));
709 tlv320aic23_add_widgets(codec); 707 tlv320aic23_add_widgets(codec);
710 ret = snd_soc_init_card(socdev);
711 if (ret < 0) {
712 printk(KERN_ERR "tlv320aic23: failed to register card\n");
713 goto card_err;
714 }
715 708
716 return ret; 709 return ret;
717 710
718card_err:
719 snd_soc_free_pcms(socdev);
720 snd_soc_dapm_free(socdev);
721pcm_err: 711pcm_err:
722 kfree(codec->reg_cache); 712 kfree(codec->reg_cache);
723 return ret; 713 return ret;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 3387d9e736ea..357b609196e3 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -356,18 +356,7 @@ static int aic26_probe(struct platform_device *pdev)
356 ARRAY_SIZE(aic26_snd_controls)); 356 ARRAY_SIZE(aic26_snd_controls));
357 WARN_ON(err < 0); 357 WARN_ON(err < 0);
358 358
359 /* CODEC is setup, we can register the card now */
360 dev_dbg(&pdev->dev, "Registering card\n");
361 ret = snd_soc_init_card(socdev);
362 if (ret < 0) {
363 dev_err(&pdev->dev, "aic26: failed to register card\n");
364 goto card_err;
365 }
366 return 0; 359 return 0;
367
368 card_err:
369 snd_soc_free_pcms(socdev);
370 return ret;
371} 360}
372 361
373static int aic26_remove(struct platform_device *pdev) 362static int aic26_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 3395cf945d56..2b4dc2b0b017 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -753,7 +753,6 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
753 /* set up audio path interconnects */ 753 /* set up audio path interconnects */
754 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 754 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
755 755
756 snd_soc_dapm_new_widgets(codec);
757 return 0; 756 return 0;
758} 757}
759 758
@@ -1405,18 +1404,8 @@ static int aic3x_probe(struct platform_device *pdev)
1405 1404
1406 aic3x_add_widgets(codec); 1405 aic3x_add_widgets(codec);
1407 1406
1408 ret = snd_soc_init_card(socdev);
1409 if (ret < 0) {
1410 printk(KERN_ERR "aic3x: failed to register card\n");
1411 goto card_err;
1412 }
1413
1414 return ret; 1407 return ret;
1415 1408
1416card_err:
1417 snd_soc_free_pcms(socdev);
1418 snd_soc_dapm_free(socdev);
1419
1420pcm_err: 1409pcm_err:
1421 kfree(codec->reg_cache); 1410 kfree(codec->reg_cache);
1422 return ret; 1411 return ret;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
new file mode 100644
index 000000000000..9c8903dbe647
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -0,0 +1,1229 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/pm.h>
29#include <linux/i2c.h>
30#include <linux/platform_device.h>
31#include <linux/interrupt.h>
32#include <linux/gpio.h>
33#include <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>
38#include <sound/initval.h>
39#include <sound/tlv.h>
40
41#include <sound/tlv320dac33-plat.h>
42#include "tlv320dac33.h"
43
44#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words,
45 * 6144 stereo */
46#define DAC33_BUFFER_SIZE_SAMPLES 6144
47
48#define NSAMPLE_MAX 5700
49
50#define LATENCY_TIME_MS 20
51
52static struct snd_soc_codec *tlv320dac33_codec;
53
54enum dac33_state {
55 DAC33_IDLE = 0,
56 DAC33_PREFILL,
57 DAC33_PLAYBACK,
58 DAC33_FLUSH,
59};
60
61struct tlv320dac33_priv {
62 struct mutex mutex;
63 struct workqueue_struct *dac33_wq;
64 struct work_struct work;
65 struct snd_soc_codec codec;
66 int power_gpio;
67 int chip_power;
68 int irq;
69 unsigned int refclk;
70
71 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
72 unsigned int nsample_min; /* nsample should not be lower than
73 * this */
74 unsigned int nsample_max; /* nsample should not be higher than
75 * this */
76 unsigned int nsample_switch; /* Use FIFO or bypass FIFO switch */
77 unsigned int nsample; /* burst read amount from host */
78
79 enum dac33_state state;
80};
81
82static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
830x00, 0x00, 0x00, 0x00, /* 0x00 - 0x03 */
840x00, 0x00, 0x00, 0x00, /* 0x04 - 0x07 */
850x00, 0x00, 0x00, 0x00, /* 0x08 - 0x0b */
860x00, 0x00, 0x00, 0x00, /* 0x0c - 0x0f */
870x00, 0x00, 0x00, 0x00, /* 0x10 - 0x13 */
880x00, 0x00, 0x00, 0x00, /* 0x14 - 0x17 */
890x00, 0x00, 0x00, 0x00, /* 0x18 - 0x1b */
900x00, 0x00, 0x00, 0x00, /* 0x1c - 0x1f */
910x00, 0x00, 0x00, 0x00, /* 0x20 - 0x23 */
920x00, 0x00, 0x00, 0x00, /* 0x24 - 0x27 */
930x00, 0x00, 0x00, 0x00, /* 0x28 - 0x2b */
940x00, 0x00, 0x00, 0x80, /* 0x2c - 0x2f */
950x80, 0x00, 0x00, 0x00, /* 0x30 - 0x33 */
960x00, 0x00, 0x00, 0x00, /* 0x34 - 0x37 */
970x00, 0x00, /* 0x38 - 0x39 */
98/* Registers 0x3a - 0x3f are reserved */
99 0x00, 0x00, /* 0x3a - 0x3b */
1000x00, 0x00, 0x00, 0x00, /* 0x3c - 0x3f */
101
1020x00, 0x00, 0x00, 0x00, /* 0x40 - 0x43 */
1030x00, 0x80, /* 0x44 - 0x45 */
104/* Registers 0x46 - 0x47 are reserved */
105 0x80, 0x80, /* 0x46 - 0x47 */
106
1070x80, 0x00, 0x00, /* 0x48 - 0x4a */
108/* Registers 0x4b - 0x7c are reserved */
109 0x00, /* 0x4b */
1100x00, 0x00, 0x00, 0x00, /* 0x4c - 0x4f */
1110x00, 0x00, 0x00, 0x00, /* 0x50 - 0x53 */
1120x00, 0x00, 0x00, 0x00, /* 0x54 - 0x57 */
1130x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5b */
1140x00, 0x00, 0x00, 0x00, /* 0x5c - 0x5f */
1150x00, 0x00, 0x00, 0x00, /* 0x60 - 0x63 */
1160x00, 0x00, 0x00, 0x00, /* 0x64 - 0x67 */
1170x00, 0x00, 0x00, 0x00, /* 0x68 - 0x6b */
1180x00, 0x00, 0x00, 0x00, /* 0x6c - 0x6f */
1190x00, 0x00, 0x00, 0x00, /* 0x70 - 0x73 */
1200x00, 0x00, 0x00, 0x00, /* 0x74 - 0x77 */
1210x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7b */
1220x00, /* 0x7c */
123
124 0xda, 0x33, 0x03, /* 0x7d - 0x7f */
125};
126
127/* Register read and write */
128static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
129 unsigned reg)
130{
131 u8 *cache = codec->reg_cache;
132 if (reg >= DAC33_CACHEREGNUM)
133 return 0;
134
135 return cache[reg];
136}
137
138static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
139 u8 reg, u8 value)
140{
141 u8 *cache = codec->reg_cache;
142 if (reg >= DAC33_CACHEREGNUM)
143 return;
144
145 cache[reg] = value;
146}
147
148static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
149 u8 *value)
150{
151 struct tlv320dac33_priv *dac33 = codec->private_data;
152 int val;
153
154 *value = reg & 0xff;
155
156 /* If powered off, return the cached value */
157 if (dac33->chip_power) {
158 val = i2c_smbus_read_byte_data(codec->control_data, value[0]);
159 if (val < 0) {
160 dev_err(codec->dev, "Read failed (%d)\n", val);
161 value[0] = dac33_read_reg_cache(codec, reg);
162 } else {
163 value[0] = val;
164 dac33_write_reg_cache(codec, reg, val);
165 }
166 } else {
167 value[0] = dac33_read_reg_cache(codec, reg);
168 }
169
170 return 0;
171}
172
173static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
174 unsigned int value)
175{
176 struct tlv320dac33_priv *dac33 = codec->private_data;
177 u8 data[2];
178 int ret = 0;
179
180 /*
181 * data is
182 * D15..D8 dac33 register offset
183 * D7...D0 register data
184 */
185 data[0] = reg & 0xff;
186 data[1] = value & 0xff;
187
188 dac33_write_reg_cache(codec, data[0], data[1]);
189 if (dac33->chip_power) {
190 ret = codec->hw_write(codec->control_data, data, 2);
191 if (ret != 2)
192 dev_err(codec->dev, "Write failed (%d)\n", ret);
193 else
194 ret = 0;
195 }
196
197 return ret;
198}
199
200static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
201 unsigned int value)
202{
203 struct tlv320dac33_priv *dac33 = codec->private_data;
204 int ret;
205
206 mutex_lock(&dac33->mutex);
207 ret = dac33_write(codec, reg, value);
208 mutex_unlock(&dac33->mutex);
209
210 return ret;
211}
212
213#define DAC33_I2C_ADDR_AUTOINC 0x80
214static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
215 unsigned int value)
216{
217 struct tlv320dac33_priv *dac33 = codec->private_data;
218 u8 data[3];
219 int ret = 0;
220
221 /*
222 * data is
223 * D23..D16 dac33 register offset
224 * D15..D8 register data MSB
225 * D7...D0 register data LSB
226 */
227 data[0] = reg & 0xff;
228 data[1] = (value >> 8) & 0xff;
229 data[2] = value & 0xff;
230
231 dac33_write_reg_cache(codec, data[0], data[1]);
232 dac33_write_reg_cache(codec, data[0] + 1, data[2]);
233
234 if (dac33->chip_power) {
235 /* We need to set autoincrement mode for 16 bit writes */
236 data[0] |= DAC33_I2C_ADDR_AUTOINC;
237 ret = codec->hw_write(codec->control_data, data, 3);
238 if (ret != 3)
239 dev_err(codec->dev, "Write failed (%d)\n", ret);
240 else
241 ret = 0;
242 }
243
244 return ret;
245}
246
247static void dac33_restore_regs(struct snd_soc_codec *codec)
248{
249 struct tlv320dac33_priv *dac33 = codec->private_data;
250 u8 *cache = codec->reg_cache;
251 u8 data[2];
252 int i, ret;
253
254 if (!dac33->chip_power)
255 return;
256
257 for (i = DAC33_PWR_CTRL; i <= DAC33_INTP_CTRL_B; i++) {
258 data[0] = i;
259 data[1] = cache[i];
260 /* Skip the read only registers */
261 if ((i >= DAC33_INT_OSC_STATUS &&
262 i <= DAC33_INT_OSC_FREQ_RAT_READ_B) ||
263 (i >= DAC33_FIFO_WPTR_MSB && i <= DAC33_FIFO_IRQ_FLAG) ||
264 i == DAC33_DAC_STATUS_FLAGS ||
265 i == DAC33_SRC_EST_REF_CLK_RATIO_A ||
266 i == DAC33_SRC_EST_REF_CLK_RATIO_B)
267 continue;
268 ret = codec->hw_write(codec->control_data, data, 2);
269 if (ret != 2)
270 dev_err(codec->dev, "Write failed (%d)\n", ret);
271 }
272 for (i = DAC33_LDAC_PWR_CTRL; i <= DAC33_LINEL_TO_LLO_VOL; i++) {
273 data[0] = i;
274 data[1] = cache[i];
275 ret = codec->hw_write(codec->control_data, data, 2);
276 if (ret != 2)
277 dev_err(codec->dev, "Write failed (%d)\n", ret);
278 }
279 for (i = DAC33_LINER_TO_RLO_VOL; i <= DAC33_OSC_TRIM; i++) {
280 data[0] = i;
281 data[1] = cache[i];
282 ret = codec->hw_write(codec->control_data, data, 2);
283 if (ret != 2)
284 dev_err(codec->dev, "Write failed (%d)\n", ret);
285 }
286}
287
288static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
289{
290 u8 reg;
291
292 reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
293 if (power)
294 reg |= DAC33_PDNALLB;
295 else
296 reg &= ~DAC33_PDNALLB;
297 dac33_write(codec, DAC33_PWR_CTRL, reg);
298}
299
300static void dac33_hard_power(struct snd_soc_codec *codec, int power)
301{
302 struct tlv320dac33_priv *dac33 = codec->private_data;
303
304 mutex_lock(&dac33->mutex);
305 if (power) {
306 if (dac33->power_gpio >= 0) {
307 gpio_set_value(dac33->power_gpio, 1);
308 dac33->chip_power = 1;
309 /* Restore registers */
310 dac33_restore_regs(codec);
311 }
312 dac33_soft_power(codec, 1);
313 } else {
314 dac33_soft_power(codec, 0);
315 if (dac33->power_gpio >= 0) {
316 gpio_set_value(dac33->power_gpio, 0);
317 dac33->chip_power = 0;
318 }
319 }
320 mutex_unlock(&dac33->mutex);
321
322}
323
324static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
325 struct snd_ctl_elem_value *ucontrol)
326{
327 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
328 struct tlv320dac33_priv *dac33 = codec->private_data;
329
330 ucontrol->value.integer.value[0] = dac33->nsample;
331
332 return 0;
333}
334
335static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_value *ucontrol)
337{
338 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
339 struct tlv320dac33_priv *dac33 = codec->private_data;
340 int ret = 0;
341
342 if (dac33->nsample == ucontrol->value.integer.value[0])
343 return 0;
344
345 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
346 ucontrol->value.integer.value[0] > dac33->nsample_max)
347 ret = -EINVAL;
348 else
349 dac33->nsample = ucontrol->value.integer.value[0];
350
351 return ret;
352}
353
354static int dac33_get_nsample_switch(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct tlv320dac33_priv *dac33 = codec->private_data;
359
360 ucontrol->value.integer.value[0] = dac33->nsample_switch;
361
362 return 0;
363}
364
365static int dac33_set_nsample_switch(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
367{
368 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct tlv320dac33_priv *dac33 = codec->private_data;
370 int ret = 0;
371
372 if (dac33->nsample_switch == ucontrol->value.integer.value[0])
373 return 0;
374 /* Do not allow changes while stream is running*/
375 if (codec->active)
376 return -EPERM;
377
378 if (ucontrol->value.integer.value[0] < 0 ||
379 ucontrol->value.integer.value[0] > 1)
380 ret = -EINVAL;
381 else
382 dac33->nsample_switch = ucontrol->value.integer.value[0];
383
384 return ret;
385}
386
387/*
388 * DACL/R digital volume control:
389 * from 0 dB to -63.5 in 0.5 dB steps
390 * Need to be inverted later on:
391 * 0x00 == 0 dB
392 * 0x7f == -63.5 dB
393 */
394static DECLARE_TLV_DB_SCALE(dac_digivol_tlv, -6350, 50, 0);
395
396static const struct snd_kcontrol_new dac33_snd_controls[] = {
397 SOC_DOUBLE_R_TLV("DAC Digital Playback Volume",
398 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL,
399 0, 0x7f, 1, dac_digivol_tlv),
400 SOC_DOUBLE_R("DAC Digital Playback Switch",
401 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1),
402 SOC_DOUBLE_R("Line to Line Out Volume",
403 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
404};
405
406static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
407 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
408 dac33_get_nsample, dac33_set_nsample),
409 SOC_SINGLE_EXT("nSample Switch", 0, 0, 1, 0,
410 dac33_get_nsample_switch, dac33_set_nsample_switch),
411};
412
413/* Analog bypass */
414static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
415 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
416
417static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
418 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
419
420static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
421 SND_SOC_DAPM_OUTPUT("LEFT_LO"),
422 SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
423
424 SND_SOC_DAPM_INPUT("LINEL"),
425 SND_SOC_DAPM_INPUT("LINER"),
426
427 SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0),
428 SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0),
429
430 /* Analog bypass */
431 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
432 &dac33_dapm_abypassl_control),
433 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
434 &dac33_dapm_abypassr_control),
435
436 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power",
437 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
438 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
439 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
440};
441
442static const struct snd_soc_dapm_route audio_map[] = {
443 /* Analog bypass */
444 {"Analog Left Bypass", "Switch", "LINEL"},
445 {"Analog Right Bypass", "Switch", "LINER"},
446
447 {"Output Left Amp Power", NULL, "DACL"},
448 {"Output Right Amp Power", NULL, "DACR"},
449
450 {"Output Left Amp Power", NULL, "Analog Left Bypass"},
451 {"Output Right Amp Power", NULL, "Analog Right Bypass"},
452
453 /* output */
454 {"LEFT_LO", NULL, "Output Left Amp Power"},
455 {"RIGHT_LO", NULL, "Output Right Amp Power"},
456};
457
458static int dac33_add_widgets(struct snd_soc_codec *codec)
459{
460 snd_soc_dapm_new_controls(codec, dac33_dapm_widgets,
461 ARRAY_SIZE(dac33_dapm_widgets));
462
463 /* set up audio path interconnects */
464 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
465
466 return 0;
467}
468
469static int dac33_set_bias_level(struct snd_soc_codec *codec,
470 enum snd_soc_bias_level level)
471{
472 switch (level) {
473 case SND_SOC_BIAS_ON:
474 dac33_soft_power(codec, 1);
475 break;
476 case SND_SOC_BIAS_PREPARE:
477 break;
478 case SND_SOC_BIAS_STANDBY:
479 if (codec->bias_level == SND_SOC_BIAS_OFF)
480 dac33_hard_power(codec, 1);
481 dac33_soft_power(codec, 0);
482 break;
483 case SND_SOC_BIAS_OFF:
484 dac33_hard_power(codec, 0);
485 break;
486 }
487 codec->bias_level = level;
488
489 return 0;
490}
491
492static void dac33_work(struct work_struct *work)
493{
494 struct snd_soc_codec *codec;
495 struct tlv320dac33_priv *dac33;
496 u8 reg;
497
498 dac33 = container_of(work, struct tlv320dac33_priv, work);
499 codec = &dac33->codec;
500
501 mutex_lock(&dac33->mutex);
502 switch (dac33->state) {
503 case DAC33_PREFILL:
504 dac33->state = DAC33_PLAYBACK;
505 dac33_write16(codec, DAC33_NSAMPLE_MSB,
506 DAC33_THRREG(dac33->nsample));
507 dac33_write16(codec, DAC33_PREFILL_MSB,
508 DAC33_THRREG(dac33->alarm_threshold));
509 break;
510 case DAC33_PLAYBACK:
511 dac33_write16(codec, DAC33_NSAMPLE_MSB,
512 DAC33_THRREG(dac33->nsample));
513 break;
514 case DAC33_IDLE:
515 break;
516 case DAC33_FLUSH:
517 dac33->state = DAC33_IDLE;
518 /* Mask all interrupts from dac33 */
519 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
520
521 /* flush fifo */
522 reg = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
523 reg |= DAC33_FIFOFLUSH;
524 dac33_write(codec, DAC33_FIFO_CTRL_A, reg);
525 break;
526 }
527 mutex_unlock(&dac33->mutex);
528}
529
530static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
531{
532 struct snd_soc_codec *codec = dev;
533 struct tlv320dac33_priv *dac33 = codec->private_data;
534
535 queue_work(dac33->dac33_wq, &dac33->work);
536
537 return IRQ_HANDLED;
538}
539
540static void dac33_shutdown(struct snd_pcm_substream *substream,
541 struct snd_soc_dai *dai)
542{
543 struct snd_soc_pcm_runtime *rtd = substream->private_data;
544 struct snd_soc_device *socdev = rtd->socdev;
545 struct snd_soc_codec *codec = socdev->card->codec;
546 struct tlv320dac33_priv *dac33 = codec->private_data;
547 unsigned int pwr_ctrl;
548
549 /* Stop pending workqueue */
550 if (dac33->nsample_switch)
551 cancel_work_sync(&dac33->work);
552
553 mutex_lock(&dac33->mutex);
554 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
555 pwr_ctrl &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
556 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
557 mutex_unlock(&dac33->mutex);
558}
559
560static void dac33_oscwait(struct snd_soc_codec *codec)
561{
562 int timeout = 20;
563 u8 reg;
564
565 do {
566 msleep(1);
567 dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
568 } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
569 if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
570 dev_err(codec->dev,
571 "internal oscillator calibration failed\n");
572}
573
574static int dac33_hw_params(struct snd_pcm_substream *substream,
575 struct snd_pcm_hw_params *params,
576 struct snd_soc_dai *dai)
577{
578 struct snd_soc_pcm_runtime *rtd = substream->private_data;
579 struct snd_soc_device *socdev = rtd->socdev;
580 struct snd_soc_codec *codec = socdev->card->codec;
581
582 /* Check parameters for validity */
583 switch (params_rate(params)) {
584 case 44100:
585 case 48000:
586 break;
587 default:
588 dev_err(codec->dev, "unsupported rate %d\n",
589 params_rate(params));
590 return -EINVAL;
591 }
592
593 switch (params_format(params)) {
594 case SNDRV_PCM_FORMAT_S16_LE:
595 break;
596 default:
597 dev_err(codec->dev, "unsupported format %d\n",
598 params_format(params));
599 return -EINVAL;
600 }
601
602 return 0;
603}
604
605#define CALC_OSCSET(rate, refclk) ( \
606 ((((rate * 10000) / refclk) * 4096) + 5000) / 10000)
607#define CALC_RATIOSET(rate, refclk) ( \
608 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
609
610/*
611 * tlv320dac33 is strict on the sequence of the register writes, if the register
612 * writes happens in different order, than dac33 might end up in unknown state.
613 * Use the known, working sequence of register writes to initialize the dac33.
614 */
615static int dac33_prepare_chip(struct snd_pcm_substream *substream)
616{
617 struct snd_soc_pcm_runtime *rtd = substream->private_data;
618 struct snd_soc_device *socdev = rtd->socdev;
619 struct snd_soc_codec *codec = socdev->card->codec;
620 struct tlv320dac33_priv *dac33 = codec->private_data;
621 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
622 u8 aictrl_a, fifoctrl_a;
623
624 switch (substream->runtime->rate) {
625 case 44100:
626 case 48000:
627 oscset = CALC_OSCSET(substream->runtime->rate, dac33->refclk);
628 ratioset = CALC_RATIOSET(substream->runtime->rate,
629 dac33->refclk);
630 break;
631 default:
632 dev_err(codec->dev, "unsupported rate %d\n",
633 substream->runtime->rate);
634 return -EINVAL;
635 }
636
637
638 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
639 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
640 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
641 fifoctrl_a &= ~DAC33_WIDTH;
642 switch (substream->runtime->format) {
643 case SNDRV_PCM_FORMAT_S16_LE:
644 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
645 fifoctrl_a |= DAC33_WIDTH;
646 break;
647 default:
648 dev_err(codec->dev, "unsupported format %d\n",
649 substream->runtime->format);
650 return -EINVAL;
651 }
652
653 mutex_lock(&dac33->mutex);
654 dac33_soft_power(codec, 1);
655
656 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
657 dac33_write(codec, DAC33_INT_OSC_CTRL, reg_tmp);
658
659 /* Write registers 0x08 and 0x09 (MSB, LSB) */
660 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
661
662 /* calib time: 128 is a nice number ;) */
663 dac33_write(codec, DAC33_CALIB_TIME, 128);
664
665 /* adjustment treshold & step */
666 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
667 DAC33_ADJSTEP(1));
668
669 /* div=4 / gain=1 / div */
670 dac33_write(codec, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
671
672 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
673 pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
674 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
675
676 dac33_oscwait(codec);
677
678 if (dac33->nsample_switch) {
679 /* 50-51 : ASRC Control registers */
680 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
681 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
682
683 /* Write registers 0x34 and 0x35 (MSB, LSB) */
684 dac33_write16(codec, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
685
686 /* Set interrupts to high active */
687 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
688
689 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
690 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
691 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
692 } else {
693 /* 50-51 : ASRC Control registers */
694 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
695 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
696 }
697
698 if (dac33->nsample_switch)
699 fifoctrl_a &= ~DAC33_FBYPAS;
700 else
701 fifoctrl_a |= DAC33_FBYPAS;
702 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
703
704 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
705 reg_tmp = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
706 if (dac33->nsample_switch)
707 reg_tmp &= ~DAC33_BCLKON;
708 else
709 reg_tmp |= DAC33_BCLKON;
710 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg_tmp);
711
712 if (dac33->nsample_switch) {
713 /* 20: BCLK divide ratio */
714 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 3);
715
716 dac33_write16(codec, DAC33_ATHR_MSB,
717 DAC33_THRREG(dac33->alarm_threshold));
718 } else {
719 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
720 }
721
722 mutex_unlock(&dac33->mutex);
723
724 return 0;
725}
726
727static void dac33_calculate_times(struct snd_pcm_substream *substream)
728{
729 struct snd_soc_pcm_runtime *rtd = substream->private_data;
730 struct snd_soc_device *socdev = rtd->socdev;
731 struct snd_soc_codec *codec = socdev->card->codec;
732 struct tlv320dac33_priv *dac33 = codec->private_data;
733 unsigned int nsample_limit;
734
735 /* Number of samples (16bit, stereo) in one period */
736 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
737
738 /* Number of samples (16bit, stereo) in ALSA buffer */
739 dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
740 /* Subtract one period from the total */
741 dac33->nsample_max -= dac33->nsample_min;
742
743 /* Number of samples for LATENCY_TIME_MS / 2 */
744 dac33->alarm_threshold = substream->runtime->rate /
745 (1000 / (LATENCY_TIME_MS / 2));
746
747 /* Find and fix up the lowest nsmaple limit */
748 nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
749
750 if (dac33->nsample_min < nsample_limit)
751 dac33->nsample_min = nsample_limit;
752
753 if (dac33->nsample < dac33->nsample_min)
754 dac33->nsample = dac33->nsample_min;
755
756 /*
757 * Find and fix up the highest nsmaple limit
758 * In order to not overflow the DAC33 buffer substract the
759 * alarm_threshold value from the size of the DAC33 buffer
760 */
761 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
762
763 if (dac33->nsample_max > nsample_limit)
764 dac33->nsample_max = nsample_limit;
765
766 if (dac33->nsample > dac33->nsample_max)
767 dac33->nsample = dac33->nsample_max;
768}
769
770static int dac33_pcm_prepare(struct snd_pcm_substream *substream,
771 struct snd_soc_dai *dai)
772{
773 dac33_calculate_times(substream);
774 dac33_prepare_chip(substream);
775
776 return 0;
777}
778
779static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
780 struct snd_soc_dai *dai)
781{
782 struct snd_soc_pcm_runtime *rtd = substream->private_data;
783 struct snd_soc_device *socdev = rtd->socdev;
784 struct snd_soc_codec *codec = socdev->card->codec;
785 struct tlv320dac33_priv *dac33 = codec->private_data;
786 int ret = 0;
787
788 switch (cmd) {
789 case SNDRV_PCM_TRIGGER_START:
790 case SNDRV_PCM_TRIGGER_RESUME:
791 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
792 if (dac33->nsample_switch) {
793 dac33->state = DAC33_PREFILL;
794 queue_work(dac33->dac33_wq, &dac33->work);
795 }
796 break;
797 case SNDRV_PCM_TRIGGER_STOP:
798 case SNDRV_PCM_TRIGGER_SUSPEND:
799 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
800 if (dac33->nsample_switch) {
801 dac33->state = DAC33_FLUSH;
802 queue_work(dac33->dac33_wq, &dac33->work);
803 }
804 break;
805 default:
806 ret = -EINVAL;
807 }
808
809 return ret;
810}
811
812static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
813 int clk_id, unsigned int freq, int dir)
814{
815 struct snd_soc_codec *codec = codec_dai->codec;
816 struct tlv320dac33_priv *dac33 = codec->private_data;
817 u8 ioc_reg, asrcb_reg;
818
819 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
820 asrcb_reg = dac33_read_reg_cache(codec, DAC33_ASRC_CTRL_B);
821 switch (clk_id) {
822 case TLV320DAC33_MCLK:
823 ioc_reg |= DAC33_REFSEL;
824 asrcb_reg |= DAC33_SRCREFSEL;
825 break;
826 case TLV320DAC33_SLEEPCLK:
827 ioc_reg &= ~DAC33_REFSEL;
828 asrcb_reg &= ~DAC33_SRCREFSEL;
829 break;
830 default:
831 dev_err(codec->dev, "Invalid clock ID (%d)\n", clk_id);
832 break;
833 }
834 dac33->refclk = freq;
835
836 dac33_write_reg_cache(codec, DAC33_INT_OSC_CTRL, ioc_reg);
837 dac33_write_reg_cache(codec, DAC33_ASRC_CTRL_B, asrcb_reg);
838
839 return 0;
840}
841
842static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
843 unsigned int fmt)
844{
845 struct snd_soc_codec *codec = codec_dai->codec;
846 u8 aictrl_a, aictrl_b;
847
848 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
849 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
850 /* set master/slave audio interface */
851 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
852 case SND_SOC_DAIFMT_CBM_CFM:
853 /* Codec Master */
854 aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK);
855 break;
856 case SND_SOC_DAIFMT_CBS_CFS:
857 /* Codec Slave */
858 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
859 break;
860 default:
861 return -EINVAL;
862 }
863
864 aictrl_a &= ~DAC33_AFMT_MASK;
865 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
866 case SND_SOC_DAIFMT_I2S:
867 aictrl_a |= DAC33_AFMT_I2S;
868 break;
869 case SND_SOC_DAIFMT_DSP_A:
870 aictrl_a |= DAC33_AFMT_DSP;
871 aictrl_b &= ~DAC33_DATA_DELAY_MASK;
872 aictrl_b |= DAC33_DATA_DELAY(1); /* 1 bit delay */
873 break;
874 case SND_SOC_DAIFMT_DSP_B:
875 aictrl_a |= DAC33_AFMT_DSP;
876 aictrl_b &= ~DAC33_DATA_DELAY_MASK; /* No delay */
877 break;
878 case SND_SOC_DAIFMT_RIGHT_J:
879 aictrl_a |= DAC33_AFMT_RIGHT_J;
880 break;
881 case SND_SOC_DAIFMT_LEFT_J:
882 aictrl_a |= DAC33_AFMT_LEFT_J;
883 break;
884 default:
885 dev_err(codec->dev, "Unsupported format (%u)\n",
886 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
887 return -EINVAL;
888 }
889
890 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
891 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
892
893 return 0;
894}
895
896static void dac33_init_chip(struct snd_soc_codec *codec)
897{
898 /* 44-46: DAC Control Registers */
899 /* A : DAC sample rate Fsref/1.5 */
900 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(1));
901 /* B : DAC src=normal, not muted */
902 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
903 DAC33_DACSRCL_LEFT);
904 /* C : (defaults) */
905 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
906
907 /* 64-65 : L&R DAC power control
908 Line In -> OUT 1V/V Gain, DAC -> OUT 4V/V Gain*/
909 dac33_write(codec, DAC33_LDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
910 dac33_write(codec, DAC33_RDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
911
912 /* 73 : volume soft stepping control,
913 clock source = internal osc (?) */
914 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
915
916 /* 66 : LOP/LOM Modes */
917 dac33_write(codec, DAC33_OUT_AMP_CM_CTRL, 0xff);
918
919 /* 68 : LOM inverted from LOP */
920 dac33_write(codec, DAC33_OUT_AMP_CTRL, (3<<2));
921
922 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
923}
924
925static int dac33_soc_probe(struct platform_device *pdev)
926{
927 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
928 struct snd_soc_codec *codec;
929 struct tlv320dac33_priv *dac33;
930 int ret = 0;
931
932 BUG_ON(!tlv320dac33_codec);
933
934 codec = tlv320dac33_codec;
935 socdev->card->codec = codec;
936 dac33 = codec->private_data;
937
938 /* Power up the codec */
939 dac33_hard_power(codec, 1);
940 /* Set default configuration */
941 dac33_init_chip(codec);
942
943 /* register pcms */
944 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
945 if (ret < 0) {
946 dev_err(codec->dev, "failed to create pcms\n");
947 goto pcm_err;
948 }
949
950 snd_soc_add_controls(codec, dac33_snd_controls,
951 ARRAY_SIZE(dac33_snd_controls));
952 /* Only add the nSample controls, if we have valid IRQ number */
953 if (dac33->irq >= 0)
954 snd_soc_add_controls(codec, dac33_nsample_snd_controls,
955 ARRAY_SIZE(dac33_nsample_snd_controls));
956
957 dac33_add_widgets(codec);
958
959 /* power on device */
960 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
961
962 return 0;
963
964pcm_err:
965 dac33_hard_power(codec, 0);
966 return ret;
967}
968
969static int dac33_soc_remove(struct platform_device *pdev)
970{
971 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
972 struct snd_soc_codec *codec = socdev->card->codec;
973
974 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
975
976 snd_soc_free_pcms(socdev);
977 snd_soc_dapm_free(socdev);
978
979 return 0;
980}
981
982static int dac33_soc_suspend(struct platform_device *pdev, pm_message_t state)
983{
984 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
985 struct snd_soc_codec *codec = socdev->card->codec;
986
987 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
988
989 return 0;
990}
991
992static int dac33_soc_resume(struct platform_device *pdev)
993{
994 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
995 struct snd_soc_codec *codec = socdev->card->codec;
996
997 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
998 dac33_set_bias_level(codec, codec->suspend_bias_level);
999
1000 return 0;
1001}
1002
1003struct snd_soc_codec_device soc_codec_dev_tlv320dac33 = {
1004 .probe = dac33_soc_probe,
1005 .remove = dac33_soc_remove,
1006 .suspend = dac33_soc_suspend,
1007 .resume = dac33_soc_resume,
1008};
1009EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1010
1011#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
1012 SNDRV_PCM_RATE_48000)
1013#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1014
1015static struct snd_soc_dai_ops dac33_dai_ops = {
1016 .shutdown = dac33_shutdown,
1017 .hw_params = dac33_hw_params,
1018 .prepare = dac33_pcm_prepare,
1019 .trigger = dac33_pcm_trigger,
1020 .set_sysclk = dac33_set_dai_sysclk,
1021 .set_fmt = dac33_set_dai_fmt,
1022};
1023
1024struct snd_soc_dai dac33_dai = {
1025 .name = "tlv320dac33",
1026 .playback = {
1027 .stream_name = "Playback",
1028 .channels_min = 2,
1029 .channels_max = 2,
1030 .rates = DAC33_RATES,
1031 .formats = DAC33_FORMATS,},
1032 .ops = &dac33_dai_ops,
1033};
1034EXPORT_SYMBOL_GPL(dac33_dai);
1035
1036static int dac33_i2c_probe(struct i2c_client *client,
1037 const struct i2c_device_id *id)
1038{
1039 struct tlv320dac33_platform_data *pdata;
1040 struct tlv320dac33_priv *dac33;
1041 struct snd_soc_codec *codec;
1042 int ret = 0;
1043
1044 if (client->dev.platform_data == NULL) {
1045 dev_err(&client->dev, "Platform data not set\n");
1046 return -ENODEV;
1047 }
1048 pdata = client->dev.platform_data;
1049
1050 dac33 = kzalloc(sizeof(struct tlv320dac33_priv), GFP_KERNEL);
1051 if (dac33 == NULL)
1052 return -ENOMEM;
1053
1054 codec = &dac33->codec;
1055 codec->private_data = dac33;
1056 codec->control_data = client;
1057
1058 mutex_init(&codec->mutex);
1059 mutex_init(&dac33->mutex);
1060 INIT_LIST_HEAD(&codec->dapm_widgets);
1061 INIT_LIST_HEAD(&codec->dapm_paths);
1062
1063 codec->name = "tlv320dac33";
1064 codec->owner = THIS_MODULE;
1065 codec->read = dac33_read_reg_cache;
1066 codec->write = dac33_write_locked;
1067 codec->hw_write = (hw_write_t) i2c_master_send;
1068 codec->bias_level = SND_SOC_BIAS_OFF;
1069 codec->set_bias_level = dac33_set_bias_level;
1070 codec->dai = &dac33_dai;
1071 codec->num_dai = 1;
1072 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
1073 codec->reg_cache = kmemdup(dac33_reg, ARRAY_SIZE(dac33_reg),
1074 GFP_KERNEL);
1075 if (codec->reg_cache == NULL) {
1076 ret = -ENOMEM;
1077 goto error_reg;
1078 }
1079
1080 i2c_set_clientdata(client, dac33);
1081
1082 dac33->power_gpio = pdata->power_gpio;
1083 dac33->irq = client->irq;
1084 dac33->nsample = NSAMPLE_MAX;
1085 /* Disable FIFO use by default */
1086 dac33->nsample_switch = 0;
1087
1088 tlv320dac33_codec = codec;
1089
1090 codec->dev = &client->dev;
1091 dac33_dai.dev = codec->dev;
1092
1093 /* Check if the reset GPIO number is valid and request it */
1094 if (dac33->power_gpio >= 0) {
1095 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
1096 if (ret < 0) {
1097 dev_err(codec->dev,
1098 "Failed to request reset GPIO (%d)\n",
1099 dac33->power_gpio);
1100 snd_soc_unregister_dai(&dac33_dai);
1101 snd_soc_unregister_codec(codec);
1102 goto error_gpio;
1103 }
1104 gpio_direction_output(dac33->power_gpio, 0);
1105 } else {
1106 dac33->chip_power = 1;
1107 }
1108
1109 /* Check if the IRQ number is valid and request it */
1110 if (dac33->irq >= 0) {
1111 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1112 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1113 codec->name, codec);
1114 if (ret < 0) {
1115 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1116 dac33->irq, ret);
1117 dac33->irq = -1;
1118 }
1119 if (dac33->irq != -1) {
1120 /* Setup work queue */
1121 dac33->dac33_wq =
1122 create_singlethread_workqueue("tlv320dac33");
1123 if (dac33->dac33_wq == NULL) {
1124 free_irq(dac33->irq, &dac33->codec);
1125 ret = -ENOMEM;
1126 goto error_wq;
1127 }
1128
1129 INIT_WORK(&dac33->work, dac33_work);
1130 }
1131 }
1132
1133 ret = snd_soc_register_codec(codec);
1134 if (ret != 0) {
1135 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1136 goto error_codec;
1137 }
1138
1139 ret = snd_soc_register_dai(&dac33_dai);
1140 if (ret != 0) {
1141 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1142 snd_soc_unregister_codec(codec);
1143 goto error_codec;
1144 }
1145
1146 /* Shut down the codec for now */
1147 dac33_hard_power(codec, 0);
1148
1149 return ret;
1150
1151error_codec:
1152 if (dac33->irq >= 0) {
1153 free_irq(dac33->irq, &dac33->codec);
1154 destroy_workqueue(dac33->dac33_wq);
1155 }
1156error_wq:
1157 if (dac33->power_gpio >= 0)
1158 gpio_free(dac33->power_gpio);
1159error_gpio:
1160 kfree(codec->reg_cache);
1161error_reg:
1162 tlv320dac33_codec = NULL;
1163 kfree(dac33);
1164
1165 return ret;
1166}
1167
1168static int dac33_i2c_remove(struct i2c_client *client)
1169{
1170 struct tlv320dac33_priv *dac33;
1171
1172 dac33 = i2c_get_clientdata(client);
1173 dac33_hard_power(&dac33->codec, 0);
1174
1175 if (dac33->power_gpio >= 0)
1176 gpio_free(dac33->power_gpio);
1177 if (dac33->irq >= 0)
1178 free_irq(dac33->irq, &dac33->codec);
1179
1180 destroy_workqueue(dac33->dac33_wq);
1181 snd_soc_unregister_dai(&dac33_dai);
1182 snd_soc_unregister_codec(&dac33->codec);
1183 kfree(dac33->codec.reg_cache);
1184 kfree(dac33);
1185 tlv320dac33_codec = NULL;
1186
1187 return 0;
1188}
1189
1190static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1191 {
1192 .name = "tlv320dac33",
1193 .driver_data = 0,
1194 },
1195 { },
1196};
1197
1198static struct i2c_driver tlv320dac33_i2c_driver = {
1199 .driver = {
1200 .name = "tlv320dac33",
1201 .owner = THIS_MODULE,
1202 },
1203 .probe = dac33_i2c_probe,
1204 .remove = __devexit_p(dac33_i2c_remove),
1205 .id_table = tlv320dac33_i2c_id,
1206};
1207
1208static int __init dac33_module_init(void)
1209{
1210 int r;
1211 r = i2c_add_driver(&tlv320dac33_i2c_driver);
1212 if (r < 0) {
1213 printk(KERN_ERR "DAC33: driver registration failed\n");
1214 return r;
1215 }
1216 return 0;
1217}
1218module_init(dac33_module_init);
1219
1220static void __exit dac33_module_exit(void)
1221{
1222 i2c_del_driver(&tlv320dac33_i2c_driver);
1223}
1224module_exit(dac33_module_exit);
1225
1226
1227MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1228MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
1229MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
new file mode 100644
index 000000000000..eb8ae07f0bd2
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -0,0 +1,267 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TLV320DAC33_H
25#define __TLV320DAC33_H
26
27#define DAC33_PAGE_SELECT 0x00
28#define DAC33_PWR_CTRL 0x01
29#define DAC33_PLL_CTRL_A 0x02
30#define DAC33_PLL_CTRL_B 0x03
31#define DAC33_PLL_CTRL_C 0x04
32#define DAC33_PLL_CTRL_D 0x05
33#define DAC33_PLL_CTRL_E 0x06
34#define DAC33_INT_OSC_CTRL 0x07
35#define DAC33_INT_OSC_FREQ_RAT_A 0x08
36#define DAC33_INT_OSC_FREQ_RAT_B 0x09
37#define DAC33_INT_OSC_DAC_RATIO_SET 0x0A
38#define DAC33_CALIB_TIME 0x0B
39#define DAC33_INT_OSC_CTRL_B 0x0C
40#define DAC33_INT_OSC_CTRL_C 0x0D
41#define DAC33_INT_OSC_STATUS 0x0E
42#define DAC33_INT_OSC_DAC_RATIO_READ 0x0F
43#define DAC33_INT_OSC_FREQ_RAT_READ_A 0x10
44#define DAC33_INT_OSC_FREQ_RAT_READ_B 0x11
45#define DAC33_SER_AUDIOIF_CTRL_A 0x12
46#define DAC33_SER_AUDIOIF_CTRL_B 0x13
47#define DAC33_SER_AUDIOIF_CTRL_C 0x14
48#define DAC33_FIFO_CTRL_A 0x15
49#define DAC33_UTHR_MSB 0x16
50#define DAC33_UTHR_LSB 0x17
51#define DAC33_ATHR_MSB 0x18
52#define DAC33_ATHR_LSB 0x19
53#define DAC33_LTHR_MSB 0x1A
54#define DAC33_LTHR_LSB 0x1B
55#define DAC33_PREFILL_MSB 0x1C
56#define DAC33_PREFILL_LSB 0x1D
57#define DAC33_NSAMPLE_MSB 0x1E
58#define DAC33_NSAMPLE_LSB 0x1F
59#define DAC33_FIFO_WPTR_MSB 0x20
60#define DAC33_FIFO_WPTR_LSB 0x21
61#define DAC33_FIFO_RPTR_MSB 0x22
62#define DAC33_FIFO_RPTR_LSB 0x23
63#define DAC33_FIFO_DEPTH_MSB 0x24
64#define DAC33_FIFO_DEPTH_LSB 0x25
65#define DAC33_SAMPLES_REMAINING_MSB 0x26
66#define DAC33_SAMPLES_REMAINING_LSB 0x27
67#define DAC33_FIFO_IRQ_FLAG 0x28
68#define DAC33_FIFO_IRQ_MASK 0x29
69#define DAC33_FIFO_IRQ_MODE_A 0x2A
70#define DAC33_FIFO_IRQ_MODE_B 0x2B
71#define DAC33_DAC_CTRL_A 0x2C
72#define DAC33_DAC_CTRL_B 0x2D
73#define DAC33_DAC_CTRL_C 0x2E
74#define DAC33_LDAC_DIG_VOL_CTRL 0x2F
75#define DAC33_RDAC_DIG_VOL_CTRL 0x30
76#define DAC33_DAC_STATUS_FLAGS 0x31
77#define DAC33_ASRC_CTRL_A 0x32
78#define DAC33_ASRC_CTRL_B 0x33
79#define DAC33_SRC_REF_CLK_RATIO_A 0x34
80#define DAC33_SRC_REF_CLK_RATIO_B 0x35
81#define DAC33_SRC_EST_REF_CLK_RATIO_A 0x36
82#define DAC33_SRC_EST_REF_CLK_RATIO_B 0x37
83#define DAC33_INTP_CTRL_A 0x38
84#define DAC33_INTP_CTRL_B 0x39
85/* Registers 0x3A - 0x3F Reserved */
86#define DAC33_LDAC_PWR_CTRL 0x40
87#define DAC33_RDAC_PWR_CTRL 0x41
88#define DAC33_OUT_AMP_CM_CTRL 0x42
89#define DAC33_OUT_AMP_PWR_CTRL 0x43
90#define DAC33_OUT_AMP_CTRL 0x44
91#define DAC33_LINEL_TO_LLO_VOL 0x45
92/* Registers 0x45 - 0x47 Reserved */
93#define DAC33_LINER_TO_RLO_VOL 0x48
94#define DAC33_ANA_VOL_SOFT_STEP_CTRL 0x49
95#define DAC33_OSC_TRIM 0x4A
96/* Registers 0x4B - 0x7C Reserved */
97#define DAC33_DEVICE_ID_MSB 0x7D
98#define DAC33_DEVICE_ID_LSB 0x7E
99#define DAC33_DEVICE_REV_ID 0x7F
100
101#define DAC33_CACHEREGNUM 128
102
103/* Bit definitions */
104
105/* DAC33_PWR_CTRL (0x01) */
106#define DAC33_DACRPDNB (0x01 << 0)
107#define DAC33_DACLPDNB (0x01 << 1)
108#define DAC33_OSCPDNB (0x01 << 2)
109#define DAC33_PLLPDNB (0x01 << 3)
110#define DAC33_PDNALLB (0x01 << 4)
111#define DAC33_SOFT_RESET (0x01 << 7)
112
113/* DAC33_INT_OSC_CTRL (0x07) */
114#define DAC33_REFSEL (0x01 << 1)
115
116/* DAC33_INT_OSC_CTRL_B (0x0C) */
117#define DAC33_ADJSTEP(x) (x << 0)
118#define DAC33_ADJTHRSHLD(x) (x << 4)
119
120/* DAC33_INT_OSC_CTRL_C (0x0D) */
121#define DAC33_REFDIV(x) (x << 4)
122
123/* DAC33_INT_OSC_STATUS (0x0E) */
124#define DAC33_OSCSTATUS_IDLE_CALIB (0x00)
125#define DAC33_OSCSTATUS_NORMAL (0x01)
126#define DAC33_OSCSTATUS_ADJUSTMENT (0x03)
127#define DAC33_OSCSTATUS_NOT_USED (0x02)
128
129/* DAC33_SER_AUDIOIF_CTRL_A (0x12) */
130#define DAC33_MSWCLK (0x01 << 0)
131#define DAC33_MSBCLK (0x01 << 1)
132#define DAC33_AFMT_MASK (0x03 << 2)
133#define DAC33_AFMT_I2S (0x00 << 2)
134#define DAC33_AFMT_DSP (0x01 << 2)
135#define DAC33_AFMT_RIGHT_J (0x02 << 2)
136#define DAC33_AFMT_LEFT_J (0x03 << 2)
137#define DAC33_WLEN_MASK (0x03 << 4)
138#define DAC33_WLEN_16 (0x00 << 4)
139#define DAC33_WLEN_20 (0x01 << 4)
140#define DAC33_WLEN_24 (0x02 << 4)
141#define DAC33_WLEN_32 (0x03 << 4)
142#define DAC33_NCYCL_MASK (0x03 << 6)
143#define DAC33_NCYCL_16 (0x00 << 6)
144#define DAC33_NCYCL_20 (0x01 << 6)
145#define DAC33_NCYCL_24 (0x02 << 6)
146#define DAC33_NCYCL_32 (0x03 << 6)
147
148/* DAC33_SER_AUDIOIF_CTRL_B (0x13) */
149#define DAC33_DATA_DELAY_MASK (0x03 << 2)
150#define DAC33_DATA_DELAY(x) (x << 2)
151#define DAC33_BCLKON (0x01 << 5)
152
153/* DAC33_FIFO_CTRL_A (0x15) */
154#define DAC33_WIDTH (0x01 << 0)
155#define DAC33_FBYPAS (0x01 << 1)
156#define DAC33_FAUTO (0x01 << 2)
157#define DAC33_FIFOFLUSH (0x01 << 3)
158
159/*
160 * UTHR, ATHR, LTHR, PREFILL, NSAMPLE (0x16 - 0x1F)
161 * 13-bit values
162*/
163#define DAC33_THRREG(x) (((x) & 0x1FFF) << 3)
164
165/* DAC33_FIFO_IRQ_MASK (0x29) */
166#define DAC33_MNS (0x01 << 0)
167#define DAC33_MPS (0x01 << 1)
168#define DAC33_MAT (0x01 << 2)
169#define DAC33_MLT (0x01 << 3)
170#define DAC33_MUT (0x01 << 4)
171#define DAC33_MUF (0x01 << 5)
172#define DAC33_MOF (0x01 << 6)
173
174#define DAC33_FIFO_IRQ_MODE_MASK (0x03)
175#define DAC33_FIFO_IRQ_MODE_RISING (0x00)
176#define DAC33_FIFO_IRQ_MODE_FALLING (0x01)
177#define DAC33_FIFO_IRQ_MODE_LEVEL (0x02)
178#define DAC33_FIFO_IRQ_MODE_EDGE (0x03)
179
180/* DAC33_FIFO_IRQ_MODE_A (0x2A) */
181#define DAC33_UTM(x) (x << 0)
182#define DAC33_UFM(x) (x << 2)
183#define DAC33_OFM(x) (x << 4)
184
185/* DAC33_FIFO_IRQ_MODE_B (0x2B) */
186#define DAC33_NSM(x) (x << 0)
187#define DAC33_PSM(x) (x << 2)
188#define DAC33_ATM(x) (x << 4)
189#define DAC33_LTM(x) (x << 6)
190
191/* DAC33_DAC_CTRL_A (0x2C) */
192#define DAC33_DACRATE(x) (x << 0)
193#define DAC33_DACDUAL (0x01 << 4)
194#define DAC33_DACLKSEL_MASK (0x03 << 5)
195#define DAC33_DACLKSEL_INTSOC (0x00 << 5)
196#define DAC33_DACLKSEL_PLL (0x01 << 5)
197#define DAC33_DACLKSEL_MCLK (0x02 << 5)
198#define DAC33_DACLKSEL_BCLK (0x03 << 5)
199
200/* DAC33_DAC_CTRL_B (0x2D) */
201#define DAC33_DACSRCR_MASK (0x03 << 0)
202#define DAC33_DACSRCR_MUTE (0x00 << 0)
203#define DAC33_DACSRCR_RIGHT (0x01 << 0)
204#define DAC33_DACSRCR_LEFT (0x02 << 0)
205#define DAC33_DACSRCR_MONOMIX (0x03 << 0)
206#define DAC33_DACSRCL_MASK (0x03 << 2)
207#define DAC33_DACSRCL_MUTE (0x00 << 2)
208#define DAC33_DACSRCL_LEFT (0x01 << 2)
209#define DAC33_DACSRCL_RIGHT (0x02 << 2)
210#define DAC33_DACSRCL_MONOMIX (0x03 << 2)
211#define DAC33_DVOLSTEP_MASK (0x03 << 4)
212#define DAC33_DVOLSTEP_SS_PERFS (0x00 << 4)
213#define DAC33_DVOLSTEP_SS_PER2FS (0x01 << 4)
214#define DAC33_DVOLSTEP_SS_DISABLED (0x02 << 4)
215#define DAC33_DVOLCTRL_MASK (0x03 << 6)
216#define DAC33_DVOLCTRL_LR_INDEPENDENT1 (0x00 << 6)
217#define DAC33_DVOLCTRL_LR_RIGHT_CONTROL (0x01 << 6)
218#define DAC33_DVOLCTRL_LR_LEFT_CONTROL (0x02 << 6)
219#define DAC33_DVOLCTRL_LR_INDEPENDENT2 (0x03 << 6)
220
221/* DAC33_DAC_CTRL_C (0x2E) */
222#define DAC33_DEEMENR (0x01 << 0)
223#define DAC33_EFFENR (0x01 << 1)
224#define DAC33_DEEMENL (0x01 << 2)
225#define DAC33_EFFENL (0x01 << 3)
226#define DAC33_EN3D (0x01 << 4)
227#define DAC33_RESYNMUTE (0x01 << 5)
228#define DAC33_RESYNEN (0x01 << 6)
229
230/* DAC33_ASRC_CTRL_A (0x32) */
231#define DAC33_SRCBYP (0x01 << 0)
232#define DAC33_SRCLKSEL_MASK (0x03 << 1)
233#define DAC33_SRCLKSEL_INTSOC (0x00 << 1)
234#define DAC33_SRCLKSEL_PLL (0x01 << 1)
235#define DAC33_SRCLKSEL_MCLK (0x02 << 1)
236#define DAC33_SRCLKSEL_BCLK (0x03 << 1)
237#define DAC33_SRCLKDIV(x) (x << 3)
238
239/* DAC33_ASRC_CTRL_B (0x33) */
240#define DAC33_SRCSETUP(x) (x << 0)
241#define DAC33_SRCREFSEL (0x01 << 4)
242#define DAC33_SRCREFDIV(x) (x << 5)
243
244/* DAC33_INTP_CTRL_A (0x38) */
245#define DAC33_INTPSEL (0x01 << 0)
246#define DAC33_INTPM_MASK (0x03 << 1)
247#define DAC33_INTPM_ALOW_OPENDRAIN (0x00 << 1)
248#define DAC33_INTPM_ALOW (0x01 << 1)
249#define DAC33_INTPM_AHIGH (0x02 << 1)
250
251/* DAC33_LDAC_PWR_CTRL (0x40) */
252/* DAC33_RDAC_PWR_CTRL (0x41) */
253#define DAC33_DACLRNUM (0x01 << 2)
254#define DAC33_LROUT_GAIN(x) (x << 0)
255
256/* DAC33_ANA_VOL_SOFT_STEP_CTRL (0x49) */
257#define DAC33_VOLCLKSEL (0x01 << 0)
258#define DAC33_VOLCLKEN (0x01 << 1)
259#define DAC33_VOLBYPASS (0x01 << 2)
260
261#define TLV320DAC33_MCLK 0
262#define TLV320DAC33_SLEEPCLK 1
263
264extern struct snd_soc_dai dac33_dai;
265extern struct snd_soc_codec_device soc_codec_dev_tlv320dac33;
266
267#endif /* __TLV320DAC33_H */
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
new file mode 100644
index 000000000000..6b650c1aa3d1
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -0,0 +1,463 @@
1/*
2 * ALSA SoC Texas Instruments TPA6130A2 headset stereo amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/device.h>
26#include <linux/i2c.h>
27#include <linux/gpio.h>
28#include <sound/tpa6130a2-plat.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h>
32
33#include "tpa6130a2.h"
34
35static struct i2c_client *tpa6130a2_client;
36
37/* This struct is used to save the context */
38struct tpa6130a2_data {
39 struct mutex mutex;
40 unsigned char regs[TPA6130A2_CACHEREGNUM];
41 int power_gpio;
42 unsigned char power_state;
43};
44
45static int tpa6130a2_i2c_read(int reg)
46{
47 struct tpa6130a2_data *data;
48 int val;
49
50 BUG_ON(tpa6130a2_client == NULL);
51 data = i2c_get_clientdata(tpa6130a2_client);
52
53 /* If powered off, return the cached value */
54 if (data->power_state) {
55 val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
56 if (val < 0)
57 dev_err(&tpa6130a2_client->dev, "Read failed\n");
58 else
59 data->regs[reg] = val;
60 } else {
61 val = data->regs[reg];
62 }
63
64 return val;
65}
66
67static int tpa6130a2_i2c_write(int reg, u8 value)
68{
69 struct tpa6130a2_data *data;
70 int val = 0;
71
72 BUG_ON(tpa6130a2_client == NULL);
73 data = i2c_get_clientdata(tpa6130a2_client);
74
75 if (data->power_state) {
76 val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
77 if (val < 0)
78 dev_err(&tpa6130a2_client->dev, "Write failed\n");
79 }
80
81 /* Either powered on or off, we save the context */
82 data->regs[reg] = value;
83
84 return val;
85}
86
87static u8 tpa6130a2_read(int reg)
88{
89 struct tpa6130a2_data *data;
90
91 BUG_ON(tpa6130a2_client == NULL);
92 data = i2c_get_clientdata(tpa6130a2_client);
93
94 return data->regs[reg];
95}
96
97static void tpa6130a2_initialize(void)
98{
99 struct tpa6130a2_data *data;
100 int i;
101
102 BUG_ON(tpa6130a2_client == NULL);
103 data = i2c_get_clientdata(tpa6130a2_client);
104
105 for (i = 1; i < TPA6130A2_REG_VERSION; i++)
106 tpa6130a2_i2c_write(i, data->regs[i]);
107}
108
109static void tpa6130a2_power(int power)
110{
111 struct tpa6130a2_data *data;
112 u8 val;
113
114 BUG_ON(tpa6130a2_client == NULL);
115 data = i2c_get_clientdata(tpa6130a2_client);
116
117 mutex_lock(&data->mutex);
118 if (power) {
119 /* Power on */
120 if (data->power_gpio >= 0) {
121 gpio_set_value(data->power_gpio, 1);
122 data->power_state = 1;
123 tpa6130a2_initialize();
124 }
125 /* Clear SWS */
126 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
127 val &= ~TPA6130A2_SWS;
128 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
129 } else {
130 /* set SWS */
131 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
132 val |= TPA6130A2_SWS;
133 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
134 /* Power off */
135 if (data->power_gpio >= 0) {
136 gpio_set_value(data->power_gpio, 0);
137 data->power_state = 0;
138 }
139 }
140 mutex_unlock(&data->mutex);
141}
142
143static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
144 struct snd_ctl_elem_value *ucontrol)
145{
146 struct soc_mixer_control *mc =
147 (struct soc_mixer_control *)kcontrol->private_value;
148 struct tpa6130a2_data *data;
149 unsigned int reg = mc->reg;
150 unsigned int shift = mc->shift;
151 unsigned int mask = mc->max;
152 unsigned int invert = mc->invert;
153
154 BUG_ON(tpa6130a2_client == NULL);
155 data = i2c_get_clientdata(tpa6130a2_client);
156
157 mutex_lock(&data->mutex);
158
159 ucontrol->value.integer.value[0] =
160 (tpa6130a2_read(reg) >> shift) & mask;
161
162 if (invert)
163 ucontrol->value.integer.value[0] =
164 mask - ucontrol->value.integer.value[0];
165
166 mutex_unlock(&data->mutex);
167 return 0;
168}
169
170static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
171 struct snd_ctl_elem_value *ucontrol)
172{
173 struct soc_mixer_control *mc =
174 (struct soc_mixer_control *)kcontrol->private_value;
175 struct tpa6130a2_data *data;
176 unsigned int reg = mc->reg;
177 unsigned int shift = mc->shift;
178 unsigned int mask = mc->max;
179 unsigned int invert = mc->invert;
180 unsigned int val = (ucontrol->value.integer.value[0] & mask);
181 unsigned int val_reg;
182
183 BUG_ON(tpa6130a2_client == NULL);
184 data = i2c_get_clientdata(tpa6130a2_client);
185
186 if (invert)
187 val = mask - val;
188
189 mutex_lock(&data->mutex);
190
191 val_reg = tpa6130a2_read(reg);
192 if (((val_reg >> shift) & mask) == val) {
193 mutex_unlock(&data->mutex);
194 return 0;
195 }
196
197 val_reg &= ~(mask << shift);
198 val_reg |= val << shift;
199 tpa6130a2_i2c_write(reg, val_reg);
200
201 mutex_unlock(&data->mutex);
202
203 return 1;
204}
205
206/*
207 * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
208 * down in gain.
209 */
210static const unsigned int tpa6130_tlv[] = {
211 TLV_DB_RANGE_HEAD(10),
212 0, 1, TLV_DB_SCALE_ITEM(-5950, 600, 0),
213 2, 3, TLV_DB_SCALE_ITEM(-5000, 250, 0),
214 4, 5, TLV_DB_SCALE_ITEM(-4550, 160, 0),
215 6, 7, TLV_DB_SCALE_ITEM(-4140, 190, 0),
216 8, 9, TLV_DB_SCALE_ITEM(-3650, 120, 0),
217 10, 11, TLV_DB_SCALE_ITEM(-3330, 160, 0),
218 12, 13, TLV_DB_SCALE_ITEM(-3040, 180, 0),
219 14, 20, TLV_DB_SCALE_ITEM(-2710, 110, 0),
220 21, 37, TLV_DB_SCALE_ITEM(-1960, 74, 0),
221 38, 63, TLV_DB_SCALE_ITEM(-720, 45, 0),
222};
223
224static const struct snd_kcontrol_new tpa6130a2_controls[] = {
225 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
226 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
227 tpa6130a2_get_reg, tpa6130a2_set_reg,
228 tpa6130_tlv),
229};
230
231/*
232 * Enable or disable channel (left or right)
233 * The bit number for mute and amplifier are the same per channel:
234 * bit 6: Right channel
235 * bit 7: Left channel
236 * in both registers.
237 */
238static void tpa6130a2_channel_enable(u8 channel, int enable)
239{
240 struct tpa6130a2_data *data;
241 u8 val;
242
243 BUG_ON(tpa6130a2_client == NULL);
244 data = i2c_get_clientdata(tpa6130a2_client);
245
246 if (enable) {
247 /* Enable channel */
248 /* Enable amplifier */
249 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
250 val |= channel;
251 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
252
253 /* Unmute channel */
254 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
255 val &= ~channel;
256 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
257 } else {
258 /* Disable channel */
259 /* Mute channel */
260 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
261 val |= channel;
262 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
263
264 /* Disable amplifier */
265 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
266 val &= ~channel;
267 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
268 }
269}
270
271static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w,
272 struct snd_kcontrol *kcontrol, int event)
273{
274 switch (event) {
275 case SND_SOC_DAPM_POST_PMU:
276 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1);
277 break;
278 case SND_SOC_DAPM_POST_PMD:
279 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0);
280 break;
281 }
282 return 0;
283}
284
285static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
286 struct snd_kcontrol *kcontrol, int event)
287{
288 switch (event) {
289 case SND_SOC_DAPM_POST_PMU:
290 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1);
291 break;
292 case SND_SOC_DAPM_POST_PMD:
293 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0);
294 break;
295 }
296 return 0;
297}
298
299static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
300 struct snd_kcontrol *kcontrol, int event)
301{
302 switch (event) {
303 case SND_SOC_DAPM_POST_PMU:
304 tpa6130a2_power(1);
305 break;
306 case SND_SOC_DAPM_POST_PMD:
307 tpa6130a2_power(0);
308 break;
309 }
310 return 0;
311}
312
313static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
314 SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM,
315 0, 0, NULL, 0, tpa6130a2_left_event,
316 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
317 SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM,
318 0, 0, NULL, 0, tpa6130a2_right_event,
319 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
320 SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM,
321 0, 0, tpa6130a2_supply_event,
322 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
323 /* Outputs */
324 SND_SOC_DAPM_HP("TPA6130A2 Headphone Left", NULL),
325 SND_SOC_DAPM_HP("TPA6130A2 Headphone Right", NULL),
326};
327
328static const struct snd_soc_dapm_route audio_map[] = {
329 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"},
330 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"},
331
332 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"},
333 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"},
334};
335
336int tpa6130a2_add_controls(struct snd_soc_codec *codec)
337{
338 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
339 ARRAY_SIZE(tpa6130a2_dapm_widgets));
340
341 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
342
343 return snd_soc_add_controls(codec, tpa6130a2_controls,
344 ARRAY_SIZE(tpa6130a2_controls));
345
346}
347EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
348
349static int tpa6130a2_probe(struct i2c_client *client,
350 const struct i2c_device_id *id)
351{
352 struct device *dev;
353 struct tpa6130a2_data *data;
354 struct tpa6130a2_platform_data *pdata;
355 int ret;
356
357 dev = &client->dev;
358
359 if (client->dev.platform_data == NULL) {
360 dev_err(dev, "Platform data not set\n");
361 dump_stack();
362 return -ENODEV;
363 }
364
365 data = kzalloc(sizeof(*data), GFP_KERNEL);
366 if (data == NULL) {
367 dev_err(dev, "Can not allocate memory\n");
368 return -ENOMEM;
369 }
370
371 tpa6130a2_client = client;
372
373 i2c_set_clientdata(tpa6130a2_client, data);
374
375 pdata = client->dev.platform_data;
376 data->power_gpio = pdata->power_gpio;
377
378 mutex_init(&data->mutex);
379
380 /* Set default register values */
381 data->regs[TPA6130A2_REG_CONTROL] = TPA6130A2_SWS;
382 data->regs[TPA6130A2_REG_VOL_MUTE] = TPA6130A2_MUTE_R |
383 TPA6130A2_MUTE_L;
384
385 if (data->power_gpio >= 0) {
386 ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
387 if (ret < 0) {
388 dev_err(dev, "Failed to request power GPIO (%d)\n",
389 data->power_gpio);
390 goto fail;
391 }
392 gpio_direction_output(data->power_gpio, 0);
393 } else {
394 data->power_state = 1;
395 tpa6130a2_initialize();
396 }
397
398 tpa6130a2_power(1);
399
400 /* Read version */
401 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
402 TPA6130A2_VERSION_MASK;
403 if ((ret != 1) && (ret != 2))
404 dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
405
406 /* Disable the chip */
407 tpa6130a2_power(0);
408
409 return 0;
410fail:
411 kfree(data);
412 i2c_set_clientdata(tpa6130a2_client, NULL);
413 tpa6130a2_client = NULL;
414
415 return ret;
416}
417
418static int tpa6130a2_remove(struct i2c_client *client)
419{
420 struct tpa6130a2_data *data = i2c_get_clientdata(client);
421
422 tpa6130a2_power(0);
423
424 if (data->power_gpio >= 0)
425 gpio_free(data->power_gpio);
426 kfree(data);
427 tpa6130a2_client = NULL;
428
429 return 0;
430}
431
432static const struct i2c_device_id tpa6130a2_id[] = {
433 { "tpa6130a2", 0 },
434 { }
435};
436MODULE_DEVICE_TABLE(i2c, tpa6130a2_id);
437
438static struct i2c_driver tpa6130a2_i2c_driver = {
439 .driver = {
440 .name = "tpa6130a2",
441 .owner = THIS_MODULE,
442 },
443 .probe = tpa6130a2_probe,
444 .remove = __devexit_p(tpa6130a2_remove),
445 .id_table = tpa6130a2_id,
446};
447
448static int __init tpa6130a2_init(void)
449{
450 return i2c_add_driver(&tpa6130a2_i2c_driver);
451}
452
453static void __exit tpa6130a2_exit(void)
454{
455 i2c_del_driver(&tpa6130a2_i2c_driver);
456}
457
458MODULE_AUTHOR("Peter Ujfalusi");
459MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
460MODULE_LICENSE("GPL");
461
462module_init(tpa6130a2_init);
463module_exit(tpa6130a2_exit);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
new file mode 100644
index 000000000000..57e867fd86d1
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -0,0 +1,61 @@
1/*
2 * ALSA SoC TPA6130A2 amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TPA6130A2_H__
25#define __TPA6130A2_H__
26
27/* Register addresses */
28#define TPA6130A2_REG_CONTROL 0x01
29#define TPA6130A2_REG_VOL_MUTE 0x02
30#define TPA6130A2_REG_OUT_IMPEDANCE 0x03
31#define TPA6130A2_REG_VERSION 0x04
32
33#define TPA6130A2_CACHEREGNUM (TPA6130A2_REG_VERSION + 1)
34
35/* Register bits */
36/* TPA6130A2_REG_CONTROL (0x01) */
37#define TPA6130A2_SWS (0x01 << 0)
38#define TPA6130A2_TERMAL (0x01 << 1)
39#define TPA6130A2_MODE(x) (x << 4)
40#define TPA6130A2_MODE_STEREO (0x00)
41#define TPA6130A2_MODE_DUAL_MONO (0x01)
42#define TPA6130A2_MODE_BRIDGE (0x02)
43#define TPA6130A2_MODE_MASK (0x03)
44#define TPA6130A2_HP_EN_R (0x01 << 6)
45#define TPA6130A2_HP_EN_L (0x01 << 7)
46
47/* TPA6130A2_REG_VOL_MUTE (0x02) */
48#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
49#define TPA6130A2_MUTE_R (0x01 << 6)
50#define TPA6130A2_MUTE_L (0x01 << 7)
51
52/* TPA6130A2_REG_OUT_IMPEDANCE (0x03) */
53#define TPA6130A2_HIZ_R (0x01 << 0)
54#define TPA6130A2_HIZ_L (0x01 << 1)
55
56/* TPA6130A2_REG_VERSION (0x04) */
57#define TPA6130A2_VERSION_MASK (0x0f)
58
59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
60
61#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 4df7c6c61c76..5f1681f6ca76 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -120,9 +120,10 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
120 120
121/* codec private data */ 121/* codec private data */
122struct twl4030_priv { 122struct twl4030_priv {
123 unsigned int bypass_state; 123 struct snd_soc_codec codec;
124
124 unsigned int codec_powered; 125 unsigned int codec_powered;
125 unsigned int codec_muted; 126 unsigned int apll_enabled;
126 127
127 struct snd_pcm_substream *master_substream; 128 struct snd_pcm_substream *master_substream;
128 struct snd_pcm_substream *slave_substream; 129 struct snd_pcm_substream *slave_substream;
@@ -183,19 +184,20 @@ static int twl4030_write(struct snd_soc_codec *codec,
183static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 184static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
184{ 185{
185 struct twl4030_priv *twl4030 = codec->private_data; 186 struct twl4030_priv *twl4030 = codec->private_data;
186 u8 mode; 187 int mode;
187 188
188 if (enable == twl4030->codec_powered) 189 if (enable == twl4030->codec_powered)
189 return; 190 return;
190 191
191 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
192 if (enable) 192 if (enable)
193 mode |= TWL4030_CODECPDZ; 193 mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
194 else 194 else
195 mode &= ~TWL4030_CODECPDZ; 195 mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
196 196
197 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); 197 if (mode >= 0) {
198 twl4030->codec_powered = enable; 198 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
199 twl4030->codec_powered = enable;
200 }
199 201
200 /* REVISIT: this delay is present in TI sample drivers */ 202 /* REVISIT: this delay is present in TI sample drivers */
201 /* but there seems to be no TRM requirement for it */ 203 /* but there seems to be no TRM requirement for it */
@@ -212,31 +214,30 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
212 214
213 /* set all audio section registers to reasonable defaults */ 215 /* set all audio section registers to reasonable defaults */
214 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) 216 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
215 twl4030_write(codec, i, cache[i]); 217 if (i != TWL4030_REG_APLL_CTL)
218 twl4030_write(codec, i, cache[i]);
216 219
217} 220}
218 221
219static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) 222static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
220{ 223{
221 struct twl4030_priv *twl4030 = codec->private_data; 224 struct twl4030_priv *twl4030 = codec->private_data;
222 u8 reg_val; 225 int status;
223 226
224 if (mute == twl4030->codec_muted) 227 if (enable == twl4030->apll_enabled)
225 return; 228 return;
226 229
227 if (mute) { 230 if (enable)
228 /* Disable PLL */
229 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
230 reg_val &= ~TWL4030_APLL_EN;
231 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
232 } else {
233 /* Enable PLL */ 231 /* Enable PLL */
234 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 232 status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
235 reg_val |= TWL4030_APLL_EN; 233 else
236 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); 234 /* Disable PLL */
237 } 235 status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
236
237 if (status >= 0)
238 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
238 239
239 twl4030->codec_muted = mute; 240 twl4030->apll_enabled = enable;
240} 241}
241 242
242static void twl4030_power_up(struct snd_soc_codec *codec) 243static void twl4030_power_up(struct snd_soc_codec *codec)
@@ -613,6 +614,27 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
613 return 0; 614 return 0;
614} 615}
615 616
617static int vibramux_event(struct snd_soc_dapm_widget *w,
618 struct snd_kcontrol *kcontrol, int event)
619{
620 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
621 return 0;
622}
623
624static int apll_event(struct snd_soc_dapm_widget *w,
625 struct snd_kcontrol *kcontrol, int event)
626{
627 switch (event) {
628 case SND_SOC_DAPM_PRE_PMU:
629 twl4030_apll_enable(w->codec, 1);
630 break;
631 case SND_SOC_DAPM_POST_PMD:
632 twl4030_apll_enable(w->codec, 0);
633 break;
634 }
635 return 0;
636}
637
616static void headset_ramp(struct snd_soc_codec *codec, int ramp) 638static void headset_ramp(struct snd_soc_codec *codec, int ramp)
617{ 639{
618 struct snd_soc_device *socdev = codec->socdev; 640 struct snd_soc_device *socdev = codec->socdev;
@@ -724,67 +746,6 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
724 return 0; 746 return 0;
725} 747}
726 748
727static int bypass_event(struct snd_soc_dapm_widget *w,
728 struct snd_kcontrol *kcontrol, int event)
729{
730 struct soc_mixer_control *m =
731 (struct soc_mixer_control *)w->kcontrols->private_value;
732 struct twl4030_priv *twl4030 = w->codec->private_data;
733 unsigned char reg, misc;
734
735 reg = twl4030_read_reg_cache(w->codec, m->reg);
736
737 /*
738 * bypass_state[0:3] - analog HiFi bypass
739 * bypass_state[4] - analog voice bypass
740 * bypass_state[5] - digital voice bypass
741 * bypass_state[6:7] - digital HiFi bypass
742 */
743 if (m->reg == TWL4030_REG_VSTPGA) {
744 /* Voice digital bypass */
745 if (reg)
746 twl4030->bypass_state |= (1 << 5);
747 else
748 twl4030->bypass_state &= ~(1 << 5);
749 } else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
750 /* Analog bypass */
751 if (reg & (1 << m->shift))
752 twl4030->bypass_state |=
753 (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
754 else
755 twl4030->bypass_state &=
756 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
757 } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
758 /* Analog voice bypass */
759 if (reg & (1 << m->shift))
760 twl4030->bypass_state |= (1 << 4);
761 else
762 twl4030->bypass_state &= ~(1 << 4);
763 } else {
764 /* Digital bypass */
765 if (reg & (0x7 << m->shift))
766 twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
767 else
768 twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
769 }
770
771 /* Enable master analog loopback mode if any analog switch is enabled*/
772 misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
773 if (twl4030->bypass_state & 0x1F)
774 misc |= TWL4030_FMLOOP_EN;
775 else
776 misc &= ~TWL4030_FMLOOP_EN;
777 twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
778
779 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
780 if (twl4030->bypass_state)
781 twl4030_codec_mute(w->codec, 0);
782 else
783 twl4030_codec_mute(w->codec, 1);
784 }
785 return 0;
786}
787
788/* 749/*
789 * Some of the gain controls in TWL (mostly those which are associated with 750 * Some of the gain controls in TWL (mostly those which are associated with
790 * the outputs) are implemented in an interesting way: 751 * the outputs) are implemented in an interesting way:
@@ -1192,32 +1153,28 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1192 SND_SOC_NOPM, 0, 0), 1153 SND_SOC_NOPM, 0, 0),
1193 1154
1194 /* Analog bypasses */ 1155 /* Analog bypasses */
1195 SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1156 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1196 &twl4030_dapm_abypassr1_control, bypass_event, 1157 &twl4030_dapm_abypassr1_control),
1197 SND_SOC_DAPM_POST_REG), 1158 SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1198 SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1159 &twl4030_dapm_abypassl1_control),
1199 &twl4030_dapm_abypassl1_control, 1160 SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1200 bypass_event, SND_SOC_DAPM_POST_REG), 1161 &twl4030_dapm_abypassr2_control),
1201 SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1162 SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1202 &twl4030_dapm_abypassr2_control, 1163 &twl4030_dapm_abypassl2_control),
1203 bypass_event, SND_SOC_DAPM_POST_REG), 1164 SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1204 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1165 &twl4030_dapm_abypassv_control),
1205 &twl4030_dapm_abypassl2_control, 1166
1206 bypass_event, SND_SOC_DAPM_POST_REG), 1167 /* Master analog loopback switch */
1207 SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0, 1168 SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
1208 &twl4030_dapm_abypassv_control, 1169 NULL, 0),
1209 bypass_event, SND_SOC_DAPM_POST_REG),
1210 1170
1211 /* Digital bypasses */ 1171 /* Digital bypasses */
1212 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, 1172 SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
1213 &twl4030_dapm_dbypassl_control, bypass_event, 1173 &twl4030_dapm_dbypassl_control),
1214 SND_SOC_DAPM_POST_REG), 1174 SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
1215 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, 1175 &twl4030_dapm_dbypassr_control),
1216 &twl4030_dapm_dbypassr_control, bypass_event, 1176 SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1217 SND_SOC_DAPM_POST_REG), 1177 &twl4030_dapm_dbypassv_control),
1218 SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1219 &twl4030_dapm_dbypassv_control, bypass_event,
1220 SND_SOC_DAPM_POST_REG),
1221 1178
1222 /* Digital mixers, power control for the physical DACs */ 1179 /* Digital mixers, power control for the physical DACs */
1223 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer", 1180 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
@@ -1243,6 +1200,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1243 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", 1200 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
1244 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0), 1201 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
1245 1202
1203 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1204 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1205
1246 /* Output MIXER controls */ 1206 /* Output MIXER controls */
1247 /* Earpiece */ 1207 /* Earpiece */
1248 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1208 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
@@ -1308,8 +1268,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1308 0, 0, NULL, 0, handsfreerpga_event, 1268 0, 0, NULL, 0, handsfreerpga_event,
1309 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1269 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1310 /* Vibra */ 1270 /* Vibra */
1311 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, 1271 SND_SOC_DAPM_MUX_E("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1312 &twl4030_dapm_vibra_control), 1272 &twl4030_dapm_vibra_control, vibramux_event,
1273 SND_SOC_DAPM_PRE_PMU),
1313 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0, 1274 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
1314 &twl4030_dapm_vibrapath_control), 1275 &twl4030_dapm_vibrapath_control),
1315 1276
@@ -1369,6 +1330,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1369 {"Digital R2 Playback Mixer", NULL, "DAC Right2"}, 1330 {"Digital R2 Playback Mixer", NULL, "DAC Right2"},
1370 {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, 1331 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1371 1332
1333 /* Supply for the digital part (APLL) */
1334 {"Digital R1 Playback Mixer", NULL, "APLL Enable"},
1335 {"Digital L1 Playback Mixer", NULL, "APLL Enable"},
1336 {"Digital R2 Playback Mixer", NULL, "APLL Enable"},
1337 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1339
1372 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, 1340 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1373 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, 1341 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1374 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, 1342 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
@@ -1482,6 +1450,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1482 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1450 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1483 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1451 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1484 1452
1453 {"ADC Virtual Left1", NULL, "APLL Enable"},
1454 {"ADC Virtual Right1", NULL, "APLL Enable"},
1455 {"ADC Virtual Left2", NULL, "APLL Enable"},
1456 {"ADC Virtual Right2", NULL, "APLL Enable"},
1457
1485 /* Analog bypass routes */ 1458 /* Analog bypass routes */
1486 {"Right1 Analog Loopback", "Switch", "Analog Right"}, 1459 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1487 {"Left1 Analog Loopback", "Switch", "Analog Left"}, 1460 {"Left1 Analog Loopback", "Switch", "Analog Left"},
@@ -1489,6 +1462,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1489 {"Left2 Analog Loopback", "Switch", "Analog Left"}, 1462 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1490 {"Voice Analog Loopback", "Switch", "Analog Left"}, 1463 {"Voice Analog Loopback", "Switch", "Analog Left"},
1491 1464
1465 /* Supply for the Analog loopbacks */
1466 {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
1467 {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
1468 {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
1469 {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
1470 {"Voice Analog Loopback", NULL, "FM Loop Enable"},
1471
1492 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1472 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1493 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1473 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1494 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, 1474 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
@@ -1513,32 +1493,20 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec)
1513 1493
1514 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 1494 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
1515 1495
1516 snd_soc_dapm_new_widgets(codec);
1517 return 0; 1496 return 0;
1518} 1497}
1519 1498
1520static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1499static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1521 enum snd_soc_bias_level level) 1500 enum snd_soc_bias_level level)
1522{ 1501{
1523 struct twl4030_priv *twl4030 = codec->private_data;
1524
1525 switch (level) { 1502 switch (level) {
1526 case SND_SOC_BIAS_ON: 1503 case SND_SOC_BIAS_ON:
1527 twl4030_codec_mute(codec, 0);
1528 break; 1504 break;
1529 case SND_SOC_BIAS_PREPARE: 1505 case SND_SOC_BIAS_PREPARE:
1530 twl4030_power_up(codec);
1531 if (twl4030->bypass_state)
1532 twl4030_codec_mute(codec, 0);
1533 else
1534 twl4030_codec_mute(codec, 1);
1535 break; 1506 break;
1536 case SND_SOC_BIAS_STANDBY: 1507 case SND_SOC_BIAS_STANDBY:
1537 twl4030_power_up(codec); 1508 if (codec->bias_level == SND_SOC_BIAS_OFF)
1538 if (twl4030->bypass_state) 1509 twl4030_power_up(codec);
1539 twl4030_codec_mute(codec, 0);
1540 else
1541 twl4030_codec_mute(codec, 1);
1542 break; 1510 break;
1543 case SND_SOC_BIAS_OFF: 1511 case SND_SOC_BIAS_OFF:
1544 twl4030_power_down(codec); 1512 twl4030_power_down(codec);
@@ -1785,29 +1753,23 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1785{ 1753{
1786 struct snd_soc_codec *codec = codec_dai->codec; 1754 struct snd_soc_codec *codec = codec_dai->codec;
1787 struct twl4030_priv *twl4030 = codec->private_data; 1755 struct twl4030_priv *twl4030 = codec->private_data;
1788 u8 infreq;
1789 1756
1790 switch (freq) { 1757 switch (freq) {
1791 case 19200000: 1758 case 19200000:
1792 infreq = TWL4030_APLL_INFREQ_19200KHZ;
1793 twl4030->sysclk = 19200;
1794 break;
1795 case 26000000: 1759 case 26000000:
1796 infreq = TWL4030_APLL_INFREQ_26000KHZ;
1797 twl4030->sysclk = 26000;
1798 break;
1799 case 38400000: 1760 case 38400000:
1800 infreq = TWL4030_APLL_INFREQ_38400KHZ;
1801 twl4030->sysclk = 38400;
1802 break; 1761 break;
1803 default: 1762 default:
1804 printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n", 1763 dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq);
1805 freq);
1806 return -EINVAL; 1764 return -EINVAL;
1807 } 1765 }
1808 1766
1809 infreq |= TWL4030_APLL_EN; 1767 if ((freq / 1000) != twl4030->sysclk) {
1810 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq); 1768 dev_err(codec->dev,
1769 "Mismatch in APLL mclk: %u (configured: %u)\n",
1770 freq, twl4030->sysclk * 1000);
1771 return -EINVAL;
1772 }
1811 1773
1812 return 0; 1774 return 0;
1813} 1775}
@@ -1905,18 +1867,16 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1905 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1867 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1906 struct snd_soc_device *socdev = rtd->socdev; 1868 struct snd_soc_device *socdev = rtd->socdev;
1907 struct snd_soc_codec *codec = socdev->card->codec; 1869 struct snd_soc_codec *codec = socdev->card->codec;
1908 u8 infreq; 1870 struct twl4030_priv *twl4030 = codec->private_data;
1909 u8 mode; 1871 u8 mode;
1910 1872
1911 /* If the system master clock is not 26MHz, the voice PCM interface is 1873 /* If the system master clock is not 26MHz, the voice PCM interface is
1912 * not avilable. 1874 * not avilable.
1913 */ 1875 */
1914 infreq = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL) 1876 if (twl4030->sysclk != 26000) {
1915 & TWL4030_APLL_INFREQ; 1877 dev_err(codec->dev, "The board is configured for %u Hz, while"
1916 1878 "the Voice interface needs 26MHz APLL mclk\n",
1917 if (infreq != TWL4030_APLL_INFREQ_26000KHZ) { 1879 twl4030->sysclk * 1000);
1918 printk(KERN_ERR "TWL4030 voice startup: "
1919 "MCLK is not 26MHz, call set_sysclk() on init\n");
1920 return -EINVAL; 1880 return -EINVAL;
1921 } 1881 }
1922 1882
@@ -1989,21 +1949,19 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1989 int clk_id, unsigned int freq, int dir) 1949 int clk_id, unsigned int freq, int dir)
1990{ 1950{
1991 struct snd_soc_codec *codec = codec_dai->codec; 1951 struct snd_soc_codec *codec = codec_dai->codec;
1992 u8 infreq; 1952 struct twl4030_priv *twl4030 = codec->private_data;
1993 1953
1994 switch (freq) { 1954 if (freq != 26000000) {
1995 case 26000000: 1955 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
1996 infreq = TWL4030_APLL_INFREQ_26000KHZ; 1956 "interface needs 26MHz APLL mclk\n", freq);
1997 break; 1957 return -EINVAL;
1998 default: 1958 }
1999 printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n", 1959 if ((freq / 1000) != twl4030->sysclk) {
2000 freq); 1960 dev_err(codec->dev,
1961 "Mismatch in APLL mclk: %u (configured: %u)\n",
1962 freq, twl4030->sysclk * 1000);
2001 return -EINVAL; 1963 return -EINVAL;
2002 } 1964 }
2003
2004 infreq |= TWL4030_APLL_EN;
2005 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
2006
2007 return 0; 1965 return 0;
2008} 1966}
2009 1967
@@ -2121,7 +2079,7 @@ struct snd_soc_dai twl4030_dai[] = {
2121}; 2079};
2122EXPORT_SYMBOL_GPL(twl4030_dai); 2080EXPORT_SYMBOL_GPL(twl4030_dai);
2123 2081
2124static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) 2082static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state)
2125{ 2083{
2126 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2084 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2127 struct snd_soc_codec *codec = socdev->card->codec; 2085 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2131,7 +2089,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
2131 return 0; 2089 return 0;
2132} 2090}
2133 2091
2134static int twl4030_resume(struct platform_device *pdev) 2092static int twl4030_soc_resume(struct platform_device *pdev)
2135{ 2093{
2136 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2094 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2137 struct snd_soc_codec *codec = socdev->card->codec; 2095 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2141,147 +2099,181 @@ static int twl4030_resume(struct platform_device *pdev)
2141 return 0; 2099 return 0;
2142} 2100}
2143 2101
2144/* 2102static struct snd_soc_codec *twl4030_codec;
2145 * initialize the driver
2146 * register the mixer and dsp interfaces with the kernel
2147 */
2148 2103
2149static int twl4030_init(struct snd_soc_device *socdev) 2104static int twl4030_soc_probe(struct platform_device *pdev)
2150{ 2105{
2151 struct snd_soc_codec *codec = socdev->card->codec; 2106 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2152 struct twl4030_setup_data *setup = socdev->codec_data; 2107 struct twl4030_setup_data *setup = socdev->codec_data;
2153 struct twl4030_priv *twl4030 = codec->private_data; 2108 struct snd_soc_codec *codec;
2154 int ret = 0; 2109 struct twl4030_priv *twl4030;
2110 int ret;
2155 2111
2156 printk(KERN_INFO "TWL4030 Audio Codec init \n"); 2112 BUG_ON(!twl4030_codec);
2157 2113
2158 codec->name = "twl4030"; 2114 codec = twl4030_codec;
2159 codec->owner = THIS_MODULE; 2115 twl4030 = codec->private_data;
2160 codec->read = twl4030_read_reg_cache; 2116 socdev->card->codec = codec;
2161 codec->write = twl4030_write;
2162 codec->set_bias_level = twl4030_set_bias_level;
2163 codec->dai = twl4030_dai;
2164 codec->num_dai = ARRAY_SIZE(twl4030_dai),
2165 codec->reg_cache_size = sizeof(twl4030_reg);
2166 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2167 GFP_KERNEL);
2168 if (codec->reg_cache == NULL)
2169 return -ENOMEM;
2170 2117
2171 /* Configuration for headset ramp delay from setup data */ 2118 /* Configuration for headset ramp delay from setup data */
2172 if (setup) { 2119 if (setup) {
2173 unsigned char hs_pop; 2120 unsigned char hs_pop;
2174 2121
2175 if (setup->sysclk) 2122 if (setup->sysclk != twl4030->sysclk)
2176 twl4030->sysclk = setup->sysclk; 2123 dev_warn(&pdev->dev,
2177 else 2124 "Mismatch in APLL mclk: %u (configured: %u)\n",
2178 twl4030->sysclk = 26000; 2125 setup->sysclk, twl4030->sysclk);
2179 2126
2180 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 2127 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
2181 hs_pop &= ~TWL4030_RAMP_DELAY; 2128 hs_pop &= ~TWL4030_RAMP_DELAY;
2182 hs_pop |= (setup->ramp_delay_value << 2); 2129 hs_pop |= (setup->ramp_delay_value << 2);
2183 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 2130 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
2184 } else {
2185 twl4030->sysclk = 26000;
2186 } 2131 }
2187 2132
2188 /* register pcms */ 2133 /* register pcms */
2189 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2134 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2190 if (ret < 0) { 2135 if (ret < 0) {
2191 printk(KERN_ERR "twl4030: failed to create pcms\n"); 2136 dev_err(&pdev->dev, "failed to create pcms\n");
2192 goto pcm_err; 2137 return ret;
2193 } 2138 }
2194 2139
2195 twl4030_init_chip(codec);
2196
2197 /* power on device */
2198 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2199
2200 snd_soc_add_controls(codec, twl4030_snd_controls, 2140 snd_soc_add_controls(codec, twl4030_snd_controls,
2201 ARRAY_SIZE(twl4030_snd_controls)); 2141 ARRAY_SIZE(twl4030_snd_controls));
2202 twl4030_add_widgets(codec); 2142 twl4030_add_widgets(codec);
2203 2143
2204 ret = snd_soc_init_card(socdev); 2144 return 0;
2205 if (ret < 0) { 2145}
2206 printk(KERN_ERR "twl4030: failed to register card\n");
2207 goto card_err;
2208 }
2209 2146
2210 return ret; 2147static int twl4030_soc_remove(struct platform_device *pdev)
2148{
2149 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2150 struct snd_soc_codec *codec = socdev->card->codec;
2211 2151
2212card_err: 2152 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2213 snd_soc_free_pcms(socdev); 2153 snd_soc_free_pcms(socdev);
2214 snd_soc_dapm_free(socdev); 2154 snd_soc_dapm_free(socdev);
2215pcm_err: 2155 kfree(codec->private_data);
2216 kfree(codec->reg_cache); 2156 kfree(codec);
2217 return ret;
2218}
2219 2157
2220static struct snd_soc_device *twl4030_socdev; 2158 return 0;
2159}
2221 2160
2222static int twl4030_probe(struct platform_device *pdev) 2161static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2223{ 2162{
2224 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2163 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
2225 struct snd_soc_codec *codec; 2164 struct snd_soc_codec *codec;
2226 struct twl4030_priv *twl4030; 2165 struct twl4030_priv *twl4030;
2166 int ret;
2227 2167
2228 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 2168 if (!pdata) {
2229 if (codec == NULL) 2169 dev_err(&pdev->dev, "platform_data is missing\n");
2230 return -ENOMEM; 2170 return -EINVAL;
2171 }
2231 2172
2232 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2173 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2233 if (twl4030 == NULL) { 2174 if (twl4030 == NULL) {
2234 kfree(codec); 2175 dev_err(&pdev->dev, "Can not allocate memroy\n");
2235 return -ENOMEM; 2176 return -ENOMEM;
2236 } 2177 }
2237 2178
2179 codec = &twl4030->codec;
2238 codec->private_data = twl4030; 2180 codec->private_data = twl4030;
2239 socdev->card->codec = codec; 2181 codec->dev = &pdev->dev;
2182 twl4030_dai[0].dev = &pdev->dev;
2183 twl4030_dai[1].dev = &pdev->dev;
2184
2240 mutex_init(&codec->mutex); 2185 mutex_init(&codec->mutex);
2241 INIT_LIST_HEAD(&codec->dapm_widgets); 2186 INIT_LIST_HEAD(&codec->dapm_widgets);
2242 INIT_LIST_HEAD(&codec->dapm_paths); 2187 INIT_LIST_HEAD(&codec->dapm_paths);
2243 2188
2244 twl4030_socdev = socdev; 2189 codec->name = "twl4030";
2245 twl4030_init(socdev); 2190 codec->owner = THIS_MODULE;
2191 codec->read = twl4030_read_reg_cache;
2192 codec->write = twl4030_write;
2193 codec->set_bias_level = twl4030_set_bias_level;
2194 codec->dai = twl4030_dai;
2195 codec->num_dai = ARRAY_SIZE(twl4030_dai),
2196 codec->reg_cache_size = sizeof(twl4030_reg);
2197 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2198 GFP_KERNEL);
2199 if (codec->reg_cache == NULL) {
2200 ret = -ENOMEM;
2201 goto error_cache;
2202 }
2203
2204 platform_set_drvdata(pdev, twl4030);
2205 twl4030_codec = codec;
2206
2207 /* Set the defaults, and power up the codec */
2208 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2209 twl4030_init_chip(codec);
2210 codec->bias_level = SND_SOC_BIAS_OFF;
2211 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2212
2213 ret = snd_soc_register_codec(codec);
2214 if (ret != 0) {
2215 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2216 goto error_codec;
2217 }
2218
2219 ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2220 if (ret != 0) {
2221 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
2222 snd_soc_unregister_codec(codec);
2223 goto error_codec;
2224 }
2246 2225
2247 return 0; 2226 return 0;
2227
2228error_codec:
2229 twl4030_power_down(codec);
2230 kfree(codec->reg_cache);
2231error_cache:
2232 kfree(twl4030);
2233 return ret;
2248} 2234}
2249 2235
2250static int twl4030_remove(struct platform_device *pdev) 2236static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2251{ 2237{
2252 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2238 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
2253 struct snd_soc_codec *codec = socdev->card->codec;
2254 2239
2255 printk(KERN_INFO "TWL4030 Audio Codec remove\n"); 2240 kfree(twl4030);
2256 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2257 snd_soc_free_pcms(socdev);
2258 snd_soc_dapm_free(socdev);
2259 kfree(codec->private_data);
2260 kfree(codec);
2261 2241
2242 twl4030_codec = NULL;
2262 return 0; 2243 return 0;
2263} 2244}
2264 2245
2265struct snd_soc_codec_device soc_codec_dev_twl4030 = { 2246MODULE_ALIAS("platform:twl4030_codec_audio");
2266 .probe = twl4030_probe, 2247
2267 .remove = twl4030_remove, 2248static struct platform_driver twl4030_codec_driver = {
2268 .suspend = twl4030_suspend, 2249 .probe = twl4030_codec_probe,
2269 .resume = twl4030_resume, 2250 .remove = __devexit_p(twl4030_codec_remove),
2251 .driver = {
2252 .name = "twl4030_codec_audio",
2253 .owner = THIS_MODULE,
2254 },
2270}; 2255};
2271EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2272 2256
2273static int __init twl4030_modinit(void) 2257static int __init twl4030_modinit(void)
2274{ 2258{
2275 return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2259 return platform_driver_register(&twl4030_codec_driver);
2276} 2260}
2277module_init(twl4030_modinit); 2261module_init(twl4030_modinit);
2278 2262
2279static void __exit twl4030_exit(void) 2263static void __exit twl4030_exit(void)
2280{ 2264{
2281 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2265 platform_driver_unregister(&twl4030_codec_driver);
2282} 2266}
2283module_exit(twl4030_exit); 2267module_exit(twl4030_exit);
2284 2268
2269struct snd_soc_codec_device soc_codec_dev_twl4030 = {
2270 .probe = twl4030_soc_probe,
2271 .remove = twl4030_soc_remove,
2272 .suspend = twl4030_soc_suspend,
2273 .resume = twl4030_soc_resume,
2274};
2275EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2276
2285MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); 2277MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2286MODULE_AUTHOR("Steve Sakoman"); 2278MODULE_AUTHOR("Steve Sakoman");
2287MODULE_LICENSE("GPL"); 2279MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 2b4bfa23f985..dd6396ec9c79 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -22,245 +22,13 @@
22#ifndef __TWL4030_AUDIO_H__ 22#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__ 23#define __TWL4030_AUDIO_H__
24 24
25#define TWL4030_REG_CODEC_MODE 0x1 25/* Register descriptions are here */
26#define TWL4030_REG_OPTION 0x2 26#include <linux/mfd/twl4030-codec.h>
27#define TWL4030_REG_UNKNOWN 0x3
28#define TWL4030_REG_MICBIAS_CTL 0x4
29#define TWL4030_REG_ANAMICL 0x5
30#define TWL4030_REG_ANAMICR 0x6
31#define TWL4030_REG_AVADC_CTL 0x7
32#define TWL4030_REG_ADCMICSEL 0x8
33#define TWL4030_REG_DIGMIXING 0x9
34#define TWL4030_REG_ATXL1PGA 0xA
35#define TWL4030_REG_ATXR1PGA 0xB
36#define TWL4030_REG_AVTXL2PGA 0xC
37#define TWL4030_REG_AVTXR2PGA 0xD
38#define TWL4030_REG_AUDIO_IF 0xE
39#define TWL4030_REG_VOICE_IF 0xF
40#define TWL4030_REG_ARXR1PGA 0x10
41#define TWL4030_REG_ARXL1PGA 0x11
42#define TWL4030_REG_ARXR2PGA 0x12
43#define TWL4030_REG_ARXL2PGA 0x13
44#define TWL4030_REG_VRXPGA 0x14
45#define TWL4030_REG_VSTPGA 0x15
46#define TWL4030_REG_VRX2ARXPGA 0x16
47#define TWL4030_REG_AVDAC_CTL 0x17
48#define TWL4030_REG_ARX2VTXPGA 0x18
49#define TWL4030_REG_ARXL1_APGA_CTL 0x19
50#define TWL4030_REG_ARXR1_APGA_CTL 0x1A
51#define TWL4030_REG_ARXL2_APGA_CTL 0x1B
52#define TWL4030_REG_ARXR2_APGA_CTL 0x1C
53#define TWL4030_REG_ATX2ARXPGA 0x1D
54#define TWL4030_REG_BT_IF 0x1E
55#define TWL4030_REG_BTPGA 0x1F
56#define TWL4030_REG_BTSTPGA 0x20
57#define TWL4030_REG_EAR_CTL 0x21
58#define TWL4030_REG_HS_SEL 0x22
59#define TWL4030_REG_HS_GAIN_SET 0x23
60#define TWL4030_REG_HS_POPN_SET 0x24
61#define TWL4030_REG_PREDL_CTL 0x25
62#define TWL4030_REG_PREDR_CTL 0x26
63#define TWL4030_REG_PRECKL_CTL 0x27
64#define TWL4030_REG_PRECKR_CTL 0x28
65#define TWL4030_REG_HFL_CTL 0x29
66#define TWL4030_REG_HFR_CTL 0x2A
67#define TWL4030_REG_ALC_CTL 0x2B
68#define TWL4030_REG_ALC_SET1 0x2C
69#define TWL4030_REG_ALC_SET2 0x2D
70#define TWL4030_REG_BOOST_CTL 0x2E
71#define TWL4030_REG_SOFTVOL_CTL 0x2F
72#define TWL4030_REG_DTMF_FREQSEL 0x30
73#define TWL4030_REG_DTMF_TONEXT1H 0x31
74#define TWL4030_REG_DTMF_TONEXT1L 0x32
75#define TWL4030_REG_DTMF_TONEXT2H 0x33
76#define TWL4030_REG_DTMF_TONEXT2L 0x34
77#define TWL4030_REG_DTMF_TONOFF 0x35
78#define TWL4030_REG_DTMF_WANONOFF 0x36
79#define TWL4030_REG_I2S_RX_SCRAMBLE_H 0x37
80#define TWL4030_REG_I2S_RX_SCRAMBLE_M 0x38
81#define TWL4030_REG_I2S_RX_SCRAMBLE_L 0x39
82#define TWL4030_REG_APLL_CTL 0x3A
83#define TWL4030_REG_DTMF_CTL 0x3B
84#define TWL4030_REG_DTMF_PGA_CTL2 0x3C
85#define TWL4030_REG_DTMF_PGA_CTL1 0x3D
86#define TWL4030_REG_MISC_SET_1 0x3E
87#define TWL4030_REG_PCMBTMUX 0x3F
88#define TWL4030_REG_RX_PATH_SEL 0x43
89#define TWL4030_REG_VDL_APGA_CTL 0x44
90#define TWL4030_REG_VIBRA_CTL 0x45
91#define TWL4030_REG_VIBRA_SET 0x46
92#define TWL4030_REG_VIBRA_PWM_SET 0x47
93#define TWL4030_REG_ANAMIC_GAIN 0x48
94#define TWL4030_REG_MISC_SET_2 0x49
95#define TWL4030_REG_SW_SHADOW 0x4A
96 27
28/* Sgadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A
97#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
98 31
99/* Bitfield Definitions */
100
101/* TWL4030_CODEC_MODE (0x01) Fields */
102
103#define TWL4030_APLL_RATE 0xF0
104#define TWL4030_APLL_RATE_8000 0x00
105#define TWL4030_APLL_RATE_11025 0x10
106#define TWL4030_APLL_RATE_12000 0x20
107#define TWL4030_APLL_RATE_16000 0x40
108#define TWL4030_APLL_RATE_22050 0x50
109#define TWL4030_APLL_RATE_24000 0x60
110#define TWL4030_APLL_RATE_32000 0x80
111#define TWL4030_APLL_RATE_44100 0x90
112#define TWL4030_APLL_RATE_48000 0xA0
113#define TWL4030_APLL_RATE_96000 0xE0
114#define TWL4030_SEL_16K 0x08
115#define TWL4030_CODECPDZ 0x02
116#define TWL4030_OPT_MODE 0x01
117#define TWL4030_OPTION_1 (1 << 0)
118#define TWL4030_OPTION_2 (0 << 0)
119
120/* TWL4030_OPTION (0x02) Fields */
121
122#define TWL4030_ATXL1_EN (1 << 0)
123#define TWL4030_ATXR1_EN (1 << 1)
124#define TWL4030_ATXL2_VTXL_EN (1 << 2)
125#define TWL4030_ATXR2_VTXR_EN (1 << 3)
126#define TWL4030_ARXL1_VRX_EN (1 << 4)
127#define TWL4030_ARXR1_EN (1 << 5)
128#define TWL4030_ARXL2_EN (1 << 6)
129#define TWL4030_ARXR2_EN (1 << 7)
130
131/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
132
133#define TWL4030_MICBIAS2_CTL 0x40
134#define TWL4030_MICBIAS1_CTL 0x20
135#define TWL4030_HSMICBIAS_EN 0x04
136#define TWL4030_MICBIAS2_EN 0x02
137#define TWL4030_MICBIAS1_EN 0x01
138
139/* ANAMICL (0x05) Fields */
140
141#define TWL4030_CNCL_OFFSET_START 0x80
142#define TWL4030_OFFSET_CNCL_SEL 0x60
143#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
144#define TWL4030_OFFSET_CNCL_SEL_ARX2 0x20
145#define TWL4030_OFFSET_CNCL_SEL_VRX 0x40
146#define TWL4030_OFFSET_CNCL_SEL_ALL 0x60
147#define TWL4030_MICAMPL_EN 0x10
148#define TWL4030_CKMIC_EN 0x08
149#define TWL4030_AUXL_EN 0x04
150#define TWL4030_HSMIC_EN 0x02
151#define TWL4030_MAINMIC_EN 0x01
152
153/* ANAMICR (0x06) Fields */
154
155#define TWL4030_MICAMPR_EN 0x10
156#define TWL4030_AUXR_EN 0x04
157#define TWL4030_SUBMIC_EN 0x01
158
159/* AVADC_CTL (0x07) Fields */
160
161#define TWL4030_ADCL_EN 0x08
162#define TWL4030_AVADC_CLK_PRIORITY 0x04
163#define TWL4030_ADCR_EN 0x02
164
165/* TWL4030_REG_ADCMICSEL (0x08) Fields */
166
167#define TWL4030_DIGMIC1_EN 0x08
168#define TWL4030_TX2IN_SEL 0x04
169#define TWL4030_DIGMIC0_EN 0x02
170#define TWL4030_TX1IN_SEL 0x01
171
172/* AUDIO_IF (0x0E) Fields */
173
174#define TWL4030_AIF_SLAVE_EN 0x80
175#define TWL4030_DATA_WIDTH 0x60
176#define TWL4030_DATA_WIDTH_16S_16W 0x00
177#define TWL4030_DATA_WIDTH_32S_16W 0x40
178#define TWL4030_DATA_WIDTH_32S_24W 0x60
179#define TWL4030_AIF_FORMAT 0x18
180#define TWL4030_AIF_FORMAT_CODEC 0x00
181#define TWL4030_AIF_FORMAT_LEFT 0x08
182#define TWL4030_AIF_FORMAT_RIGHT 0x10
183#define TWL4030_AIF_FORMAT_TDM 0x18
184#define TWL4030_AIF_TRI_EN 0x04
185#define TWL4030_CLK256FS_EN 0x02
186#define TWL4030_AIF_EN 0x01
187
188/* VOICE_IF (0x0F) Fields */
189
190#define TWL4030_VIF_SLAVE_EN 0x80
191#define TWL4030_VIF_DIN_EN 0x40
192#define TWL4030_VIF_DOUT_EN 0x20
193#define TWL4030_VIF_SWAP 0x10
194#define TWL4030_VIF_FORMAT 0x08
195#define TWL4030_VIF_TRI_EN 0x04
196#define TWL4030_VIF_SUB_EN 0x02
197#define TWL4030_VIF_EN 0x01
198
199/* EAR_CTL (0x21) */
200#define TWL4030_EAR_GAIN 0x30
201
202/* HS_GAIN_SET (0x23) Fields */
203
204#define TWL4030_HSR_GAIN 0x0C
205#define TWL4030_HSR_GAIN_PWR_DOWN 0x00
206#define TWL4030_HSR_GAIN_PLUS_6DB 0x04
207#define TWL4030_HSR_GAIN_0DB 0x08
208#define TWL4030_HSR_GAIN_MINUS_6DB 0x0C
209#define TWL4030_HSL_GAIN 0x03
210#define TWL4030_HSL_GAIN_PWR_DOWN 0x00
211#define TWL4030_HSL_GAIN_PLUS_6DB 0x01
212#define TWL4030_HSL_GAIN_0DB 0x02
213#define TWL4030_HSL_GAIN_MINUS_6DB 0x03
214
215/* HS_POPN_SET (0x24) Fields */
216
217#define TWL4030_VMID_EN 0x40
218#define TWL4030_EXTMUTE 0x20
219#define TWL4030_RAMP_DELAY 0x1C
220#define TWL4030_RAMP_DELAY_20MS 0x00
221#define TWL4030_RAMP_DELAY_40MS 0x04
222#define TWL4030_RAMP_DELAY_81MS 0x08
223#define TWL4030_RAMP_DELAY_161MS 0x0C
224#define TWL4030_RAMP_DELAY_323MS 0x10
225#define TWL4030_RAMP_DELAY_645MS 0x14
226#define TWL4030_RAMP_DELAY_1291MS 0x18
227#define TWL4030_RAMP_DELAY_2581MS 0x1C
228#define TWL4030_RAMP_EN 0x02
229
230/* PREDL_CTL (0x25) */
231#define TWL4030_PREDL_GAIN 0x30
232
233/* PREDR_CTL (0x26) */
234#define TWL4030_PREDR_GAIN 0x30
235
236/* PRECKL_CTL (0x27) */
237#define TWL4030_PRECKL_GAIN 0x30
238
239/* PRECKR_CTL (0x28) */
240#define TWL4030_PRECKR_GAIN 0x30
241
242/* HFL_CTL (0x29, 0x2A) Fields */
243#define TWL4030_HF_CTL_HB_EN 0x04
244#define TWL4030_HF_CTL_LOOP_EN 0x08
245#define TWL4030_HF_CTL_RAMP_EN 0x10
246#define TWL4030_HF_CTL_REF_EN 0x20
247
248/* APLL_CTL (0x3A) Fields */
249
250#define TWL4030_APLL_EN 0x10
251#define TWL4030_APLL_INFREQ 0x0F
252#define TWL4030_APLL_INFREQ_19200KHZ 0x05
253#define TWL4030_APLL_INFREQ_26000KHZ 0x06
254#define TWL4030_APLL_INFREQ_38400KHZ 0x0F
255
256/* REG_MISC_SET_1 (0x3E) Fields */
257
258#define TWL4030_CLK64_EN 0x80
259#define TWL4030_SCRAMBLE_EN 0x40
260#define TWL4030_FMLOOP_EN 0x20
261#define TWL4030_SMOOTH_ANAVOL_EN 0x02
262#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
263
264/* TWL4030_REG_SW_SHADOW (0x4A) Fields */ 32/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
265#define TWL4030_HFL_EN 0x01 33#define TWL4030_HFL_EN 0x01
266#define TWL4030_HFR_EN 0x02 34#define TWL4030_HFR_EN 0x02
@@ -279,3 +47,5 @@ struct twl4030_setup_data {
279}; 47};
280 48
281#endif /* End of __TWL4030_AUDIO_H__ */ 49#endif /* End of __TWL4030_AUDIO_H__ */
50
51
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index c33b92edbded..3e99fe5131dd 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -101,7 +101,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value); 101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
102 102
103 if (reg >= UDA134X_REGS_NUM) { 103 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %u", 104 printk(KERN_ERR "%s unknown register: reg: %u",
105 __func__, reg); 105 __func__, reg);
106 return -EINVAL; 106 return -EINVAL;
107 } 107 }
@@ -552,7 +552,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
552 ARRAY_SIZE(uda1341_snd_controls)); 552 ARRAY_SIZE(uda1341_snd_controls));
553 break; 553 break;
554 default: 554 default:
555 printk(KERN_ERR "%s unkown codec type: %d", 555 printk(KERN_ERR "%s unknown codec type: %d",
556 __func__, pd->model); 556 __func__, pd->model);
557 return -EINVAL; 557 return -EINVAL;
558 } 558 }
@@ -562,17 +562,8 @@ static int uda134x_soc_probe(struct platform_device *pdev)
562 goto pcm_err; 562 goto pcm_err;
563 } 563 }
564 564
565 ret = snd_soc_init_card(socdev);
566 if (ret < 0) {
567 printk(KERN_ERR "UDA134X: failed to register card\n");
568 goto card_err;
569 }
570
571 return 0; 565 return 0;
572 566
573card_err:
574 snd_soc_free_pcms(socdev);
575 snd_soc_dapm_free(socdev);
576pcm_err: 567pcm_err:
577 kfree(codec->reg_cache); 568 kfree(codec->reg_cache);
578reg_err: 569reg_err:
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 92ec03442154..a2763c2e7348 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -378,7 +378,6 @@ static int uda1380_add_widgets(struct snd_soc_codec *codec)
378 378
379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
380 380
381 snd_soc_dapm_new_widgets(codec);
382 return 0; 381 return 0;
383} 382}
384 383
@@ -713,17 +712,9 @@ static int uda1380_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, uda1380_snd_controls, 712 snd_soc_add_controls(codec, uda1380_snd_controls,
714 ARRAY_SIZE(uda1380_snd_controls)); 713 ARRAY_SIZE(uda1380_snd_controls));
715 uda1380_add_widgets(codec); 714 uda1380_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 715
722 return ret; 716 return ret;
723 717
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 718pcm_err:
728 return ret; 719 return ret;
729} 720}
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 593d5b9c9f03..f82125d9e85a 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -800,7 +800,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
800 return ret; 800 return ret;
801 } 801 }
802 802
803 return snd_soc_dapm_new_widgets(codec); 803 return 0;
804} 804}
805 805
806static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai, 806static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
@@ -1101,7 +1101,7 @@ static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
1101} 1101}
1102 1102
1103static int wm8350_set_fll(struct snd_soc_dai *codec_dai, 1103static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1104 int pll_id, unsigned int freq_in, 1104 int pll_id, int source, unsigned int freq_in,
1105 unsigned int freq_out) 1105 unsigned int freq_out)
1106{ 1106{
1107 struct snd_soc_codec *codec = codec_dai->codec; 1107 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1501,18 +1501,7 @@ static int wm8350_probe(struct platform_device *pdev)
1501 1501
1502 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1502 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1503 1503
1504 ret = snd_soc_init_card(socdev);
1505 if (ret < 0) {
1506 dev_err(&pdev->dev, "failed to register card\n");
1507 goto card_err;
1508 }
1509
1510 return 0; 1504 return 0;
1511
1512card_err:
1513 snd_soc_free_pcms(socdev);
1514 snd_soc_dapm_free(socdev);
1515 return ret;
1516} 1505}
1517 1506
1518static int wm8350_remove(struct platform_device *pdev) 1507static int wm8350_remove(struct platform_device *pdev)
@@ -1680,21 +1669,6 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1680 return 0; 1669 return 0;
1681} 1670}
1682 1671
1683#ifdef CONFIG_PM
1684static int wm8350_codec_suspend(struct platform_device *pdev, pm_message_t m)
1685{
1686 return snd_soc_suspend_device(&pdev->dev);
1687}
1688
1689static int wm8350_codec_resume(struct platform_device *pdev)
1690{
1691 return snd_soc_resume_device(&pdev->dev);
1692}
1693#else
1694#define wm8350_codec_suspend NULL
1695#define wm8350_codec_resume NULL
1696#endif
1697
1698static struct platform_driver wm8350_codec_driver = { 1672static struct platform_driver wm8350_codec_driver = {
1699 .driver = { 1673 .driver = {
1700 .name = "wm8350-codec", 1674 .name = "wm8350-codec",
@@ -1702,8 +1676,6 @@ static struct platform_driver wm8350_codec_driver = {
1702 }, 1676 },
1703 .probe = wm8350_codec_probe, 1677 .probe = wm8350_codec_probe,
1704 .remove = __devexit_p(wm8350_codec_remove), 1678 .remove = __devexit_p(wm8350_codec_remove),
1705 .suspend = wm8350_codec_suspend,
1706 .resume = wm8350_codec_resume,
1707}; 1679};
1708 1680
1709static __init int wm8350_init(void) 1681static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index b9ef4d915221..b432f4d4a324 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -915,7 +915,6 @@ static int wm8400_add_widgets(struct snd_soc_codec *codec)
915 915
916 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 916 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
917 917
918 snd_soc_dapm_new_widgets(codec);
919 return 0; 918 return 0;
920} 919}
921 920
@@ -1011,7 +1010,8 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
1011} 1010}
1012 1011
1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 1012static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1014 unsigned int freq_in, unsigned int freq_out) 1013 int source, unsigned int freq_in,
1014 unsigned int freq_out)
1015{ 1015{
1016 struct snd_soc_codec *codec = codec_dai->codec; 1016 struct snd_soc_codec *codec = codec_dai->codec;
1017 struct wm8400_priv *wm8400 = codec->private_data; 1017 struct wm8400_priv *wm8400 = codec->private_data;
@@ -1399,17 +1399,6 @@ static int wm8400_probe(struct platform_device *pdev)
1399 wm8400_add_controls(codec); 1399 wm8400_add_controls(codec);
1400 wm8400_add_widgets(codec); 1400 wm8400_add_widgets(codec);
1401 1401
1402 ret = snd_soc_init_card(socdev);
1403 if (ret < 0) {
1404 dev_err(&pdev->dev, "failed to register card\n");
1405 goto card_err;
1406 }
1407
1408 return ret;
1409
1410card_err:
1411 snd_soc_free_pcms(socdev);
1412 snd_soc_dapm_free(socdev);
1413pcm_err: 1402pcm_err:
1414 return ret; 1403 return ret;
1415} 1404}
@@ -1558,21 +1547,6 @@ static int __exit wm8400_codec_remove(struct platform_device *dev)
1558 return 0; 1547 return 0;
1559} 1548}
1560 1549
1561#ifdef CONFIG_PM
1562static int wm8400_pdev_suspend(struct platform_device *pdev, pm_message_t msg)
1563{
1564 return snd_soc_suspend_device(&pdev->dev);
1565}
1566
1567static int wm8400_pdev_resume(struct platform_device *pdev)
1568{
1569 return snd_soc_resume_device(&pdev->dev);
1570}
1571#else
1572#define wm8400_pdev_suspend NULL
1573#define wm8400_pdev_resume NULL
1574#endif
1575
1576static struct platform_driver wm8400_codec_driver = { 1550static struct platform_driver wm8400_codec_driver = {
1577 .driver = { 1551 .driver = {
1578 .name = "wm8400-codec", 1552 .name = "wm8400-codec",
@@ -1580,8 +1554,6 @@ static struct platform_driver wm8400_codec_driver = {
1580 }, 1554 },
1581 .probe = wm8400_codec_probe, 1555 .probe = wm8400_codec_probe,
1582 .remove = __exit_p(wm8400_codec_remove), 1556 .remove = __exit_p(wm8400_codec_remove),
1583 .suspend = wm8400_pdev_suspend,
1584 .resume = wm8400_pdev_resume,
1585}; 1557};
1586 1558
1587static int __init wm8400_codec_init(void) 1559static int __init wm8400_codec_init(void)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 060d5d06ba95..265e68c75df8 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -219,7 +219,6 @@ static int wm8510_add_widgets(struct snd_soc_codec *codec)
219 219
220 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 220 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
221 221
222 snd_soc_dapm_new_widgets(codec);
223 return 0; 222 return 0;
224} 223}
225 224
@@ -271,8 +270,8 @@ static void pll_factors(unsigned int target, unsigned int source)
271 pll_div.k = K; 270 pll_div.k = K;
272} 271}
273 272
274static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, 273static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
275 int pll_id, unsigned int freq_in, unsigned int freq_out) 274 int source, unsigned int freq_in, unsigned int freq_out)
276{ 275{
277 struct snd_soc_codec *codec = codec_dai->codec; 276 struct snd_soc_codec *codec = codec_dai->codec;
278 u16 reg; 277 u16 reg;
@@ -604,16 +603,9 @@ static int wm8510_init(struct snd_soc_device *socdev,
604 snd_soc_add_controls(codec, wm8510_snd_controls, 603 snd_soc_add_controls(codec, wm8510_snd_controls,
605 ARRAY_SIZE(wm8510_snd_controls)); 604 ARRAY_SIZE(wm8510_snd_controls));
606 wm8510_add_widgets(codec); 605 wm8510_add_widgets(codec);
607 ret = snd_soc_init_card(socdev); 606
608 if (ret < 0) {
609 printk(KERN_ERR "wm8510: failed to register card\n");
610 goto card_err;
611 }
612 return ret; 607 return ret;
613 608
614card_err:
615 snd_soc_free_pcms(socdev);
616 snd_soc_dapm_free(socdev);
617err: 609err:
618 kfree(codec->reg_cache); 610 kfree(codec->reg_cache);
619 return ret; 611 return ret;
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 25870a4652fb..d3a61d7ea0c5 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -117,7 +117,6 @@ static int wm8523_add_widgets(struct snd_soc_codec *codec)
117 117
118 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 118 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
119 119
120 snd_soc_dapm_new_widgets(codec);
121 return 0; 120 return 0;
122} 121}
123 122
@@ -448,17 +447,9 @@ static int wm8523_probe(struct platform_device *pdev)
448 snd_soc_add_controls(codec, wm8523_snd_controls, 447 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls)); 448 ARRAY_SIZE(wm8523_snd_controls));
450 wm8523_add_widgets(codec); 449 wm8523_add_widgets(codec);
451 ret = snd_soc_init_card(socdev);
452 if (ret < 0) {
453 dev_err(codec->dev, "failed to register card: %d\n", ret);
454 goto card_err;
455 }
456 450
457 return ret; 451 return ret;
458 452
459card_err:
460 snd_soc_free_pcms(socdev);
461 snd_soc_dapm_free(socdev);
462pcm_err: 453pcm_err:
463 return ret; 454 return ret;
464} 455}
@@ -638,21 +629,6 @@ static __devexit int wm8523_i2c_remove(struct i2c_client *client)
638 return 0; 629 return 0;
639} 630}
640 631
641#ifdef CONFIG_PM
642static int wm8523_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
643{
644 return snd_soc_suspend_device(&i2c->dev);
645}
646
647static int wm8523_i2c_resume(struct i2c_client *i2c)
648{
649 return snd_soc_resume_device(&i2c->dev);
650}
651#else
652#define wm8523_i2c_suspend NULL
653#define wm8523_i2c_resume NULL
654#endif
655
656static const struct i2c_device_id wm8523_i2c_id[] = { 632static const struct i2c_device_id wm8523_i2c_id[] = {
657 { "wm8523", 0 }, 633 { "wm8523", 0 },
658 { } 634 { }
@@ -666,8 +642,6 @@ static struct i2c_driver wm8523_i2c_driver = {
666 }, 642 },
667 .probe = wm8523_i2c_probe, 643 .probe = wm8523_i2c_probe,
668 .remove = __devexit_p(wm8523_i2c_remove), 644 .remove = __devexit_p(wm8523_i2c_remove),
669 .suspend = wm8523_i2c_suspend,
670 .resume = wm8523_i2c_resume,
671 .id_table = wm8523_i2c_id, 645 .id_table = wm8523_i2c_id,
672}; 646};
673#endif 647#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 6bded8c78150..d077df6f5e75 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -315,7 +315,6 @@ static int wm8580_add_widgets(struct snd_soc_codec *codec)
315 315
316 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 316 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
317 317
318 snd_soc_dapm_new_widgets(codec);
319 return 0; 318 return 0;
320} 319}
321 320
@@ -407,8 +406,8 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
407 return 0; 406 return 0;
408} 407}
409 408
410static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, 409static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
411 int pll_id, unsigned int freq_in, unsigned int freq_out) 410 int source, unsigned int freq_in, unsigned int freq_out)
412{ 411{
413 int offset; 412 int offset;
414 struct snd_soc_codec *codec = codec_dai->codec; 413 struct snd_soc_codec *codec = codec_dai->codec;
@@ -800,17 +799,9 @@ static int wm8580_probe(struct platform_device *pdev)
800 snd_soc_add_controls(codec, wm8580_snd_controls, 799 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls)); 800 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec); 801 wm8580_add_widgets(codec);
803 ret = snd_soc_init_card(socdev);
804 if (ret < 0) {
805 dev_err(codec->dev, "failed to register card: %d\n", ret);
806 goto card_err;
807 }
808 802
809 return ret; 803 return ret;
810 804
811card_err:
812 snd_soc_free_pcms(socdev);
813 snd_soc_dapm_free(socdev);
814pcm_err: 805pcm_err:
815 return ret; 806 return ret;
816} 807}
@@ -961,21 +952,6 @@ static int wm8580_i2c_remove(struct i2c_client *client)
961 return 0; 952 return 0;
962} 953}
963 954
964#ifdef CONFIG_PM
965static int wm8580_i2c_suspend(struct i2c_client *client, pm_message_t msg)
966{
967 return snd_soc_suspend_device(&client->dev);
968}
969
970static int wm8580_i2c_resume(struct i2c_client *client)
971{
972 return snd_soc_resume_device(&client->dev);
973}
974#else
975#define wm8580_i2c_suspend NULL
976#define wm8580_i2c_resume NULL
977#endif
978
979static const struct i2c_device_id wm8580_i2c_id[] = { 955static const struct i2c_device_id wm8580_i2c_id[] = {
980 { "wm8580", 0 }, 956 { "wm8580", 0 },
981 { } 957 { }
@@ -989,8 +965,6 @@ static struct i2c_driver wm8580_i2c_driver = {
989 }, 965 },
990 .probe = wm8580_i2c_probe, 966 .probe = wm8580_i2c_probe,
991 .remove = wm8580_i2c_remove, 967 .remove = wm8580_i2c_remove,
992 .suspend = wm8580_i2c_suspend,
993 .resume = wm8580_i2c_resume,
994 .id_table = wm8580_i2c_id, 968 .id_table = wm8580_i2c_id,
995}; 969};
996#endif 970#endif
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
new file mode 100644
index 000000000000..24a35603bcf7
--- /dev/null
+++ b/sound/soc/codecs/wm8711.c
@@ -0,0 +1,633 @@
1/*
2 * wm8711.c -- WM8711 ALSA SoC Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.c by Richard Purdie
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <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/tlv.h>
29#include <sound/initval.h>
30
31#include "wm8711.h"
32
33static struct snd_soc_codec *wm8711_codec;
34
35/* codec private data */
36struct wm8711_priv {
37 struct snd_soc_codec codec;
38 u16 reg_cache[WM8711_CACHEREGNUM];
39 unsigned int sysclk;
40};
41
42/*
43 * wm8711 register cache
44 * We can't read the WM8711 register space when we are
45 * using 2 wire for device control, so we cache them instead.
46 * There is no point in caching the reset register
47 */
48static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
49 0x0079, 0x0079, 0x000a, 0x0008,
50 0x009f, 0x000a, 0x0000, 0x0000
51};
52
53#define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0)
54
55static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
56
57static const struct snd_kcontrol_new wm8711_snd_controls[] = {
58
59SOC_DOUBLE_R_TLV("Master Playback Volume", WM8711_LOUT1V, WM8711_ROUT1V,
60 0, 127, 0, out_tlv),
61SOC_DOUBLE_R("Master Playback ZC Switch", WM8711_LOUT1V, WM8711_ROUT1V,
62 7, 1, 0),
63
64};
65
66/* Output Mixer */
67static const struct snd_kcontrol_new wm8711_output_mixer_controls[] = {
68SOC_DAPM_SINGLE("Line Bypass Switch", WM8711_APANA, 3, 1, 0),
69SOC_DAPM_SINGLE("HiFi Playback Switch", WM8711_APANA, 4, 1, 0),
70};
71
72static const struct snd_soc_dapm_widget wm8711_dapm_widgets[] = {
73SND_SOC_DAPM_MIXER("Output Mixer", WM8711_PWR, 4, 1,
74 &wm8711_output_mixer_controls[0],
75 ARRAY_SIZE(wm8711_output_mixer_controls)),
76SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8711_PWR, 3, 1),
77SND_SOC_DAPM_OUTPUT("LOUT"),
78SND_SOC_DAPM_OUTPUT("LHPOUT"),
79SND_SOC_DAPM_OUTPUT("ROUT"),
80SND_SOC_DAPM_OUTPUT("RHPOUT"),
81};
82
83static const struct snd_soc_dapm_route intercon[] = {
84 /* output mixer */
85 {"Output Mixer", "Line Bypass Switch", "Line Input"},
86 {"Output Mixer", "HiFi Playback Switch", "DAC"},
87
88 /* outputs */
89 {"RHPOUT", NULL, "Output Mixer"},
90 {"ROUT", NULL, "Output Mixer"},
91 {"LHPOUT", NULL, "Output Mixer"},
92 {"LOUT", NULL, "Output Mixer"},
93};
94
95static int wm8711_add_widgets(struct snd_soc_codec *codec)
96{
97 snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets,
98 ARRAY_SIZE(wm8711_dapm_widgets));
99
100 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
101
102 return 0;
103}
104
105struct _coeff_div {
106 u32 mclk;
107 u32 rate;
108 u16 fs;
109 u8 sr:4;
110 u8 bosr:1;
111 u8 usb:1;
112};
113
114/* codec mclk clock divider coefficients */
115static const struct _coeff_div coeff_div[] = {
116 /* 48k */
117 {12288000, 48000, 256, 0x0, 0x0, 0x0},
118 {18432000, 48000, 384, 0x0, 0x1, 0x0},
119 {12000000, 48000, 250, 0x0, 0x0, 0x1},
120
121 /* 32k */
122 {12288000, 32000, 384, 0x6, 0x0, 0x0},
123 {18432000, 32000, 576, 0x6, 0x1, 0x0},
124 {12000000, 32000, 375, 0x6, 0x0, 0x1},
125
126 /* 8k */
127 {12288000, 8000, 1536, 0x3, 0x0, 0x0},
128 {18432000, 8000, 2304, 0x3, 0x1, 0x0},
129 {11289600, 8000, 1408, 0xb, 0x0, 0x0},
130 {16934400, 8000, 2112, 0xb, 0x1, 0x0},
131 {12000000, 8000, 1500, 0x3, 0x0, 0x1},
132
133 /* 96k */
134 {12288000, 96000, 128, 0x7, 0x0, 0x0},
135 {18432000, 96000, 192, 0x7, 0x1, 0x0},
136 {12000000, 96000, 125, 0x7, 0x0, 0x1},
137
138 /* 44.1k */
139 {11289600, 44100, 256, 0x8, 0x0, 0x0},
140 {16934400, 44100, 384, 0x8, 0x1, 0x0},
141 {12000000, 44100, 272, 0x8, 0x1, 0x1},
142
143 /* 88.2k */
144 {11289600, 88200, 128, 0xf, 0x0, 0x0},
145 {16934400, 88200, 192, 0xf, 0x1, 0x0},
146 {12000000, 88200, 136, 0xf, 0x1, 0x1},
147};
148
149static inline int get_coeff(int mclk, int rate)
150{
151 int i;
152
153 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
154 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
155 return i;
156 }
157 return 0;
158}
159
160static int wm8711_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params,
162 struct snd_soc_dai *dai)
163{
164 struct snd_soc_codec *codec = dai->codec;
165 struct wm8711_priv *wm8711 = codec->private_data;
166 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
167 int i = get_coeff(wm8711->sysclk, params_rate(params));
168 u16 srate = (coeff_div[i].sr << 2) |
169 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
170
171 snd_soc_write(codec, WM8711_SRATE, srate);
172
173 /* bit size */
174 switch (params_format(params)) {
175 case SNDRV_PCM_FORMAT_S16_LE:
176 break;
177 case SNDRV_PCM_FORMAT_S20_3LE:
178 iface |= 0x0004;
179 break;
180 case SNDRV_PCM_FORMAT_S24_LE:
181 iface |= 0x0008;
182 break;
183 }
184
185 snd_soc_write(codec, WM8711_IFACE, iface);
186 return 0;
187}
188
189static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
190 struct snd_soc_dai *dai)
191{
192 struct snd_soc_codec *codec = dai->codec;
193
194 /* set active */
195 snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
196
197 return 0;
198}
199
200static void wm8711_shutdown(struct snd_pcm_substream *substream,
201 struct snd_soc_dai *dai)
202{
203 struct snd_soc_codec *codec = dai->codec;
204
205 /* deactivate */
206 if (!codec->active) {
207 udelay(50);
208 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
209 }
210}
211
212static int wm8711_mute(struct snd_soc_dai *dai, int mute)
213{
214 struct snd_soc_codec *codec = dai->codec;
215 u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
216
217 if (mute)
218 snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
219 else
220 snd_soc_write(codec, WM8711_APDIGI, mute_reg);
221
222 return 0;
223}
224
225static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
226 int clk_id, unsigned int freq, int dir)
227{
228 struct snd_soc_codec *codec = codec_dai->codec;
229 struct wm8711_priv *wm8711 = codec->private_data;
230
231 switch (freq) {
232 case 11289600:
233 case 12000000:
234 case 12288000:
235 case 16934400:
236 case 18432000:
237 wm8711->sysclk = freq;
238 return 0;
239 }
240 return -EINVAL;
241}
242
243static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
244 unsigned int fmt)
245{
246 struct snd_soc_codec *codec = codec_dai->codec;
247 u16 iface = 0;
248
249 /* set master/slave audio interface */
250 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
251 case SND_SOC_DAIFMT_CBM_CFM:
252 iface |= 0x0040;
253 break;
254 case SND_SOC_DAIFMT_CBS_CFS:
255 break;
256 default:
257 return -EINVAL;
258 }
259
260 /* interface format */
261 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
262 case SND_SOC_DAIFMT_I2S:
263 iface |= 0x0002;
264 break;
265 case SND_SOC_DAIFMT_RIGHT_J:
266 break;
267 case SND_SOC_DAIFMT_LEFT_J:
268 iface |= 0x0001;
269 break;
270 case SND_SOC_DAIFMT_DSP_A:
271 iface |= 0x0003;
272 break;
273 case SND_SOC_DAIFMT_DSP_B:
274 iface |= 0x0013;
275 break;
276 default:
277 return -EINVAL;
278 }
279
280 /* clock inversion */
281 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
282 case SND_SOC_DAIFMT_NB_NF:
283 break;
284 case SND_SOC_DAIFMT_IB_IF:
285 iface |= 0x0090;
286 break;
287 case SND_SOC_DAIFMT_IB_NF:
288 iface |= 0x0080;
289 break;
290 case SND_SOC_DAIFMT_NB_IF:
291 iface |= 0x0010;
292 break;
293 default:
294 return -EINVAL;
295 }
296
297 /* set iface */
298 snd_soc_write(codec, WM8711_IFACE, iface);
299 return 0;
300}
301
302
303static int wm8711_set_bias_level(struct snd_soc_codec *codec,
304 enum snd_soc_bias_level level)
305{
306 u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
307
308 switch (level) {
309 case SND_SOC_BIAS_ON:
310 snd_soc_write(codec, WM8711_PWR, reg);
311 break;
312 case SND_SOC_BIAS_PREPARE:
313 break;
314 case SND_SOC_BIAS_STANDBY:
315 snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
316 break;
317 case SND_SOC_BIAS_OFF:
318 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
319 snd_soc_write(codec, WM8711_PWR, 0xffff);
320 break;
321 }
322 codec->bias_level = level;
323 return 0;
324}
325
326#define WM8711_RATES SNDRV_PCM_RATE_8000_96000
327
328#define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
329 SNDRV_PCM_FMTBIT_S24_LE)
330
331static struct snd_soc_dai_ops wm8711_ops = {
332 .prepare = wm8711_pcm_prepare,
333 .hw_params = wm8711_hw_params,
334 .shutdown = wm8711_shutdown,
335 .digital_mute = wm8711_mute,
336 .set_sysclk = wm8711_set_dai_sysclk,
337 .set_fmt = wm8711_set_dai_fmt,
338};
339
340struct snd_soc_dai wm8711_dai = {
341 .name = "WM8711",
342 .playback = {
343 .stream_name = "Playback",
344 .channels_min = 1,
345 .channels_max = 2,
346 .rates = WM8711_RATES,
347 .formats = WM8711_FORMATS,
348 },
349 .ops = &wm8711_ops,
350};
351EXPORT_SYMBOL_GPL(wm8711_dai);
352
353static int wm8711_suspend(struct platform_device *pdev, pm_message_t state)
354{
355 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
356 struct snd_soc_codec *codec = socdev->card->codec;
357
358 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
359 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
360 return 0;
361}
362
363static int wm8711_resume(struct platform_device *pdev)
364{
365 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
366 struct snd_soc_codec *codec = socdev->card->codec;
367 int i;
368 u8 data[2];
369 u16 *cache = codec->reg_cache;
370
371 /* Sync reg_cache with the hardware */
372 for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) {
373 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
374 data[1] = cache[i] & 0x00ff;
375 codec->hw_write(codec->control_data, data, 2);
376 }
377 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
378 wm8711_set_bias_level(codec, codec->suspend_bias_level);
379 return 0;
380}
381
382static int wm8711_probe(struct platform_device *pdev)
383{
384 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
385 struct snd_soc_codec *codec;
386 int ret = 0;
387
388 if (wm8711_codec == NULL) {
389 dev_err(&pdev->dev, "Codec device not registered\n");
390 return -ENODEV;
391 }
392
393 socdev->card->codec = wm8711_codec;
394 codec = wm8711_codec;
395
396 /* register pcms */
397 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
398 if (ret < 0) {
399 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
400 goto pcm_err;
401 }
402
403 snd_soc_add_controls(codec, wm8711_snd_controls,
404 ARRAY_SIZE(wm8711_snd_controls));
405 wm8711_add_widgets(codec);
406
407 return ret;
408
409pcm_err:
410 return ret;
411}
412
413/* power down chip */
414static int wm8711_remove(struct platform_device *pdev)
415{
416 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
417
418 snd_soc_free_pcms(socdev);
419 snd_soc_dapm_free(socdev);
420
421 return 0;
422}
423
424struct snd_soc_codec_device soc_codec_dev_wm8711 = {
425 .probe = wm8711_probe,
426 .remove = wm8711_remove,
427 .suspend = wm8711_suspend,
428 .resume = wm8711_resume,
429};
430EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
431
432static int wm8711_register(struct wm8711_priv *wm8711,
433 enum snd_soc_control_type control)
434{
435 int ret;
436 struct snd_soc_codec *codec = &wm8711->codec;
437 u16 reg;
438
439 if (wm8711_codec) {
440 dev_err(codec->dev, "Another WM8711 is registered\n");
441 return -EINVAL;
442 }
443
444 mutex_init(&codec->mutex);
445 INIT_LIST_HEAD(&codec->dapm_widgets);
446 INIT_LIST_HEAD(&codec->dapm_paths);
447
448 codec->private_data = wm8711;
449 codec->name = "WM8711";
450 codec->owner = THIS_MODULE;
451 codec->bias_level = SND_SOC_BIAS_OFF;
452 codec->set_bias_level = wm8711_set_bias_level;
453 codec->dai = &wm8711_dai;
454 codec->num_dai = 1;
455 codec->reg_cache_size = WM8711_CACHEREGNUM;
456 codec->reg_cache = &wm8711->reg_cache;
457
458 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
459
460 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
461 if (ret < 0) {
462 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
463 goto err;
464 }
465
466 ret = wm8711_reset(codec);
467 if (ret < 0) {
468 dev_err(codec->dev, "Failed to issue reset\n");
469 goto err;
470 }
471
472 wm8711_dai.dev = codec->dev;
473
474 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
475
476 /* Latch the update bits */
477 reg = snd_soc_read(codec, WM8711_LOUT1V);
478 snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100);
479 reg = snd_soc_read(codec, WM8711_ROUT1V);
480 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
481
482 wm8711_codec = codec;
483
484 ret = snd_soc_register_codec(codec);
485 if (ret != 0) {
486 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
487 goto err;
488 }
489
490 ret = snd_soc_register_dai(&wm8711_dai);
491 if (ret != 0) {
492 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
493 goto err_codec;
494 }
495
496 return 0;
497
498err_codec:
499 snd_soc_unregister_codec(codec);
500err:
501 kfree(wm8711);
502 return ret;
503}
504
505static void wm8711_unregister(struct wm8711_priv *wm8711)
506{
507 wm8711_set_bias_level(&wm8711->codec, SND_SOC_BIAS_OFF);
508 snd_soc_unregister_dai(&wm8711_dai);
509 snd_soc_unregister_codec(&wm8711->codec);
510 kfree(wm8711);
511 wm8711_codec = NULL;
512}
513
514#if defined(CONFIG_SPI_MASTER)
515static int __devinit wm8711_spi_probe(struct spi_device *spi)
516{
517 struct snd_soc_codec *codec;
518 struct wm8711_priv *wm8711;
519
520 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
521 if (wm8711 == NULL)
522 return -ENOMEM;
523
524 codec = &wm8711->codec;
525 codec->control_data = spi;
526 codec->dev = &spi->dev;
527
528 dev_set_drvdata(&spi->dev, wm8711);
529
530 return wm8711_register(wm8711, SND_SOC_SPI);
531}
532
533static int __devexit wm8711_spi_remove(struct spi_device *spi)
534{
535 struct wm8711_priv *wm8711 = dev_get_drvdata(&spi->dev);
536
537 wm8711_unregister(wm8711);
538
539 return 0;
540}
541
542static struct spi_driver wm8711_spi_driver = {
543 .driver = {
544 .name = "wm8711",
545 .bus = &spi_bus_type,
546 .owner = THIS_MODULE,
547 },
548 .probe = wm8711_spi_probe,
549 .remove = __devexit_p(wm8711_spi_remove),
550};
551#endif /* CONFIG_SPI_MASTER */
552
553#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
554static __devinit int wm8711_i2c_probe(struct i2c_client *i2c,
555 const struct i2c_device_id *id)
556{
557 struct wm8711_priv *wm8711;
558 struct snd_soc_codec *codec;
559
560 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
561 if (wm8711 == NULL)
562 return -ENOMEM;
563
564 codec = &wm8711->codec;
565 codec->hw_write = (hw_write_t)i2c_master_send;
566
567 i2c_set_clientdata(i2c, wm8711);
568 codec->control_data = i2c;
569
570 codec->dev = &i2c->dev;
571
572 return wm8711_register(wm8711, SND_SOC_I2C);
573}
574
575static __devexit int wm8711_i2c_remove(struct i2c_client *client)
576{
577 struct wm8711_priv *wm8711 = i2c_get_clientdata(client);
578 wm8711_unregister(wm8711);
579 return 0;
580}
581
582static const struct i2c_device_id wm8711_i2c_id[] = {
583 { "wm8711", 0 },
584 { }
585};
586MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
587
588static struct i2c_driver wm8711_i2c_driver = {
589 .driver = {
590 .name = "WM8711 I2C Codec",
591 .owner = THIS_MODULE,
592 },
593 .probe = wm8711_i2c_probe,
594 .remove = __devexit_p(wm8711_i2c_remove),
595 .id_table = wm8711_i2c_id,
596};
597#endif
598
599static int __init wm8711_modinit(void)
600{
601 int ret;
602#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
603 ret = i2c_add_driver(&wm8711_i2c_driver);
604 if (ret != 0) {
605 printk(KERN_ERR "Failed to register WM8711 I2C driver: %d\n",
606 ret);
607 }
608#endif
609#if defined(CONFIG_SPI_MASTER)
610 ret = spi_register_driver(&wm8711_spi_driver);
611 if (ret != 0) {
612 printk(KERN_ERR "Failed to register WM8711 SPI driver: %d\n",
613 ret);
614 }
615#endif
616 return 0;
617}
618module_init(wm8711_modinit);
619
620static void __exit wm8711_exit(void)
621{
622#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
623 i2c_del_driver(&wm8711_i2c_driver);
624#endif
625#if defined(CONFIG_SPI_MASTER)
626 spi_unregister_driver(&wm8711_spi_driver);
627#endif
628}
629module_exit(wm8711_exit);
630
631MODULE_DESCRIPTION("ASoC WM8711 driver");
632MODULE_AUTHOR("Mike Arthur");
633MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8711.h b/sound/soc/codecs/wm8711.h
new file mode 100644
index 000000000000..381e84a43816
--- /dev/null
+++ b/sound/soc/codecs/wm8711.h
@@ -0,0 +1,42 @@
1/*
2 * wm8711.h -- WM8711 Soc Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _WM8711_H
16#define _WM8711_H
17
18/* WM8711 register space */
19
20#define WM8711_LOUT1V 0x02
21#define WM8711_ROUT1V 0x03
22#define WM8711_APANA 0x04
23#define WM8711_APDIGI 0x05
24#define WM8711_PWR 0x06
25#define WM8711_IFACE 0x07
26#define WM8711_SRATE 0x08
27#define WM8711_ACTIVE 0x09
28#define WM8711_RESET 0x0f
29
30#define WM8711_CACHEREGNUM 8
31
32#define WM8711_SYSCLK 0
33#define WM8711_DAI 0
34
35struct wm8711_setup_data {
36 unsigned short i2c_address;
37};
38
39extern struct snd_soc_dai wm8711_dai;
40extern struct snd_soc_codec_device soc_codec_dev_wm8711;
41
42#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
new file mode 100644
index 000000000000..d8ffbd641d71
--- /dev/null
+++ b/sound/soc/codecs/wm8727.c
@@ -0,0 +1,135 @@
1/*
2 * wm8727.c
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/ac97_codec.h>
22#include <sound/initval.h>
23#include <sound/soc.h>
24
25#include "wm8727.h"
26/*
27 * Note this is a simple chip with no configuration interface, sample rate is
28 * determined automatically by examining the Master clock and Bit clock ratios
29 */
30#define WM8727_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
31 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
32 SNDRV_PCM_RATE_192000)
33
34
35struct snd_soc_dai wm8727_dai = {
36 .name = "WM8727",
37 .playback = {
38 .stream_name = "Playback",
39 .channels_min = 2,
40 .channels_max = 2,
41 .rates = WM8727_RATES,
42 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
43 },
44};
45EXPORT_SYMBOL_GPL(wm8727_dai);
46
47static int wm8727_soc_probe(struct platform_device *pdev)
48{
49 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
50 struct snd_soc_codec *codec;
51 int ret = 0;
52
53 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
54 if (codec == NULL)
55 return -ENOMEM;
56 mutex_init(&codec->mutex);
57 codec->name = "WM8727";
58 codec->owner = THIS_MODULE;
59 codec->dai = &wm8727_dai;
60 codec->num_dai = 1;
61 socdev->card->codec = codec;
62 INIT_LIST_HEAD(&codec->dapm_widgets);
63 INIT_LIST_HEAD(&codec->dapm_paths);
64
65 /* register pcms */
66 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
67 if (ret < 0) {
68 printk(KERN_ERR "wm8727: failed to create pcms\n");
69 goto pcm_err;
70 }
71
72 return ret;
73
74pcm_err:
75 kfree(socdev->card->codec);
76 socdev->card->codec = NULL;
77 return ret;
78}
79
80static int wm8727_soc_remove(struct platform_device *pdev)
81{
82 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
83 struct snd_soc_codec *codec = socdev->card->codec;
84
85 if (codec == NULL)
86 return 0;
87 snd_soc_free_pcms(socdev);
88 kfree(codec);
89 return 0;
90}
91
92struct snd_soc_codec_device soc_codec_dev_wm8727 = {
93 .probe = wm8727_soc_probe,
94 .remove = wm8727_soc_remove,
95};
96EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
97
98
99static __devinit int wm8727_platform_probe(struct platform_device *pdev)
100{
101 wm8727_dai.dev = &pdev->dev;
102 return snd_soc_register_dai(&wm8727_dai);
103}
104
105static int __devexit wm8727_platform_remove(struct platform_device *pdev)
106{
107 snd_soc_unregister_dai(&wm8727_dai);
108 return 0;
109}
110
111static struct platform_driver wm8727_codec_driver = {
112 .driver = {
113 .name = "wm8727-codec",
114 .owner = THIS_MODULE,
115 },
116
117 .probe = wm8727_platform_probe,
118 .remove = __devexit_p(wm8727_platform_remove),
119};
120
121static int __init wm8727_init(void)
122{
123 return platform_driver_register(&wm8727_codec_driver);
124}
125module_init(wm8727_init);
126
127static void __exit wm8727_exit(void)
128{
129 platform_driver_unregister(&wm8727_codec_driver);
130}
131module_exit(wm8727_exit);
132
133MODULE_DESCRIPTION("ASoC wm8727 driver");
134MODULE_AUTHOR("Neil Jones");
135MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8727.h b/sound/soc/codecs/wm8727.h
new file mode 100644
index 000000000000..ee19aa71bcdc
--- /dev/null
+++ b/sound/soc/codecs/wm8727.h
@@ -0,0 +1,21 @@
1/*
2 * wm8727.h
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#ifndef WM8727_H_
16#define WM8727_H_
17
18extern struct snd_soc_dai wm8727_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8727;
20
21#endif /* WM8727_H_ */
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 16e969a762c3..3fb653ba363a 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -74,8 +74,6 @@ static int wm8728_add_widgets(struct snd_soc_codec *codec)
74 74
75 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 75 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
76 76
77 snd_soc_dapm_new_widgets(codec);
78
79 return 0; 77 return 0;
80} 78}
81 79
@@ -287,17 +285,9 @@ static int wm8728_init(struct snd_soc_device *socdev,
287 snd_soc_add_controls(codec, wm8728_snd_controls, 285 snd_soc_add_controls(codec, wm8728_snd_controls,
288 ARRAY_SIZE(wm8728_snd_controls)); 286 ARRAY_SIZE(wm8728_snd_controls));
289 wm8728_add_widgets(codec); 287 wm8728_add_widgets(codec);
290 ret = snd_soc_init_card(socdev);
291 if (ret < 0) {
292 printk(KERN_ERR "wm8728: failed to register card\n");
293 goto card_err;
294 }
295 288
296 return ret; 289 return ret;
297 290
298card_err:
299 snd_soc_free_pcms(socdev);
300 snd_soc_dapm_free(socdev);
301err: 291err:
302 kfree(codec->reg_cache); 292 kfree(codec->reg_cache);
303 return ret; 293 return ret;
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index d3fd4f28d96e..3a497810f939 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
@@ -33,9 +34,18 @@
33static struct snd_soc_codec *wm8731_codec; 34static struct snd_soc_codec *wm8731_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8731; 35struct snd_soc_codec_device soc_codec_dev_wm8731;
35 36
37#define WM8731_NUM_SUPPLIES 4
38static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
39 "AVDD",
40 "HPVDD",
41 "DCVDD",
42 "DBVDD",
43};
44
36/* codec private data */ 45/* codec private data */
37struct wm8731_priv { 46struct wm8731_priv {
38 struct snd_soc_codec codec; 47 struct snd_soc_codec codec;
48 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
39 u16 reg_cache[WM8731_CACHEREGNUM]; 49 u16 reg_cache[WM8731_CACHEREGNUM];
40 unsigned int sysclk; 50 unsigned int sysclk;
41}; 51};
@@ -149,7 +159,6 @@ static int wm8731_add_widgets(struct snd_soc_codec *codec)
149 159
150 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 160 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
151 161
152 snd_soc_dapm_new_widgets(codec);
153 return 0; 162 return 0;
154} 163}
155 164
@@ -422,9 +431,12 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
422{ 431{
423 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 432 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
424 struct snd_soc_codec *codec = socdev->card->codec; 433 struct snd_soc_codec *codec = socdev->card->codec;
434 struct wm8731_priv *wm8731 = codec->private_data;
425 435
426 snd_soc_write(codec, WM8731_ACTIVE, 0x0); 436 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
427 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 437 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
438 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
439 wm8731->supplies);
428 return 0; 440 return 0;
429} 441}
430 442
@@ -432,10 +444,16 @@ static int wm8731_resume(struct platform_device *pdev)
432{ 444{
433 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 445 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
434 struct snd_soc_codec *codec = socdev->card->codec; 446 struct snd_soc_codec *codec = socdev->card->codec;
435 int i; 447 struct wm8731_priv *wm8731 = codec->private_data;
448 int i, ret;
436 u8 data[2]; 449 u8 data[2];
437 u16 *cache = codec->reg_cache; 450 u16 *cache = codec->reg_cache;
438 451
452 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
453 wm8731->supplies);
454 if (ret != 0)
455 return ret;
456
439 /* Sync reg_cache with the hardware */ 457 /* Sync reg_cache with the hardware */
440 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 458 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
441 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 459 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
@@ -444,6 +462,7 @@ static int wm8731_resume(struct platform_device *pdev)
444 } 462 }
445 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 463 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
446 wm8731_set_bias_level(codec, codec->suspend_bias_level); 464 wm8731_set_bias_level(codec, codec->suspend_bias_level);
465
447 return 0; 466 return 0;
448} 467}
449#else 468#else
@@ -475,17 +494,9 @@ static int wm8731_probe(struct platform_device *pdev)
475 snd_soc_add_controls(codec, wm8731_snd_controls, 494 snd_soc_add_controls(codec, wm8731_snd_controls,
476 ARRAY_SIZE(wm8731_snd_controls)); 495 ARRAY_SIZE(wm8731_snd_controls));
477 wm8731_add_widgets(codec); 496 wm8731_add_widgets(codec);
478 ret = snd_soc_init_card(socdev);
479 if (ret < 0) {
480 dev_err(codec->dev, "failed to register card: %d\n", ret);
481 goto card_err;
482 }
483 497
484 return ret; 498 return ret;
485 499
486card_err:
487 snd_soc_free_pcms(socdev);
488 snd_soc_dapm_free(socdev);
489pcm_err: 500pcm_err:
490 return ret; 501 return ret;
491} 502}
@@ -512,7 +523,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
512static int wm8731_register(struct wm8731_priv *wm8731, 523static int wm8731_register(struct wm8731_priv *wm8731,
513 enum snd_soc_control_type control) 524 enum snd_soc_control_type control)
514{ 525{
515 int ret; 526 int ret, i;
516 struct snd_soc_codec *codec = &wm8731->codec; 527 struct snd_soc_codec *codec = &wm8731->codec;
517 528
518 if (wm8731_codec) { 529 if (wm8731_codec) {
@@ -543,10 +554,27 @@ static int wm8731_register(struct wm8731_priv *wm8731,
543 goto err; 554 goto err;
544 } 555 }
545 556
557 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
558 wm8731->supplies[i].supply = wm8731_supply_names[i];
559
560 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8731->supplies),
561 wm8731->supplies);
562 if (ret != 0) {
563 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
564 goto err;
565 }
566
567 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
568 wm8731->supplies);
569 if (ret != 0) {
570 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
571 goto err_regulator_get;
572 }
573
546 ret = wm8731_reset(codec); 574 ret = wm8731_reset(codec);
547 if (ret < 0) { 575 if (ret < 0) {
548 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 576 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
549 goto err; 577 goto err_regulator_enable;
550 } 578 }
551 579
552 wm8731_dai.dev = codec->dev; 580 wm8731_dai.dev = codec->dev;
@@ -567,7 +595,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
567 ret = snd_soc_register_codec(codec); 595 ret = snd_soc_register_codec(codec);
568 if (ret != 0) { 596 if (ret != 0) {
569 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 597 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
570 goto err; 598 goto err_regulator_enable;
571 } 599 }
572 600
573 ret = snd_soc_register_dai(&wm8731_dai); 601 ret = snd_soc_register_dai(&wm8731_dai);
@@ -581,6 +609,10 @@ static int wm8731_register(struct wm8731_priv *wm8731,
581 609
582err_codec: 610err_codec:
583 snd_soc_unregister_codec(codec); 611 snd_soc_unregister_codec(codec);
612err_regulator_enable:
613 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
614err_regulator_get:
615 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
584err: 616err:
585 kfree(wm8731); 617 kfree(wm8731);
586 return ret; 618 return ret;
@@ -591,6 +623,8 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
591 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 623 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
592 snd_soc_unregister_dai(&wm8731_dai); 624 snd_soc_unregister_dai(&wm8731_dai);
593 snd_soc_unregister_codec(&wm8731->codec); 625 snd_soc_unregister_codec(&wm8731->codec);
626 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
627 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
594 kfree(wm8731); 628 kfree(wm8731);
595 wm8731_codec = NULL; 629 wm8731_codec = NULL;
596} 630}
@@ -623,21 +657,6 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
623 return 0; 657 return 0;
624} 658}
625 659
626#ifdef CONFIG_PM
627static int wm8731_spi_suspend(struct spi_device *spi, pm_message_t msg)
628{
629 return snd_soc_suspend_device(&spi->dev);
630}
631
632static int wm8731_spi_resume(struct spi_device *spi)
633{
634 return snd_soc_resume_device(&spi->dev);
635}
636#else
637#define wm8731_spi_suspend NULL
638#define wm8731_spi_resume NULL
639#endif
640
641static struct spi_driver wm8731_spi_driver = { 660static struct spi_driver wm8731_spi_driver = {
642 .driver = { 661 .driver = {
643 .name = "wm8731", 662 .name = "wm8731",
@@ -645,8 +664,6 @@ static struct spi_driver wm8731_spi_driver = {
645 .owner = THIS_MODULE, 664 .owner = THIS_MODULE,
646 }, 665 },
647 .probe = wm8731_spi_probe, 666 .probe = wm8731_spi_probe,
648 .suspend = wm8731_spi_suspend,
649 .resume = wm8731_spi_resume,
650 .remove = __devexit_p(wm8731_spi_remove), 667 .remove = __devexit_p(wm8731_spi_remove),
651}; 668};
652#endif /* CONFIG_SPI_MASTER */ 669#endif /* CONFIG_SPI_MASTER */
@@ -679,21 +696,6 @@ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
679 return 0; 696 return 0;
680} 697}
681 698
682#ifdef CONFIG_PM
683static int wm8731_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
684{
685 return snd_soc_suspend_device(&i2c->dev);
686}
687
688static int wm8731_i2c_resume(struct i2c_client *i2c)
689{
690 return snd_soc_resume_device(&i2c->dev);
691}
692#else
693#define wm8731_i2c_suspend NULL
694#define wm8731_i2c_resume NULL
695#endif
696
697static const struct i2c_device_id wm8731_i2c_id[] = { 699static const struct i2c_device_id wm8731_i2c_id[] = {
698 { "wm8731", 0 }, 700 { "wm8731", 0 },
699 { } 701 { }
@@ -707,8 +709,6 @@ static struct i2c_driver wm8731_i2c_driver = {
707 }, 709 },
708 .probe = wm8731_i2c_probe, 710 .probe = wm8731_i2c_probe,
709 .remove = __devexit_p(wm8731_i2c_remove), 711 .remove = __devexit_p(wm8731_i2c_remove),
710 .suspend = wm8731_i2c_suspend,
711 .resume = wm8731_i2c_resume,
712 .id_table = wm8731_i2c_id, 712 .id_table = wm8731_i2c_id,
713}; 713};
714#endif 714#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 4ba1e7e93fb4..475c67ac7818 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -403,7 +403,6 @@ static int wm8750_add_widgets(struct snd_soc_codec *codec)
403 403
404 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 404 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
405 405
406 snd_soc_dapm_new_widgets(codec);
407 return 0; 406 return 0;
408} 407}
409 408
@@ -772,16 +771,8 @@ static int wm8750_init(struct snd_soc_device *socdev,
772 snd_soc_add_controls(codec, wm8750_snd_controls, 771 snd_soc_add_controls(codec, wm8750_snd_controls,
773 ARRAY_SIZE(wm8750_snd_controls)); 772 ARRAY_SIZE(wm8750_snd_controls));
774 wm8750_add_widgets(codec); 773 wm8750_add_widgets(codec);
775 ret = snd_soc_init_card(socdev);
776 if (ret < 0) {
777 printk(KERN_ERR "wm8750: failed to register card\n");
778 goto card_err;
779 }
780 return ret; 774 return ret;
781 775
782card_err:
783 snd_soc_free_pcms(socdev);
784 snd_soc_dapm_free(socdev);
785err: 776err:
786 kfree(codec->reg_cache); 777 kfree(codec->reg_cache);
787 return ret; 778 return ret;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5ad677ce80da..d6850dacda29 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -673,7 +673,6 @@ static int wm8753_add_widgets(struct snd_soc_codec *codec)
673 673
674 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 674 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
675 675
676 snd_soc_dapm_new_widgets(codec);
677 return 0; 676 return 0;
678} 677}
679 678
@@ -724,8 +723,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
724 pll_div->k = K; 723 pll_div->k = K;
725} 724}
726 725
727static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, 726static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
728 int pll_id, unsigned int freq_in, unsigned int freq_out) 727 int source, unsigned int freq_in, unsigned int freq_out)
729{ 728{
730 u16 reg, enable; 729 u16 reg, enable;
731 int offset; 730 int offset;
@@ -1583,18 +1582,9 @@ static int wm8753_probe(struct platform_device *pdev)
1583 snd_soc_add_controls(codec, wm8753_snd_controls, 1582 snd_soc_add_controls(codec, wm8753_snd_controls,
1584 ARRAY_SIZE(wm8753_snd_controls)); 1583 ARRAY_SIZE(wm8753_snd_controls));
1585 wm8753_add_widgets(codec); 1584 wm8753_add_widgets(codec);
1586 ret = snd_soc_init_card(socdev);
1587 if (ret < 0) {
1588 printk(KERN_ERR "wm8753: failed to register card\n");
1589 goto card_err;
1590 }
1591 1585
1592 return 0; 1586 return 0;
1593 1587
1594card_err:
1595 snd_soc_free_pcms(socdev);
1596 snd_soc_dapm_free(socdev);
1597
1598pcm_err: 1588pcm_err:
1599 return ret; 1589 return ret;
1600} 1590}
@@ -1767,21 +1757,6 @@ static int wm8753_i2c_remove(struct i2c_client *client)
1767 return 0; 1757 return 0;
1768} 1758}
1769 1759
1770#ifdef CONFIG_PM
1771static int wm8753_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1772{
1773 return snd_soc_suspend_device(&client->dev);
1774}
1775
1776static int wm8753_i2c_resume(struct i2c_client *client)
1777{
1778 return snd_soc_resume_device(&client->dev);
1779}
1780#else
1781#define wm8753_i2c_suspend NULL
1782#define wm8753_i2c_resume NULL
1783#endif
1784
1785static const struct i2c_device_id wm8753_i2c_id[] = { 1760static const struct i2c_device_id wm8753_i2c_id[] = {
1786 { "wm8753", 0 }, 1761 { "wm8753", 0 },
1787 { } 1762 { }
@@ -1795,8 +1770,6 @@ static struct i2c_driver wm8753_i2c_driver = {
1795 }, 1770 },
1796 .probe = wm8753_i2c_probe, 1771 .probe = wm8753_i2c_probe,
1797 .remove = wm8753_i2c_remove, 1772 .remove = wm8753_i2c_remove,
1798 .suspend = wm8753_i2c_suspend,
1799 .resume = wm8753_i2c_resume,
1800 .id_table = wm8753_i2c_id, 1773 .id_table = wm8753_i2c_id,
1801}; 1774};
1802#endif 1775#endif
@@ -1852,22 +1825,6 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1852 return 0; 1825 return 0;
1853} 1826}
1854 1827
1855#ifdef CONFIG_PM
1856static int wm8753_spi_suspend(struct spi_device *spi, pm_message_t msg)
1857{
1858 return snd_soc_suspend_device(&spi->dev);
1859}
1860
1861static int wm8753_spi_resume(struct spi_device *spi)
1862{
1863 return snd_soc_resume_device(&spi->dev);
1864}
1865
1866#else
1867#define wm8753_spi_suspend NULL
1868#define wm8753_spi_resume NULL
1869#endif
1870
1871static struct spi_driver wm8753_spi_driver = { 1828static struct spi_driver wm8753_spi_driver = {
1872 .driver = { 1829 .driver = {
1873 .name = "wm8753", 1830 .name = "wm8753",
@@ -1876,8 +1833,6 @@ static struct spi_driver wm8753_spi_driver = {
1876 }, 1833 },
1877 .probe = wm8753_spi_probe, 1834 .probe = wm8753_spi_probe,
1878 .remove = __devexit_p(wm8753_spi_remove), 1835 .remove = __devexit_p(wm8753_spi_remove),
1879 .suspend = wm8753_spi_suspend,
1880 .resume = wm8753_spi_resume,
1881}; 1836};
1882#endif 1837#endif
1883 1838
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index a9829aa26e53..ab2c0da18091 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -447,17 +447,8 @@ static int wm8776_probe(struct platform_device *pdev)
447 ARRAY_SIZE(wm8776_dapm_widgets)); 447 ARRAY_SIZE(wm8776_dapm_widgets));
448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
449 449
450 ret = snd_soc_init_card(socdev);
451 if (ret < 0) {
452 dev_err(codec->dev, "failed to register card: %d\n", ret);
453 goto card_err;
454 }
455
456 return ret; 450 return ret;
457 451
458card_err:
459 snd_soc_free_pcms(socdev);
460 snd_soc_dapm_free(socdev);
461pcm_err: 452pcm_err:
462 return ret; 453 return ret;
463} 454}
@@ -616,21 +607,6 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi)
616 return 0; 607 return 0;
617} 608}
618 609
619#ifdef CONFIG_PM
620static int wm8776_spi_suspend(struct spi_device *spi, pm_message_t msg)
621{
622 return snd_soc_suspend_device(&spi->dev);
623}
624
625static int wm8776_spi_resume(struct spi_device *spi)
626{
627 return snd_soc_resume_device(&spi->dev);
628}
629#else
630#define wm8776_spi_suspend NULL
631#define wm8776_spi_resume NULL
632#endif
633
634static struct spi_driver wm8776_spi_driver = { 610static struct spi_driver wm8776_spi_driver = {
635 .driver = { 611 .driver = {
636 .name = "wm8776", 612 .name = "wm8776",
@@ -638,8 +614,6 @@ static struct spi_driver wm8776_spi_driver = {
638 .owner = THIS_MODULE, 614 .owner = THIS_MODULE,
639 }, 615 },
640 .probe = wm8776_spi_probe, 616 .probe = wm8776_spi_probe,
641 .suspend = wm8776_spi_suspend,
642 .resume = wm8776_spi_resume,
643 .remove = __devexit_p(wm8776_spi_remove), 617 .remove = __devexit_p(wm8776_spi_remove),
644}; 618};
645#endif /* CONFIG_SPI_MASTER */ 619#endif /* CONFIG_SPI_MASTER */
@@ -673,21 +647,6 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client)
673 return 0; 647 return 0;
674} 648}
675 649
676#ifdef CONFIG_PM
677static int wm8776_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
678{
679 return snd_soc_suspend_device(&i2c->dev);
680}
681
682static int wm8776_i2c_resume(struct i2c_client *i2c)
683{
684 return snd_soc_resume_device(&i2c->dev);
685}
686#else
687#define wm8776_i2c_suspend NULL
688#define wm8776_i2c_resume NULL
689#endif
690
691static const struct i2c_device_id wm8776_i2c_id[] = { 650static const struct i2c_device_id wm8776_i2c_id[] = {
692 { "wm8776", 0 }, 651 { "wm8776", 0 },
693 { } 652 { }
@@ -701,8 +660,6 @@ static struct i2c_driver wm8776_i2c_driver = {
701 }, 660 },
702 .probe = wm8776_i2c_probe, 661 .probe = wm8776_i2c_probe,
703 .remove = __devexit_p(wm8776_i2c_remove), 662 .remove = __devexit_p(wm8776_i2c_remove),
704 .suspend = wm8776_i2c_suspend,
705 .resume = wm8776_i2c_resume,
706 .id_table = wm8776_i2c_id, 663 .id_table = wm8776_i2c_id,
707}; 664};
708#endif 665#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5e9c855c0036..c9438dd62df3 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -618,8 +618,6 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
618 618
619 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 619 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
620 620
621 snd_soc_dapm_new_widgets(codec);
622
623 return 0; 621 return 0;
624} 622}
625 623
@@ -814,8 +812,8 @@ reenable:
814 return 0; 812 return 0;
815} 813}
816 814
817static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, 815static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
818 int pll_id, unsigned int freq_in, unsigned int freq_out) 816 int source, unsigned int freq_in, unsigned int freq_out)
819{ 817{
820 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out); 818 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
821} 819}
@@ -1312,21 +1310,6 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1312 return 0; 1310 return 0;
1313} 1311}
1314 1312
1315#ifdef CONFIG_PM
1316static int wm8900_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1317{
1318 return snd_soc_suspend_device(&client->dev);
1319}
1320
1321static int wm8900_i2c_resume(struct i2c_client *client)
1322{
1323 return snd_soc_resume_device(&client->dev);
1324}
1325#else
1326#define wm8900_i2c_suspend NULL
1327#define wm8900_i2c_resume NULL
1328#endif
1329
1330static const struct i2c_device_id wm8900_i2c_id[] = { 1313static const struct i2c_device_id wm8900_i2c_id[] = {
1331 { "wm8900", 0 }, 1314 { "wm8900", 0 },
1332 { } 1315 { }
@@ -1340,8 +1323,6 @@ static struct i2c_driver wm8900_i2c_driver = {
1340 }, 1323 },
1341 .probe = wm8900_i2c_probe, 1324 .probe = wm8900_i2c_probe,
1342 .remove = __devexit_p(wm8900_i2c_remove), 1325 .remove = __devexit_p(wm8900_i2c_remove),
1343 .suspend = wm8900_i2c_suspend,
1344 .resume = wm8900_i2c_resume,
1345 .id_table = wm8900_i2c_id, 1326 .id_table = wm8900_i2c_id,
1346}; 1327};
1347 1328
@@ -1370,17 +1351,6 @@ static int wm8900_probe(struct platform_device *pdev)
1370 ARRAY_SIZE(wm8900_snd_controls)); 1351 ARRAY_SIZE(wm8900_snd_controls));
1371 wm8900_add_widgets(codec); 1352 wm8900_add_widgets(codec);
1372 1353
1373 ret = snd_soc_init_card(socdev);
1374 if (ret < 0) {
1375 dev_err(&pdev->dev, "Failed to register card\n");
1376 goto card_err;
1377 }
1378
1379 return ret;
1380
1381card_err:
1382 snd_soc_free_pcms(socdev);
1383 snd_soc_dapm_free(socdev);
1384pcm_err: 1354pcm_err:
1385 return ret; 1355 return ret;
1386} 1356}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fe1307b500cf..ce5515e3f2b0 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -607,7 +607,7 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
607SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), 607SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
608SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), 608SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
609SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), 609SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
610SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1, 610SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1,
611 drc_tlv_thresh), 611 drc_tlv_thresh),
612SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp), 612SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
613SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min), 613SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
@@ -617,11 +617,11 @@ SOC_ENUM("DRC Decay Rate", drc_decay),
617SOC_ENUM("DRC FF Delay", drc_ff_delay), 617SOC_ENUM("DRC FF Delay", drc_ff_delay),
618SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0), 618SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
619SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0), 619SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
620SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max), 620SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
621SOC_ENUM("DRC QR Decay Rate", drc_qr_decay), 621SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
622SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0), 622SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
623SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0), 623SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
624SOC_ENUM("DRC Smoothing Threashold", drc_smoothing), 624SOC_ENUM("DRC Smoothing Threshold", drc_smoothing),
625SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), 625SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
626 626
627SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, 627SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
@@ -919,8 +919,6 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
919 919
920 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 920 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
921 921
922 snd_soc_dapm_new_widgets(codec);
923
924 return 0; 922 return 0;
925} 923}
926 924
@@ -1655,21 +1653,6 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1655 return 0; 1653 return 0;
1656} 1654}
1657 1655
1658#ifdef CONFIG_PM
1659static int wm8903_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1660{
1661 return snd_soc_suspend_device(&client->dev);
1662}
1663
1664static int wm8903_i2c_resume(struct i2c_client *client)
1665{
1666 return snd_soc_resume_device(&client->dev);
1667}
1668#else
1669#define wm8903_i2c_suspend NULL
1670#define wm8903_i2c_resume NULL
1671#endif
1672
1673/* i2c codec control layer */ 1656/* i2c codec control layer */
1674static const struct i2c_device_id wm8903_i2c_id[] = { 1657static const struct i2c_device_id wm8903_i2c_id[] = {
1675 { "wm8903", 0 }, 1658 { "wm8903", 0 },
@@ -1684,8 +1667,6 @@ static struct i2c_driver wm8903_i2c_driver = {
1684 }, 1667 },
1685 .probe = wm8903_i2c_probe, 1668 .probe = wm8903_i2c_probe,
1686 .remove = __devexit_p(wm8903_i2c_remove), 1669 .remove = __devexit_p(wm8903_i2c_remove),
1687 .suspend = wm8903_i2c_suspend,
1688 .resume = wm8903_i2c_resume,
1689 .id_table = wm8903_i2c_id, 1670 .id_table = wm8903_i2c_id,
1690}; 1671};
1691 1672
@@ -1712,17 +1693,8 @@ static int wm8903_probe(struct platform_device *pdev)
1712 ARRAY_SIZE(wm8903_snd_controls)); 1693 ARRAY_SIZE(wm8903_snd_controls));
1713 wm8903_add_widgets(socdev->card->codec); 1694 wm8903_add_widgets(socdev->card->codec);
1714 1695
1715 ret = snd_soc_init_card(socdev);
1716 if (ret < 0) {
1717 dev_err(&pdev->dev, "wm8903: failed to register card\n");
1718 goto card_err;
1719 }
1720
1721 return ret; 1696 return ret;
1722 1697
1723card_err:
1724 snd_soc_free_pcms(socdev);
1725 snd_soc_dapm_free(socdev);
1726err: 1698err:
1727 return ret; 1699 return ret;
1728} 1700}
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 1ef2454c5205..3d850b97037a 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -298,7 +298,6 @@ static int wm8940_add_widgets(struct snd_soc_codec *codec)
298 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 298 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
299 if (ret) 299 if (ret)
300 goto error_ret; 300 goto error_ret;
301 ret = snd_soc_dapm_new_widgets(codec);
302 301
303error_ret: 302error_ret:
304 return ret; 303 return ret;
@@ -536,8 +535,8 @@ static void pll_factors(unsigned int target, unsigned int source)
536} 535}
537 536
538/* Untested at the moment */ 537/* Untested at the moment */
539static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, 538static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
540 int pll_id, unsigned int freq_in, unsigned int freq_out) 539 int source, unsigned int freq_in, unsigned int freq_out)
541{ 540{
542 struct snd_soc_codec *codec = codec_dai->codec; 541 struct snd_soc_codec *codec = codec_dai->codec;
543 u16 reg; 542 u16 reg;
@@ -731,12 +730,6 @@ static int wm8940_probe(struct platform_device *pdev)
731 if (ret) 730 if (ret)
732 goto error_free_pcms; 731 goto error_free_pcms;
733 732
734 ret = snd_soc_init_card(socdev);
735 if (ret < 0) {
736 dev_err(codec->dev, "failed to register card: %d\n", ret);
737 goto error_free_pcms;
738 }
739
740 return ret; 733 return ret;
741 734
742error_free_pcms: 735error_free_pcms:
@@ -877,21 +870,6 @@ static int __devexit wm8940_i2c_remove(struct i2c_client *client)
877 return 0; 870 return 0;
878} 871}
879 872
880#ifdef CONFIG_PM
881static int wm8940_i2c_suspend(struct i2c_client *client, pm_message_t msg)
882{
883 return snd_soc_suspend_device(&client->dev);
884}
885
886static int wm8940_i2c_resume(struct i2c_client *client)
887{
888 return snd_soc_resume_device(&client->dev);
889}
890#else
891#define wm8940_i2c_suspend NULL
892#define wm8940_i2c_resume NULL
893#endif
894
895static const struct i2c_device_id wm8940_i2c_id[] = { 873static const struct i2c_device_id wm8940_i2c_id[] = {
896 { "wm8940", 0 }, 874 { "wm8940", 0 },
897 { } 875 { }
@@ -905,8 +883,6 @@ static struct i2c_driver wm8940_i2c_driver = {
905 }, 883 },
906 .probe = wm8940_i2c_probe, 884 .probe = wm8940_i2c_probe,
907 .remove = __devexit_p(wm8940_i2c_remove), 885 .remove = __devexit_p(wm8940_i2c_remove),
908 .suspend = wm8940_i2c_suspend,
909 .resume = wm8940_i2c_resume,
910 .id_table = wm8940_i2c_id, 886 .id_table = wm8940_i2c_id,
911}; 887};
912 888
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f59703be61c8..d07bcc1e1c60 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -307,7 +307,6 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
307 307
308 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 308 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
309 309
310 snd_soc_dapm_new_widgets(codec);
311 return 0; 310 return 0;
312} 311}
313 312
@@ -540,8 +539,8 @@ static int pll_factors(unsigned int source, unsigned int target,
540 return 0; 539 return 0;
541} 540}
542 541
543static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, 542static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
544 int pll_id, unsigned int freq_in, unsigned int freq_out) 543 int source, unsigned int freq_in, unsigned int freq_out)
545{ 544{
546 struct snd_soc_codec *codec = codec_dai->codec; 545 struct snd_soc_codec *codec = codec_dai->codec;
547 u16 reg; 546 u16 reg;
@@ -713,17 +712,9 @@ static int wm8960_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, wm8960_snd_controls, 712 snd_soc_add_controls(codec, wm8960_snd_controls,
714 ARRAY_SIZE(wm8960_snd_controls)); 713 ARRAY_SIZE(wm8960_snd_controls));
715 wm8960_add_widgets(codec); 714 wm8960_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 715
722 return ret; 716 return ret;
723 717
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 718pcm_err:
728 return ret; 719 return ret;
729} 720}
@@ -883,21 +874,6 @@ static __devexit int wm8960_i2c_remove(struct i2c_client *client)
883 return 0; 874 return 0;
884} 875}
885 876
886#ifdef CONFIG_PM
887static int wm8960_i2c_suspend(struct i2c_client *client, pm_message_t msg)
888{
889 return snd_soc_suspend_device(&client->dev);
890}
891
892static int wm8960_i2c_resume(struct i2c_client *client)
893{
894 return snd_soc_resume_device(&client->dev);
895}
896#else
897#define wm8960_i2c_suspend NULL
898#define wm8960_i2c_resume NULL
899#endif
900
901static const struct i2c_device_id wm8960_i2c_id[] = { 877static const struct i2c_device_id wm8960_i2c_id[] = {
902 { "wm8960", 0 }, 878 { "wm8960", 0 },
903 { } 879 { }
@@ -911,8 +887,6 @@ static struct i2c_driver wm8960_i2c_driver = {
911 }, 887 },
912 .probe = wm8960_i2c_probe, 888 .probe = wm8960_i2c_probe,
913 .remove = __devexit_p(wm8960_i2c_remove), 889 .remove = __devexit_p(wm8960_i2c_remove),
914 .suspend = wm8960_i2c_suspend,
915 .resume = wm8960_i2c_resume,
916 .id_table = wm8960_i2c_id, 890 .id_table = wm8960_i2c_id,
917}; 891};
918 892
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 503032085899..a8007d58813f 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -986,19 +986,9 @@ static int wm8961_probe(struct platform_device *pdev)
986 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets, 986 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
987 ARRAY_SIZE(wm8961_dapm_widgets)); 987 ARRAY_SIZE(wm8961_dapm_widgets));
988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
989 snd_soc_dapm_new_widgets(codec);
990
991 ret = snd_soc_init_card(socdev);
992 if (ret < 0) {
993 dev_err(codec->dev, "failed to register card: %d\n", ret);
994 goto card_err;
995 }
996 989
997 return ret; 990 return ret;
998 991
999card_err:
1000 snd_soc_free_pcms(socdev);
1001 snd_soc_dapm_free(socdev);
1002pcm_err: 992pcm_err:
1003 return ret; 993 return ret;
1004} 994}
@@ -1206,21 +1196,6 @@ static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1206 return 0; 1196 return 0;
1207} 1197}
1208 1198
1209#ifdef CONFIG_PM
1210static int wm8961_i2c_suspend(struct i2c_client *client, pm_message_t state)
1211{
1212 return snd_soc_suspend_device(&client->dev);
1213}
1214
1215static int wm8961_i2c_resume(struct i2c_client *client)
1216{
1217 return snd_soc_resume_device(&client->dev);
1218}
1219#else
1220#define wm8961_i2c_suspend NULL
1221#define wm8961_i2c_resume NULL
1222#endif
1223
1224static const struct i2c_device_id wm8961_i2c_id[] = { 1199static const struct i2c_device_id wm8961_i2c_id[] = {
1225 { "wm8961", 0 }, 1200 { "wm8961", 0 },
1226 { } 1201 { }
@@ -1234,8 +1209,6 @@ static struct i2c_driver wm8961_i2c_driver = {
1234 }, 1209 },
1235 .probe = wm8961_i2c_probe, 1210 .probe = wm8961_i2c_probe,
1236 .remove = __devexit_p(wm8961_i2c_remove), 1211 .remove = __devexit_p(wm8961_i2c_remove),
1237 .suspend = wm8961_i2c_suspend,
1238 .resume = wm8961_i2c_resume,
1239 .id_table = wm8961_i2c_id, 1212 .id_table = wm8961_i2c_id,
1240}; 1213};
1241 1214
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index d66efb0546ea..d9540d55fc89 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -338,8 +338,6 @@ static int wm8971_add_widgets(struct snd_soc_codec *codec)
338 338
339 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 339 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
340 340
341 snd_soc_dapm_new_widgets(codec);
342
343 return 0; 341 return 0;
344} 342}
345 343
@@ -703,16 +701,9 @@ static int wm8971_init(struct snd_soc_device *socdev,
703 snd_soc_add_controls(codec, wm8971_snd_controls, 701 snd_soc_add_controls(codec, wm8971_snd_controls,
704 ARRAY_SIZE(wm8971_snd_controls)); 702 ARRAY_SIZE(wm8971_snd_controls));
705 wm8971_add_widgets(codec); 703 wm8971_add_widgets(codec);
706 ret = snd_soc_init_card(socdev); 704
707 if (ret < 0) {
708 printk(KERN_ERR "wm8971: failed to register card\n");
709 goto card_err;
710 }
711 return ret; 705 return ret;
712 706
713card_err:
714 snd_soc_free_pcms(socdev);
715 snd_soc_dapm_free(socdev);
716err: 707err:
717 kfree(codec->reg_cache); 708 kfree(codec->reg_cache);
718 return ret; 709 return ret;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 98d663afc97d..81c57b5c591c 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -276,41 +276,42 @@ static int wm8974_add_widgets(struct snd_soc_codec *codec)
276 276
277 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 277 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
278 278
279 snd_soc_dapm_new_widgets(codec);
280 return 0; 279 return 0;
281} 280}
282 281
283struct pll_ { 282struct pll_ {
284 unsigned int pre_div:4; /* prescale - 1 */ 283 unsigned int pre_div:1;
285 unsigned int n:4; 284 unsigned int n:4;
286 unsigned int k; 285 unsigned int k;
287}; 286};
288 287
289static struct pll_ pll_div;
290
291/* The size in bits of the pll divide multiplied by 10 288/* The size in bits of the pll divide multiplied by 10
292 * to allow rounding later */ 289 * to allow rounding later */
293#define FIXED_PLL_SIZE ((1 << 24) * 10) 290#define FIXED_PLL_SIZE ((1 << 24) * 10)
294 291
295static void pll_factors(unsigned int target, unsigned int source) 292static void pll_factors(struct pll_ *pll_div,
293 unsigned int target, unsigned int source)
296{ 294{
297 unsigned long long Kpart; 295 unsigned long long Kpart;
298 unsigned int K, Ndiv, Nmod; 296 unsigned int K, Ndiv, Nmod;
299 297
298 /* There is a fixed divide by 4 in the output path */
299 target *= 4;
300
300 Ndiv = target / source; 301 Ndiv = target / source;
301 if (Ndiv < 6) { 302 if (Ndiv < 6) {
302 source >>= 1; 303 source /= 2;
303 pll_div.pre_div = 1; 304 pll_div->pre_div = 1;
304 Ndiv = target / source; 305 Ndiv = target / source;
305 } else 306 } else
306 pll_div.pre_div = 0; 307 pll_div->pre_div = 0;
307 308
308 if ((Ndiv < 6) || (Ndiv > 12)) 309 if ((Ndiv < 6) || (Ndiv > 12))
309 printk(KERN_WARNING 310 printk(KERN_WARNING
310 "WM8974 N value %u outwith recommended range!\n", 311 "WM8974 N value %u outwith recommended range!\n",
311 Ndiv); 312 Ndiv);
312 313
313 pll_div.n = Ndiv; 314 pll_div->n = Ndiv;
314 Nmod = target % source; 315 Nmod = target % source;
315 Kpart = FIXED_PLL_SIZE * (long long)Nmod; 316 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
316 317
@@ -325,13 +326,14 @@ static void pll_factors(unsigned int target, unsigned int source)
325 /* Move down to proper range now rounding is done */ 326 /* Move down to proper range now rounding is done */
326 K /= 10; 327 K /= 10;
327 328
328 pll_div.k = K; 329 pll_div->k = K;
329} 330}
330 331
331static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, 332static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
332 int pll_id, unsigned int freq_in, unsigned int freq_out) 333 int source, unsigned int freq_in, unsigned int freq_out)
333{ 334{
334 struct snd_soc_codec *codec = codec_dai->codec; 335 struct snd_soc_codec *codec = codec_dai->codec;
336 struct pll_ pll_div;
335 u16 reg; 337 u16 reg;
336 338
337 if (freq_in == 0 || freq_out == 0) { 339 if (freq_in == 0 || freq_out == 0) {
@@ -345,7 +347,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
345 return 0; 347 return 0;
346 } 348 }
347 349
348 pll_factors(freq_out*4, freq_in); 350 pll_factors(&pll_div, freq_out, freq_in);
349 351
350 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); 352 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
351 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18); 353 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
@@ -638,17 +640,9 @@ static int wm8974_probe(struct platform_device *pdev)
638 snd_soc_add_controls(codec, wm8974_snd_controls, 640 snd_soc_add_controls(codec, wm8974_snd_controls,
639 ARRAY_SIZE(wm8974_snd_controls)); 641 ARRAY_SIZE(wm8974_snd_controls));
640 wm8974_add_widgets(codec); 642 wm8974_add_widgets(codec);
641 ret = snd_soc_init_card(socdev);
642 if (ret < 0) {
643 dev_err(codec->dev, "failed to register card: %d\n", ret);
644 goto card_err;
645 }
646 643
647 return ret; 644 return ret;
648 645
649card_err:
650 snd_soc_free_pcms(socdev);
651 snd_soc_dapm_free(socdev);
652pcm_err: 646pcm_err:
653 return ret; 647 return ret;
654} 648}
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 3f530f8a972a..2862e4dced27 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -790,19 +790,9 @@ static int wm8988_probe(struct platform_device *pdev)
790 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, 790 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
791 ARRAY_SIZE(wm8988_dapm_widgets)); 791 ARRAY_SIZE(wm8988_dapm_widgets));
792 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 792 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
793 snd_soc_dapm_new_widgets(codec);
794
795 ret = snd_soc_init_card(socdev);
796 if (ret < 0) {
797 dev_err(codec->dev, "failed to register card: %d\n", ret);
798 goto card_err;
799 }
800 793
801 return ret; 794 return ret;
802 795
803card_err:
804 snd_soc_free_pcms(socdev);
805 snd_soc_dapm_free(socdev);
806pcm_err: 796pcm_err:
807 return ret; 797 return ret;
808} 798}
@@ -944,21 +934,6 @@ static int wm8988_i2c_remove(struct i2c_client *client)
944 return 0; 934 return 0;
945} 935}
946 936
947#ifdef CONFIG_PM
948static int wm8988_i2c_suspend(struct i2c_client *client, pm_message_t msg)
949{
950 return snd_soc_suspend_device(&client->dev);
951}
952
953static int wm8988_i2c_resume(struct i2c_client *client)
954{
955 return snd_soc_resume_device(&client->dev);
956}
957#else
958#define wm8988_i2c_suspend NULL
959#define wm8988_i2c_resume NULL
960#endif
961
962static const struct i2c_device_id wm8988_i2c_id[] = { 937static const struct i2c_device_id wm8988_i2c_id[] = {
963 { "wm8988", 0 }, 938 { "wm8988", 0 },
964 { } 939 { }
@@ -972,8 +947,6 @@ static struct i2c_driver wm8988_i2c_driver = {
972 }, 947 },
973 .probe = wm8988_i2c_probe, 948 .probe = wm8988_i2c_probe,
974 .remove = wm8988_i2c_remove, 949 .remove = wm8988_i2c_remove,
975 .suspend = wm8988_i2c_suspend,
976 .resume = wm8988_i2c_resume,
977 .id_table = wm8988_i2c_id, 950 .id_table = wm8988_i2c_id,
978}; 951};
979#endif 952#endif
@@ -1006,21 +979,6 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi)
1006 return 0; 979 return 0;
1007} 980}
1008 981
1009#ifdef CONFIG_PM
1010static int wm8988_spi_suspend(struct spi_device *spi, pm_message_t msg)
1011{
1012 return snd_soc_suspend_device(&spi->dev);
1013}
1014
1015static int wm8988_spi_resume(struct spi_device *spi)
1016{
1017 return snd_soc_resume_device(&spi->dev);
1018}
1019#else
1020#define wm8988_spi_suspend NULL
1021#define wm8988_spi_resume NULL
1022#endif
1023
1024static struct spi_driver wm8988_spi_driver = { 982static struct spi_driver wm8988_spi_driver = {
1025 .driver = { 983 .driver = {
1026 .name = "wm8988", 984 .name = "wm8988",
@@ -1029,8 +987,6 @@ static struct spi_driver wm8988_spi_driver = {
1029 }, 987 },
1030 .probe = wm8988_spi_probe, 988 .probe = wm8988_spi_probe,
1031 .remove = __devexit_p(wm8988_spi_remove), 989 .remove = __devexit_p(wm8988_spi_remove),
1032 .suspend = wm8988_spi_suspend,
1033 .resume = wm8988_spi_resume,
1034}; 990};
1035#endif 991#endif
1036 992
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 2d702db4131d..341481e0e830 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -920,7 +920,6 @@ static int wm8990_add_widgets(struct snd_soc_codec *codec)
920 /* set up the WM8990 audio map */ 920 /* set up the WM8990 audio map */
921 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 921 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
922 922
923 snd_soc_dapm_new_widgets(codec);
924 return 0; 923 return 0;
925} 924}
926 925
@@ -972,8 +971,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
972 pll_div->k = K; 971 pll_div->k = K;
973} 972}
974 973
975static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, 974static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
976 int pll_id, unsigned int freq_in, unsigned int freq_out) 975 int source, unsigned int freq_in, unsigned int freq_out)
977{ 976{
978 u16 reg; 977 u16 reg;
979 struct snd_soc_codec *codec = codec_dai->codec; 978 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1409,16 +1408,9 @@ static int wm8990_init(struct snd_soc_device *socdev)
1409 snd_soc_add_controls(codec, wm8990_snd_controls, 1408 snd_soc_add_controls(codec, wm8990_snd_controls,
1410 ARRAY_SIZE(wm8990_snd_controls)); 1409 ARRAY_SIZE(wm8990_snd_controls));
1411 wm8990_add_widgets(codec); 1410 wm8990_add_widgets(codec);
1412 ret = snd_soc_init_card(socdev); 1411
1413 if (ret < 0) {
1414 printk(KERN_ERR "wm8990: failed to register card\n");
1415 goto card_err;
1416 }
1417 return ret; 1412 return ret;
1418 1413
1419card_err:
1420 snd_soc_free_pcms(socdev);
1421 snd_soc_dapm_free(socdev);
1422pcm_err: 1414pcm_err:
1423 kfree(codec->reg_cache); 1415 kfree(codec->reg_cache);
1424 return ret; 1416 return ret;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d9987999e92c..2981afae842c 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -422,7 +422,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
422 return 0; 422 return 0;
423} 423}
424 424
425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, 425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
426 unsigned int Fref, unsigned int Fout) 426 unsigned int Fref, unsigned int Fout)
427{ 427{
428 struct snd_soc_codec *codec = dai->codec; 428 struct snd_soc_codec *codec = dai->codec;
@@ -689,7 +689,7 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE,
689 689
690SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0), 690SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0),
691SOC_ENUM("DRC Path", drc_path), 691SOC_ENUM("DRC Path", drc_path),
692SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8993_DRC_CONTROL_2, 692SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8993_DRC_CONTROL_2,
693 2, 60, 1, drc_comp_threash), 693 2, 60, 1, drc_comp_threash),
694SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3, 694SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3,
695 11, 30, 1, drc_comp_amp), 695 11, 30, 1, drc_comp_amp),
@@ -709,7 +709,7 @@ SOC_SINGLE_TLV("DRC Quick Release Volume", WM8993_DRC_CONTROL_3, 2, 3, 0,
709SOC_ENUM("DRC Quick Release Rate", drc_qr_rate), 709SOC_ENUM("DRC Quick Release Rate", drc_qr_rate),
710SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0), 710SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0),
711SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0), 711SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0),
712SOC_ENUM("DRC Smoothing Hysteresis Threashold", drc_smooth), 712SOC_ENUM("DRC Smoothing Hysteresis Threshold", drc_smooth),
713SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0, 713SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0,
714 drc_startup_tlv), 714 drc_startup_tlv),
715 715
@@ -1464,19 +1464,8 @@ static int wm8993_probe(struct platform_device *pdev)
1464 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1464 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1465 wm8993->pdata.lineout2_diff); 1465 wm8993->pdata.lineout2_diff);
1466 1466
1467 snd_soc_dapm_new_widgets(codec);
1468
1469 ret = snd_soc_init_card(socdev);
1470 if (ret < 0) {
1471 dev_err(codec->dev, "failed to register card\n");
1472 goto card_err;
1473 }
1474
1475 return ret; 1467 return ret;
1476 1468
1477card_err:
1478 snd_soc_free_pcms(socdev);
1479 snd_soc_dapm_free(socdev);
1480err: 1469err:
1481 return ret; 1470 return ret;
1482} 1471}
@@ -1572,33 +1561,15 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1572 /* Use automatic clock configuration */ 1561 /* Use automatic clock configuration */
1573 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0); 1562 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1574 1563
1575 if (!wm8993->pdata.lineout1_diff) 1564 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1576 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 1565 wm8993->pdata.lineout2_diff,
1577 WM8993_LINEOUT1_MODE, 1566 wm8993->pdata.lineout1fb,
1578 WM8993_LINEOUT1_MODE); 1567 wm8993->pdata.lineout2fb,
1579 if (!wm8993->pdata.lineout2_diff) 1568 wm8993->pdata.jd_scthr,
1580 snd_soc_update_bits(codec, WM8993_LINE_MIXER2, 1569 wm8993->pdata.jd_thr,
1581 WM8993_LINEOUT2_MODE, 1570 wm8993->pdata.micbias1_lvl,
1582 WM8993_LINEOUT2_MODE); 1571 wm8993->pdata.micbias2_lvl);
1583 1572
1584 if (wm8993->pdata.lineout1fb)
1585 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1586 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
1587
1588 if (wm8993->pdata.lineout2fb)
1589 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1590 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
1591
1592 /* Apply the microphone bias/detection configuration - the
1593 * platform data is directly applicable to the register. */
1594 snd_soc_update_bits(codec, WM8993_MICBIAS,
1595 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
1596 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
1597 wm8993->pdata.jd_scthr << WM8993_JD_SCTHR_SHIFT |
1598 wm8993->pdata.jd_thr << WM8993_JD_THR_SHIFT |
1599 wm8993->pdata.micbias1_lvl |
1600 wm8993->pdata.micbias1_lvl << 1);
1601
1602 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1573 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1603 if (ret != 0) 1574 if (ret != 0)
1604 goto err; 1575 goto err;
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 686e5aa97206..c468497314ba 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1262,19 +1262,9 @@ static int wm9081_probe(struct platform_device *pdev)
1262 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets, 1262 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets,
1263 ARRAY_SIZE(wm9081_dapm_widgets)); 1263 ARRAY_SIZE(wm9081_dapm_widgets));
1264 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1264 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1265 snd_soc_dapm_new_widgets(codec);
1266
1267 ret = snd_soc_init_card(socdev);
1268 if (ret < 0) {
1269 dev_err(codec->dev, "failed to register card: %d\n", ret);
1270 goto card_err;
1271 }
1272 1265
1273 return ret; 1266 return ret;
1274 1267
1275card_err:
1276 snd_soc_free_pcms(socdev);
1277 snd_soc_dapm_free(socdev);
1278pcm_err: 1268pcm_err:
1279 return ret; 1269 return ret;
1280} 1270}
@@ -1452,21 +1442,6 @@ static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1452 return 0; 1442 return 0;
1453} 1443}
1454 1444
1455#ifdef CONFIG_PM
1456static int wm9081_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1457{
1458 return snd_soc_suspend_device(&client->dev);
1459}
1460
1461static int wm9081_i2c_resume(struct i2c_client *client)
1462{
1463 return snd_soc_resume_device(&client->dev);
1464}
1465#else
1466#define wm9081_i2c_suspend NULL
1467#define wm9081_i2c_resume NULL
1468#endif
1469
1470static const struct i2c_device_id wm9081_i2c_id[] = { 1445static const struct i2c_device_id wm9081_i2c_id[] = {
1471 { "wm9081", 0 }, 1446 { "wm9081", 0 },
1472 { } 1447 { }
@@ -1480,8 +1455,6 @@ static struct i2c_driver wm9081_i2c_driver = {
1480 }, 1455 },
1481 .probe = wm9081_i2c_probe, 1456 .probe = wm9081_i2c_probe,
1482 .remove = __devexit_p(wm9081_i2c_remove), 1457 .remove = __devexit_p(wm9081_i2c_remove),
1483 .suspend = wm9081_i2c_suspend,
1484 .resume = wm9081_i2c_resume,
1485 .id_table = wm9081_i2c_id, 1458 .id_table = wm9081_i2c_id,
1486}; 1459};
1487 1460
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index e7d2840d9e59..ec54c6da9856 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -205,7 +205,6 @@ static int wm9705_add_widgets(struct snd_soc_codec *codec)
205 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, 205 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets,
206 ARRAY_SIZE(wm9705_dapm_widgets)); 206 ARRAY_SIZE(wm9705_dapm_widgets));
207 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 207 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
208 snd_soc_dapm_new_widgets(codec);
209 208
210 return 0; 209 return 0;
211} 210}
@@ -403,12 +402,6 @@ static int wm9705_soc_probe(struct platform_device *pdev)
403 ARRAY_SIZE(wm9705_snd_ac97_controls)); 402 ARRAY_SIZE(wm9705_snd_ac97_controls));
404 wm9705_add_widgets(codec); 403 wm9705_add_widgets(codec);
405 404
406 ret = snd_soc_init_card(socdev);
407 if (ret < 0) {
408 printk(KERN_ERR "wm9705: failed to register card\n");
409 goto reset_err;
410 }
411
412 return 0; 405 return 0;
413 406
414reset_err: 407reset_err:
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 1fd4e88f50cf..0ac1215dcd9b 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -436,7 +436,6 @@ static int wm9712_add_widgets(struct snd_soc_codec *codec)
436 436
437 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 437 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
438 438
439 snd_soc_dapm_new_widgets(codec);
440 return 0; 439 return 0;
441} 440}
442 441
@@ -695,17 +694,11 @@ static int wm9712_soc_probe(struct platform_device *pdev)
695 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 694 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
696 ARRAY_SIZE(wm9712_snd_ac97_controls)); 695 ARRAY_SIZE(wm9712_snd_ac97_controls));
697 wm9712_add_widgets(codec); 696 wm9712_add_widgets(codec);
698 ret = snd_soc_init_card(socdev);
699 if (ret < 0) {
700 printk(KERN_ERR "wm9712: failed to register card\n");
701 goto reset_err;
702 }
703 697
704 return 0; 698 return 0;
705 699
706reset_err: 700reset_err:
707 snd_soc_free_pcms(socdev); 701 snd_soc_free_pcms(socdev);
708
709pcm_err: 702pcm_err:
710 snd_soc_free_ac97_codec(codec); 703 snd_soc_free_ac97_codec(codec);
711 704
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 60e360b10468..c58aab375edb 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -625,7 +625,6 @@ static int wm9713_add_widgets(struct snd_soc_codec *codec)
625 625
626 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 626 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
627 627
628 snd_soc_dapm_new_widgets(codec);
629 return 0; 628 return 0;
630} 629}
631 630
@@ -800,8 +799,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
800 return 0; 799 return 0;
801} 800}
802 801
803static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, 802static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
804 int pll_id, unsigned int freq_in, unsigned int freq_out) 803 int source, unsigned int freq_in, unsigned int freq_out)
805{ 804{
806 struct snd_soc_codec *codec = codec_dai->codec; 805 struct snd_soc_codec *codec = codec_dai->codec;
807 return wm9713_set_pll(codec, pll_id, freq_in, freq_out); 806 return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
@@ -1247,14 +1246,11 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1247 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1246 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1248 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1247 ARRAY_SIZE(wm9713_snd_ac97_controls));
1249 wm9713_add_widgets(codec); 1248 wm9713_add_widgets(codec);
1250 ret = snd_soc_init_card(socdev); 1249
1251 if (ret < 0)
1252 goto reset_err;
1253 return 0; 1250 return 0;
1254 1251
1255reset_err: 1252reset_err:
1256 snd_soc_free_pcms(socdev); 1253 snd_soc_free_pcms(socdev);
1257
1258pcm_err: 1254pcm_err:
1259 snd_soc_free_ac97_codec(codec); 1255 snd_soc_free_ac97_codec(codec);
1260 1256
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e542027eea89..d73c30536a2c 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -438,11 +438,11 @@ static const struct snd_soc_dapm_widget analogue_dapm_widgets[] = {
438SND_SOC_DAPM_INPUT("IN1LN"), 438SND_SOC_DAPM_INPUT("IN1LN"),
439SND_SOC_DAPM_INPUT("IN1LP"), 439SND_SOC_DAPM_INPUT("IN1LP"),
440SND_SOC_DAPM_INPUT("IN2LN"), 440SND_SOC_DAPM_INPUT("IN2LN"),
441SND_SOC_DAPM_INPUT("IN2LP/VXRN"), 441SND_SOC_DAPM_INPUT("IN2LP:VXRN"),
442SND_SOC_DAPM_INPUT("IN1RN"), 442SND_SOC_DAPM_INPUT("IN1RN"),
443SND_SOC_DAPM_INPUT("IN1RP"), 443SND_SOC_DAPM_INPUT("IN1RP"),
444SND_SOC_DAPM_INPUT("IN2RN"), 444SND_SOC_DAPM_INPUT("IN2RN"),
445SND_SOC_DAPM_INPUT("IN2RP/VXRP"), 445SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
446 446
447SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0), 447SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0),
448SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0), 448SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0),
@@ -537,14 +537,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
537 { "IN1R PGA", "IN1RP Switch", "IN1RP" }, 537 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
538 { "IN1R PGA", "IN1RN Switch", "IN1RN" }, 538 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
539 539
540 { "IN2L PGA", "IN2LP Switch", "IN2LP/VXRN" }, 540 { "IN2L PGA", "IN2LP Switch", "IN2LP:VXRN" },
541 { "IN2L PGA", "IN2LN Switch", "IN2LN" }, 541 { "IN2L PGA", "IN2LN Switch", "IN2LN" },
542 542
543 { "IN2R PGA", "IN2RP Switch", "IN2RP/VXRP" }, 543 { "IN2R PGA", "IN2RP Switch", "IN2RP:VXRP" },
544 { "IN2R PGA", "IN2RN Switch", "IN2RN" }, 544 { "IN2R PGA", "IN2RN Switch", "IN2RN" },
545 545
546 { "Direct Voice", NULL, "IN2LP/VXRN" }, 546 { "Direct Voice", NULL, "IN2LP:VXRN" },
547 { "Direct Voice", NULL, "IN2RP/VXRP" }, 547 { "Direct Voice", NULL, "IN2RP:VXRP" },
548 548
549 { "MIXINL", "IN1L Switch", "IN1L PGA" }, 549 { "MIXINL", "IN1L Switch", "IN1L PGA" },
550 { "MIXINL", "IN2L Switch", "IN2L PGA" }, 550 { "MIXINL", "IN2L Switch", "IN2L PGA" },
@@ -565,7 +565,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
565 { "Left Output Mixer", "Right Input Switch", "MIXINR" }, 565 { "Left Output Mixer", "Right Input Switch", "MIXINR" },
566 { "Left Output Mixer", "IN2RN Switch", "IN2RN" }, 566 { "Left Output Mixer", "IN2RN Switch", "IN2RN" },
567 { "Left Output Mixer", "IN2LN Switch", "IN2LN" }, 567 { "Left Output Mixer", "IN2LN Switch", "IN2LN" },
568 { "Left Output Mixer", "IN2LP Switch", "IN2LP/VXRN" }, 568 { "Left Output Mixer", "IN2LP Switch", "IN2LP:VXRN" },
569 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" }, 569 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" },
570 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" }, 570 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" },
571 571
@@ -573,7 +573,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
573 { "Right Output Mixer", "Right Input Switch", "MIXINR" }, 573 { "Right Output Mixer", "Right Input Switch", "MIXINR" },
574 { "Right Output Mixer", "IN2LN Switch", "IN2LN" }, 574 { "Right Output Mixer", "IN2LN Switch", "IN2LN" },
575 { "Right Output Mixer", "IN2RN Switch", "IN2RN" }, 575 { "Right Output Mixer", "IN2RN Switch", "IN2RN" },
576 { "Right Output Mixer", "IN2RP Switch", "IN2RP/VXRP" }, 576 { "Right Output Mixer", "IN2RP Switch", "IN2RP:VXRP" },
577 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" }, 577 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" },
578 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" }, 578 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" },
579 579
@@ -738,6 +738,41 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
738} 738}
739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes); 739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
740 740
741int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
742 int lineout1_diff, int lineout2_diff,
743 int lineout1fb, int lineout2fb,
744 int jd_scthr, int jd_thr, int micbias1_lvl,
745 int micbias2_lvl)
746{
747 if (!lineout1_diff)
748 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
749 WM8993_LINEOUT1_MODE,
750 WM8993_LINEOUT1_MODE);
751 if (!lineout2_diff)
752 snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
753 WM8993_LINEOUT2_MODE,
754 WM8993_LINEOUT2_MODE);
755
756 if (lineout1fb)
757 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
758 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
759
760 if (lineout2fb)
761 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
762 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
763
764 snd_soc_update_bits(codec, WM8993_MICBIAS,
765 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
766 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
767 jd_scthr << WM8993_JD_SCTHR_SHIFT |
768 jd_thr << WM8993_JD_THR_SHIFT |
769 micbias1_lvl |
770 micbias2_lvl << WM8993_MICB2_LVL_SHIFT);
771
772 return 0;
773}
774EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
775
741MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 776MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
742MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 777MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
743MODULE_LICENSE("GPL"); 778MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index ec09cb6a2939..36d3fba1de8b 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -20,5 +20,10 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
20 20
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int); 22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
23extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
24 int lineout1_diff, int lineout2_diff,
25 int lineout1fb, int lineout2fb,
26 int jd_scthr, int jd_thr,
27 int micbias1_lvl, int micbias2_lvl);
23 28
24#endif 29#endif