aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-03-23 19:35:53 -0400
committerTakashi Iwai <tiwai@suse.de>2009-03-23 19:35:53 -0400
commitb5c784894c90042f4fc6348aedc7524e899df281 (patch)
tree0db86a93d73e4aabca04e361d7e6807aa4c1d307 /sound
parentff4fc3656e489ed6ee575959b0510286aefe1e20 (diff)
parent1f2186951e02f2a5bcda9459f63136918932385a (diff)
Merge branch 'topic/asoc' into for-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c71
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/atmel/atmel-pcm.c2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c33
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c24
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c124
-rw-r--r--sound/soc/au1x/dbdma2.c2
-rw-r--r--sound/soc/au1x/psc-ac97.c10
-rw-r--r--sound/soc/au1x/psc-i2s.c12
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c94
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c4
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c14
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c104
-rw-r--r--sound/soc/codecs/Kconfig23
-rw-r--r--sound/soc/codecs/Makefile7
-rw-r--r--sound/soc/codecs/ac97.c29
-rw-r--r--sound/soc/codecs/ad1980.c33
-rw-r--r--sound/soc/codecs/ad73311.c8
-rw-r--r--sound/soc/codecs/ad73311.h2
-rw-r--r--sound/soc/codecs/ak4104.c365
-rw-r--r--sound/soc/codecs/ak4104.h7
-rw-r--r--sound/soc/codecs/ak4535.c46
-rw-r--r--sound/soc/codecs/cs4270.c667
-rw-r--r--sound/soc/codecs/pcm3008.c12
-rw-r--r--sound/soc/codecs/ssm2602.c58
-rw-r--r--sound/soc/codecs/tlv320aic23.c57
-rw-r--r--sound/soc/codecs/tlv320aic26.c29
-rw-r--r--sound/soc/codecs/tlv320aic3x.c161
-rw-r--r--sound/soc/codecs/twl4030.c524
-rw-r--r--sound/soc/codecs/twl4030.h15
-rw-r--r--sound/soc/codecs/uda134x.c84
-rw-r--r--sound/soc/codecs/uda1380.c241
-rw-r--r--sound/soc/codecs/wm8350.c166
-rw-r--r--sound/soc/codecs/wm8350.h8
-rw-r--r--sound/soc/codecs/wm8400.c1582
-rw-r--r--sound/soc/codecs/wm8400.h62
-rw-r--r--sound/soc/codecs/wm8510.c55
-rw-r--r--sound/soc/codecs/wm8580.c381
-rw-r--r--sound/soc/codecs/wm8580.h5
-rw-r--r--sound/soc/codecs/wm8728.c50
-rw-r--r--sound/soc/codecs/wm8731.c432
-rw-r--r--sound/soc/codecs/wm8731.h6
-rw-r--r--sound/soc/codecs/wm8750.c48
-rw-r--r--sound/soc/codecs/wm8753.c542
-rw-r--r--sound/soc/codecs/wm8753.h6
-rw-r--r--sound/soc/codecs/wm8900.c51
-rw-r--r--sound/soc/codecs/wm8903.c60
-rw-r--r--sound/soc/codecs/wm8971.c46
-rw-r--r--sound/soc/codecs/wm8990.c54
-rw-r--r--sound/soc/codecs/wm9705.c415
-rw-r--r--sound/soc/codecs/wm9705.h14
-rw-r--r--sound/soc/codecs/wm9712.c57
-rw-r--r--sound/soc/codecs/wm9713.c96
-rw-r--r--sound/soc/davinci/Kconfig2
-rw-r--r--sound/soc/davinci/davinci-evm.c3
-rw-r--r--sound/soc/davinci/davinci-i2s.c14
-rw-r--r--sound/soc/davinci/davinci-pcm.c2
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c43
-rw-r--r--sound/soc/fsl/Kconfig17
-rw-r--r--sound/soc/fsl/Makefile7
-rw-r--r--sound/soc/fsl/fsl_dma.c181
-rw-r--r--sound/soc/fsl/fsl_ssi.c98
-rw-r--r--sound/soc/fsl/fsl_ssi.h2
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c20
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c5
-rw-r--r--sound/soc/omap/Kconfig14
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/n810.c47
-rw-r--r--sound/soc/omap/omap-mcbsp.c20
-rw-r--r--sound/soc/omap/omap-pcm.c2
-rw-r--r--sound/soc/omap/omap3pandora.c49
-rw-r--r--sound/soc/omap/osk5912.c12
-rw-r--r--sound/soc/omap/sdp3430.c115
-rw-r--r--sound/soc/pxa/Kconfig27
-rw-r--r--sound/soc/pxa/Makefile6
-rw-r--r--sound/soc/pxa/corgi.c58
-rw-r--r--sound/soc/pxa/e740_wm9705.c211
-rw-r--r--sound/soc/pxa/e750_wm9705.c187
-rw-r--r--sound/soc/pxa/e800_wm9712.c115
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c250
-rw-r--r--sound/soc/pxa/palm27x.c15
-rw-r--r--sound/soc/pxa/poodle.c56
-rw-r--r--sound/soc/pxa/pxa-ssp.c150
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c59
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c54
-rw-r--r--sound/soc/pxa/spitz.c14
-rw-r--r--sound/soc/pxa/tosa.c14
-rw-r--r--sound/soc/pxa/zylonite.c132
-rw-r--r--sound/soc/s3c24xx/Kconfig29
-rw-r--r--sound/soc/s3c24xx/Makefile6
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c201
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c67
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c638
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.h90
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c622
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.h17
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c20
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c71
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c49
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c2
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c222
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h31
-rw-r--r--sound/soc/sh/hac.c12
-rw-r--r--sound/soc/sh/ssi.c30
-rw-r--r--sound/soc/soc-core.c173
-rw-r--r--sound/soc/soc-dapm.c390
-rw-r--r--sound/soc/soc-jack.c267
110 files changed, 8411 insertions, 3534 deletions
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 35afd0c33be5..2e6355f4cbb9 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -31,6 +31,7 @@ static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
31static volatile long gsr_bits; 31static volatile long gsr_bits;
32static struct clk *ac97_clk; 32static struct clk *ac97_clk;
33static struct clk *ac97conf_clk; 33static struct clk *ac97conf_clk;
34static int reset_gpio;
34 35
35/* 36/*
36 * Beware PXA27x bugs: 37 * Beware PXA27x bugs:
@@ -42,6 +43,45 @@ static struct clk *ac97conf_clk;
42 * 1 jiffy timeout if interrupt never comes). 43 * 1 jiffy timeout if interrupt never comes).
43 */ 44 */
44 45
46enum {
47 RESETGPIO_FORCE_HIGH,
48 RESETGPIO_FORCE_LOW,
49 RESETGPIO_NORMAL_ALTFUNC
50};
51
52/**
53 * set_resetgpio_mode - computes and sets the AC97_RESET gpio mode on PXA
54 * @mode: chosen action
55 *
56 * As the PXA27x CPUs suffer from a AC97 bug, a manual control of the reset line
57 * must be done to insure proper work of AC97 reset line. This function
58 * computes the correct gpio_mode for further use by reset functions, and
59 * applied the change through pxa_gpio_mode.
60 */
61static void set_resetgpio_mode(int resetgpio_action)
62{
63 int mode = 0;
64
65 if (reset_gpio)
66 switch (resetgpio_action) {
67 case RESETGPIO_NORMAL_ALTFUNC:
68 if (reset_gpio == 113)
69 mode = 113 | GPIO_OUT | GPIO_DFLT_LOW;
70 if (reset_gpio == 95)
71 mode = 95 | GPIO_ALT_FN_1_OUT;
72 break;
73 case RESETGPIO_FORCE_LOW:
74 mode = reset_gpio | GPIO_OUT | GPIO_DFLT_LOW;
75 break;
76 case RESETGPIO_FORCE_HIGH:
77 mode = reset_gpio | GPIO_OUT | GPIO_DFLT_HIGH;
78 break;
79 };
80
81 if (mode)
82 pxa_gpio_mode(mode);
83}
84
45unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 85unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
46{ 86{
47 unsigned short val = -1; 87 unsigned short val = -1;
@@ -137,10 +177,10 @@ static inline void pxa_ac97_warm_pxa27x(void)
137 177
138 /* warm reset broken on Bulverde, 178 /* warm reset broken on Bulverde,
139 so manually keep AC97 reset high */ 179 so manually keep AC97 reset high */
140 pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); 180 set_resetgpio_mode(RESETGPIO_FORCE_HIGH);
141 udelay(10); 181 udelay(10);
142 GCR |= GCR_WARM_RST; 182 GCR |= GCR_WARM_RST;
143 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 183 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
144 udelay(500); 184 udelay(500);
145} 185}
146 186
@@ -308,8 +348,8 @@ int pxa2xx_ac97_hw_resume(void)
308 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); 348 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
309 } 349 }
310 if (cpu_is_pxa27x()) { 350 if (cpu_is_pxa27x()) {
311 /* Use GPIO 113 as AC97 Reset on Bulverde */ 351 /* Use GPIO 113 or 95 as AC97 Reset on Bulverde */
312 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 352 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
313 } 353 }
314 clk_enable(ac97_clk); 354 clk_enable(ac97_clk);
315 return 0; 355 return 0;
@@ -320,6 +360,27 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
320int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) 360int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
321{ 361{
322 int ret; 362 int ret;
363 struct pxa2xx_ac97_platform_data *pdata = dev->dev.platform_data;
364
365 if (pdata) {
366 switch (pdata->reset_gpio) {
367 case 95:
368 case 113:
369 reset_gpio = pdata->reset_gpio;
370 break;
371 case 0:
372 reset_gpio = 113;
373 break;
374 case -1:
375 break;
376 default:
377 dev_err(&dev->dev, "Invalid reset GPIO %d\n",
378 pdata->reset_gpio);
379 }
380 } else {
381 if (cpu_is_pxa27x())
382 reset_gpio = 113;
383 }
323 384
324 if (cpu_is_pxa25x() || cpu_is_pxa27x()) { 385 if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
325 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 386 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
@@ -330,7 +391,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
330 391
331 if (cpu_is_pxa27x()) { 392 if (cpu_is_pxa27x()) {
332 /* Use GPIO 113 as AC97 Reset on Bulverde */ 393 /* Use GPIO 113 as AC97 Reset on Bulverde */
333 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 394 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
334 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); 395 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
335 if (IS_ERR(ac97conf_clk)) { 396 if (IS_ERR(ac97conf_clk)) {
336 ret = PTR_ERR(ac97conf_clk); 397 ret = PTR_ERR(ac97conf_clk);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index ef025c66cc66..3d2bb6fc6dcc 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -6,6 +6,7 @@ menuconfig SND_SOC
6 tristate "ALSA for SoC audio support" 6 tristate "ALSA for SoC audio support"
7 select SND_PCM 7 select SND_PCM
8 select AC97_BUS if SND_SOC_AC97_BUS 8 select AC97_BUS if SND_SOC_AC97_BUS
9 select SND_JACK if INPUT=y || INPUT=SND
9 ---help--- 10 ---help---
10 11
11 If you want ASoC support, you should say Y here and also to the 12 If you want ASoC support, you should say Y here and also to the
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 86a9b1f5b0f3..0237879fd412 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,4 +1,4 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ 4obj-$(CONFIG_SND_SOC) += codecs/
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 3dcdc4e3cfa0..9ef6b96373f5 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -347,7 +347,7 @@ static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
347 vma->vm_end - vma->vm_start, vma->vm_page_prot); 347 vma->vm_end - vma->vm_start, vma->vm_page_prot);
348} 348}
349 349
350struct snd_pcm_ops atmel_pcm_ops = { 350static struct snd_pcm_ops atmel_pcm_ops = {
351 .open = atmel_pcm_open, 351 .open = atmel_pcm_open,
352 .close = atmel_pcm_close, 352 .close = atmel_pcm_close,
353 .ioctl = snd_pcm_lib_ioctl, 353 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index ff0054b76502..e588e63f18d2 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -697,6 +697,15 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
697#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ 697#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
698 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 698 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
699 699
700static struct snd_soc_dai_ops atmel_ssc_dai_ops = {
701 .startup = atmel_ssc_startup,
702 .shutdown = atmel_ssc_shutdown,
703 .prepare = atmel_ssc_prepare,
704 .hw_params = atmel_ssc_hw_params,
705 .set_fmt = atmel_ssc_set_dai_fmt,
706 .set_clkdiv = atmel_ssc_set_dai_clkdiv,
707};
708
700struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = { 709struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
701 { .name = "atmel-ssc0", 710 { .name = "atmel-ssc0",
702 .id = 0, 711 .id = 0,
@@ -712,13 +721,7 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
712 .channels_max = 2, 721 .channels_max = 2,
713 .rates = ATMEL_SSC_RATES, 722 .rates = ATMEL_SSC_RATES,
714 .formats = ATMEL_SSC_FORMATS,}, 723 .formats = ATMEL_SSC_FORMATS,},
715 .ops = { 724 .ops = &atmel_ssc_dai_ops,
716 .startup = atmel_ssc_startup,
717 .shutdown = atmel_ssc_shutdown,
718 .prepare = atmel_ssc_prepare,
719 .hw_params = atmel_ssc_hw_params,
720 .set_fmt = atmel_ssc_set_dai_fmt,
721 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
722 .private_data = &ssc_info[0], 725 .private_data = &ssc_info[0],
723 }, 726 },
724#if NUM_SSC_DEVICES == 3 727#if NUM_SSC_DEVICES == 3
@@ -736,13 +739,7 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
736 .channels_max = 2, 739 .channels_max = 2,
737 .rates = ATMEL_SSC_RATES, 740 .rates = ATMEL_SSC_RATES,
738 .formats = ATMEL_SSC_FORMATS,}, 741 .formats = ATMEL_SSC_FORMATS,},
739 .ops = { 742 .ops = &atmel_ssc_dai_ops,
740 .startup = atmel_ssc_startup,
741 .shutdown = atmel_ssc_shutdown,
742 .prepare = atmel_ssc_prepare,
743 .hw_params = atmel_ssc_hw_params,
744 .set_fmt = atmel_ssc_set_dai_fmt,
745 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
746 .private_data = &ssc_info[1], 743 .private_data = &ssc_info[1],
747 }, 744 },
748 { .name = "atmel-ssc2", 745 { .name = "atmel-ssc2",
@@ -759,13 +756,7 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
759 .channels_max = 2, 756 .channels_max = 2,
760 .rates = ATMEL_SSC_RATES, 757 .rates = ATMEL_SSC_RATES,
761 .formats = ATMEL_SSC_FORMATS,}, 758 .formats = ATMEL_SSC_FORMATS,},
762 .ops = { 759 .ops = &atmel_ssc_dai_ops,
763 .startup = atmel_ssc_startup,
764 .shutdown = atmel_ssc_shutdown,
765 .prepare = atmel_ssc_prepare,
766 .hw_params = atmel_ssc_hw_params,
767 .set_fmt = atmel_ssc_set_dai_fmt,
768 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
769 .private_data = &ssc_info[2], 760 .private_data = &ssc_info[2],
770 }, 761 },
771#endif 762#endif
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 43dd8cee83c6..70657534e6b1 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -164,38 +164,38 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
164 */ 164 */
165 switch (params_rate(params)) { 165 switch (params_rate(params)) {
166 case 48000: 166 case 48000:
167 pll_out = 12288000; 167 pll_out = 24576000;
168 mclk_div = WM8510_MCLKDIV_1; 168 mclk_div = WM8510_MCLKDIV_2;
169 bclk = WM8510_BCLKDIV_8; 169 bclk = WM8510_BCLKDIV_8;
170 break; 170 break;
171 171
172 case 44100: 172 case 44100:
173 pll_out = 11289600; 173 pll_out = 22579200;
174 mclk_div = WM8510_MCLKDIV_1; 174 mclk_div = WM8510_MCLKDIV_2;
175 bclk = WM8510_BCLKDIV_8; 175 bclk = WM8510_BCLKDIV_8;
176 break; 176 break;
177 177
178 case 22050: 178 case 22050:
179 pll_out = 11289600; 179 pll_out = 22579200;
180 mclk_div = WM8510_MCLKDIV_2; 180 mclk_div = WM8510_MCLKDIV_4;
181 bclk = WM8510_BCLKDIV_8; 181 bclk = WM8510_BCLKDIV_8;
182 break; 182 break;
183 183
184 case 16000: 184 case 16000:
185 pll_out = 12288000; 185 pll_out = 24576000;
186 mclk_div = WM8510_MCLKDIV_3; 186 mclk_div = WM8510_MCLKDIV_6;
187 bclk = WM8510_BCLKDIV_8; 187 bclk = WM8510_BCLKDIV_8;
188 break; 188 break;
189 189
190 case 11025: 190 case 11025:
191 pll_out = 11289600; 191 pll_out = 22579200;
192 mclk_div = WM8510_MCLKDIV_4; 192 mclk_div = WM8510_MCLKDIV_8;
193 bclk = WM8510_BCLKDIV_8; 193 bclk = WM8510_BCLKDIV_8;
194 break; 194 break;
195 195
196 case 8000: 196 case 8000:
197 pll_out = 12288000; 197 pll_out = 24576000;
198 mclk_div = WM8510_MCLKDIV_6; 198 mclk_div = WM8510_MCLKDIV_12;
199 bclk = WM8510_BCLKDIV_8; 199 bclk = WM8510_BCLKDIV_8;
200 break; 200 break;
201 201
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 6ea04be911d0..173a239a541c 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -36,6 +36,7 @@
36#include <linux/timer.h> 36#include <linux/timer.h>
37#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/i2c.h>
39 40
40#include <linux/atmel-ssc.h> 41#include <linux/atmel-ssc.h>
41 42
@@ -45,6 +46,7 @@
45#include <sound/soc.h> 46#include <sound/soc.h>
46#include <sound/soc-dapm.h> 47#include <sound/soc-dapm.h>
47 48
49#include <asm/mach-types.h>
48#include <mach/hardware.h> 50#include <mach/hardware.h>
49#include <mach/gpio.h> 51#include <mach/gpio.h>
50 52
@@ -52,6 +54,9 @@
52#include "atmel-pcm.h" 54#include "atmel-pcm.h"
53#include "atmel_ssc_dai.h" 55#include "atmel_ssc_dai.h"
54 56
57#define MCLK_RATE 12000000
58
59static struct clk *mclk;
55 60
56static int at91sam9g20ek_startup(struct snd_pcm_substream *substream) 61static int at91sam9g20ek_startup(struct snd_pcm_substream *substream)
57{ 62{
@@ -59,11 +64,12 @@ static int at91sam9g20ek_startup(struct snd_pcm_substream *substream)
59 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 64 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
60 int ret; 65 int ret;
61 66
62 /* codec system clock is supplied by PCK0, set to 12MHz */
63 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, 67 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
64 12000000, SND_SOC_CLOCK_IN); 68 MCLK_RATE, SND_SOC_CLOCK_IN);
65 if (ret < 0) 69 if (ret < 0) {
70 clk_disable(mclk);
66 return ret; 71 return ret;
72 }
67 73
68 return 0; 74 return 0;
69} 75}
@@ -189,6 +195,31 @@ static struct snd_soc_ops at91sam9g20ek_ops = {
189 .shutdown = at91sam9g20ek_shutdown, 195 .shutdown = at91sam9g20ek_shutdown,
190}; 196};
191 197
198static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card,
199 enum snd_soc_bias_level level)
200{
201 static int mclk_on;
202 int ret = 0;
203
204 switch (level) {
205 case SND_SOC_BIAS_ON:
206 case SND_SOC_BIAS_PREPARE:
207 if (!mclk_on)
208 ret = clk_enable(mclk);
209 if (ret == 0)
210 mclk_on = 1;
211 break;
212
213 case SND_SOC_BIAS_OFF:
214 case SND_SOC_BIAS_STANDBY:
215 if (mclk_on)
216 clk_disable(mclk);
217 mclk_on = 0;
218 break;
219 }
220
221 return ret;
222}
192 223
193static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = { 224static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
194 SND_SOC_DAPM_MIC("Int Mic", NULL), 225 SND_SOC_DAPM_MIC("Int Mic", NULL),
@@ -243,21 +274,48 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = {
243}; 274};
244 275
245static struct snd_soc_card snd_soc_at91sam9g20ek = { 276static struct snd_soc_card snd_soc_at91sam9g20ek = {
246 .name = "WM8731", 277 .name = "AT91SAMG20-EK",
247 .platform = &atmel_soc_platform, 278 .platform = &atmel_soc_platform,
248 .dai_link = &at91sam9g20ek_dai, 279 .dai_link = &at91sam9g20ek_dai,
249 .num_links = 1, 280 .num_links = 1,
281 .set_bias_level = at91sam9g20ek_set_bias_level,
250}; 282};
251 283
252static struct wm8731_setup_data at91sam9g20ek_wm8731_setup = { 284/*
253 .i2c_bus = 0, 285 * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
254 .i2c_address = 0x1b, 286 * New drivers should register the wm8731 I2C device in the machine
255}; 287 * setup code (under arch/arm for ARM systems).
288 */
289static int wm8731_i2c_register(void)
290{
291 struct i2c_board_info info;
292 struct i2c_adapter *adapter;
293 struct i2c_client *client;
294
295 memset(&info, 0, sizeof(struct i2c_board_info));
296 info.addr = 0x1b;
297 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
298
299 adapter = i2c_get_adapter(0);
300 if (!adapter) {
301 printk(KERN_ERR "can't get i2c adapter 0\n");
302 return -ENODEV;
303 }
304
305 client = i2c_new_device(adapter, &info);
306 i2c_put_adapter(adapter);
307 if (!client) {
308 printk(KERN_ERR "can't add i2c device at 0x%x\n",
309 (unsigned int)info.addr);
310 return -ENODEV;
311 }
312
313 return 0;
314}
256 315
257static struct snd_soc_device at91sam9g20ek_snd_devdata = { 316static struct snd_soc_device at91sam9g20ek_snd_devdata = {
258 .card = &snd_soc_at91sam9g20ek, 317 .card = &snd_soc_at91sam9g20ek,
259 .codec_dev = &soc_codec_dev_wm8731, 318 .codec_dev = &soc_codec_dev_wm8731,
260 .codec_data = &at91sam9g20ek_wm8731_setup,
261}; 319};
262 320
263static struct platform_device *at91sam9g20ek_snd_device; 321static struct platform_device *at91sam9g20ek_snd_device;
@@ -266,23 +324,56 @@ static int __init at91sam9g20ek_init(void)
266{ 324{
267 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data; 325 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
268 struct ssc_device *ssc = NULL; 326 struct ssc_device *ssc = NULL;
327 struct clk *pllb;
269 int ret; 328 int ret;
270 329
330 if (!machine_is_at91sam9g20ek())
331 return -ENODEV;
332
333 /*
334 * Codec MCLK is supplied by PCK0 - set it up.
335 */
336 mclk = clk_get(NULL, "pck0");
337 if (IS_ERR(mclk)) {
338 printk(KERN_ERR "ASoC: Failed to get MCLK\n");
339 ret = PTR_ERR(mclk);
340 goto err;
341 }
342
343 pllb = clk_get(NULL, "pllb");
344 if (IS_ERR(mclk)) {
345 printk(KERN_ERR "ASoC: Failed to get PLLB\n");
346 ret = PTR_ERR(mclk);
347 goto err_mclk;
348 }
349 ret = clk_set_parent(mclk, pllb);
350 clk_put(pllb);
351 if (ret != 0) {
352 printk(KERN_ERR "ASoC: Failed to set MCLK parent\n");
353 goto err_mclk;
354 }
355
356 clk_set_rate(mclk, MCLK_RATE);
357
271 /* 358 /*
272 * Request SSC device 359 * Request SSC device
273 */ 360 */
274 ssc = ssc_request(0); 361 ssc = ssc_request(0);
275 if (IS_ERR(ssc)) { 362 if (IS_ERR(ssc)) {
363 printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
276 ret = PTR_ERR(ssc); 364 ret = PTR_ERR(ssc);
277 ssc = NULL; 365 ssc = NULL;
278 goto err_ssc; 366 goto err_ssc;
279 } 367 }
280 ssc_p->ssc = ssc; 368 ssc_p->ssc = ssc;
281 369
370 ret = wm8731_i2c_register();
371 if (ret != 0)
372 goto err_ssc;
373
282 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); 374 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
283 if (!at91sam9g20ek_snd_device) { 375 if (!at91sam9g20ek_snd_device) {
284 printk(KERN_DEBUG 376 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
285 "platform device allocation failed\n");
286 ret = -ENOMEM; 377 ret = -ENOMEM;
287 } 378 }
288 379
@@ -292,14 +383,19 @@ static int __init at91sam9g20ek_init(void)
292 383
293 ret = platform_device_add(at91sam9g20ek_snd_device); 384 ret = platform_device_add(at91sam9g20ek_snd_device);
294 if (ret) { 385 if (ret) {
295 printk(KERN_DEBUG 386 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
296 "platform device allocation failed\n");
297 platform_device_put(at91sam9g20ek_snd_device); 387 platform_device_put(at91sam9g20ek_snd_device);
298 } 388 }
299 389
300 return ret; 390 return ret;
301 391
302err_ssc: 392err_ssc:
393 ssc_free(ssc);
394 ssc_p->ssc = NULL;
395err_mclk:
396 clk_put(mclk);
397 mclk = NULL;
398err:
303 return ret; 399 return ret;
304} 400}
305 401
@@ -317,6 +413,8 @@ static void __exit at91sam9g20ek_exit(void)
317 413
318 platform_device_unregister(at91sam9g20ek_snd_device); 414 platform_device_unregister(at91sam9g20ek_snd_device);
319 at91sam9g20ek_snd_device = NULL; 415 at91sam9g20ek_snd_device = NULL;
416 clk_put(mclk);
417 mclk = NULL;
320} 418}
321 419
322module_init(at91sam9g20ek_init); 420module_init(at91sam9g20ek_init);
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index bc8d654576c0..30490a259148 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -305,7 +305,7 @@ static int au1xpsc_pcm_close(struct snd_pcm_substream *substream)
305 return 0; 305 return 0;
306} 306}
307 307
308struct snd_pcm_ops au1xpsc_pcm_ops = { 308static struct snd_pcm_ops au1xpsc_pcm_ops = {
309 .open = au1xpsc_pcm_open, 309 .open = au1xpsc_pcm_open,
310 .close = au1xpsc_pcm_close, 310 .close = au1xpsc_pcm_close,
311 .ioctl = snd_pcm_lib_ioctl, 311 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index f0e30aec7f23..479d7bdf1865 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -342,6 +342,11 @@ static int au1xpsc_ac97_resume(struct snd_soc_dai *dai)
342 return 0; 342 return 0;
343} 343}
344 344
345static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
346 .trigger = au1xpsc_ac97_trigger,
347 .hw_params = au1xpsc_ac97_hw_params,
348};
349
345struct snd_soc_dai au1xpsc_ac97_dai = { 350struct snd_soc_dai au1xpsc_ac97_dai = {
346 .name = "au1xpsc_ac97", 351 .name = "au1xpsc_ac97",
347 .ac97_control = 1, 352 .ac97_control = 1,
@@ -361,10 +366,7 @@ struct snd_soc_dai au1xpsc_ac97_dai = {
361 .channels_min = 2, 366 .channels_min = 2,
362 .channels_max = 2, 367 .channels_max = 2,
363 }, 368 },
364 .ops = { 369 .ops = &au1xpsc_ac97_dai_ops,
365 .trigger = au1xpsc_ac97_trigger,
366 .hw_params = au1xpsc_ac97_hw_params,
367 },
368}; 370};
369EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai); 371EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
370 372
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index f916de4400ed..bb589327ee32 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -367,6 +367,12 @@ static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai)
367 return 0; 367 return 0;
368} 368}
369 369
370static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
371 .trigger = au1xpsc_i2s_trigger,
372 .hw_params = au1xpsc_i2s_hw_params,
373 .set_fmt = au1xpsc_i2s_set_fmt,
374};
375
370struct snd_soc_dai au1xpsc_i2s_dai = { 376struct snd_soc_dai au1xpsc_i2s_dai = {
371 .name = "au1xpsc_i2s", 377 .name = "au1xpsc_i2s",
372 .probe = au1xpsc_i2s_probe, 378 .probe = au1xpsc_i2s_probe,
@@ -385,11 +391,7 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
385 .channels_min = 2, 391 .channels_min = 2,
386 .channels_max = 8, /* 2 without external help */ 392 .channels_max = 8, /* 2 without external help */
387 }, 393 },
388 .ops = { 394 .ops = &au1xpsc_i2s_dai_ops,
389 .trigger = au1xpsc_i2s_trigger,
390 .hw_params = au1xpsc_i2s_hw_params,
391 .set_fmt = au1xpsc_i2s_set_fmt,
392 },
393}; 395};
394EXPORT_SYMBOL(au1xpsc_i2s_dai); 396EXPORT_SYMBOL(au1xpsc_i2s_dai);
395 397
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 8067cfafa3a7..8cfed1a5dcbe 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -297,7 +297,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
297} 297}
298#endif 298#endif
299 299
300struct snd_pcm_ops bf5xx_pcm_ac97_ops = { 300static struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
301 .open = bf5xx_pcm_open, 301 .open = bf5xx_pcm_open,
302 .ioctl = snd_pcm_lib_ioctl, 302 .ioctl = snd_pcm_lib_ioctl,
303 .hw_params = bf5xx_pcm_hw_params, 303 .hw_params = bf5xx_pcm_hw_params,
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 3be2be60576d..8a935f2d1767 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -31,72 +31,46 @@
31#include "bf5xx-sport.h" 31#include "bf5xx-sport.h"
32#include "bf5xx-ac97.h" 32#include "bf5xx-ac97.h"
33 33
34#if defined(CONFIG_BF54x)
35#define PIN_REQ_SPORT_0 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, \
36 P_SPORT0_RFS, P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}
37
38#define PIN_REQ_SPORT_1 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, \
39 P_SPORT1_RFS, P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}
40
41#define PIN_REQ_SPORT_2 {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, \
42 P_SPORT2_RFS, P_SPORT2_DRPRI, P_SPORT2_RSCLK, 0}
43
44#define PIN_REQ_SPORT_3 {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, \
45 P_SPORT3_RFS, P_SPORT3_DRPRI, P_SPORT3_RSCLK, 0}
46#else
47#define PIN_REQ_SPORT_0 {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \
48 P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}
49
50#define PIN_REQ_SPORT_1 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \
51 P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}
52#endif
53
54static int *cmd_count; 34static int *cmd_count;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; 35static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56 36
37#define SPORT_REQ(x) \
38 [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
39 P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
57static u16 sport_req[][7] = { 40static u16 sport_req[][7] = {
58 PIN_REQ_SPORT_0, 41#ifdef SPORT0_TCR1
59#ifdef PIN_REQ_SPORT_1 42 SPORT_REQ(0),
60 PIN_REQ_SPORT_1, 43#endif
44#ifdef SPORT1_TCR1
45 SPORT_REQ(1),
61#endif 46#endif
62#ifdef PIN_REQ_SPORT_2 47#ifdef SPORT2_TCR1
63 PIN_REQ_SPORT_2, 48 SPORT_REQ(2),
64#endif 49#endif
65#ifdef PIN_REQ_SPORT_3 50#ifdef SPORT3_TCR1
66 PIN_REQ_SPORT_3, 51 SPORT_REQ(3),
67#endif 52#endif
68 }; 53};
69 54
55#define SPORT_PARAMS(x) \
56 [x] = { \
57 .dma_rx_chan = CH_SPORT##x##_RX, \
58 .dma_tx_chan = CH_SPORT##x##_TX, \
59 .err_irq = IRQ_SPORT##x##_ERROR, \
60 .regs = (struct sport_register *)SPORT##x##_TCR1, \
61 }
70static struct sport_param sport_params[4] = { 62static struct sport_param sport_params[4] = {
71 { 63#ifdef SPORT0_TCR1
72 .dma_rx_chan = CH_SPORT0_RX, 64 SPORT_PARAMS(0),
73 .dma_tx_chan = CH_SPORT0_TX,
74 .err_irq = IRQ_SPORT0_ERROR,
75 .regs = (struct sport_register *)SPORT0_TCR1,
76 },
77#ifdef PIN_REQ_SPORT_1
78 {
79 .dma_rx_chan = CH_SPORT1_RX,
80 .dma_tx_chan = CH_SPORT1_TX,
81 .err_irq = IRQ_SPORT1_ERROR,
82 .regs = (struct sport_register *)SPORT1_TCR1,
83 },
84#endif 65#endif
85#ifdef PIN_REQ_SPORT_2 66#ifdef SPORT1_TCR1
86 { 67 SPORT_PARAMS(1),
87 .dma_rx_chan = CH_SPORT2_RX,
88 .dma_tx_chan = CH_SPORT2_TX,
89 .err_irq = IRQ_SPORT2_ERROR,
90 .regs = (struct sport_register *)SPORT2_TCR1,
91 },
92#endif 68#endif
93#ifdef PIN_REQ_SPORT_3 69#ifdef SPORT2_TCR1
94 { 70 SPORT_PARAMS(2),
95 .dma_rx_chan = CH_SPORT3_RX, 71#endif
96 .dma_tx_chan = CH_SPORT3_TX, 72#ifdef SPORT3_TCR1
97 .err_irq = IRQ_SPORT3_ERROR, 73 SPORT_PARAMS(3),
98 .regs = (struct sport_register *)SPORT3_TCR1,
99 }
100#endif 74#endif
101}; 75};
102 76
@@ -332,11 +306,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
332 if (cmd_count == NULL) 306 if (cmd_count == NULL)
333 return -ENOMEM; 307 return -ENOMEM;
334 308
335 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { 309 if (peripheral_request_list(sport_req[sport_num], "soc-audio")) {
336 pr_err("Requesting Peripherals failed\n"); 310 pr_err("Requesting Peripherals failed\n");
337 ret = -EFAULT; 311 ret = -EFAULT;
338 goto peripheral_err; 312 goto peripheral_err;
339 } 313 }
340 314
341#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 315#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
342 /* Request PB3 as reset pin */ 316 /* Request PB3 as reset pin */
@@ -383,9 +357,9 @@ sport_config_err:
383sport_err: 357sport_err:
384#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 358#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
385 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 359 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
386#endif
387gpio_err: 360gpio_err:
388 peripheral_free_list(&sport_req[sport_num][0]); 361#endif
362 peripheral_free_list(sport_req[sport_num]);
389peripheral_err: 363peripheral_err:
390 free_page((unsigned long)cmd_count); 364 free_page((unsigned long)cmd_count);
391 cmd_count = NULL; 365 cmd_count = NULL;
@@ -398,7 +372,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
398{ 372{
399 free_page((unsigned long)cmd_count); 373 free_page((unsigned long)cmd_count);
400 cmd_count = NULL; 374 cmd_count = NULL;
401 peripheral_free_list(&sport_req[sport_num][0]); 375 peripheral_free_list(sport_req[sport_num]);
402#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 376#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
403 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 377 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
404#endif 378#endif
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 7f2a5e199075..edfbdc024e66 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -114,7 +114,7 @@ static int snd_ad73311_configure(void)
114 SSYNC(); 114 SSYNC();
115 115
116 /* When TUVF is set, the data is already send out */ 116 /* When TUVF is set, the data is already send out */
117 while (!(status & TUVF) && count++ < 10000) { 117 while (!(status & TUVF) && ++count < 10000) {
118 udelay(1); 118 udelay(1);
119 status = bfin_read_SPORT_STAT(); 119 status = bfin_read_SPORT_STAT();
120 SSYNC(); 120 SSYNC();
@@ -123,7 +123,7 @@ static int snd_ad73311_configure(void)
123 SSYNC(); 123 SSYNC();
124 local_irq_enable(); 124 local_irq_enable();
125 125
126 if (count == 10000) { 126 if (count >= 10000) {
127 printk(KERN_ERR "ad73311: failed to configure codec\n"); 127 printk(KERN_ERR "ad73311: failed to configure codec\n");
128 return -1; 128 return -1;
129 } 129 }
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 53d290b3ea47..1318c4f627b7 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -184,7 +184,7 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
184 return 0 ; 184 return 0 ;
185} 185}
186 186
187struct snd_pcm_ops bf5xx_pcm_i2s_ops = { 187static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
188 .open = bf5xx_pcm_open, 188 .open = bf5xx_pcm_open,
189 .ioctl = snd_pcm_lib_ioctl, 189 .ioctl = snd_pcm_lib_ioctl,
190 .hw_params = bf5xx_pcm_hw_params, 190 .hw_params = bf5xx_pcm_hw_params,
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index d1d95d2393fe..964824419678 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -287,6 +287,13 @@ static int bf5xx_i2s_resume(struct platform_device *pdev,
287#define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ 287#define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
288 SNDRV_PCM_FMTBIT_S32_LE) 288 SNDRV_PCM_FMTBIT_S32_LE)
289 289
290static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
291 .startup = bf5xx_i2s_startup,
292 .shutdown = bf5xx_i2s_shutdown,
293 .hw_params = bf5xx_i2s_hw_params,
294 .set_fmt = bf5xx_i2s_set_dai_fmt,
295};
296
290struct snd_soc_dai bf5xx_i2s_dai = { 297struct snd_soc_dai bf5xx_i2s_dai = {
291 .name = "bf5xx-i2s", 298 .name = "bf5xx-i2s",
292 .id = 0, 299 .id = 0,
@@ -304,12 +311,7 @@ struct snd_soc_dai bf5xx_i2s_dai = {
304 .channels_max = 2, 311 .channels_max = 2,
305 .rates = BF5XX_I2S_RATES, 312 .rates = BF5XX_I2S_RATES,
306 .formats = BF5XX_I2S_FORMATS,}, 313 .formats = BF5XX_I2S_FORMATS,},
307 .ops = { 314 .ops = &bf5xx_i2s_dai_ops,
308 .startup = bf5xx_i2s_startup,
309 .shutdown = bf5xx_i2s_shutdown,
310 .hw_params = bf5xx_i2s_hw_params,
311 .set_fmt = bf5xx_i2s_set_dai_fmt,
312 },
313}; 315};
314EXPORT_SYMBOL_GPL(bf5xx_i2s_dai); 316EXPORT_SYMBOL_GPL(bf5xx_i2s_dai);
315 317
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
index 3b99e484d555..b7953c8cf838 100644
--- a/sound/soc/blackfin/bf5xx-sport.c
+++ b/sound/soc/blackfin/bf5xx-sport.c
@@ -133,7 +133,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
133 int i; 133 int i;
134 134
135 for (i = 0; i < fragcount; ++i) { 135 for (i = 0; i < fragcount; ++i) {
136 desc[i].next_desc_addr = (unsigned long)&(desc[i + 1]); 136 desc[i].next_desc_addr = &(desc[i + 1]);
137 desc[i].start_addr = (unsigned long)buf + i*fragsize; 137 desc[i].start_addr = (unsigned long)buf + i*fragsize;
138 desc[i].cfg = cfg; 138 desc[i].cfg = cfg;
139 desc[i].x_count = x_count; 139 desc[i].x_count = x_count;
@@ -143,12 +143,12 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
143 } 143 }
144 144
145 /* make circular */ 145 /* make circular */
146 desc[fragcount-1].next_desc_addr = (unsigned long)desc; 146 desc[fragcount-1].next_desc_addr = desc;
147 147
148 pr_debug("setup desc: desc0=%p, next0=%lx, desc1=%p," 148 pr_debug("setup desc: desc0=%p, next0=%p, desc1=%p,"
149 "next1=%lx\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n", 149 "next1=%p\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n",
150 &(desc[0]), desc[0].next_desc_addr, 150 desc, desc[0].next_desc_addr,
151 &(desc[1]), desc[1].next_desc_addr, 151 desc+1, desc[1].next_desc_addr,
152 desc[0].x_count, desc[0].y_count, 152 desc[0].x_count, desc[0].y_count,
153 desc[0].start_addr, desc[0].cfg); 153 desc[0].start_addr, desc[0].cfg);
154} 154}
@@ -184,22 +184,20 @@ static inline int sport_hook_rx_dummy(struct sport_device *sport)
184 BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc); 184 BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc);
185 185
186 /* Maybe the dummy buffer descriptor ring is damaged */ 186 /* Maybe the dummy buffer descriptor ring is damaged */
187 sport->dummy_rx_desc->next_desc_addr = \ 187 sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc + 1;
188 (unsigned long)(sport->dummy_rx_desc+1);
189 188
190 local_irq_save(flags); 189 local_irq_save(flags);
191 desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_rx_chan); 190 desc = get_dma_next_desc_ptr(sport->dma_rx_chan);
192 /* Copy the descriptor which will be damaged to backup */ 191 /* Copy the descriptor which will be damaged to backup */
193 temp_desc = *desc; 192 temp_desc = *desc;
194 desc->x_count = 0xa; 193 desc->x_count = 0xa;
195 desc->y_count = 0; 194 desc->y_count = 0;
196 desc->next_desc_addr = (unsigned long)(sport->dummy_rx_desc); 195 desc->next_desc_addr = sport->dummy_rx_desc;
197 local_irq_restore(flags); 196 local_irq_restore(flags);
198 /* Waiting for dummy buffer descriptor is already hooked*/ 197 /* Waiting for dummy buffer descriptor is already hooked*/
199 while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - 198 while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
200 sizeof(struct dmasg)) != 199 sizeof(struct dmasg)) != sport->dummy_rx_desc)
201 (unsigned long)sport->dummy_rx_desc) 200 continue;
202 ;
203 sport->curr_rx_desc = sport->dummy_rx_desc; 201 sport->curr_rx_desc = sport->dummy_rx_desc;
204 /* Restore the damaged descriptor */ 202 /* Restore the damaged descriptor */
205 *desc = temp_desc; 203 *desc = temp_desc;
@@ -210,14 +208,12 @@ static inline int sport_hook_rx_dummy(struct sport_device *sport)
210static inline int sport_rx_dma_start(struct sport_device *sport, int dummy) 208static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
211{ 209{
212 if (dummy) { 210 if (dummy) {
213 sport->dummy_rx_desc->next_desc_addr = \ 211 sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc;
214 (unsigned long) sport->dummy_rx_desc;
215 sport->curr_rx_desc = sport->dummy_rx_desc; 212 sport->curr_rx_desc = sport->dummy_rx_desc;
216 } else 213 } else
217 sport->curr_rx_desc = sport->dma_rx_desc; 214 sport->curr_rx_desc = sport->dma_rx_desc;
218 215
219 set_dma_next_desc_addr(sport->dma_rx_chan, \ 216 set_dma_next_desc_addr(sport->dma_rx_chan, sport->curr_rx_desc);
220 (unsigned long)(sport->curr_rx_desc));
221 set_dma_x_count(sport->dma_rx_chan, 0); 217 set_dma_x_count(sport->dma_rx_chan, 0);
222 set_dma_x_modify(sport->dma_rx_chan, 0); 218 set_dma_x_modify(sport->dma_rx_chan, 0);
223 set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \ 219 set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \
@@ -231,14 +227,12 @@ static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
231static inline int sport_tx_dma_start(struct sport_device *sport, int dummy) 227static inline int sport_tx_dma_start(struct sport_device *sport, int dummy)
232{ 228{
233 if (dummy) { 229 if (dummy) {
234 sport->dummy_tx_desc->next_desc_addr = \ 230 sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc;
235 (unsigned long) sport->dummy_tx_desc;
236 sport->curr_tx_desc = sport->dummy_tx_desc; 231 sport->curr_tx_desc = sport->dummy_tx_desc;
237 } else 232 } else
238 sport->curr_tx_desc = sport->dma_tx_desc; 233 sport->curr_tx_desc = sport->dma_tx_desc;
239 234
240 set_dma_next_desc_addr(sport->dma_tx_chan, \ 235 set_dma_next_desc_addr(sport->dma_tx_chan, sport->curr_tx_desc);
241 (unsigned long)(sport->curr_tx_desc));
242 set_dma_x_count(sport->dma_tx_chan, 0); 236 set_dma_x_count(sport->dma_tx_chan, 0);
243 set_dma_x_modify(sport->dma_tx_chan, 0); 237 set_dma_x_modify(sport->dma_tx_chan, 0);
244 set_dma_config(sport->dma_tx_chan, 238 set_dma_config(sport->dma_tx_chan,
@@ -261,11 +255,9 @@ int sport_rx_start(struct sport_device *sport)
261 BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc); 255 BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc);
262 local_irq_save(flags); 256 local_irq_save(flags);
263 while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - 257 while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
264 sizeof(struct dmasg)) != 258 sizeof(struct dmasg)) != sport->dummy_rx_desc)
265 (unsigned long)sport->dummy_rx_desc) 259 continue;
266 ; 260 sport->dummy_rx_desc->next_desc_addr = sport->dma_rx_desc;
267 sport->dummy_rx_desc->next_desc_addr =
268 (unsigned long)(sport->dma_rx_desc);
269 local_irq_restore(flags); 261 local_irq_restore(flags);
270 sport->curr_rx_desc = sport->dma_rx_desc; 262 sport->curr_rx_desc = sport->dma_rx_desc;
271 } else { 263 } else {
@@ -310,23 +302,21 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport)
310 BUG_ON(sport->dummy_tx_desc == NULL); 302 BUG_ON(sport->dummy_tx_desc == NULL);
311 BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc); 303 BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc);
312 304
313 sport->dummy_tx_desc->next_desc_addr = \ 305 sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc + 1;
314 (unsigned long)(sport->dummy_tx_desc+1);
315 306
316 /* Shorten the time on last normal descriptor */ 307 /* Shorten the time on last normal descriptor */
317 local_irq_save(flags); 308 local_irq_save(flags);
318 desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_tx_chan); 309 desc = get_dma_next_desc_ptr(sport->dma_tx_chan);
319 /* Store the descriptor which will be damaged */ 310 /* Store the descriptor which will be damaged */
320 temp_desc = *desc; 311 temp_desc = *desc;
321 desc->x_count = 0xa; 312 desc->x_count = 0xa;
322 desc->y_count = 0; 313 desc->y_count = 0;
323 desc->next_desc_addr = (unsigned long)(sport->dummy_tx_desc); 314 desc->next_desc_addr = sport->dummy_tx_desc;
324 local_irq_restore(flags); 315 local_irq_restore(flags);
325 /* Waiting for dummy buffer descriptor is already hooked*/ 316 /* Waiting for dummy buffer descriptor is already hooked*/
326 while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \ 317 while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
327 sizeof(struct dmasg)) != \ 318 sizeof(struct dmasg)) != sport->dummy_tx_desc)
328 (unsigned long)sport->dummy_tx_desc) 319 continue;
329 ;
330 sport->curr_tx_desc = sport->dummy_tx_desc; 320 sport->curr_tx_desc = sport->dummy_tx_desc;
331 /* Restore the damaged descriptor */ 321 /* Restore the damaged descriptor */
332 *desc = temp_desc; 322 *desc = temp_desc;
@@ -347,11 +337,9 @@ int sport_tx_start(struct sport_device *sport)
347 /* Hook the normal buffer descriptor */ 337 /* Hook the normal buffer descriptor */
348 local_irq_save(flags); 338 local_irq_save(flags);
349 while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - 339 while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) -
350 sizeof(struct dmasg)) != 340 sizeof(struct dmasg)) != sport->dummy_tx_desc)
351 (unsigned long)sport->dummy_tx_desc) 341 continue;
352 ; 342 sport->dummy_tx_desc->next_desc_addr = sport->dma_tx_desc;
353 sport->dummy_tx_desc->next_desc_addr =
354 (unsigned long)(sport->dma_tx_desc);
355 local_irq_restore(flags); 343 local_irq_restore(flags);
356 sport->curr_tx_desc = sport->dma_tx_desc; 344 sport->curr_tx_desc = sport->dma_tx_desc;
357 } else { 345 } else {
@@ -536,19 +524,17 @@ static int sport_config_rx_dummy(struct sport_device *sport)
536 unsigned config; 524 unsigned config;
537 525
538 pr_debug("%s entered\n", __func__); 526 pr_debug("%s entered\n", __func__);
539#if L1_DATA_A_LENGTH != 0 527 if (L1_DATA_A_LENGTH)
540 desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc)); 528 desc = l1_data_sram_zalloc(2 * sizeof(*desc));
541#else 529 else {
542 {
543 dma_addr_t addr; 530 dma_addr_t addr;
544 desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0); 531 desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
532 memset(desc, 0, 2 * sizeof(*desc));
545 } 533 }
546#endif
547 if (desc == NULL) { 534 if (desc == NULL) {
548 pr_err("Failed to allocate memory for dummy rx desc\n"); 535 pr_err("Failed to allocate memory for dummy rx desc\n");
549 return -ENOMEM; 536 return -ENOMEM;
550 } 537 }
551 memset(desc, 0, 2 * sizeof(*desc));
552 sport->dummy_rx_desc = desc; 538 sport->dummy_rx_desc = desc;
553 desc->start_addr = (unsigned long)sport->dummy_buf; 539 desc->start_addr = (unsigned long)sport->dummy_buf;
554 config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize) 540 config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize)
@@ -559,8 +545,8 @@ static int sport_config_rx_dummy(struct sport_device *sport)
559 desc->y_count = 0; 545 desc->y_count = 0;
560 desc->y_modify = 0; 546 desc->y_modify = 0;
561 memcpy(desc+1, desc, sizeof(*desc)); 547 memcpy(desc+1, desc, sizeof(*desc));
562 desc->next_desc_addr = (unsigned long)(desc+1); 548 desc->next_desc_addr = desc + 1;
563 desc[1].next_desc_addr = (unsigned long)desc; 549 desc[1].next_desc_addr = desc;
564 return 0; 550 return 0;
565} 551}
566 552
@@ -571,19 +557,17 @@ static int sport_config_tx_dummy(struct sport_device *sport)
571 557
572 pr_debug("%s entered\n", __func__); 558 pr_debug("%s entered\n", __func__);
573 559
574#if L1_DATA_A_LENGTH != 0 560 if (L1_DATA_A_LENGTH)
575 desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc)); 561 desc = l1_data_sram_zalloc(2 * sizeof(*desc));
576#else 562 else {
577 {
578 dma_addr_t addr; 563 dma_addr_t addr;
579 desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0); 564 desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
565 memset(desc, 0, 2 * sizeof(*desc));
580 } 566 }
581#endif
582 if (!desc) { 567 if (!desc) {
583 pr_err("Failed to allocate memory for dummy tx desc\n"); 568 pr_err("Failed to allocate memory for dummy tx desc\n");
584 return -ENOMEM; 569 return -ENOMEM;
585 } 570 }
586 memset(desc, 0, 2 * sizeof(*desc));
587 sport->dummy_tx_desc = desc; 571 sport->dummy_tx_desc = desc;
588 desc->start_addr = (unsigned long)sport->dummy_buf + \ 572 desc->start_addr = (unsigned long)sport->dummy_buf + \
589 sport->dummy_count; 573 sport->dummy_count;
@@ -595,8 +579,8 @@ static int sport_config_tx_dummy(struct sport_device *sport)
595 desc->y_count = 0; 579 desc->y_count = 0;
596 desc->y_modify = 0; 580 desc->y_modify = 0;
597 memcpy(desc+1, desc, sizeof(*desc)); 581 memcpy(desc+1, desc, sizeof(*desc));
598 desc->next_desc_addr = (unsigned long)(desc+1); 582 desc->next_desc_addr = desc + 1;
599 desc[1].next_desc_addr = (unsigned long)desc; 583 desc[1].next_desc_addr = desc;
600 return 0; 584 return 0;
601} 585}
602 586
@@ -872,17 +856,15 @@ struct sport_device *sport_init(struct sport_param *param, unsigned wdsize,
872 sport->wdsize = wdsize; 856 sport->wdsize = wdsize;
873 sport->dummy_count = dummy_count; 857 sport->dummy_count = dummy_count;
874 858
875#if L1_DATA_A_LENGTH != 0 859 if (L1_DATA_A_LENGTH)
876 sport->dummy_buf = l1_data_sram_alloc(dummy_count * 2); 860 sport->dummy_buf = l1_data_sram_zalloc(dummy_count * 2);
877#else 861 else
878 sport->dummy_buf = kmalloc(dummy_count * 2, GFP_KERNEL); 862 sport->dummy_buf = kzalloc(dummy_count * 2, GFP_KERNEL);
879#endif
880 if (sport->dummy_buf == NULL) { 863 if (sport->dummy_buf == NULL) {
881 pr_err("Failed to allocate dummy buffer\n"); 864 pr_err("Failed to allocate dummy buffer\n");
882 goto __error; 865 goto __error;
883 } 866 }
884 867
885 memset(sport->dummy_buf, 0, dummy_count * 2);
886 ret = sport_config_rx_dummy(sport); 868 ret = sport_config_rx_dummy(sport);
887 if (ret) { 869 if (ret) {
888 pr_err("Failed to config rx dummy ring\n"); 870 pr_err("Failed to config rx dummy ring\n");
@@ -939,6 +921,7 @@ void sport_done(struct sport_device *sport)
939 sport = NULL; 921 sport = NULL;
940} 922}
941EXPORT_SYMBOL(sport_done); 923EXPORT_SYMBOL(sport_done);
924
942/* 925/*
943* It is only used to send several bytes when dma is not enabled 926* It is only used to send several bytes when dma is not enabled
944 * sport controller is configured but not enabled. 927 * sport controller is configured but not enabled.
@@ -1029,4 +1012,3 @@ EXPORT_SYMBOL(sport_send_and_recv);
1029MODULE_AUTHOR("Roy Huang"); 1012MODULE_AUTHOR("Roy Huang");
1030MODULE_DESCRIPTION("SPORT driver for ADI Blackfin"); 1013MODULE_DESCRIPTION("SPORT driver for ADI Blackfin");
1031MODULE_LICENSE("GPL"); 1014MODULE_LICENSE("GPL");
1032
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index d0e0d691ae51..b6c7f7a01cb0 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -10,9 +10,11 @@ config SND_SOC_I2C_AND_SPI
10 10
11config SND_SOC_ALL_CODECS 11config SND_SOC_ALL_CODECS
12 tristate "Build all ASoC CODEC drivers" 12 tristate "Build all ASoC CODEC drivers"
13 select SND_SOC_L3
13 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
14 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 15 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
15 select SND_SOC_AD73311 if I2C 16 select SND_SOC_AD73311 if I2C
17 select SND_SOC_AK4104 if SPI_MASTER
16 select SND_SOC_AK4535 if I2C 18 select SND_SOC_AK4535 if I2C
17 select SND_SOC_CS4270 if I2C 19 select SND_SOC_CS4270 if I2C
18 select SND_SOC_PCM3008 20 select SND_SOC_PCM3008
@@ -24,6 +26,7 @@ config SND_SOC_ALL_CODECS
24 select SND_SOC_UDA134X 26 select SND_SOC_UDA134X
25 select SND_SOC_UDA1380 if I2C 27 select SND_SOC_UDA1380 if I2C
26 select SND_SOC_WM8350 if MFD_WM8350 28 select SND_SOC_WM8350 if MFD_WM8350
29 select SND_SOC_WM8400 if MFD_WM8400
27 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 30 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
28 select SND_SOC_WM8580 if I2C 31 select SND_SOC_WM8580 if I2C
29 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 32 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
@@ -34,6 +37,7 @@ config SND_SOC_ALL_CODECS
34 select SND_SOC_WM8903 if I2C 37 select SND_SOC_WM8903 if I2C
35 select SND_SOC_WM8971 if I2C 38 select SND_SOC_WM8971 if I2C
36 select SND_SOC_WM8990 if I2C 39 select SND_SOC_WM8990 if I2C
40 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
37 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 41 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
38 select SND_SOC_WM9713 if SND_SOC_AC97_BUS 42 select SND_SOC_WM9713 if SND_SOC_AC97_BUS
39 help 43 help
@@ -58,6 +62,9 @@ config SND_SOC_AD1980
58config SND_SOC_AD73311 62config SND_SOC_AD73311
59 tristate 63 tristate
60 64
65config SND_SOC_AK4104
66 tristate
67
61config SND_SOC_AK4535 68config SND_SOC_AK4535
62 tristate 69 tristate
63 70
@@ -65,12 +72,6 @@ config SND_SOC_AK4535
65config SND_SOC_CS4270 72config SND_SOC_CS4270
66 tristate 73 tristate
67 74
68# Cirrus Logic CS4270 Codec Hardware Mute Support
69# Select if you have external muting circuitry attached to your CS4270.
70config SND_SOC_CS4270_HWMUTE
71 bool
72 depends on SND_SOC_CS4270
73
74# Cirrus Logic CS4270 Codec VD = 3.3V Errata 75# Cirrus Logic CS4270 Codec VD = 3.3V Errata
75# Select if you are affected by the errata where the part will not function 76# Select if you are affected by the errata where the part will not function
76# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will 77# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
@@ -90,7 +91,6 @@ config SND_SOC_SSM2602
90 91
91config SND_SOC_TLV320AIC23 92config SND_SOC_TLV320AIC23
92 tristate 93 tristate
93 depends on I2C
94 94
95config SND_SOC_TLV320AIC26 95config SND_SOC_TLV320AIC26
96 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE 96 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
@@ -98,15 +98,12 @@ config SND_SOC_TLV320AIC26
98 98
99config SND_SOC_TLV320AIC3X 99config SND_SOC_TLV320AIC3X
100 tristate 100 tristate
101 depends on I2C
102 101
103config SND_SOC_TWL4030 102config SND_SOC_TWL4030
104 tristate 103 tristate
105 depends on TWL4030_CORE
106 104
107config SND_SOC_UDA134X 105config SND_SOC_UDA134X
108 tristate 106 tristate
109 select SND_SOC_L3
110 107
111config SND_SOC_UDA1380 108config SND_SOC_UDA1380
112 tristate 109 tristate
@@ -114,6 +111,9 @@ config SND_SOC_UDA1380
114config SND_SOC_WM8350 111config SND_SOC_WM8350
115 tristate 112 tristate
116 113
114config SND_SOC_WM8400
115 tristate
116
117config SND_SOC_WM8510 117config SND_SOC_WM8510
118 tristate 118 tristate
119 119
@@ -144,6 +144,9 @@ config SND_SOC_WM8971
144config SND_SOC_WM8990 144config SND_SOC_WM8990
145 tristate 145 tristate
146 146
147config SND_SOC_WM9705
148 tristate
149
147config SND_SOC_WM9712 150config SND_SOC_WM9712
148 tristate 151 tristate
149 152
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index c4ddc9aa2bbd..030d2454725f 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,6 +1,7 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1980-objs := ad1980.o 2snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o 3snd-soc-ad73311-objs := ad73311.o
4snd-soc-ak4104-objs := ak4104.o
4snd-soc-ak4535-objs := ak4535.o 5snd-soc-ak4535-objs := ak4535.o
5snd-soc-cs4270-objs := cs4270.o 6snd-soc-cs4270-objs := cs4270.o
6snd-soc-l3-objs := l3.o 7snd-soc-l3-objs := l3.o
@@ -13,6 +14,7 @@ snd-soc-twl4030-objs := twl4030.o
13snd-soc-uda134x-objs := uda134x.o 14snd-soc-uda134x-objs := uda134x.o
14snd-soc-uda1380-objs := uda1380.o 15snd-soc-uda1380-objs := uda1380.o
15snd-soc-wm8350-objs := wm8350.o 16snd-soc-wm8350-objs := wm8350.o
17snd-soc-wm8400-objs := wm8400.o
16snd-soc-wm8510-objs := wm8510.o 18snd-soc-wm8510-objs := wm8510.o
17snd-soc-wm8580-objs := wm8580.o 19snd-soc-wm8580-objs := wm8580.o
18snd-soc-wm8728-objs := wm8728.o 20snd-soc-wm8728-objs := wm8728.o
@@ -23,12 +25,14 @@ snd-soc-wm8900-objs := wm8900.o
23snd-soc-wm8903-objs := wm8903.o 25snd-soc-wm8903-objs := wm8903.o
24snd-soc-wm8971-objs := wm8971.o 26snd-soc-wm8971-objs := wm8971.o
25snd-soc-wm8990-objs := wm8990.o 27snd-soc-wm8990-objs := wm8990.o
28snd-soc-wm9705-objs := wm9705.o
26snd-soc-wm9712-objs := wm9712.o 29snd-soc-wm9712-objs := wm9712.o
27snd-soc-wm9713-objs := wm9713.o 30snd-soc-wm9713-objs := wm9713.o
28 31
29obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 32obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
30obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 33obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
31obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 34obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
35obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
32obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 36obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
33obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 37obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
34obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 38obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
@@ -41,6 +45,7 @@ obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
41obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 45obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
42obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 46obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
43obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 47obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
48obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
44obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 49obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
45obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 50obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
46obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 51obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
@@ -51,5 +56,7 @@ obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
51obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 56obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
52obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 57obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
53obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 58obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
59obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o
60obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
54obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 61obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
55obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o 62obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index fb53e6511af2..b0d4af145b87 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -30,7 +30,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
30 struct snd_pcm_runtime *runtime = substream->runtime; 30 struct snd_pcm_runtime *runtime = substream->runtime;
31 struct snd_soc_pcm_runtime *rtd = substream->private_data; 31 struct snd_soc_pcm_runtime *rtd = substream->private_data;
32 struct snd_soc_device *socdev = rtd->socdev; 32 struct snd_soc_device *socdev = rtd->socdev;
33 struct snd_soc_codec *codec = socdev->codec; 33 struct snd_soc_codec *codec = socdev->card->codec;
34 34
35 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 35 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
36 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; 36 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
@@ -41,6 +41,10 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
41 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ 41 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
42 SNDRV_PCM_RATE_48000) 42 SNDRV_PCM_RATE_48000)
43 43
44static struct snd_soc_dai_ops ac97_dai_ops = {
45 .prepare = ac97_prepare,
46};
47
44struct snd_soc_dai ac97_dai = { 48struct snd_soc_dai ac97_dai = {
45 .name = "AC97 HiFi", 49 .name = "AC97 HiFi",
46 .ac97_control = 1, 50 .ac97_control = 1,
@@ -56,8 +60,7 @@ struct snd_soc_dai ac97_dai = {
56 .channels_max = 2, 60 .channels_max = 2,
57 .rates = STD_AC97_RATES, 61 .rates = STD_AC97_RATES,
58 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 62 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
59 .ops = { 63 .ops = &ac97_dai_ops,
60 .prepare = ac97_prepare,},
61}; 64};
62EXPORT_SYMBOL_GPL(ac97_dai); 65EXPORT_SYMBOL_GPL(ac97_dai);
63 66
@@ -84,10 +87,10 @@ static int ac97_soc_probe(struct platform_device *pdev)
84 87
85 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); 88 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
86 89
87 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 90 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
88 if (!socdev->codec) 91 if (!socdev->card->codec)
89 return -ENOMEM; 92 return -ENOMEM;
90 codec = socdev->codec; 93 codec = socdev->card->codec;
91 mutex_init(&codec->mutex); 94 mutex_init(&codec->mutex);
92 95
93 codec->name = "AC97"; 96 codec->name = "AC97";
@@ -123,23 +126,21 @@ bus_err:
123 snd_soc_free_pcms(socdev); 126 snd_soc_free_pcms(socdev);
124 127
125err: 128err:
126 kfree(socdev->codec->reg_cache); 129 kfree(socdev->card->codec);
127 kfree(socdev->codec); 130 socdev->card->codec = NULL;
128 socdev->codec = NULL;
129 return ret; 131 return ret;
130} 132}
131 133
132static int ac97_soc_remove(struct platform_device *pdev) 134static int ac97_soc_remove(struct platform_device *pdev)
133{ 135{
134 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 136 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
135 struct snd_soc_codec *codec = socdev->codec; 137 struct snd_soc_codec *codec = socdev->card->codec;
136 138
137 if (!codec) 139 if (!codec)
138 return 0; 140 return 0;
139 141
140 snd_soc_free_pcms(socdev); 142 snd_soc_free_pcms(socdev);
141 kfree(socdev->codec->reg_cache); 143 kfree(socdev->card->codec);
142 kfree(socdev->codec);
143 144
144 return 0; 145 return 0;
145} 146}
@@ -149,7 +150,7 @@ static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg)
149{ 150{
150 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 151 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
151 152
152 snd_ac97_suspend(socdev->codec->ac97); 153 snd_ac97_suspend(socdev->card->codec->ac97);
153 154
154 return 0; 155 return 0;
155} 156}
@@ -158,7 +159,7 @@ static int ac97_soc_resume(struct platform_device *pdev)
158{ 159{
159 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 160 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
160 161
161 snd_ac97_resume(socdev->codec->ac97); 162 snd_ac97_resume(socdev->card->codec->ac97);
162 163
163 return 0; 164 return 0;
164} 165}
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 73fdbb4d4a3d..ddb3b08ac23c 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -93,20 +93,6 @@ SOC_ENUM("Capture Source", ad1980_cap_src),
93SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0), 93SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
94}; 94};
95 95
96/* add non dapm controls */
97static int ad1980_add_controls(struct snd_soc_codec *codec)
98{
99 int err, i;
100
101 for (i = 0; i < ARRAY_SIZE(ad1980_snd_ac97_controls); i++) {
102 err = snd_ctl_add(codec->card, snd_soc_cnew(
103 &ad1980_snd_ac97_controls[i], codec, NULL));
104 if (err < 0)
105 return err;
106 }
107 return 0;
108}
109
110static unsigned int ac97_read(struct snd_soc_codec *codec, 96static unsigned int ac97_read(struct snd_soc_codec *codec,
111 unsigned int reg) 97 unsigned int reg)
112{ 98{
@@ -123,7 +109,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
123 default: 109 default:
124 reg = reg >> 1; 110 reg = reg >> 1;
125 111
126 if (reg >= (ARRAY_SIZE(ad1980_reg))) 112 if (reg >= ARRAY_SIZE(ad1980_reg))
127 return -EINVAL; 113 return -EINVAL;
128 114
129 return cache[reg]; 115 return cache[reg];
@@ -137,7 +123,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
137 123
138 soc_ac97_ops.write(codec->ac97, reg, val); 124 soc_ac97_ops.write(codec->ac97, reg, val);
139 reg = reg >> 1; 125 reg = reg >> 1;
140 if (reg < (ARRAY_SIZE(ad1980_reg))) 126 if (reg < ARRAY_SIZE(ad1980_reg))
141 cache[reg] = val; 127 cache[reg] = val;
142 128
143 return 0; 129 return 0;
@@ -200,10 +186,10 @@ static int ad1980_soc_probe(struct platform_device *pdev)
200 186
201 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 187 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
202 188
203 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 189 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
204 if (socdev->codec == NULL) 190 if (socdev->card->codec == NULL)
205 return -ENOMEM; 191 return -ENOMEM;
206 codec = socdev->codec; 192 codec = socdev->card->codec;
207 mutex_init(&codec->mutex); 193 mutex_init(&codec->mutex);
208 194
209 codec->reg_cache = 195 codec->reg_cache =
@@ -269,7 +255,8 @@ static int ad1980_soc_probe(struct platform_device *pdev)
269 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); 255 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
270 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); 256 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
271 257
272 ad1980_add_controls(codec); 258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls,
259 ARRAY_SIZE(ad1980_snd_ac97_controls));
273 ret = snd_soc_init_card(socdev); 260 ret = snd_soc_init_card(socdev);
274 if (ret < 0) { 261 if (ret < 0) {
275 printk(KERN_ERR "ad1980: failed to register card\n"); 262 printk(KERN_ERR "ad1980: failed to register card\n");
@@ -288,15 +275,15 @@ codec_err:
288 kfree(codec->reg_cache); 275 kfree(codec->reg_cache);
289 276
290cache_err: 277cache_err:
291 kfree(socdev->codec); 278 kfree(socdev->card->codec);
292 socdev->codec = NULL; 279 socdev->card->codec = NULL;
293 return ret; 280 return ret;
294} 281}
295 282
296static int ad1980_soc_remove(struct platform_device *pdev) 283static int ad1980_soc_remove(struct platform_device *pdev)
297{ 284{
298 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 285 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
299 struct snd_soc_codec *codec = socdev->codec; 286 struct snd_soc_codec *codec = socdev->card->codec;
300 287
301 if (codec == NULL) 288 if (codec == NULL)
302 return 0; 289 return 0;
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index b09289a1e55a..e61dac5e7b8f 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -53,7 +53,7 @@ static int ad73311_soc_probe(struct platform_device *pdev)
53 codec->owner = THIS_MODULE; 53 codec->owner = THIS_MODULE;
54 codec->dai = &ad73311_dai; 54 codec->dai = &ad73311_dai;
55 codec->num_dai = 1; 55 codec->num_dai = 1;
56 socdev->codec = codec; 56 socdev->card->codec = codec;
57 INIT_LIST_HEAD(&codec->dapm_widgets); 57 INIT_LIST_HEAD(&codec->dapm_widgets);
58 INIT_LIST_HEAD(&codec->dapm_paths); 58 INIT_LIST_HEAD(&codec->dapm_paths);
59 59
@@ -75,15 +75,15 @@ static int ad73311_soc_probe(struct platform_device *pdev)
75register_err: 75register_err:
76 snd_soc_free_pcms(socdev); 76 snd_soc_free_pcms(socdev);
77pcm_err: 77pcm_err:
78 kfree(socdev->codec); 78 kfree(socdev->card->codec);
79 socdev->codec = NULL; 79 socdev->card->codec = NULL;
80 return ret; 80 return ret;
81} 81}
82 82
83static int ad73311_soc_remove(struct platform_device *pdev) 83static int ad73311_soc_remove(struct platform_device *pdev)
84{ 84{
85 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 85 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
86 struct snd_soc_codec *codec = socdev->codec; 86 struct snd_soc_codec *codec = socdev->card->codec;
87 87
88 if (codec == NULL) 88 if (codec == NULL)
89 return 0; 89 return 0;
diff --git a/sound/soc/codecs/ad73311.h b/sound/soc/codecs/ad73311.h
index 507ce0c30edf..569573d2d4d7 100644
--- a/sound/soc/codecs/ad73311.h
+++ b/sound/soc/codecs/ad73311.h
@@ -70,7 +70,7 @@
70#define REGD_IGS(x) (x & 0x7) 70#define REGD_IGS(x) (x & 0x7)
71#define REGD_RMOD (1 << 3) 71#define REGD_RMOD (1 << 3)
72#define REGD_OGS(x) ((x & 0x7) << 4) 72#define REGD_OGS(x) ((x & 0x7) << 4)
73#define REGD_MUTE (x << 7) 73#define REGD_MUTE (1 << 7)
74 74
75/* Control register E */ 75/* Control register E */
76#define CTRL_REG_E (4 << 8) 76#define CTRL_REG_E (4 << 8)
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
new file mode 100644
index 000000000000..4d47bc4f7428
--- /dev/null
+++ b/sound/soc/codecs/ak4104.c
@@ -0,0 +1,365 @@
1/*
2 * AK4104 ALSA SoC (ASoC) driver
3 *
4 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/module.h>
13#include <sound/core.h>
14#include <sound/soc.h>
15#include <sound/initval.h>
16#include <linux/spi/spi.h>
17#include <sound/asoundef.h>
18
19#include "ak4104.h"
20
21/* AK4104 registers addresses */
22#define AK4104_REG_CONTROL1 0x00
23#define AK4104_REG_RESERVED 0x01
24#define AK4104_REG_CONTROL2 0x02
25#define AK4104_REG_TX 0x03
26#define AK4104_REG_CHN_STATUS(x) ((x) + 0x04)
27#define AK4104_NUM_REGS 10
28
29#define AK4104_REG_MASK 0x1f
30#define AK4104_READ 0xc0
31#define AK4104_WRITE 0xe0
32#define AK4104_RESERVED_VAL 0x5b
33
34/* Bit masks for AK4104 registers */
35#define AK4104_CONTROL1_RSTN (1 << 0)
36#define AK4104_CONTROL1_PW (1 << 1)
37#define AK4104_CONTROL1_DIF0 (1 << 2)
38#define AK4104_CONTROL1_DIF1 (1 << 3)
39
40#define AK4104_CONTROL2_SEL0 (1 << 0)
41#define AK4104_CONTROL2_SEL1 (1 << 1)
42#define AK4104_CONTROL2_MODE (1 << 2)
43
44#define AK4104_TX_TXE (1 << 0)
45#define AK4104_TX_V (1 << 1)
46
47#define DRV_NAME "ak4104"
48
49struct ak4104_private {
50 struct snd_soc_codec codec;
51 u8 reg_cache[AK4104_NUM_REGS];
52};
53
54static int ak4104_fill_cache(struct snd_soc_codec *codec)
55{
56 int i;
57 u8 *reg_cache = codec->reg_cache;
58 struct spi_device *spi = codec->control_data;
59
60 for (i = 0; i < codec->reg_cache_size; i++) {
61 int ret = spi_w8r8(spi, i | AK4104_READ);
62 if (ret < 0) {
63 dev_err(&spi->dev, "SPI write failure\n");
64 return ret;
65 }
66
67 reg_cache[i] = ret;
68 }
69
70 return 0;
71}
72
73static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
74 unsigned int reg)
75{
76 u8 *reg_cache = codec->reg_cache;
77
78 if (reg >= codec->reg_cache_size)
79 return -EINVAL;
80
81 return reg_cache[reg];
82}
83
84static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
85 unsigned int value)
86{
87 u8 *cache = codec->reg_cache;
88 struct spi_device *spi = codec->control_data;
89
90 if (reg >= codec->reg_cache_size)
91 return -EINVAL;
92
93 reg &= AK4104_REG_MASK;
94 reg |= AK4104_WRITE;
95
96 /* only write to the hardware if value has changed */
97 if (cache[reg] != value) {
98 u8 tmp[2] = { reg, value };
99 if (spi_write(spi, tmp, sizeof(tmp))) {
100 dev_err(&spi->dev, "SPI write failed\n");
101 return -EIO;
102 }
103
104 cache[reg] = value;
105 }
106
107 return 0;
108}
109
110static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
111 unsigned int format)
112{
113 struct snd_soc_codec *codec = codec_dai->codec;
114 int val = 0;
115
116 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
117 if (val < 0)
118 return val;
119
120 val &= ~(AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1);
121
122 /* set DAI format */
123 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
124 case SND_SOC_DAIFMT_RIGHT_J:
125 break;
126 case SND_SOC_DAIFMT_LEFT_J:
127 val |= AK4104_CONTROL1_DIF0;
128 break;
129 case SND_SOC_DAIFMT_I2S:
130 val |= AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1;
131 break;
132 default:
133 dev_err(codec->dev, "invalid dai format\n");
134 return -EINVAL;
135 }
136
137 /* This device can only be slave */
138 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
139 return -EINVAL;
140
141 return ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
142}
143
144static int ak4104_hw_params(struct snd_pcm_substream *substream,
145 struct snd_pcm_hw_params *params,
146 struct snd_soc_dai *dai)
147{
148 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct snd_soc_device *socdev = rtd->socdev;
150 struct snd_soc_codec *codec = socdev->card->codec;
151 int val = 0;
152
153 /* set the IEC958 bits: consumer mode, no copyright bit */
154 val |= IEC958_AES0_CON_NOT_COPYRIGHT;
155 ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(0), val);
156
157 val = 0;
158
159 switch (params_rate(params)) {
160 case 44100:
161 val |= IEC958_AES3_CON_FS_44100;
162 break;
163 case 48000:
164 val |= IEC958_AES3_CON_FS_48000;
165 break;
166 case 32000:
167 val |= IEC958_AES3_CON_FS_32000;
168 break;
169 default:
170 dev_err(codec->dev, "unsupported sampling rate\n");
171 return -EINVAL;
172 }
173
174 return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val);
175}
176
177static struct snd_soc_dai_ops ak4101_dai_ops = {
178 .hw_params = ak4104_hw_params,
179 .set_fmt = ak4104_set_dai_fmt,
180};
181
182struct snd_soc_dai ak4104_dai = {
183 .name = DRV_NAME,
184 .playback = {
185 .stream_name = "Playback",
186 .channels_min = 2,
187 .channels_max = 2,
188 .rates = SNDRV_PCM_RATE_44100 |
189 SNDRV_PCM_RATE_48000 |
190 SNDRV_PCM_RATE_32000,
191 .formats = SNDRV_PCM_FMTBIT_S16_LE |
192 SNDRV_PCM_FMTBIT_S24_3LE |
193 SNDRV_PCM_FMTBIT_S24_LE
194 },
195 .ops = &ak4101_dai_ops,
196};
197
198static struct snd_soc_codec *ak4104_codec;
199
200static int ak4104_spi_probe(struct spi_device *spi)
201{
202 struct snd_soc_codec *codec;
203 struct ak4104_private *ak4104;
204 int ret, val;
205
206 spi->bits_per_word = 8;
207 spi->mode = SPI_MODE_0;
208 ret = spi_setup(spi);
209 if (ret < 0)
210 return ret;
211
212 ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
213 if (!ak4104) {
214 dev_err(&spi->dev, "could not allocate codec\n");
215 return -ENOMEM;
216 }
217
218 codec = &ak4104->codec;
219 mutex_init(&codec->mutex);
220 INIT_LIST_HEAD(&codec->dapm_widgets);
221 INIT_LIST_HEAD(&codec->dapm_paths);
222
223 codec->dev = &spi->dev;
224 codec->name = DRV_NAME;
225 codec->owner = THIS_MODULE;
226 codec->dai = &ak4104_dai;
227 codec->num_dai = 1;
228 codec->private_data = ak4104;
229 codec->control_data = spi;
230 codec->reg_cache = ak4104->reg_cache;
231 codec->reg_cache_size = AK4104_NUM_REGS;
232
233 /* read all regs and fill the cache */
234 ret = ak4104_fill_cache(codec);
235 if (ret < 0) {
236 dev_err(&spi->dev, "failed to fill register cache\n");
237 return ret;
238 }
239
240 /* read the 'reserved' register - according to the datasheet, it
241 * should contain 0x5b. Not a good way to verify the presence of
242 * the device, but there is no hardware ID register. */
243 if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
244 AK4104_RESERVED_VAL) {
245 ret = -ENODEV;
246 goto error_free_codec;
247 }
248
249 /* set power-up and non-reset bits */
250 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
251 val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN;
252 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
253 if (ret < 0)
254 goto error_free_codec;
255
256 /* enable transmitter */
257 val = ak4104_read_reg_cache(codec, AK4104_REG_TX);
258 val |= AK4104_TX_TXE;
259 ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
260 if (ret < 0)
261 goto error_free_codec;
262
263 ak4104_codec = codec;
264 ret = snd_soc_register_dai(&ak4104_dai);
265 if (ret < 0) {
266 dev_err(&spi->dev, "failed to register DAI\n");
267 goto error_free_codec;
268 }
269
270 spi_set_drvdata(spi, ak4104);
271 dev_info(&spi->dev, "SPI device initialized\n");
272 return 0;
273
274error_free_codec:
275 kfree(ak4104);
276 ak4104_dai.dev = NULL;
277 return ret;
278}
279
280static int __devexit ak4104_spi_remove(struct spi_device *spi)
281{
282 int ret, val;
283 struct ak4104_private *ak4104 = spi_get_drvdata(spi);
284
285 val = ak4104_read_reg_cache(&ak4104->codec, AK4104_REG_CONTROL1);
286 if (val < 0)
287 return val;
288
289 /* clear power-up and non-reset bits */
290 val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
291 ret = ak4104_spi_write(&ak4104->codec, AK4104_REG_CONTROL1, val);
292 if (ret < 0)
293 return ret;
294
295 ak4104_codec = NULL;
296 kfree(ak4104);
297 return 0;
298}
299
300static int ak4104_probe(struct platform_device *pdev)
301{
302 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
303 struct snd_soc_codec *codec = ak4104_codec;
304 int ret;
305
306 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
307 socdev->card->codec = codec;
308
309 /* Register PCMs */
310 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
311 if (ret < 0) {
312 dev_err(codec->dev, "failed to create pcms\n");
313 return ret;
314 }
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;
325}
326
327static int ak4104_remove(struct platform_device *pdev)
328{
329 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
330 snd_soc_free_pcms(socdev);
331 return 0;
332};
333
334struct snd_soc_codec_device soc_codec_device_ak4104 = {
335 .probe = ak4104_probe,
336 .remove = ak4104_remove
337};
338EXPORT_SYMBOL_GPL(soc_codec_device_ak4104);
339
340static struct spi_driver ak4104_spi_driver = {
341 .driver = {
342 .name = DRV_NAME,
343 .owner = THIS_MODULE,
344 },
345 .probe = ak4104_spi_probe,
346 .remove = __devexit_p(ak4104_spi_remove),
347};
348
349static int __init ak4104_init(void)
350{
351 pr_info("Asahi Kasei AK4104 ALSA SoC Codec Driver\n");
352 return spi_register_driver(&ak4104_spi_driver);
353}
354module_init(ak4104_init);
355
356static void __exit ak4104_exit(void)
357{
358 spi_unregister_driver(&ak4104_spi_driver);
359}
360module_exit(ak4104_exit);
361
362MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
363MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver");
364MODULE_LICENSE("GPL");
365
diff --git a/sound/soc/codecs/ak4104.h b/sound/soc/codecs/ak4104.h
new file mode 100644
index 000000000000..eb88fe7e4def
--- /dev/null
+++ b/sound/soc/codecs/ak4104.h
@@ -0,0 +1,7 @@
1#ifndef _AK4104_H
2#define _AK4104_H
3
4extern struct snd_soc_dai ak4104_dai;
5extern struct snd_soc_codec_device soc_codec_device_ak4104;
6
7#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 81300d8d42ca..1f63d387a2f4 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -155,21 +155,6 @@ static const struct snd_kcontrol_new ak4535_snd_controls[] = {
155 SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL, 4, 7, 0), 155 SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL, 4, 7, 0),
156}; 156};
157 157
158/* add non dapm controls */
159static int ak4535_add_controls(struct snd_soc_codec *codec)
160{
161 int err, i;
162
163 for (i = 0; i < ARRAY_SIZE(ak4535_snd_controls); i++) {
164 err = snd_ctl_add(codec->card,
165 snd_soc_cnew(&ak4535_snd_controls[i], codec, NULL));
166 if (err < 0)
167 return err;
168 }
169
170 return 0;
171}
172
173/* Mono 1 Mixer */ 158/* Mono 1 Mixer */
174static const struct snd_kcontrol_new ak4535_mono1_mixer_controls[] = { 159static const struct snd_kcontrol_new ak4535_mono1_mixer_controls[] = {
175 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1, 4, 1, 0), 160 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1, 4, 1, 0),
@@ -344,7 +329,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
344{ 329{
345 struct snd_soc_pcm_runtime *rtd = substream->private_data; 330 struct snd_soc_pcm_runtime *rtd = substream->private_data;
346 struct snd_soc_device *socdev = rtd->socdev; 331 struct snd_soc_device *socdev = rtd->socdev;
347 struct snd_soc_codec *codec = socdev->codec; 332 struct snd_soc_codec *codec = socdev->card->codec;
348 struct ak4535_priv *ak4535 = codec->private_data; 333 struct ak4535_priv *ak4535 = codec->private_data;
349 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); 334 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
350 int rate = params_rate(params), fs = 256; 335 int rate = params_rate(params), fs = 256;
@@ -436,6 +421,13 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
436 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ 421 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
437 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 422 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
438 423
424static struct snd_soc_dai_ops ak4535_dai_ops = {
425 .hw_params = ak4535_hw_params,
426 .set_fmt = ak4535_set_dai_fmt,
427 .digital_mute = ak4535_mute,
428 .set_sysclk = ak4535_set_dai_sysclk,
429};
430
439struct snd_soc_dai ak4535_dai = { 431struct snd_soc_dai ak4535_dai = {
440 .name = "AK4535", 432 .name = "AK4535",
441 .playback = { 433 .playback = {
@@ -450,19 +442,14 @@ struct snd_soc_dai ak4535_dai = {
450 .channels_max = 2, 442 .channels_max = 2,
451 .rates = AK4535_RATES, 443 .rates = AK4535_RATES,
452 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 444 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
453 .ops = { 445 .ops = &ak4535_dai_ops,
454 .hw_params = ak4535_hw_params,
455 .set_fmt = ak4535_set_dai_fmt,
456 .digital_mute = ak4535_mute,
457 .set_sysclk = ak4535_set_dai_sysclk,
458 },
459}; 446};
460EXPORT_SYMBOL_GPL(ak4535_dai); 447EXPORT_SYMBOL_GPL(ak4535_dai);
461 448
462static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) 449static int ak4535_suspend(struct platform_device *pdev, pm_message_t state)
463{ 450{
464 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 451 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
465 struct snd_soc_codec *codec = socdev->codec; 452 struct snd_soc_codec *codec = socdev->card->codec;
466 453
467 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); 454 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
468 return 0; 455 return 0;
@@ -471,7 +458,7 @@ static int ak4535_suspend(struct platform_device *pdev, pm_message_t state)
471static int ak4535_resume(struct platform_device *pdev) 458static int ak4535_resume(struct platform_device *pdev)
472{ 459{
473 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 460 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
474 struct snd_soc_codec *codec = socdev->codec; 461 struct snd_soc_codec *codec = socdev->card->codec;
475 ak4535_sync(codec); 462 ak4535_sync(codec);
476 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 463 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
477 ak4535_set_bias_level(codec, codec->suspend_bias_level); 464 ak4535_set_bias_level(codec, codec->suspend_bias_level);
@@ -484,7 +471,7 @@ static int ak4535_resume(struct platform_device *pdev)
484 */ 471 */
485static int ak4535_init(struct snd_soc_device *socdev) 472static int ak4535_init(struct snd_soc_device *socdev)
486{ 473{
487 struct snd_soc_codec *codec = socdev->codec; 474 struct snd_soc_codec *codec = socdev->card->codec;
488 int ret = 0; 475 int ret = 0;
489 476
490 codec->name = "AK4535"; 477 codec->name = "AK4535";
@@ -510,7 +497,8 @@ static int ak4535_init(struct snd_soc_device *socdev)
510 /* power on device */ 497 /* power on device */
511 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 498 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
512 499
513 ak4535_add_controls(codec); 500 snd_soc_add_controls(codec, ak4535_snd_controls,
501 ARRAY_SIZE(ak4535_snd_controls));
514 ak4535_add_widgets(codec); 502 ak4535_add_widgets(codec);
515 ret = snd_soc_init_card(socdev); 503 ret = snd_soc_init_card(socdev);
516 if (ret < 0) { 504 if (ret < 0) {
@@ -537,7 +525,7 @@ static int ak4535_i2c_probe(struct i2c_client *i2c,
537 const struct i2c_device_id *id) 525 const struct i2c_device_id *id)
538{ 526{
539 struct snd_soc_device *socdev = ak4535_socdev; 527 struct snd_soc_device *socdev = ak4535_socdev;
540 struct snd_soc_codec *codec = socdev->codec; 528 struct snd_soc_codec *codec = socdev->card->codec;
541 int ret; 529 int ret;
542 530
543 i2c_set_clientdata(i2c, codec); 531 i2c_set_clientdata(i2c, codec);
@@ -636,7 +624,7 @@ static int ak4535_probe(struct platform_device *pdev)
636 } 624 }
637 625
638 codec->private_data = ak4535; 626 codec->private_data = ak4535;
639 socdev->codec = codec; 627 socdev->card->codec = codec;
640 mutex_init(&codec->mutex); 628 mutex_init(&codec->mutex);
641 INIT_LIST_HEAD(&codec->dapm_widgets); 629 INIT_LIST_HEAD(&codec->dapm_widgets);
642 INIT_LIST_HEAD(&codec->dapm_paths); 630 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -663,7 +651,7 @@ static int ak4535_probe(struct platform_device *pdev)
663static int ak4535_remove(struct platform_device *pdev) 651static int ak4535_remove(struct platform_device *pdev)
664{ 652{
665 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 653 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
666 struct snd_soc_codec *codec = socdev->codec; 654 struct snd_soc_codec *codec = socdev->card->codec;
667 655
668 if (codec->control_data) 656 if (codec->control_data)
669 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); 657 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index f1aa0c34421c..7fa09a387622 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -3,27 +3,22 @@
3 * 3 *
4 * Author: Timur Tabi <timur@freescale.com> 4 * Author: Timur Tabi <timur@freescale.com>
5 * 5 *
6 * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under 6 * Copyright 2007-2009 Freescale Semiconductor, Inc. This file is licensed
7 * the terms of the GNU General Public License version 2. This program 7 * under the terms of the GNU General Public License version 2. This
8 * is licensed "as is" without any warranty of any kind, whether express 8 * program is licensed "as is" without any warranty of any kind, whether
9 * or implied. 9 * express or implied.
10 * 10 *
11 * This is an ASoC device driver for the Cirrus Logic CS4270 codec. 11 * This is an ASoC device driver for the Cirrus Logic CS4270 codec.
12 * 12 *
13 * Current features/limitations: 13 * Current features/limitations:
14 * 14 *
15 * 1) Software mode is supported. Stand-alone mode is automatically 15 * - Software mode is supported. Stand-alone mode is not supported.
16 * selected if I2C is disabled or if a CS4270 is not found on the I2C 16 * - Only I2C is supported, not SPI
17 * bus. However, stand-alone mode is only partially implemented because 17 * - Support for master and slave mode
18 * there is no mechanism yet for this driver and the machine driver to 18 * - The machine driver's 'startup' function must call
19 * communicate the values of the M0, M1, MCLK1, and MCLK2 pins. 19 * cs4270_set_dai_sysclk() with the value of MCLK.
20 * 2) Only I2C is supported, not SPI 20 * - Only I2S and left-justified modes are supported
21 * 3) Only Master mode is supported, not Slave. 21 * - Power management is not supported
22 * 4) The machine driver's 'startup' function must call
23 * cs4270_set_dai_sysclk() with the value of MCLK.
24 * 5) Only I2S and left-justified modes are supported
25 * 6) Power management is not supported
26 * 7) The only supported control is volume and hardware mute (if enabled)
27 */ 22 */
28 23
29#include <linux/module.h> 24#include <linux/module.h>
@@ -35,18 +30,6 @@
35 30
36#include "cs4270.h" 31#include "cs4270.h"
37 32
38/* If I2C is defined, then we support software mode. However, if we're
39 not compiled as module but I2C is, then we can't use I2C calls. */
40#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
41#define USE_I2C
42#endif
43
44/* Private data for the CS4270 */
45struct cs4270_private {
46 unsigned int mclk; /* Input frequency of the MCLK pin */
47 unsigned int mode; /* The mode (I2S or left-justified) */
48};
49
50/* 33/*
51 * The codec isn't really big-endian or little-endian, since the I2S 34 * The codec isn't really big-endian or little-endian, since the I2S
52 * interface requires data to be sent serially with the MSbit first. 35 * interface requires data to be sent serially with the MSbit first.
@@ -60,8 +43,6 @@ struct cs4270_private {
60 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ 43 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
61 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) 44 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
62 45
63#ifdef USE_I2C
64
65/* CS4270 registers addresses */ 46/* CS4270 registers addresses */
66#define CS4270_CHIPID 0x01 /* Chip ID */ 47#define CS4270_CHIPID 0x01 /* Chip ID */
67#define CS4270_PWRCTL 0x02 /* Power Control */ 48#define CS4270_PWRCTL 0x02 /* Power Control */
@@ -121,8 +102,22 @@ struct cs4270_private {
121#define CS4270_MUTE_DAC_A 0x01 102#define CS4270_MUTE_DAC_A 0x01
122#define CS4270_MUTE_DAC_B 0x02 103#define CS4270_MUTE_DAC_B 0x02
123 104
124/* 105/* Private data for the CS4270 */
125 * Clock Ratio Selection for Master Mode with I2C enabled 106struct cs4270_private {
107 struct snd_soc_codec codec;
108 u8 reg_cache[CS4270_NUMREGS];
109 unsigned int mclk; /* Input frequency of the MCLK pin */
110 unsigned int mode; /* The mode (I2S or left-justified) */
111 unsigned int slave_mode;
112};
113
114/**
115 * struct cs4270_mode_ratios - clock ratio tables
116 * @ratio: the ratio of MCLK to the sample rate
117 * @speed_mode: the Speed Mode bits to set in the Mode Control register for
118 * this ratio
119 * @mclk: the Ratio Select bits to set in the Mode Control register for this
120 * ratio
126 * 121 *
127 * The data for this chart is taken from Table 5 of the CS4270 reference 122 * The data for this chart is taken from Table 5 of the CS4270 reference
128 * manual. 123 * manual.
@@ -131,31 +126,30 @@ struct cs4270_private {
131 * It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling 126 * It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling
132 * rates the CS4270 currently supports. 127 * rates the CS4270 currently supports.
133 * 128 *
134 * Each element in this array corresponds to the ratios in mclk_ratios[]. 129 * @speed_mode is the corresponding bit pattern to be written to the
135 * These two arrays need to be in sync.
136 *
137 * 'speed_mode' is the corresponding bit pattern to be written to the
138 * MODE bits of the Mode Control Register 130 * MODE bits of the Mode Control Register
139 * 131 *
140 * 'mclk' is the corresponding bit pattern to be wirten to the MCLK bits of 132 * @mclk is the corresponding bit pattern to be wirten to the MCLK bits of
141 * the Mode Control Register. 133 * the Mode Control Register.
142 * 134 *
143 * In situations where a single ratio is represented by multiple speed 135 * In situations where a single ratio is represented by multiple speed
144 * modes, we favor the slowest speed. E.g, for a ratio of 128, we pick 136 * modes, we favor the slowest speed. E.g, for a ratio of 128, we pick
145 * double-speed instead of quad-speed. However, the CS4270 errata states 137 * double-speed instead of quad-speed. However, the CS4270 errata states
146 * that Divide-By-1.5 can cause failures, so we avoid that mode where 138 * that divide-By-1.5 can cause failures, so we avoid that mode where
147 * possible. 139 * possible.
148 * 140 *
149 * ERRATA: There is an errata for the CS4270 where divide-by-1.5 does not 141 * Errata: There is an errata for the CS4270 where divide-by-1.5 does not
150 * work if VD = 3.3V. If this effects you, select the 142 * work if Vd is 3.3V. If this effects you, select the
151 * CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will 143 * CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will
152 * never select any sample rates that require divide-by-1.5. 144 * never select any sample rates that require divide-by-1.5.
153 */ 145 */
154static struct { 146struct cs4270_mode_ratios {
155 unsigned int ratio; 147 unsigned int ratio;
156 u8 speed_mode; 148 u8 speed_mode;
157 u8 mclk; 149 u8 mclk;
158} cs4270_mode_ratios[] = { 150};
151
152static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
159 {64, CS4270_MODE_4X, CS4270_MODE_DIV1}, 153 {64, CS4270_MODE_4X, CS4270_MODE_DIV1},
160#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA 154#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
161 {96, CS4270_MODE_4X, CS4270_MODE_DIV15}, 155 {96, CS4270_MODE_4X, CS4270_MODE_DIV15},
@@ -172,34 +166,27 @@ static struct {
172/* The number of MCLK/LRCK ratios supported by the CS4270 */ 166/* The number of MCLK/LRCK ratios supported by the CS4270 */
173#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) 167#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
174 168
175/* 169/**
176 * Determine the CS4270 samples rates. 170 * cs4270_set_dai_sysclk - determine the CS4270 samples rates.
171 * @codec_dai: the codec DAI
172 * @clk_id: the clock ID (ignored)
173 * @freq: the MCLK input frequency
174 * @dir: the clock direction (ignored)
177 * 175 *
178 * 'freq' is the input frequency to MCLK. The other parameters are ignored. 176 * This function is used to tell the codec driver what the input MCLK
177 * frequency is.
179 * 178 *
180 * The value of MCLK is used to determine which sample rates are supported 179 * The value of MCLK is used to determine which sample rates are supported
181 * by the CS4270. The ratio of MCLK / Fs must be equal to one of nine 180 * by the CS4270. The ratio of MCLK / Fs must be equal to one of nine
182 * support values: 64, 96, 128, 192, 256, 384, 512, 768, and 1024. 181 * supported values - 64, 96, 128, 192, 256, 384, 512, 768, and 1024.
183 * 182 *
184 * This function calculates the nine ratios and determines which ones match 183 * This function calculates the nine ratios and determines which ones match
185 * a standard sample rate. If there's a match, then it is added to the list 184 * a standard sample rate. If there's a match, then it is added to the list
186 * of support sample rates. 185 * of supported sample rates.
187 * 186 *
188 * This function must be called by the machine driver's 'startup' function, 187 * This function must be called by the machine driver's 'startup' function,
189 * otherwise the list of supported sample rates will not be available in 188 * otherwise the list of supported sample rates will not be available in
190 * time for ALSA. 189 * time for ALSA.
191 *
192 * Note that in stand-alone mode, the sample rate is determined by input
193 * pins M0, M1, MDIV1, and MDIV2. Also in stand-alone mode, divide-by-3
194 * is not a programmable option. However, divide-by-3 is not an available
195 * option in stand-alone mode. This cases two problems: a ratio of 768 is
196 * not available (it requires divide-by-3) and B) ratios 192 and 384 can
197 * only be selected with divide-by-1.5, but there is an errate that make
198 * this selection difficult.
199 *
200 * In addition, there is no mechanism for communicating with the machine
201 * driver what the input settings can be. This would need to be implemented
202 * for stand-alone mode to work.
203 */ 190 */
204static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, 191static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
205 int clk_id, unsigned int freq, int dir) 192 int clk_id, unsigned int freq, int dir)
@@ -225,7 +212,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
225 rates &= ~SNDRV_PCM_RATE_KNOT; 212 rates &= ~SNDRV_PCM_RATE_KNOT;
226 213
227 if (!rates) { 214 if (!rates) {
228 printk(KERN_ERR "cs4270: could not find a valid sample rate\n"); 215 dev_err(codec->dev, "could not find a valid sample rate\n");
229 return -EINVAL; 216 return -EINVAL;
230 } 217 }
231 218
@@ -240,8 +227,10 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
240 return 0; 227 return 0;
241} 228}
242 229
243/* 230/**
244 * Configure the codec for the selected audio format 231 * cs4270_set_dai_fmt - configure the codec for the selected audio format
232 * @codec_dai: the codec DAI
233 * @format: a SND_SOC_DAIFMT_x value indicating the data format
245 * 234 *
246 * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the 235 * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
247 * codec accordingly. 236 * codec accordingly.
@@ -258,32 +247,43 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
258 struct cs4270_private *cs4270 = codec->private_data; 247 struct cs4270_private *cs4270 = codec->private_data;
259 int ret = 0; 248 int ret = 0;
260 249
250 /* set DAI format */
261 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 251 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
262 case SND_SOC_DAIFMT_I2S: 252 case SND_SOC_DAIFMT_I2S:
263 case SND_SOC_DAIFMT_LEFT_J: 253 case SND_SOC_DAIFMT_LEFT_J:
264 cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK; 254 cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
265 break; 255 break;
266 default: 256 default:
267 printk(KERN_ERR "cs4270: invalid DAI format\n"); 257 dev_err(codec->dev, "invalid dai format\n");
258 ret = -EINVAL;
259 }
260
261 /* set master/slave audio interface */
262 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
263 case SND_SOC_DAIFMT_CBS_CFS:
264 cs4270->slave_mode = 1;
265 break;
266 case SND_SOC_DAIFMT_CBM_CFM:
267 cs4270->slave_mode = 0;
268 break;
269 default:
270 /* all other modes are unsupported by the hardware */
268 ret = -EINVAL; 271 ret = -EINVAL;
269 } 272 }
270 273
271 return ret; 274 return ret;
272} 275}
273 276
274/* 277/**
275 * A list of addresses on which this CS4270 could use. I2C addresses are 278 * cs4270_fill_cache - pre-fill the CS4270 register cache.
276 * 7 bits. For the CS4270, the upper four bits are always 1001, and the 279 * @codec: the codec for this CS4270
277 * lower three bits are determined via the AD2, AD1, and AD0 pins 280 *
278 * (respectively). 281 * This function fills in the CS4270 register cache by reading the register
279 */ 282 * values from the hardware.
280static const unsigned short normal_i2c[] = { 283 *
281 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, I2C_CLIENT_END 284 * This CS4270 registers are cached to avoid excessive I2C I/O operations.
282}; 285 * After the initial read to pre-fill the cache, the CS4270 never updates
283I2C_CLIENT_INSMOD; 286 * the register values, so we won't have a cache coherency problem.
284
285/*
286 * Pre-fill the CS4270 register cache.
287 * 287 *
288 * We use the auto-increment feature of the CS4270 to read all registers in 288 * We use the auto-increment feature of the CS4270 to read all registers in
289 * one shot. 289 * one shot.
@@ -298,7 +298,7 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec)
298 CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache); 298 CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache);
299 299
300 if (length != CS4270_NUMREGS) { 300 if (length != CS4270_NUMREGS) {
301 printk(KERN_ERR "cs4270: I2C read failure, addr=0x%x\n", 301 dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
302 i2c_client->addr); 302 i2c_client->addr);
303 return -EIO; 303 return -EIO;
304 } 304 }
@@ -306,12 +306,17 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec)
306 return 0; 306 return 0;
307} 307}
308 308
309/* 309/**
310 * Read from the CS4270 register cache. 310 * cs4270_read_reg_cache - read from the CS4270 register cache.
311 * @codec: the codec for this CS4270
312 * @reg: the register to read
313 *
314 * This function returns the value for a given register. It reads only from
315 * the register cache, not the hardware itself.
311 * 316 *
312 * This CS4270 registers are cached to avoid excessive I2C I/O operations. 317 * This CS4270 registers are cached to avoid excessive I2C I/O operations.
313 * After the initial read to pre-fill the cache, the CS4270 never updates 318 * After the initial read to pre-fill the cache, the CS4270 never updates
314 * the register values, so we won't have a cache coherncy problem. 319 * the register values, so we won't have a cache coherency problem.
315 */ 320 */
316static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, 321static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec,
317 unsigned int reg) 322 unsigned int reg)
@@ -324,8 +329,11 @@ static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec,
324 return cache[reg - CS4270_FIRSTREG]; 329 return cache[reg - CS4270_FIRSTREG];
325} 330}
326 331
327/* 332/**
328 * Write to a CS4270 register via the I2C bus. 333 * cs4270_i2c_write - write to a CS4270 register via the I2C bus.
334 * @codec: the codec for this CS4270
335 * @reg: the register to write
336 * @value: the value to write to the register
329 * 337 *
330 * This function writes the given value to the given CS4270 register, and 338 * This function writes the given value to the given CS4270 register, and
331 * also updates the register cache. 339 * also updates the register cache.
@@ -346,7 +354,7 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
346 if (cache[reg - CS4270_FIRSTREG] != value) { 354 if (cache[reg - CS4270_FIRSTREG] != value) {
347 struct i2c_client *client = codec->control_data; 355 struct i2c_client *client = codec->control_data;
348 if (i2c_smbus_write_byte_data(client, reg, value)) { 356 if (i2c_smbus_write_byte_data(client, reg, value)) {
349 printk(KERN_ERR "cs4270: I2C write failed\n"); 357 dev_err(codec->dev, "i2c write failed\n");
350 return -EIO; 358 return -EIO;
351 } 359 }
352 360
@@ -357,11 +365,17 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
357 return 0; 365 return 0;
358} 366}
359 367
360/* 368/**
361 * Program the CS4270 with the given hardware parameters. 369 * cs4270_hw_params - program the CS4270 with the given hardware parameters.
370 * @substream: the audio stream
371 * @params: the hardware parameters to set
372 * @dai: the SOC DAI (ignored)
373 *
374 * This function programs the hardware with the values provided.
375 * Specifically, the sample rate and the data format.
362 * 376 *
363 * The .ops functions are used to provide board-specific data, like 377 * The .ops functions are used to provide board-specific data, like input
364 * input frequencies, to this driver. This function takes that information, 378 * frequencies, to this driver. This function takes that information,
365 * combines it with the hardware parameters provided, and programs the 379 * combines it with the hardware parameters provided, and programs the
366 * hardware accordingly. 380 * hardware accordingly.
367 */ 381 */
@@ -371,7 +385,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
371{ 385{
372 struct snd_soc_pcm_runtime *rtd = substream->private_data; 386 struct snd_soc_pcm_runtime *rtd = substream->private_data;
373 struct snd_soc_device *socdev = rtd->socdev; 387 struct snd_soc_device *socdev = rtd->socdev;
374 struct snd_soc_codec *codec = socdev->codec; 388 struct snd_soc_codec *codec = socdev->card->codec;
375 struct cs4270_private *cs4270 = codec->private_data; 389 struct cs4270_private *cs4270 = codec->private_data;
376 int ret; 390 int ret;
377 unsigned int i; 391 unsigned int i;
@@ -391,33 +405,28 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
391 405
392 if (i == NUM_MCLK_RATIOS) { 406 if (i == NUM_MCLK_RATIOS) {
393 /* We did not find a matching ratio */ 407 /* We did not find a matching ratio */
394 printk(KERN_ERR "cs4270: could not find matching ratio\n"); 408 dev_err(codec->dev, "could not find matching ratio\n");
395 return -EINVAL; 409 return -EINVAL;
396 } 410 }
397 411
398 /* Freeze and power-down the codec */ 412 /* Set the sample rate */
399
400 ret = snd_soc_write(codec, CS4270_PWRCTL, CS4270_PWRCTL_FREEZE |
401 CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC |
402 CS4270_PWRCTL_PDN);
403 if (ret < 0) {
404 printk(KERN_ERR "cs4270: I2C write failed\n");
405 return ret;
406 }
407
408 /* Program the mode control register */
409 413
410 reg = snd_soc_read(codec, CS4270_MODE); 414 reg = snd_soc_read(codec, CS4270_MODE);
411 reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK); 415 reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
412 reg |= cs4270_mode_ratios[i].speed_mode | cs4270_mode_ratios[i].mclk; 416 reg |= cs4270_mode_ratios[i].mclk;
417
418 if (cs4270->slave_mode)
419 reg |= CS4270_MODE_SLAVE;
420 else
421 reg |= cs4270_mode_ratios[i].speed_mode;
413 422
414 ret = snd_soc_write(codec, CS4270_MODE, reg); 423 ret = snd_soc_write(codec, CS4270_MODE, reg);
415 if (ret < 0) { 424 if (ret < 0) {
416 printk(KERN_ERR "cs4270: I2C write failed\n"); 425 dev_err(codec->dev, "i2c write failed\n");
417 return ret; 426 return ret;
418 } 427 }
419 428
420 /* Program the format register */ 429 /* Set the DAI format */
421 430
422 reg = snd_soc_read(codec, CS4270_FORMAT); 431 reg = snd_soc_read(codec, CS4270_FORMAT);
423 reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK); 432 reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
@@ -430,55 +439,23 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
430 reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ; 439 reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
431 break; 440 break;
432 default: 441 default:
433 printk(KERN_ERR "cs4270: unknown format\n"); 442 dev_err(codec->dev, "unknown dai format\n");
434 return -EINVAL; 443 return -EINVAL;
435 } 444 }
436 445
437 ret = snd_soc_write(codec, CS4270_FORMAT, reg); 446 ret = snd_soc_write(codec, CS4270_FORMAT, reg);
438 if (ret < 0) { 447 if (ret < 0) {
439 printk(KERN_ERR "cs4270: I2C write failed\n"); 448 dev_err(codec->dev, "i2c write failed\n");
440 return ret;
441 }
442
443 /* Disable auto-mute. This feature appears to be buggy, because in
444 some situations, auto-mute will not deactivate when it should. */
445
446 reg = snd_soc_read(codec, CS4270_MUTE);
447 reg &= ~CS4270_MUTE_AUTO;
448 ret = snd_soc_write(codec, CS4270_MUTE, reg);
449 if (ret < 0) {
450 printk(KERN_ERR "cs4270: I2C write failed\n");
451 return ret;
452 }
453
454 /* Disable automatic volume control. It's enabled by default, and
455 * it causes volume change commands to be delayed, sometimes until
456 * after playback has started.
457 */
458
459 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
460 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
461 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
462 if (ret < 0) {
463 printk(KERN_ERR "I2C write failed\n");
464 return ret;
465 }
466
467 /* Thaw and power-up the codec */
468
469 ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
470 if (ret < 0) {
471 printk(KERN_ERR "cs4270: I2C write failed\n");
472 return ret; 449 return ret;
473 } 450 }
474 451
475 return ret; 452 return ret;
476} 453}
477 454
478#ifdef CONFIG_SND_SOC_CS4270_HWMUTE 455/**
479 456 * cs4270_mute - enable/disable the CS4270 external mute
480/* 457 * @dai: the SOC DAI
481 * Set the CS4270 external mute 458 * @mute: 0 = disable mute, 1 = enable mute
482 * 459 *
483 * This function toggles the mute bits in the MUTE register. The CS4270's 460 * This function toggles the mute bits in the MUTE register. The CS4270's
484 * mute capability is intended for external muting circuitry, so if the 461 * mute capability is intended for external muting circuitry, so if the
@@ -493,276 +470,306 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
493 reg6 = snd_soc_read(codec, CS4270_MUTE); 470 reg6 = snd_soc_read(codec, CS4270_MUTE);
494 471
495 if (mute) 472 if (mute)
496 reg6 |= CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | 473 reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
497 CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
498 else 474 else
499 reg6 &= ~(CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | 475 reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
500 CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
501 476
502 return snd_soc_write(codec, CS4270_MUTE, reg6); 477 return snd_soc_write(codec, CS4270_MUTE, reg6);
503} 478}
504 479
505#endif
506
507static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
508
509/* A list of non-DAPM controls that the CS4270 supports */ 480/* A list of non-DAPM controls that the CS4270 supports */
510static const struct snd_kcontrol_new cs4270_snd_controls[] = { 481static const struct snd_kcontrol_new cs4270_snd_controls[] = {
511 SOC_DOUBLE_R("Master Playback Volume", 482 SOC_DOUBLE_R("Master Playback Volume",
512 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) 483 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1),
513}; 484 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
514 485 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
515static const struct i2c_device_id cs4270_id[] = { 486 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
516 {"cs4270", 0}, 487 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
517 {} 488 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
518}; 489 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0)
519MODULE_DEVICE_TABLE(i2c, cs4270_id);
520
521static struct i2c_driver cs4270_i2c_driver = {
522 .driver = {
523 .name = "CS4270 I2C",
524 .owner = THIS_MODULE,
525 },
526 .id_table = cs4270_id,
527 .probe = cs4270_i2c_probe,
528}; 490};
529 491
530/* 492/*
531 * Global variable to store socdev for i2c probe function. 493 * cs4270_codec - global variable to store codec for the ASoC probe function
532 * 494 *
533 * If struct i2c_driver had a private_data field, we wouldn't need to use 495 * If struct i2c_driver had a private_data field, we wouldn't need to use
534 * cs4270_socdec. This is the only way to pass the socdev structure to 496 * cs4270_codec. This is the only way to pass the codec structure from
535 * cs4270_i2c_probe(). 497 * cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good
536 * 498 * way to synchronize these two functions. cs4270_i2c_probe() can be called
537 * The real solution to cs4270_socdev is to create a mechanism 499 * multiple times before cs4270_probe() is called even once. So for now, we
538 * that maps I2C addresses to snd_soc_device structures. Perhaps the 500 * also only allow cs4270_i2c_probe() to be run once. That means that we do
539 * creation of the snd_soc_device object should be moved out of 501 * not support more than one cs4270 device in the system, at least for now.
540 * cs4270_probe() and into cs4270_i2c_probe(), but that would make this
541 * driver dependent on I2C. The CS4270 supports "stand-alone" mode, whereby
542 * the chip is *not* connected to the I2C bus, but is instead configured via
543 * input pins.
544 */ 502 */
545static struct snd_soc_device *cs4270_socdev; 503static struct snd_soc_codec *cs4270_codec;
546 504
547/* 505static struct snd_soc_dai_ops cs4270_dai_ops = {
548 * Initialize the I2C interface of the CS4270 506 .hw_params = cs4270_hw_params,
549 * 507 .set_sysclk = cs4270_set_dai_sysclk,
550 * This function is called for whenever the I2C subsystem finds a device 508 .set_fmt = cs4270_set_dai_fmt,
551 * at a particular address. 509 .digital_mute = cs4270_mute,
510};
511
512struct snd_soc_dai cs4270_dai = {
513 .name = "cs4270",
514 .playback = {
515 .stream_name = "Playback",
516 .channels_min = 1,
517 .channels_max = 2,
518 .rates = 0,
519 .formats = CS4270_FORMATS,
520 },
521 .capture = {
522 .stream_name = "Capture",
523 .channels_min = 1,
524 .channels_max = 2,
525 .rates = 0,
526 .formats = CS4270_FORMATS,
527 },
528 .ops = &cs4270_dai_ops,
529};
530EXPORT_SYMBOL_GPL(cs4270_dai);
531
532/**
533 * cs4270_probe - ASoC probe function
534 * @pdev: platform device
552 * 535 *
553 * Note: snd_soc_new_pcms() must be called before this function can be called, 536 * This function is called when ASoC has all the pieces it needs to
554 * because of snd_ctl_add(). 537 * instantiate a sound driver.
555 */ 538 */
556static int cs4270_i2c_probe(struct i2c_client *i2c_client, 539static int cs4270_probe(struct platform_device *pdev)
557 const struct i2c_device_id *id)
558{ 540{
559 struct snd_soc_device *socdev = cs4270_socdev; 541 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
560 struct snd_soc_codec *codec = socdev->codec; 542 struct snd_soc_codec *codec = cs4270_codec;
561 int i; 543 int ret;
562 int ret = 0;
563
564 /* Probing all possible addresses has one drawback: if there are
565 multiple CS4270s on the bus, then you cannot specify which
566 socdev is matched with which CS4270. For now, we just reject
567 this I2C device if the socdev already has one attached. */
568 if (codec->control_data)
569 return -ENODEV;
570
571 /* Note: codec_dai->codec is NULL here */
572
573 codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
574 if (!codec->reg_cache) {
575 printk(KERN_ERR "cs4270: could not allocate register cache\n");
576 ret = -ENOMEM;
577 goto error;
578 }
579 544
580 /* Verify that we have a CS4270 */ 545 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
546 socdev->card->codec = codec;
581 547
582 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); 548 /* Register PCMs */
549 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
583 if (ret < 0) { 550 if (ret < 0) {
584 printk(KERN_ERR "cs4270: failed to read I2C\n"); 551 dev_err(codec->dev, "failed to create pcms\n");
585 goto error; 552 return ret;
586 }
587 /* The top four bits of the chip ID should be 1100. */
588 if ((ret & 0xF0) != 0xC0) {
589 /* The device at this address is not a CS4270 codec */
590 ret = -ENODEV;
591 goto error;
592 } 553 }
593 554
594 printk(KERN_INFO "cs4270: found device at I2C address %X\n", 555 /* Add the non-DAPM controls */
595 i2c_client->addr); 556 ret = snd_soc_add_controls(codec, cs4270_snd_controls,
596 printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF); 557 ARRAY_SIZE(cs4270_snd_controls));
597
598 codec->control_data = i2c_client;
599 codec->read = cs4270_read_reg_cache;
600 codec->write = cs4270_i2c_write;
601 codec->reg_cache_size = CS4270_NUMREGS;
602
603 /* The I2C interface is set up, so pre-fill our register cache */
604
605 ret = cs4270_fill_cache(codec);
606 if (ret < 0) { 558 if (ret < 0) {
607 printk(KERN_ERR "cs4270: failed to fill register cache\n"); 559 dev_err(codec->dev, "failed to add controls\n");
608 goto error; 560 goto error_free_pcms;
609 } 561 }
610 562
611 /* Add the non-DAPM controls */ 563 /* And finally, register the socdev */
612 564 ret = snd_soc_init_card(socdev);
613 for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) { 565 if (ret < 0) {
614 struct snd_kcontrol *kctrl = 566 dev_err(codec->dev, "failed to register card\n");
615 snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL); 567 goto error_free_pcms;
616
617 ret = snd_ctl_add(codec->card, kctrl);
618 if (ret < 0)
619 goto error;
620 } 568 }
621 569
622 i2c_set_clientdata(i2c_client, codec);
623
624 return 0; 570 return 0;
625 571
626error: 572error_free_pcms:
627 codec->control_data = NULL; 573 snd_soc_free_pcms(socdev);
628
629 kfree(codec->reg_cache);
630 codec->reg_cache = NULL;
631 codec->reg_cache_size = 0;
632 574
633 return ret; 575 return ret;
634} 576}
635 577
636#endif /* USE_I2C*/ 578/**
579 * cs4270_remove - ASoC remove function
580 * @pdev: platform device
581 *
582 * This function is the counterpart to cs4270_probe().
583 */
584static int cs4270_remove(struct platform_device *pdev)
585{
586 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
637 587
638struct snd_soc_dai cs4270_dai = { 588 snd_soc_free_pcms(socdev);
639 .name = "CS4270", 589
640 .playback = { 590 return 0;
641 .stream_name = "Playback",
642 .channels_min = 1,
643 .channels_max = 2,
644 .rates = 0,
645 .formats = CS4270_FORMATS,
646 },
647 .capture = {
648 .stream_name = "Capture",
649 .channels_min = 1,
650 .channels_max = 2,
651 .rates = 0,
652 .formats = CS4270_FORMATS,
653 },
654}; 591};
655EXPORT_SYMBOL_GPL(cs4270_dai);
656 592
657/* 593/**
658 * ASoC probe function 594 * cs4270_i2c_probe - initialize the I2C interface of the CS4270
595 * @i2c_client: the I2C client object
596 * @id: the I2C device ID (ignored)
659 * 597 *
660 * This function is called when the machine driver calls 598 * This function is called whenever the I2C subsystem finds a device that
661 * platform_device_add(). 599 * matches the device ID given via a prior call to i2c_add_driver().
662 */ 600 */
663static int cs4270_probe(struct platform_device *pdev) 601static int cs4270_i2c_probe(struct i2c_client *i2c_client,
602 const struct i2c_device_id *id)
664{ 603{
665 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
666 struct snd_soc_codec *codec; 604 struct snd_soc_codec *codec;
667 int ret = 0; 605 struct cs4270_private *cs4270;
606 unsigned int reg;
607 int ret;
668 608
669 printk(KERN_INFO "CS4270 ALSA SoC Codec\n"); 609 /* For now, we only support one cs4270 device in the system. See the
610 * comment for cs4270_codec.
611 */
612 if (cs4270_codec) {
613 dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
614 i2c_client->addr);
615 dev_err(&i2c_client->dev, "only one per board allowed\n");
616 /* Should we return something other than ENODEV here? */
617 return -ENODEV;
618 }
619
620 /* Verify that we have a CS4270 */
621
622 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
623 if (ret < 0) {
624 dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
625 i2c_client->addr);
626 return ret;
627 }
628 /* The top four bits of the chip ID should be 1100. */
629 if ((ret & 0xF0) != 0xC0) {
630 dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
631 i2c_client->addr);
632 return -ENODEV;
633 }
634
635 dev_info(&i2c_client->dev, "found device at i2c address %X\n",
636 i2c_client->addr);
637 dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
670 638
671 /* Allocate enough space for the snd_soc_codec structure 639 /* Allocate enough space for the snd_soc_codec structure
672 and our private data together. */ 640 and our private data together. */
673 codec = kzalloc(ALIGN(sizeof(struct snd_soc_codec), 4) + 641 cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
674 sizeof(struct cs4270_private), GFP_KERNEL); 642 if (!cs4270) {
675 if (!codec) { 643 dev_err(&i2c_client->dev, "could not allocate codec\n");
676 printk(KERN_ERR "cs4270: Could not allocate codec structure\n");
677 return -ENOMEM; 644 return -ENOMEM;
678 } 645 }
646 codec = &cs4270->codec;
679 647
680 mutex_init(&codec->mutex); 648 mutex_init(&codec->mutex);
681 INIT_LIST_HEAD(&codec->dapm_widgets); 649 INIT_LIST_HEAD(&codec->dapm_widgets);
682 INIT_LIST_HEAD(&codec->dapm_paths); 650 INIT_LIST_HEAD(&codec->dapm_paths);
683 651
652 codec->dev = &i2c_client->dev;
684 codec->name = "CS4270"; 653 codec->name = "CS4270";
685 codec->owner = THIS_MODULE; 654 codec->owner = THIS_MODULE;
686 codec->dai = &cs4270_dai; 655 codec->dai = &cs4270_dai;
687 codec->num_dai = 1; 656 codec->num_dai = 1;
688 codec->private_data = (void *) codec + 657 codec->private_data = cs4270;
689 ALIGN(sizeof(struct snd_soc_codec), 4); 658 codec->control_data = i2c_client;
690 659 codec->read = cs4270_read_reg_cache;
691 socdev->codec = codec; 660 codec->write = cs4270_i2c_write;
661 codec->reg_cache = cs4270->reg_cache;
662 codec->reg_cache_size = CS4270_NUMREGS;
692 663
693 /* Register PCMs */ 664 /* The I2C interface is set up, so pre-fill our register cache */
694 665
695 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 666 ret = cs4270_fill_cache(codec);
696 if (ret < 0) { 667 if (ret < 0) {
697 printk(KERN_ERR "cs4270: failed to create PCMs\n"); 668 dev_err(&i2c_client->dev, "failed to fill register cache\n");
698 goto error_free_codec; 669 goto error_free_codec;
699 } 670 }
700 671
701#ifdef USE_I2C 672 /* Disable auto-mute. This feature appears to be buggy. In some
702 cs4270_socdev = socdev; 673 * situations, auto-mute will not deactivate when it should, so we want
674 * this feature disabled by default. An application (e.g. alsactl) can
675 * re-enabled it by using the controls.
676 */
703 677
704 ret = i2c_add_driver(&cs4270_i2c_driver); 678 reg = cs4270_read_reg_cache(codec, CS4270_MUTE);
705 if (ret) { 679 reg &= ~CS4270_MUTE_AUTO;
706 printk(KERN_ERR "cs4270: failed to attach driver"); 680 ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
707 goto error_free_pcms; 681 if (ret < 0) {
682 dev_err(&i2c_client->dev, "i2c write failed\n");
683 return ret;
708 } 684 }
709 685
710 /* Did we find a CS4270 on the I2C bus? */ 686 /* Disable automatic volume control. The hardware enables, and it
711 if (codec->control_data) { 687 * causes volume change commands to be delayed, sometimes until after
712 /* Initialize codec ops */ 688 * playback has started. An application (e.g. alsactl) can
713 cs4270_dai.ops.hw_params = cs4270_hw_params; 689 * re-enabled it by using the controls.
714 cs4270_dai.ops.set_sysclk = cs4270_set_dai_sysclk; 690 */
715 cs4270_dai.ops.set_fmt = cs4270_set_dai_fmt;
716#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
717 cs4270_dai.ops.digital_mute = cs4270_mute;
718#endif
719 } else
720 printk(KERN_INFO "cs4270: no I2C device found, "
721 "using stand-alone mode\n");
722#else
723 printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n");
724#endif
725 691
726 ret = snd_soc_init_card(socdev); 692 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
693 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
694 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
727 if (ret < 0) { 695 if (ret < 0) {
728 printk(KERN_ERR "cs4270: failed to register card\n"); 696 dev_err(&i2c_client->dev, "i2c write failed\n");
729 goto error_del_driver; 697 return ret;
730 } 698 }
731 699
732 return 0; 700 /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI
701 * structure for each CS4270 device, but the machine driver needs to
702 * have a pointer to the DAI structure, so for now it must be a global
703 * variable.
704 */
705 cs4270_dai.dev = &i2c_client->dev;
733 706
734error_del_driver: 707 /* Register the DAI. If all the other ASoC driver have already
735#ifdef USE_I2C 708 * registered, then this will call our probe function, so
736 i2c_del_driver(&cs4270_i2c_driver); 709 * cs4270_codec needs to be ready.
710 */
711 cs4270_codec = codec;
712 ret = snd_soc_register_dai(&cs4270_dai);
713 if (ret < 0) {
714 dev_err(&i2c_client->dev, "failed to register DAIe\n");
715 goto error_free_codec;
716 }
737 717
738error_free_pcms: 718 i2c_set_clientdata(i2c_client, cs4270);
739#endif 719
740 snd_soc_free_pcms(socdev); 720 return 0;
741 721
742error_free_codec: 722error_free_codec:
743 kfree(socdev->codec); 723 kfree(cs4270);
744 socdev->codec = NULL; 724 cs4270_codec = NULL;
725 cs4270_dai.dev = NULL;
745 726
746 return ret; 727 return ret;
747} 728}
748 729
749static int cs4270_remove(struct platform_device *pdev) 730/**
731 * cs4270_i2c_remove - remove an I2C device
732 * @i2c_client: the I2C client object
733 *
734 * This function is the counterpart to cs4270_i2c_probe().
735 */
736static int cs4270_i2c_remove(struct i2c_client *i2c_client)
750{ 737{
751 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 738 struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
752
753 snd_soc_free_pcms(socdev);
754
755#ifdef USE_I2C
756 i2c_del_driver(&cs4270_i2c_driver);
757#endif
758 739
759 kfree(socdev->codec); 740 kfree(cs4270);
760 socdev->codec = NULL; 741 cs4270_codec = NULL;
742 cs4270_dai.dev = NULL;
761 743
762 return 0; 744 return 0;
763} 745}
764 746
765/* 747/*
748 * cs4270_id - I2C device IDs supported by this driver
749 */
750static struct i2c_device_id cs4270_id[] = {
751 {"cs4270", 0},
752 {}
753};
754MODULE_DEVICE_TABLE(i2c, cs4270_id);
755
756/*
757 * cs4270_i2c_driver - I2C device identification
758 *
759 * This structure tells the I2C subsystem how to identify and support a
760 * given I2C device type.
761 */
762static struct i2c_driver cs4270_i2c_driver = {
763 .driver = {
764 .name = "cs4270",
765 .owner = THIS_MODULE,
766 },
767 .id_table = cs4270_id,
768 .probe = cs4270_i2c_probe,
769 .remove = cs4270_i2c_remove,
770};
771
772/*
766 * ASoC codec device structure 773 * ASoC codec device structure
767 * 774 *
768 * Assign this variable to the codec_dev field of the machine driver's 775 * Assign this variable to the codec_dev field of the machine driver's
@@ -776,13 +783,15 @@ EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
776 783
777static int __init cs4270_init(void) 784static int __init cs4270_init(void)
778{ 785{
779 return snd_soc_register_dai(&cs4270_dai); 786 pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
787
788 return i2c_add_driver(&cs4270_i2c_driver);
780} 789}
781module_init(cs4270_init); 790module_init(cs4270_init);
782 791
783static void __exit cs4270_exit(void) 792static void __exit cs4270_exit(void)
784{ 793{
785 snd_soc_unregister_dai(&cs4270_dai); 794 i2c_del_driver(&cs4270_i2c_driver);
786} 795}
787module_exit(cs4270_exit); 796module_exit(cs4270_exit);
788 797
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 9a3e67e5319c..5cda9e6b5a74 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -67,11 +67,11 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
67 67
68 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION); 68 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
69 69
70 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 70 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
71 if (!socdev->codec) 71 if (!socdev->card->codec)
72 return -ENOMEM; 72 return -ENOMEM;
73 73
74 codec = socdev->codec; 74 codec = socdev->card->codec;
75 mutex_init(&codec->mutex); 75 mutex_init(&codec->mutex);
76 76
77 codec->name = "PCM3008"; 77 codec->name = "PCM3008";
@@ -139,7 +139,7 @@ gpio_err:
139card_err: 139card_err:
140 snd_soc_free_pcms(socdev); 140 snd_soc_free_pcms(socdev);
141pcm_err: 141pcm_err:
142 kfree(socdev->codec); 142 kfree(socdev->card->codec);
143 143
144 return ret; 144 return ret;
145} 145}
@@ -147,7 +147,7 @@ pcm_err:
147static int pcm3008_soc_remove(struct platform_device *pdev) 147static int pcm3008_soc_remove(struct platform_device *pdev)
148{ 148{
149 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 149 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
150 struct snd_soc_codec *codec = socdev->codec; 150 struct snd_soc_codec *codec = socdev->card->codec;
151 struct pcm3008_setup_data *setup = socdev->codec_data; 151 struct pcm3008_setup_data *setup = socdev->codec_data;
152 152
153 if (!codec) 153 if (!codec)
@@ -155,7 +155,7 @@ static int pcm3008_soc_remove(struct platform_device *pdev)
155 155
156 pcm3008_gpio_free(setup); 156 pcm3008_gpio_free(setup);
157 snd_soc_free_pcms(socdev); 157 snd_soc_free_pcms(socdev);
158 kfree(socdev->codec); 158 kfree(socdev->card->codec);
159 159
160 return 0; 160 return 0;
161} 161}
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index cac373616768..87f606c76822 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -151,21 +151,6 @@ SOC_ENUM("Capture Source", ssm2602_enum[0]),
151SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]), 151SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
152}; 152};
153 153
154/* add non dapm controls */
155static int ssm2602_add_controls(struct snd_soc_codec *codec)
156{
157 int err, i;
158
159 for (i = 0; i < ARRAY_SIZE(ssm2602_snd_controls); i++) {
160 err = snd_ctl_add(codec->card,
161 snd_soc_cnew(&ssm2602_snd_controls[i], codec, NULL));
162 if (err < 0)
163 return err;
164 }
165
166 return 0;
167}
168
169/* Output Mixer */ 154/* Output Mixer */
170static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = { 155static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = {
171SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0), 156SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
@@ -291,7 +276,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
291 u16 srate; 276 u16 srate;
292 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
293 struct snd_soc_device *socdev = rtd->socdev; 278 struct snd_soc_device *socdev = rtd->socdev;
294 struct snd_soc_codec *codec = socdev->codec; 279 struct snd_soc_codec *codec = socdev->card->codec;
295 struct ssm2602_priv *ssm2602 = codec->private_data; 280 struct ssm2602_priv *ssm2602 = codec->private_data;
296 struct i2c_client *i2c = codec->control_data; 281 struct i2c_client *i2c = codec->control_data;
297 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 282 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
@@ -336,7 +321,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
336{ 321{
337 struct snd_soc_pcm_runtime *rtd = substream->private_data; 322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
338 struct snd_soc_device *socdev = rtd->socdev; 323 struct snd_soc_device *socdev = rtd->socdev;
339 struct snd_soc_codec *codec = socdev->codec; 324 struct snd_soc_codec *codec = socdev->card->codec;
340 struct ssm2602_priv *ssm2602 = codec->private_data; 325 struct ssm2602_priv *ssm2602 = codec->private_data;
341 struct i2c_client *i2c = codec->control_data; 326 struct i2c_client *i2c = codec->control_data;
342 struct snd_pcm_runtime *master_runtime; 327 struct snd_pcm_runtime *master_runtime;
@@ -373,7 +358,7 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
373{ 358{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 359 struct snd_soc_pcm_runtime *rtd = substream->private_data;
375 struct snd_soc_device *socdev = rtd->socdev; 360 struct snd_soc_device *socdev = rtd->socdev;
376 struct snd_soc_codec *codec = socdev->codec; 361 struct snd_soc_codec *codec = socdev->card->codec;
377 /* set active */ 362 /* set active */
378 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); 363 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
379 364
@@ -385,7 +370,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
385{ 370{
386 struct snd_soc_pcm_runtime *rtd = substream->private_data; 371 struct snd_soc_pcm_runtime *rtd = substream->private_data;
387 struct snd_soc_device *socdev = rtd->socdev; 372 struct snd_soc_device *socdev = rtd->socdev;
388 struct snd_soc_codec *codec = socdev->codec; 373 struct snd_soc_codec *codec = socdev->card->codec;
389 struct ssm2602_priv *ssm2602 = codec->private_data; 374 struct ssm2602_priv *ssm2602 = codec->private_data;
390 /* deactivate */ 375 /* deactivate */
391 if (!codec->active) 376 if (!codec->active)
@@ -521,6 +506,16 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
521#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 506#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
522 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 507 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
523 508
509static struct snd_soc_dai_ops ssm2602_dai_ops = {
510 .startup = ssm2602_startup,
511 .prepare = ssm2602_pcm_prepare,
512 .hw_params = ssm2602_hw_params,
513 .shutdown = ssm2602_shutdown,
514 .digital_mute = ssm2602_mute,
515 .set_sysclk = ssm2602_set_dai_sysclk,
516 .set_fmt = ssm2602_set_dai_fmt,
517};
518
524struct snd_soc_dai ssm2602_dai = { 519struct snd_soc_dai ssm2602_dai = {
525 .name = "SSM2602", 520 .name = "SSM2602",
526 .playback = { 521 .playback = {
@@ -535,22 +530,14 @@ struct snd_soc_dai ssm2602_dai = {
535 .channels_max = 2, 530 .channels_max = 2,
536 .rates = SSM2602_RATES, 531 .rates = SSM2602_RATES,
537 .formats = SSM2602_FORMATS,}, 532 .formats = SSM2602_FORMATS,},
538 .ops = { 533 .ops = &ssm2602_dai_ops,
539 .startup = ssm2602_startup,
540 .prepare = ssm2602_pcm_prepare,
541 .hw_params = ssm2602_hw_params,
542 .shutdown = ssm2602_shutdown,
543 .digital_mute = ssm2602_mute,
544 .set_sysclk = ssm2602_set_dai_sysclk,
545 .set_fmt = ssm2602_set_dai_fmt,
546 }
547}; 534};
548EXPORT_SYMBOL_GPL(ssm2602_dai); 535EXPORT_SYMBOL_GPL(ssm2602_dai);
549 536
550static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state) 537static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
551{ 538{
552 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 539 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
553 struct snd_soc_codec *codec = socdev->codec; 540 struct snd_soc_codec *codec = socdev->card->codec;
554 541
555 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); 542 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
556 return 0; 543 return 0;
@@ -559,7 +546,7 @@ static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
559static int ssm2602_resume(struct platform_device *pdev) 546static int ssm2602_resume(struct platform_device *pdev)
560{ 547{
561 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 548 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
562 struct snd_soc_codec *codec = socdev->codec; 549 struct snd_soc_codec *codec = socdev->card->codec;
563 int i; 550 int i;
564 u8 data[2]; 551 u8 data[2];
565 u16 *cache = codec->reg_cache; 552 u16 *cache = codec->reg_cache;
@@ -581,7 +568,7 @@ static int ssm2602_resume(struct platform_device *pdev)
581 */ 568 */
582static int ssm2602_init(struct snd_soc_device *socdev) 569static int ssm2602_init(struct snd_soc_device *socdev)
583{ 570{
584 struct snd_soc_codec *codec = socdev->codec; 571 struct snd_soc_codec *codec = socdev->card->codec;
585 int reg, ret = 0; 572 int reg, ret = 0;
586 573
587 codec->name = "SSM2602"; 574 codec->name = "SSM2602";
@@ -622,7 +609,8 @@ static int ssm2602_init(struct snd_soc_device *socdev)
622 APANA_ENABLE_MIC_BOOST); 609 APANA_ENABLE_MIC_BOOST);
623 ssm2602_write(codec, SSM2602_PWR, 0); 610 ssm2602_write(codec, SSM2602_PWR, 0);
624 611
625 ssm2602_add_controls(codec); 612 snd_soc_add_controls(codec, ssm2602_snd_controls,
613 ARRAY_SIZE(ssm2602_snd_controls));
626 ssm2602_add_widgets(codec); 614 ssm2602_add_widgets(codec);
627 ret = snd_soc_init_card(socdev); 615 ret = snd_soc_init_card(socdev);
628 if (ret < 0) { 616 if (ret < 0) {
@@ -653,7 +641,7 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c,
653 const struct i2c_device_id *id) 641 const struct i2c_device_id *id)
654{ 642{
655 struct snd_soc_device *socdev = ssm2602_socdev; 643 struct snd_soc_device *socdev = ssm2602_socdev;
656 struct snd_soc_codec *codec = socdev->codec; 644 struct snd_soc_codec *codec = socdev->card->codec;
657 int ret; 645 int ret;
658 646
659 i2c_set_clientdata(i2c, codec); 647 i2c_set_clientdata(i2c, codec);
@@ -747,7 +735,7 @@ static int ssm2602_probe(struct platform_device *pdev)
747 } 735 }
748 736
749 codec->private_data = ssm2602; 737 codec->private_data = ssm2602;
750 socdev->codec = codec; 738 socdev->card->codec = codec;
751 mutex_init(&codec->mutex); 739 mutex_init(&codec->mutex);
752 INIT_LIST_HEAD(&codec->dapm_widgets); 740 INIT_LIST_HEAD(&codec->dapm_widgets);
753 INIT_LIST_HEAD(&codec->dapm_paths); 741 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -768,7 +756,7 @@ static int ssm2602_probe(struct platform_device *pdev)
768static int ssm2602_remove(struct platform_device *pdev) 756static int ssm2602_remove(struct platform_device *pdev)
769{ 757{
770 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 758 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
771 struct snd_soc_codec *codec = socdev->codec; 759 struct snd_soc_codec *codec = socdev->card->codec;
772 760
773 if (codec->control_data) 761 if (codec->control_data)
774 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); 762 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index cfdea007c4cb..c3f4afb5d017 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -183,24 +183,6 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
183 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), 183 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
184}; 184};
185 185
186/* add non dapm controls */
187static int tlv320aic23_add_controls(struct snd_soc_codec *codec)
188{
189
190 int err, i;
191
192 for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) {
193 err = snd_ctl_add(codec->card,
194 snd_soc_cnew(&tlv320aic23_snd_controls[i],
195 codec, NULL));
196 if (err < 0)
197 return err;
198 }
199
200 return 0;
201
202}
203
204/* PGA Mixer controls for Line and Mic switch */ 186/* PGA Mixer controls for Line and Mic switch */
205static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = { 187static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = {
206 SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0), 188 SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0),
@@ -423,7 +405,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
423{ 405{
424 struct snd_soc_pcm_runtime *rtd = substream->private_data; 406 struct snd_soc_pcm_runtime *rtd = substream->private_data;
425 struct snd_soc_device *socdev = rtd->socdev; 407 struct snd_soc_device *socdev = rtd->socdev;
426 struct snd_soc_codec *codec = socdev->codec; 408 struct snd_soc_codec *codec = socdev->card->codec;
427 u16 iface_reg; 409 u16 iface_reg;
428 int ret; 410 int ret;
429 struct aic23 *aic23 = container_of(codec, struct aic23, codec); 411 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
@@ -471,7 +453,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
471{ 453{
472 struct snd_soc_pcm_runtime *rtd = substream->private_data; 454 struct snd_soc_pcm_runtime *rtd = substream->private_data;
473 struct snd_soc_device *socdev = rtd->socdev; 455 struct snd_soc_device *socdev = rtd->socdev;
474 struct snd_soc_codec *codec = socdev->codec; 456 struct snd_soc_codec *codec = socdev->card->codec;
475 457
476 /* set active */ 458 /* set active */
477 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); 459 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
@@ -484,7 +466,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
484{ 466{
485 struct snd_soc_pcm_runtime *rtd = substream->private_data; 467 struct snd_soc_pcm_runtime *rtd = substream->private_data;
486 struct snd_soc_device *socdev = rtd->socdev; 468 struct snd_soc_device *socdev = rtd->socdev;
487 struct snd_soc_codec *codec = socdev->codec; 469 struct snd_soc_codec *codec = socdev->card->codec;
488 struct aic23 *aic23 = container_of(codec, struct aic23, codec); 470 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
489 471
490 /* deactivate */ 472 /* deactivate */
@@ -598,6 +580,15 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
598#define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 580#define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
599 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 581 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
600 582
583static struct snd_soc_dai_ops tlv320aic23_dai_ops = {
584 .prepare = tlv320aic23_pcm_prepare,
585 .hw_params = tlv320aic23_hw_params,
586 .shutdown = tlv320aic23_shutdown,
587 .digital_mute = tlv320aic23_mute,
588 .set_fmt = tlv320aic23_set_dai_fmt,
589 .set_sysclk = tlv320aic23_set_dai_sysclk,
590};
591
601struct snd_soc_dai tlv320aic23_dai = { 592struct snd_soc_dai tlv320aic23_dai = {
602 .name = "tlv320aic23", 593 .name = "tlv320aic23",
603 .playback = { 594 .playback = {
@@ -612,14 +603,7 @@ struct snd_soc_dai tlv320aic23_dai = {
612 .channels_max = 2, 603 .channels_max = 2,
613 .rates = AIC23_RATES, 604 .rates = AIC23_RATES,
614 .formats = AIC23_FORMATS,}, 605 .formats = AIC23_FORMATS,},
615 .ops = { 606 .ops = &tlv320aic23_dai_ops,
616 .prepare = tlv320aic23_pcm_prepare,
617 .hw_params = tlv320aic23_hw_params,
618 .shutdown = tlv320aic23_shutdown,
619 .digital_mute = tlv320aic23_mute,
620 .set_fmt = tlv320aic23_set_dai_fmt,
621 .set_sysclk = tlv320aic23_set_dai_sysclk,
622 }
623}; 607};
624EXPORT_SYMBOL_GPL(tlv320aic23_dai); 608EXPORT_SYMBOL_GPL(tlv320aic23_dai);
625 609
@@ -627,7 +611,7 @@ static int tlv320aic23_suspend(struct platform_device *pdev,
627 pm_message_t state) 611 pm_message_t state)
628{ 612{
629 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 613 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
630 struct snd_soc_codec *codec = socdev->codec; 614 struct snd_soc_codec *codec = socdev->card->codec;
631 615
632 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 616 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
633 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 617 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -638,7 +622,7 @@ static int tlv320aic23_suspend(struct platform_device *pdev,
638static int tlv320aic23_resume(struct platform_device *pdev) 622static int tlv320aic23_resume(struct platform_device *pdev)
639{ 623{
640 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 624 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
641 struct snd_soc_codec *codec = socdev->codec; 625 struct snd_soc_codec *codec = socdev->card->codec;
642 int i; 626 int i;
643 u16 reg; 627 u16 reg;
644 628
@@ -660,7 +644,7 @@ static int tlv320aic23_resume(struct platform_device *pdev)
660 */ 644 */
661static int tlv320aic23_init(struct snd_soc_device *socdev) 645static int tlv320aic23_init(struct snd_soc_device *socdev)
662{ 646{
663 struct snd_soc_codec *codec = socdev->codec; 647 struct snd_soc_codec *codec = socdev->card->codec;
664 int ret = 0; 648 int ret = 0;
665 u16 reg; 649 u16 reg;
666 650
@@ -718,7 +702,8 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
718 702
719 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); 703 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1);
720 704
721 tlv320aic23_add_controls(codec); 705 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
706 ARRAY_SIZE(tlv320aic23_snd_controls));
722 tlv320aic23_add_widgets(codec); 707 tlv320aic23_add_widgets(codec);
723 ret = snd_soc_init_card(socdev); 708 ret = snd_soc_init_card(socdev);
724 if (ret < 0) { 709 if (ret < 0) {
@@ -746,7 +731,7 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c,
746 const struct i2c_device_id *i2c_id) 731 const struct i2c_device_id *i2c_id)
747{ 732{
748 struct snd_soc_device *socdev = tlv320aic23_socdev; 733 struct snd_soc_device *socdev = tlv320aic23_socdev;
749 struct snd_soc_codec *codec = socdev->codec; 734 struct snd_soc_codec *codec = socdev->card->codec;
750 int ret; 735 int ret;
751 736
752 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 737 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -804,7 +789,7 @@ static int tlv320aic23_probe(struct platform_device *pdev)
804 if (aic23 == NULL) 789 if (aic23 == NULL)
805 return -ENOMEM; 790 return -ENOMEM;
806 codec = &aic23->codec; 791 codec = &aic23->codec;
807 socdev->codec = codec; 792 socdev->card->codec = codec;
808 mutex_init(&codec->mutex); 793 mutex_init(&codec->mutex);
809 INIT_LIST_HEAD(&codec->dapm_widgets); 794 INIT_LIST_HEAD(&codec->dapm_widgets);
810 INIT_LIST_HEAD(&codec->dapm_paths); 795 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -823,7 +808,7 @@ static int tlv320aic23_probe(struct platform_device *pdev)
823static int tlv320aic23_remove(struct platform_device *pdev) 808static int tlv320aic23_remove(struct platform_device *pdev)
824{ 809{
825 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 810 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
826 struct snd_soc_codec *codec = socdev->codec; 811 struct snd_soc_codec *codec = socdev->card->codec;
827 struct aic23 *aic23 = container_of(codec, struct aic23, codec); 812 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
828 813
829 if (codec->control_data) 814 if (codec->control_data)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 29f2f1a017fd..3387d9e736ea 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -130,7 +130,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
130{ 130{
131 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
132 struct snd_soc_device *socdev = rtd->socdev; 132 struct snd_soc_device *socdev = rtd->socdev;
133 struct snd_soc_codec *codec = socdev->codec; 133 struct snd_soc_codec *codec = socdev->card->codec;
134 struct aic26 *aic26 = codec->private_data; 134 struct aic26 *aic26 = codec->private_data;
135 int fsref, divisor, wlen, pval, jval, dval, qval; 135 int fsref, divisor, wlen, pval, jval, dval, qval;
136 u16 reg; 136 u16 reg;
@@ -270,6 +270,13 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
270#define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\ 270#define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\
271 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE) 271 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
272 272
273static struct snd_soc_dai_ops aic26_dai_ops = {
274 .hw_params = aic26_hw_params,
275 .digital_mute = aic26_mute,
276 .set_sysclk = aic26_set_sysclk,
277 .set_fmt = aic26_set_fmt,
278};
279
273struct snd_soc_dai aic26_dai = { 280struct snd_soc_dai aic26_dai = {
274 .name = "tlv320aic26", 281 .name = "tlv320aic26",
275 .playback = { 282 .playback = {
@@ -286,12 +293,7 @@ struct snd_soc_dai aic26_dai = {
286 .rates = AIC26_RATES, 293 .rates = AIC26_RATES,
287 .formats = AIC26_FORMATS, 294 .formats = AIC26_FORMATS,
288 }, 295 },
289 .ops = { 296 .ops = &aic26_dai_ops,
290 .hw_params = aic26_hw_params,
291 .digital_mute = aic26_mute,
292 .set_sysclk = aic26_set_sysclk,
293 .set_fmt = aic26_set_fmt,
294 },
295}; 297};
296EXPORT_SYMBOL_GPL(aic26_dai); 298EXPORT_SYMBOL_GPL(aic26_dai);
297 299
@@ -322,9 +324,8 @@ static int aic26_probe(struct platform_device *pdev)
322{ 324{
323 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 325 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
324 struct snd_soc_codec *codec; 326 struct snd_soc_codec *codec;
325 struct snd_kcontrol *kcontrol;
326 struct aic26 *aic26; 327 struct aic26 *aic26;
327 int i, ret, err; 328 int ret, err;
328 329
329 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n"); 330 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
330 dev_dbg(&pdev->dev, "socdev=%p\n", socdev); 331 dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
@@ -338,7 +339,7 @@ static int aic26_probe(struct platform_device *pdev)
338 return -ENODEV; 339 return -ENODEV;
339 } 340 }
340 codec = &aic26->codec; 341 codec = &aic26->codec;
341 socdev->codec = codec; 342 socdev->card->codec = codec;
342 343
343 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n", 344 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
344 &pdev->dev, socdev->dev); 345 &pdev->dev, socdev->dev);
@@ -351,11 +352,9 @@ static int aic26_probe(struct platform_device *pdev)
351 352
352 /* register controls */ 353 /* register controls */
353 dev_dbg(&pdev->dev, "Registering controls\n"); 354 dev_dbg(&pdev->dev, "Registering controls\n");
354 for (i = 0; i < ARRAY_SIZE(aic26_snd_controls); i++) { 355 err = snd_soc_add_controls(codec, aic26_snd_controls,
355 kcontrol = snd_soc_cnew(&aic26_snd_controls[i], codec, NULL); 356 ARRAY_SIZE(aic26_snd_controls));
356 err = snd_ctl_add(codec->card, kcontrol); 357 WARN_ON(err < 0);
357 WARN_ON(err < 0);
358 }
359 358
360 /* CODEC is setup, we can register the card now */ 359 /* CODEC is setup, we can register the card now */
361 dev_dbg(&pdev->dev, "Registering card\n"); 360 dev_dbg(&pdev->dev, "Registering card\n");
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index aea0cb72d80a..ab099f482487 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -45,6 +45,7 @@
45#include <sound/soc.h> 45#include <sound/soc.h>
46#include <sound/soc-dapm.h> 46#include <sound/soc-dapm.h>
47#include <sound/initval.h> 47#include <sound/initval.h>
48#include <sound/tlv.h>
48 49
49#include "tlv320aic3x.h" 50#include "tlv320aic3x.h"
50 51
@@ -250,56 +251,86 @@ static const struct soc_enum aic3x_enum[] = {
250 SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf), 251 SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf),
251}; 252};
252 253
254/*
255 * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps
256 */
257static DECLARE_TLV_DB_SCALE(dac_tlv, -6350, 50, 0);
258/* ADC PGA gain volumes. From 0 to 59.5 dB in 0.5 dB steps */
259static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0);
260/*
261 * Output stage volumes. From -78.3 to 0 dB. Muted below -78.3 dB.
262 * Step size is approximately 0.5 dB over most of the scale but increasing
263 * near the very low levels.
264 * Define dB scale so that it is mostly correct for range about -55 to 0 dB
265 * but having increasing dB difference below that (and where it doesn't count
266 * so much). This setting shows -50 dB (actual is -50.3 dB) for register
267 * value 100 and -58.5 dB (actual is -78.3 dB) for register value 117.
268 */
269static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1);
270
253static const struct snd_kcontrol_new aic3x_snd_controls[] = { 271static const struct snd_kcontrol_new aic3x_snd_controls[] = {
254 /* Output */ 272 /* Output */
255 SOC_DOUBLE_R("PCM Playback Volume", LDAC_VOL, RDAC_VOL, 0, 0x7f, 1), 273 SOC_DOUBLE_R_TLV("PCM Playback Volume",
274 LDAC_VOL, RDAC_VOL, 0, 0x7f, 1, dac_tlv),
256 275
257 SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL, 276 SOC_DOUBLE_R_TLV("Line DAC Playback Volume",
258 DACR1_2_RLOPM_VOL, 0, 0x7f, 1), 277 DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL,
278 0, 118, 1, output_stage_tlv),
259 SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0), 279 SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0),
260 SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0), 280 SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0),
261 SOC_DOUBLE_R("LineL DAC Playback Volume", DACL1_2_LLOPM_VOL, 281 SOC_DOUBLE_R_TLV("LineL DAC Playback Volume",
262 DACR1_2_LLOPM_VOL, 0, 0x7f, 1), 282 DACL1_2_LLOPM_VOL, DACR1_2_LLOPM_VOL,
263 SOC_SINGLE("LineL Left PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL, 283 0, 118, 1, output_stage_tlv),
264 0, 0x7f, 1), 284 SOC_SINGLE_TLV("LineL Left PGA Bypass Playback Volume",
265 SOC_SINGLE("LineR Right PGA Bypass Playback Volume", PGAR_2_RLOPM_VOL, 285 PGAL_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
266 0, 0x7f, 1), 286 SOC_SINGLE_TLV("LineR Right PGA Bypass Playback Volume",
267 SOC_DOUBLE_R("LineL Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL, 287 PGAR_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
268 LINE2R_2_LLOPM_VOL, 0, 0x7f, 1), 288 SOC_DOUBLE_R_TLV("LineL Line2 Bypass Playback Volume",
269 SOC_DOUBLE_R("LineR Line2 Bypass Playback Volume", LINE2L_2_RLOPM_VOL, 289 LINE2L_2_LLOPM_VOL, LINE2R_2_LLOPM_VOL,
270 LINE2R_2_RLOPM_VOL, 0, 0x7f, 1), 290 0, 118, 1, output_stage_tlv),
271 291 SOC_DOUBLE_R_TLV("LineR Line2 Bypass Playback Volume",
272 SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL, 292 LINE2L_2_RLOPM_VOL, LINE2R_2_RLOPM_VOL,
273 DACR1_2_MONOLOPM_VOL, 0, 0x7f, 1), 293 0, 118, 1, output_stage_tlv),
294
295 SOC_DOUBLE_R_TLV("Mono DAC Playback Volume",
296 DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL,
297 0, 118, 1, output_stage_tlv),
274 SOC_SINGLE("Mono DAC Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0), 298 SOC_SINGLE("Mono DAC Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0),
275 SOC_DOUBLE_R("Mono PGA Bypass Playback Volume", PGAL_2_MONOLOPM_VOL, 299 SOC_DOUBLE_R_TLV("Mono PGA Bypass Playback Volume",
276 PGAR_2_MONOLOPM_VOL, 0, 0x7f, 1), 300 PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL,
277 SOC_DOUBLE_R("Mono Line2 Bypass Playback Volume", LINE2L_2_MONOLOPM_VOL, 301 0, 118, 1, output_stage_tlv),
278 LINE2R_2_MONOLOPM_VOL, 0, 0x7f, 1), 302 SOC_DOUBLE_R_TLV("Mono Line2 Bypass Playback Volume",
279 303 LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL,
280 SOC_DOUBLE_R("HP DAC Playback Volume", DACL1_2_HPLOUT_VOL, 304 0, 118, 1, output_stage_tlv),
281 DACR1_2_HPROUT_VOL, 0, 0x7f, 1), 305
306 SOC_DOUBLE_R_TLV("HP DAC Playback Volume",
307 DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL,
308 0, 118, 1, output_stage_tlv),
282 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, 309 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
283 0x01, 0), 310 0x01, 0),
284 SOC_DOUBLE_R("HP Right PGA Bypass Playback Volume", PGAR_2_HPLOUT_VOL, 311 SOC_DOUBLE_R_TLV("HP Right PGA Bypass Playback Volume",
285 PGAR_2_HPROUT_VOL, 0, 0x7f, 1), 312 PGAR_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL,
286 SOC_SINGLE("HPL PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL, 313 0, 118, 1, output_stage_tlv),
287 0, 0x7f, 1), 314 SOC_SINGLE_TLV("HPL PGA Bypass Playback Volume",
288 SOC_SINGLE("HPR PGA Bypass Playback Volume", PGAL_2_HPROUT_VOL, 315 PGAL_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
289 0, 0x7f, 1), 316 SOC_SINGLE_TLV("HPR PGA Bypass Playback Volume",
290 SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL, 317 PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
291 LINE2R_2_HPROUT_VOL, 0, 0x7f, 1), 318 SOC_DOUBLE_R_TLV("HP Line2 Bypass Playback Volume",
292 319 LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL,
293 SOC_DOUBLE_R("HPCOM DAC Playback Volume", DACL1_2_HPLCOM_VOL, 320 0, 118, 1, output_stage_tlv),
294 DACR1_2_HPRCOM_VOL, 0, 0x7f, 1), 321
322 SOC_DOUBLE_R_TLV("HPCOM DAC Playback Volume",
323 DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL,
324 0, 118, 1, output_stage_tlv),
295 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, 325 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
296 0x01, 0), 326 0x01, 0),
297 SOC_SINGLE("HPLCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL, 327 SOC_SINGLE_TLV("HPLCOM PGA Bypass Playback Volume",
298 0, 0x7f, 1), 328 PGAL_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
299 SOC_SINGLE("HPRCOM PGA Bypass Playback Volume", PGAL_2_HPRCOM_VOL, 329 SOC_SINGLE_TLV("HPRCOM PGA Bypass Playback Volume",
300 0, 0x7f, 1), 330 PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
301 SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL, 331 SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Playback Volume",
302 LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1), 332 LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL,
333 0, 118, 1, output_stage_tlv),
303 334
304 /* 335 /*
305 * Note: enable Automatic input Gain Controller with care. It can 336 * Note: enable Automatic input Gain Controller with care. It can
@@ -308,28 +339,13 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
308 SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0), 339 SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0),
309 340
310 /* Input */ 341 /* Input */
311 SOC_DOUBLE_R("PGA Capture Volume", LADC_VOL, RADC_VOL, 0, 0x7f, 0), 342 SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL,
343 0, 119, 0, adc_tlv),
312 SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), 344 SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1),
313 345
314 SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), 346 SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]),
315}; 347};
316 348
317/* add non dapm controls */
318static int aic3x_add_controls(struct snd_soc_codec *codec)
319{
320 int err, i;
321
322 for (i = 0; i < ARRAY_SIZE(aic3x_snd_controls); i++) {
323 err = snd_ctl_add(codec->card,
324 snd_soc_cnew(&aic3x_snd_controls[i],
325 codec, NULL));
326 if (err < 0)
327 return err;
328 }
329
330 return 0;
331}
332
333/* Left DAC Mux */ 349/* Left DAC Mux */
334static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = 350static const struct snd_kcontrol_new aic3x_left_dac_mux_controls =
335SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]); 351SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]);
@@ -746,7 +762,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
746{ 762{
747 struct snd_soc_pcm_runtime *rtd = substream->private_data; 763 struct snd_soc_pcm_runtime *rtd = substream->private_data;
748 struct snd_soc_device *socdev = rtd->socdev; 764 struct snd_soc_device *socdev = rtd->socdev;
749 struct snd_soc_codec *codec = socdev->codec; 765 struct snd_soc_codec *codec = socdev->card->codec;
750 struct aic3x_priv *aic3x = codec->private_data; 766 struct aic3x_priv *aic3x = codec->private_data;
751 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
752 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 768 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
@@ -1072,6 +1088,13 @@ EXPORT_SYMBOL_GPL(aic3x_button_pressed);
1072#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1088#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1073 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 1089 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
1074 1090
1091static struct snd_soc_dai_ops aic3x_dai_ops = {
1092 .hw_params = aic3x_hw_params,
1093 .digital_mute = aic3x_mute,
1094 .set_sysclk = aic3x_set_dai_sysclk,
1095 .set_fmt = aic3x_set_dai_fmt,
1096};
1097
1075struct snd_soc_dai aic3x_dai = { 1098struct snd_soc_dai aic3x_dai = {
1076 .name = "tlv320aic3x", 1099 .name = "tlv320aic3x",
1077 .playback = { 1100 .playback = {
@@ -1086,19 +1109,14 @@ struct snd_soc_dai aic3x_dai = {
1086 .channels_max = 2, 1109 .channels_max = 2,
1087 .rates = AIC3X_RATES, 1110 .rates = AIC3X_RATES,
1088 .formats = AIC3X_FORMATS,}, 1111 .formats = AIC3X_FORMATS,},
1089 .ops = { 1112 .ops = &aic3x_dai_ops,
1090 .hw_params = aic3x_hw_params,
1091 .digital_mute = aic3x_mute,
1092 .set_sysclk = aic3x_set_dai_sysclk,
1093 .set_fmt = aic3x_set_dai_fmt,
1094 }
1095}; 1113};
1096EXPORT_SYMBOL_GPL(aic3x_dai); 1114EXPORT_SYMBOL_GPL(aic3x_dai);
1097 1115
1098static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) 1116static int aic3x_suspend(struct platform_device *pdev, pm_message_t state)
1099{ 1117{
1100 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1118 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1101 struct snd_soc_codec *codec = socdev->codec; 1119 struct snd_soc_codec *codec = socdev->card->codec;
1102 1120
1103 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1121 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1104 1122
@@ -1108,7 +1126,7 @@ static int aic3x_suspend(struct platform_device *pdev, pm_message_t state)
1108static int aic3x_resume(struct platform_device *pdev) 1126static int aic3x_resume(struct platform_device *pdev)
1109{ 1127{
1110 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1128 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1111 struct snd_soc_codec *codec = socdev->codec; 1129 struct snd_soc_codec *codec = socdev->card->codec;
1112 int i; 1130 int i;
1113 u8 data[2]; 1131 u8 data[2];
1114 u8 *cache = codec->reg_cache; 1132 u8 *cache = codec->reg_cache;
@@ -1131,7 +1149,7 @@ static int aic3x_resume(struct platform_device *pdev)
1131 */ 1149 */
1132static int aic3x_init(struct snd_soc_device *socdev) 1150static int aic3x_init(struct snd_soc_device *socdev)
1133{ 1151{
1134 struct snd_soc_codec *codec = socdev->codec; 1152 struct snd_soc_codec *codec = socdev->card->codec;
1135 struct aic3x_setup_data *setup = socdev->codec_data; 1153 struct aic3x_setup_data *setup = socdev->codec_data;
1136 int reg, ret = 0; 1154 int reg, ret = 0;
1137 1155
@@ -1227,7 +1245,8 @@ static int aic3x_init(struct snd_soc_device *socdev)
1227 aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); 1245 aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4);
1228 aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); 1246 aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4);
1229 1247
1230 aic3x_add_controls(codec); 1248 snd_soc_add_controls(codec, aic3x_snd_controls,
1249 ARRAY_SIZE(aic3x_snd_controls));
1231 aic3x_add_widgets(codec); 1250 aic3x_add_widgets(codec);
1232 ret = snd_soc_init_card(socdev); 1251 ret = snd_soc_init_card(socdev);
1233 if (ret < 0) { 1252 if (ret < 0) {
@@ -1261,7 +1280,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1261 const struct i2c_device_id *id) 1280 const struct i2c_device_id *id)
1262{ 1281{
1263 struct snd_soc_device *socdev = aic3x_socdev; 1282 struct snd_soc_device *socdev = aic3x_socdev;
1264 struct snd_soc_codec *codec = socdev->codec; 1283 struct snd_soc_codec *codec = socdev->card->codec;
1265 int ret; 1284 int ret;
1266 1285
1267 i2c_set_clientdata(i2c, codec); 1286 i2c_set_clientdata(i2c, codec);
@@ -1366,7 +1385,7 @@ static int aic3x_probe(struct platform_device *pdev)
1366 } 1385 }
1367 1386
1368 codec->private_data = aic3x; 1387 codec->private_data = aic3x;
1369 socdev->codec = codec; 1388 socdev->card->codec = codec;
1370 mutex_init(&codec->mutex); 1389 mutex_init(&codec->mutex);
1371 INIT_LIST_HEAD(&codec->dapm_widgets); 1390 INIT_LIST_HEAD(&codec->dapm_widgets);
1372 INIT_LIST_HEAD(&codec->dapm_paths); 1391 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -1392,7 +1411,7 @@ static int aic3x_probe(struct platform_device *pdev)
1392static int aic3x_remove(struct platform_device *pdev) 1411static int aic3x_remove(struct platform_device *pdev)
1393{ 1412{
1394 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1413 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1395 struct snd_soc_codec *codec = socdev->codec; 1414 struct snd_soc_codec *codec = socdev->card->codec;
1396 1415
1397 /* power down chip */ 1416 /* power down chip */
1398 if (codec->control_data) 1417 if (codec->control_data)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index ea370a4f86d5..97738e2ece04 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -42,7 +42,7 @@
42 */ 42 */
43static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { 43static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
44 0x00, /* this register not used */ 44 0x00, /* this register not used */
45 0x93, /* REG_CODEC_MODE (0x1) */ 45 0x91, /* REG_CODEC_MODE (0x1) */
46 0xc3, /* REG_OPTION (0x2) */ 46 0xc3, /* REG_OPTION (0x2) */
47 0x00, /* REG_UNKNOWN (0x3) */ 47 0x00, /* REG_UNKNOWN (0x3) */
48 0x00, /* REG_MICBIAS_CTL (0x4) */ 48 0x00, /* REG_MICBIAS_CTL (0x4) */
@@ -117,6 +117,13 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
117 0x00, /* REG_MISC_SET_2 (0x49) */ 117 0x00, /* REG_MISC_SET_2 (0x49) */
118}; 118};
119 119
120/* codec private data */
121struct twl4030_priv {
122 unsigned int bypass_state;
123 unsigned int codec_powered;
124 unsigned int codec_muted;
125};
126
120/* 127/*
121 * read twl4030 register cache 128 * read twl4030 register cache
122 */ 129 */
@@ -125,6 +132,9 @@ static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
125{ 132{
126 u8 *cache = codec->reg_cache; 133 u8 *cache = codec->reg_cache;
127 134
135 if (reg >= TWL4030_CACHEREGNUM)
136 return -EIO;
137
128 return cache[reg]; 138 return cache[reg];
129} 139}
130 140
@@ -151,26 +161,22 @@ static int twl4030_write(struct snd_soc_codec *codec,
151 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); 161 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
152} 162}
153 163
154static void twl4030_clear_codecpdz(struct snd_soc_codec *codec) 164static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
155{ 165{
166 struct twl4030_priv *twl4030 = codec->private_data;
156 u8 mode; 167 u8 mode;
157 168
158 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); 169 if (enable == twl4030->codec_powered)
159 twl4030_write(codec, TWL4030_REG_CODEC_MODE, 170 return;
160 mode & ~TWL4030_CODECPDZ);
161
162 /* REVISIT: this delay is present in TI sample drivers */
163 /* but there seems to be no TRM requirement for it */
164 udelay(10);
165}
166
167static void twl4030_set_codecpdz(struct snd_soc_codec *codec)
168{
169 u8 mode;
170 171
171 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); 172 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
172 twl4030_write(codec, TWL4030_REG_CODEC_MODE, 173 if (enable)
173 mode | TWL4030_CODECPDZ); 174 mode |= TWL4030_CODECPDZ;
175 else
176 mode &= ~TWL4030_CODECPDZ;
177
178 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
179 twl4030->codec_powered = enable;
174 180
175 /* REVISIT: this delay is present in TI sample drivers */ 181 /* REVISIT: this delay is present in TI sample drivers */
176 /* but there seems to be no TRM requirement for it */ 182 /* but there seems to be no TRM requirement for it */
@@ -182,7 +188,7 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
182 int i; 188 int i;
183 189
184 /* clear CODECPDZ prior to setting register defaults */ 190 /* clear CODECPDZ prior to setting register defaults */
185 twl4030_clear_codecpdz(codec); 191 twl4030_codec_enable(codec, 0);
186 192
187 /* set all audio section registers to reasonable defaults */ 193 /* set all audio section registers to reasonable defaults */
188 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) 194 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
@@ -190,6 +196,122 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
190 196
191} 197}
192 198
199static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute)
200{
201 struct twl4030_priv *twl4030 = codec->private_data;
202 u8 reg_val;
203
204 if (mute == twl4030->codec_muted)
205 return;
206
207 if (mute) {
208 /* Bypass the reg_cache and mute the volumes
209 * Headset mute is done in it's own event handler
210 * Things to mute: Earpiece, PreDrivL/R, CarkitL/R
211 */
212 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL);
213 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
214 reg_val & (~TWL4030_EAR_GAIN),
215 TWL4030_REG_EAR_CTL);
216
217 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL);
218 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
219 reg_val & (~TWL4030_PREDL_GAIN),
220 TWL4030_REG_PREDL_CTL);
221 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL);
222 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
223 reg_val & (~TWL4030_PREDR_GAIN),
224 TWL4030_REG_PREDL_CTL);
225
226 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL);
227 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
228 reg_val & (~TWL4030_PRECKL_GAIN),
229 TWL4030_REG_PRECKL_CTL);
230 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL);
231 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
232 reg_val & (~TWL4030_PRECKL_GAIN),
233 TWL4030_REG_PRECKR_CTL);
234
235 /* Disable PLL */
236 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
237 reg_val &= ~TWL4030_APLL_EN;
238 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
239 } else {
240 /* Restore the volumes
241 * Headset mute is done in it's own event handler
242 * Things to restore: Earpiece, PreDrivL/R, CarkitL/R
243 */
244 twl4030_write(codec, TWL4030_REG_EAR_CTL,
245 twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL));
246
247 twl4030_write(codec, TWL4030_REG_PREDL_CTL,
248 twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL));
249 twl4030_write(codec, TWL4030_REG_PREDR_CTL,
250 twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL));
251
252 twl4030_write(codec, TWL4030_REG_PRECKL_CTL,
253 twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL));
254 twl4030_write(codec, TWL4030_REG_PRECKR_CTL,
255 twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL));
256
257 /* Enable PLL */
258 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
259 reg_val |= TWL4030_APLL_EN;
260 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
261 }
262
263 twl4030->codec_muted = mute;
264}
265
266static void twl4030_power_up(struct snd_soc_codec *codec)
267{
268 struct twl4030_priv *twl4030 = codec->private_data;
269 u8 anamicl, regmisc1, byte;
270 int i = 0;
271
272 if (twl4030->codec_powered)
273 return;
274
275 /* set CODECPDZ to turn on codec */
276 twl4030_codec_enable(codec, 1);
277
278 /* initiate offset cancellation */
279 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
280 twl4030_write(codec, TWL4030_REG_ANAMICL,
281 anamicl | TWL4030_CNCL_OFFSET_START);
282
283 /* wait for offset cancellation to complete */
284 do {
285 /* this takes a little while, so don't slam i2c */
286 udelay(2000);
287 twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
288 TWL4030_REG_ANAMICL);
289 } while ((i++ < 100) &&
290 ((byte & TWL4030_CNCL_OFFSET_START) ==
291 TWL4030_CNCL_OFFSET_START));
292
293 /* Make sure that the reg_cache has the same value as the HW */
294 twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte);
295
296 /* anti-pop when changing analog gain */
297 regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
298 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
299 regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
300
301 /* toggle CODECPDZ as per TRM */
302 twl4030_codec_enable(codec, 0);
303 twl4030_codec_enable(codec, 1);
304}
305
306/*
307 * Unconditional power down
308 */
309static void twl4030_power_down(struct snd_soc_codec *codec)
310{
311 /* power down */
312 twl4030_codec_enable(codec, 0);
313}
314
193/* Earpiece */ 315/* Earpiece */
194static const char *twl4030_earpiece_texts[] = 316static const char *twl4030_earpiece_texts[] =
195 {"Off", "DACL1", "DACL2", "DACR1"}; 317 {"Off", "DACL1", "DACL2", "DACR1"};
@@ -366,6 +488,41 @@ static const struct soc_enum twl4030_micpathtx2_enum =
366static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control = 488static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control =
367SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum); 489SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum);
368 490
491/* Analog bypass for AudioR1 */
492static const struct snd_kcontrol_new twl4030_dapm_abypassr1_control =
493 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR1_APGA_CTL, 2, 1, 0);
494
495/* Analog bypass for AudioL1 */
496static const struct snd_kcontrol_new twl4030_dapm_abypassl1_control =
497 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL1_APGA_CTL, 2, 1, 0);
498
499/* Analog bypass for AudioR2 */
500static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control =
501 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR2_APGA_CTL, 2, 1, 0);
502
503/* Analog bypass for AudioL2 */
504static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
505 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
506
507/* Digital bypass gain, 0 mutes the bypass */
508static const unsigned int twl4030_dapm_dbypass_tlv[] = {
509 TLV_DB_RANGE_HEAD(2),
510 0, 3, TLV_DB_SCALE_ITEM(-2400, 0, 1),
511 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0),
512};
513
514/* Digital bypass left (TX1L -> RX2L) */
515static const struct snd_kcontrol_new twl4030_dapm_dbypassl_control =
516 SOC_DAPM_SINGLE_TLV("Volume",
517 TWL4030_REG_ATX2ARXPGA, 3, 7, 0,
518 twl4030_dapm_dbypass_tlv);
519
520/* Digital bypass right (TX1R -> RX2R) */
521static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control =
522 SOC_DAPM_SINGLE_TLV("Volume",
523 TWL4030_REG_ATX2ARXPGA, 0, 7, 0,
524 twl4030_dapm_dbypass_tlv);
525
369static int micpath_event(struct snd_soc_dapm_widget *w, 526static int micpath_event(struct snd_soc_dapm_widget *w,
370 struct snd_kcontrol *kcontrol, int event) 527 struct snd_kcontrol *kcontrol, int event)
371{ 528{
@@ -420,6 +577,79 @@ static int handsfree_event(struct snd_soc_dapm_widget *w,
420 return 0; 577 return 0;
421} 578}
422 579
580static int headsetl_event(struct snd_soc_dapm_widget *w,
581 struct snd_kcontrol *kcontrol, int event)
582{
583 unsigned char hs_gain, hs_pop;
584
585 /* Save the current volume */
586 hs_gain = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_GAIN_SET);
587 hs_pop = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_POPN_SET);
588
589 switch (event) {
590 case SND_SOC_DAPM_POST_PMU:
591 /* Do the anti-pop/bias ramp enable according to the TRM */
592 hs_pop |= TWL4030_VMID_EN;
593 twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
594 /* Is this needed? Can we just use whatever gain here? */
595 twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET,
596 (hs_gain & (~0x0f)) | 0x0a);
597 hs_pop |= TWL4030_RAMP_EN;
598 twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
599
600 /* Restore the original volume */
601 twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET, hs_gain);
602 break;
603 case SND_SOC_DAPM_POST_PMD:
604 /* Do the anti-pop/bias ramp disable according to the TRM */
605 hs_pop &= ~TWL4030_RAMP_EN;
606 twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
607 /* Bypass the reg_cache to mute the headset */
608 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
609 hs_gain & (~0x0f),
610 TWL4030_REG_HS_GAIN_SET);
611 hs_pop &= ~TWL4030_VMID_EN;
612 twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop);
613 break;
614 }
615 return 0;
616}
617
618static int bypass_event(struct snd_soc_dapm_widget *w,
619 struct snd_kcontrol *kcontrol, int event)
620{
621 struct soc_mixer_control *m =
622 (struct soc_mixer_control *)w->kcontrols->private_value;
623 struct twl4030_priv *twl4030 = w->codec->private_data;
624 unsigned char reg;
625
626 reg = twl4030_read_reg_cache(w->codec, m->reg);
627
628 if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
629 /* Analog bypass */
630 if (reg & (1 << m->shift))
631 twl4030->bypass_state |=
632 (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
633 else
634 twl4030->bypass_state &=
635 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
636 } else {
637 /* Digital bypass */
638 if (reg & (0x7 << m->shift))
639 twl4030->bypass_state |= (1 << (m->shift ? 5 : 4));
640 else
641 twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4));
642 }
643
644 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
645 if (twl4030->bypass_state)
646 twl4030_codec_mute(w->codec, 0);
647 else
648 twl4030_codec_mute(w->codec, 1);
649 }
650 return 0;
651}
652
423/* 653/*
424 * Some of the gain controls in TWL (mostly those which are associated with 654 * Some of the gain controls in TWL (mostly those which are associated with
425 * the outputs) are implemented in an interesting way: 655 * the outputs) are implemented in an interesting way:
@@ -614,6 +844,17 @@ static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
614 */ 844 */
615static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0); 845static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
616 846
847static const char *twl4030_rampdelay_texts[] = {
848 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms",
849 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms",
850 "3495/2581/1748 ms"
851};
852
853static const struct soc_enum twl4030_rampdelay_enum =
854 SOC_ENUM_SINGLE(TWL4030_REG_HS_POPN_SET, 2,
855 ARRAY_SIZE(twl4030_rampdelay_texts),
856 twl4030_rampdelay_texts);
857
617static const struct snd_kcontrol_new twl4030_snd_controls[] = { 858static const struct snd_kcontrol_new twl4030_snd_controls[] = {
618 /* Common playback gain controls */ 859 /* Common playback gain controls */
619 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume", 860 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
@@ -668,23 +909,9 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
668 909
669 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN, 910 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
670 0, 3, 5, 0, input_gain_tlv), 911 0, 3, 5, 0, input_gain_tlv),
671};
672
673/* add non dapm controls */
674static int twl4030_add_controls(struct snd_soc_codec *codec)
675{
676 int err, i;
677
678 for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) {
679 err = snd_ctl_add(codec->card,
680 snd_soc_cnew(&twl4030_snd_controls[i],
681 codec, NULL));
682 if (err < 0)
683 return err;
684 }
685 912
686 return 0; 913 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
687} 914};
688 915
689static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { 916static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
690 /* Left channel inputs */ 917 /* Left channel inputs */
@@ -714,13 +941,13 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
714 941
715 /* DACs */ 942 /* DACs */
716 SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", 943 SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
717 TWL4030_REG_AVDAC_CTL, 0, 0), 944 SND_SOC_NOPM, 0, 0),
718 SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback", 945 SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
719 TWL4030_REG_AVDAC_CTL, 1, 0), 946 SND_SOC_NOPM, 0, 0),
720 SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback", 947 SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback",
721 TWL4030_REG_AVDAC_CTL, 2, 0), 948 SND_SOC_NOPM, 0, 0),
722 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", 949 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
723 TWL4030_REG_AVDAC_CTL, 3, 0), 950 SND_SOC_NOPM, 0, 0),
724 951
725 /* Analog PGAs */ 952 /* Analog PGAs */
726 SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, 953 SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
@@ -732,6 +959,37 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
732 SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL, 959 SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
733 0, 0, NULL, 0), 960 0, 0, NULL, 0),
734 961
962 /* Analog bypasses */
963 SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
964 &twl4030_dapm_abypassr1_control, bypass_event,
965 SND_SOC_DAPM_POST_REG),
966 SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
967 &twl4030_dapm_abypassl1_control,
968 bypass_event, SND_SOC_DAPM_POST_REG),
969 SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
970 &twl4030_dapm_abypassr2_control,
971 bypass_event, SND_SOC_DAPM_POST_REG),
972 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
973 &twl4030_dapm_abypassl2_control,
974 bypass_event, SND_SOC_DAPM_POST_REG),
975
976 /* Digital bypasses */
977 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
978 &twl4030_dapm_dbypassl_control, bypass_event,
979 SND_SOC_DAPM_POST_REG),
980 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
981 &twl4030_dapm_dbypassr_control, bypass_event,
982 SND_SOC_DAPM_POST_REG),
983
984 SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL,
985 0, 0, NULL, 0),
986 SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer", TWL4030_REG_AVDAC_CTL,
987 1, 0, NULL, 0),
988 SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer", TWL4030_REG_AVDAC_CTL,
989 2, 0, NULL, 0),
990 SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL,
991 3, 0, NULL, 0),
992
735 /* Output MUX controls */ 993 /* Output MUX controls */
736 /* Earpiece */ 994 /* Earpiece */
737 SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0, 995 SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0,
@@ -742,8 +1000,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
742 SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0, 1000 SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0,
743 &twl4030_dapm_predriver_control), 1001 &twl4030_dapm_predriver_control),
744 /* HeadsetL/R */ 1002 /* HeadsetL/R */
745 SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0, 1003 SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
746 &twl4030_dapm_hsol_control), 1004 &twl4030_dapm_hsol_control, headsetl_event,
1005 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
747 SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, 1006 SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
748 &twl4030_dapm_hsor_control), 1007 &twl4030_dapm_hsor_control),
749 /* CarkitL/R */ 1008 /* CarkitL/R */
@@ -782,16 +1041,16 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
782 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD| 1041 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
783 SND_SOC_DAPM_POST_REG), 1042 SND_SOC_DAPM_POST_REG),
784 1043
785 /* Analog input muxes with power switch for the physical ADCL/R */ 1044 /* Analog input muxes with switch for the capture amplifiers */
786 SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route", 1045 SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route",
787 TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control), 1046 TWL4030_REG_ANAMICL, 4, 0, &twl4030_dapm_analoglmic_control),
788 SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route", 1047 SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route",
789 TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control), 1048 TWL4030_REG_ANAMICR, 4, 0, &twl4030_dapm_analogrmic_control),
790 1049
791 SND_SOC_DAPM_PGA("Analog Left Amplifier", 1050 SND_SOC_DAPM_PGA("ADC Physical Left",
792 TWL4030_REG_ANAMICL, 4, 0, NULL, 0), 1051 TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0),
793 SND_SOC_DAPM_PGA("Analog Right Amplifier", 1052 SND_SOC_DAPM_PGA("ADC Physical Right",
794 TWL4030_REG_ANAMICR, 4, 0, NULL, 0), 1053 TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0),
795 1054
796 SND_SOC_DAPM_PGA("Digimic0 Enable", 1055 SND_SOC_DAPM_PGA("Digimic0 Enable",
797 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0), 1056 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0),
@@ -801,13 +1060,19 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
801 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), 1060 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
802 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), 1061 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
803 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0), 1062 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0),
1063
804}; 1064};
805 1065
806static const struct snd_soc_dapm_route intercon[] = { 1066static const struct snd_soc_dapm_route intercon[] = {
807 {"ARXL1_APGA", NULL, "DAC Left1"}, 1067 {"Analog L1 Playback Mixer", NULL, "DAC Left1"},
808 {"ARXR1_APGA", NULL, "DAC Right1"}, 1068 {"Analog R1 Playback Mixer", NULL, "DAC Right1"},
809 {"ARXL2_APGA", NULL, "DAC Left2"}, 1069 {"Analog L2 Playback Mixer", NULL, "DAC Left2"},
810 {"ARXR2_APGA", NULL, "DAC Right2"}, 1070 {"Analog R2 Playback Mixer", NULL, "DAC Right2"},
1071
1072 {"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"},
1073 {"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"},
1074 {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"},
1075 {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"},
811 1076
812 /* Internal playback routings */ 1077 /* Internal playback routings */
813 /* Earpiece */ 1078 /* Earpiece */
@@ -865,23 +1130,23 @@ static const struct snd_soc_dapm_route intercon[] = {
865 {"Analog Right Capture Route", "Sub mic", "SUBMIC"}, 1130 {"Analog Right Capture Route", "Sub mic", "SUBMIC"},
866 {"Analog Right Capture Route", "AUXR", "AUXR"}, 1131 {"Analog Right Capture Route", "AUXR", "AUXR"},
867 1132
868 {"Analog Left Amplifier", NULL, "Analog Left Capture Route"}, 1133 {"ADC Physical Left", NULL, "Analog Left Capture Route"},
869 {"Analog Right Amplifier", NULL, "Analog Right Capture Route"}, 1134 {"ADC Physical Right", NULL, "Analog Right Capture Route"},
870 1135
871 {"Digimic0 Enable", NULL, "DIGIMIC0"}, 1136 {"Digimic0 Enable", NULL, "DIGIMIC0"},
872 {"Digimic1 Enable", NULL, "DIGIMIC1"}, 1137 {"Digimic1 Enable", NULL, "DIGIMIC1"},
873 1138
874 /* TX1 Left capture path */ 1139 /* TX1 Left capture path */
875 {"TX1 Capture Route", "Analog", "Analog Left Amplifier"}, 1140 {"TX1 Capture Route", "Analog", "ADC Physical Left"},
876 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, 1141 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
877 /* TX1 Right capture path */ 1142 /* TX1 Right capture path */
878 {"TX1 Capture Route", "Analog", "Analog Right Amplifier"}, 1143 {"TX1 Capture Route", "Analog", "ADC Physical Right"},
879 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, 1144 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
880 /* TX2 Left capture path */ 1145 /* TX2 Left capture path */
881 {"TX2 Capture Route", "Analog", "Analog Left Amplifier"}, 1146 {"TX2 Capture Route", "Analog", "ADC Physical Left"},
882 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"}, 1147 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
883 /* TX2 Right capture path */ 1148 /* TX2 Right capture path */
884 {"TX2 Capture Route", "Analog", "Analog Right Amplifier"}, 1149 {"TX2 Capture Route", "Analog", "ADC Physical Right"},
885 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"}, 1150 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
886 1151
887 {"ADC Virtual Left1", NULL, "TX1 Capture Route"}, 1152 {"ADC Virtual Left1", NULL, "TX1 Capture Route"},
@@ -889,6 +1154,24 @@ static const struct snd_soc_dapm_route intercon[] = {
889 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1154 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
890 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1155 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
891 1156
1157 /* Analog bypass routes */
1158 {"Right1 Analog Loopback", "Switch", "Analog Right Capture Route"},
1159 {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"},
1160 {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"},
1161 {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"},
1162
1163 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1164 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1165 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
1166 {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
1167
1168 /* Digital bypass routes */
1169 {"Right Digital Loopback", "Volume", "TX1 Capture Route"},
1170 {"Left Digital Loopback", "Volume", "TX1 Capture Route"},
1171
1172 {"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"},
1173 {"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"},
1174
892}; 1175};
893 1176
894static int twl4030_add_widgets(struct snd_soc_codec *codec) 1177static int twl4030_add_widgets(struct snd_soc_codec *codec)
@@ -902,82 +1185,28 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec)
902 return 0; 1185 return 0;
903} 1186}
904 1187
905static void twl4030_power_up(struct snd_soc_codec *codec)
906{
907 u8 anamicl, regmisc1, byte, popn;
908 int i = 0;
909
910 /* set CODECPDZ to turn on codec */
911 twl4030_set_codecpdz(codec);
912
913 /* initiate offset cancellation */
914 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
915 twl4030_write(codec, TWL4030_REG_ANAMICL,
916 anamicl | TWL4030_CNCL_OFFSET_START);
917
918
919 /* wait for offset cancellation to complete */
920 do {
921 /* this takes a little while, so don't slam i2c */
922 udelay(2000);
923 twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
924 TWL4030_REG_ANAMICL);
925 } while ((i++ < 100) &&
926 ((byte & TWL4030_CNCL_OFFSET_START) ==
927 TWL4030_CNCL_OFFSET_START));
928
929 /* anti-pop when changing analog gain */
930 regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
931 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
932 regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
933
934 /* toggle CODECPDZ as per TRM */
935 twl4030_clear_codecpdz(codec);
936 twl4030_set_codecpdz(codec);
937
938 /* program anti-pop with bias ramp delay */
939 popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
940 popn &= TWL4030_RAMP_DELAY;
941 popn |= TWL4030_RAMP_DELAY_645MS;
942 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
943 popn |= TWL4030_VMID_EN;
944 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
945
946 /* enable anti-pop ramp */
947 popn |= TWL4030_RAMP_EN;
948 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
949}
950
951static void twl4030_power_down(struct snd_soc_codec *codec)
952{
953 u8 popn;
954
955 /* disable anti-pop ramp */
956 popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
957 popn &= ~TWL4030_RAMP_EN;
958 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
959
960 /* disable bias out */
961 popn &= ~TWL4030_VMID_EN;
962 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
963
964 /* power down */
965 twl4030_clear_codecpdz(codec);
966}
967
968static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1188static int twl4030_set_bias_level(struct snd_soc_codec *codec,
969 enum snd_soc_bias_level level) 1189 enum snd_soc_bias_level level)
970{ 1190{
1191 struct twl4030_priv *twl4030 = codec->private_data;
1192
971 switch (level) { 1193 switch (level) {
972 case SND_SOC_BIAS_ON: 1194 case SND_SOC_BIAS_ON:
973 twl4030_power_up(codec); 1195 twl4030_codec_mute(codec, 0);
974 break; 1196 break;
975 case SND_SOC_BIAS_PREPARE: 1197 case SND_SOC_BIAS_PREPARE:
976 /* TODO: develop a twl4030_prepare function */ 1198 twl4030_power_up(codec);
1199 if (twl4030->bypass_state)
1200 twl4030_codec_mute(codec, 0);
1201 else
1202 twl4030_codec_mute(codec, 1);
977 break; 1203 break;
978 case SND_SOC_BIAS_STANDBY: 1204 case SND_SOC_BIAS_STANDBY:
979 /* TODO: develop a twl4030_standby function */ 1205 twl4030_power_up(codec);
980 twl4030_power_down(codec); 1206 if (twl4030->bypass_state)
1207 twl4030_codec_mute(codec, 0);
1208 else
1209 twl4030_codec_mute(codec, 1);
981 break; 1210 break;
982 case SND_SOC_BIAS_OFF: 1211 case SND_SOC_BIAS_OFF:
983 twl4030_power_down(codec); 1212 twl4030_power_down(codec);
@@ -994,10 +1223,9 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
994{ 1223{
995 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1224 struct snd_soc_pcm_runtime *rtd = substream->private_data;
996 struct snd_soc_device *socdev = rtd->socdev; 1225 struct snd_soc_device *socdev = rtd->socdev;
997 struct snd_soc_codec *codec = socdev->codec; 1226 struct snd_soc_codec *codec = socdev->card->codec;
998 u8 mode, old_mode, format, old_format; 1227 u8 mode, old_mode, format, old_format;
999 1228
1000
1001 /* bit rate */ 1229 /* bit rate */
1002 old_mode = twl4030_read_reg_cache(codec, 1230 old_mode = twl4030_read_reg_cache(codec,
1003 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; 1231 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
@@ -1039,8 +1267,9 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1039 1267
1040 if (mode != old_mode) { 1268 if (mode != old_mode) {
1041 /* change rate and set CODECPDZ */ 1269 /* change rate and set CODECPDZ */
1270 twl4030_codec_enable(codec, 0);
1042 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); 1271 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1043 twl4030_set_codecpdz(codec); 1272 twl4030_codec_enable(codec, 1);
1044 } 1273 }
1045 1274
1046 /* sample size */ 1275 /* sample size */
@@ -1063,13 +1292,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1063 if (format != old_format) { 1292 if (format != old_format) {
1064 1293
1065 /* clear CODECPDZ before changing format (codec requirement) */ 1294 /* clear CODECPDZ before changing format (codec requirement) */
1066 twl4030_clear_codecpdz(codec); 1295 twl4030_codec_enable(codec, 0);
1067 1296
1068 /* change format */ 1297 /* change format */
1069 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); 1298 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1070 1299
1071 /* set CODECPDZ afterwards */ 1300 /* set CODECPDZ afterwards */
1072 twl4030_set_codecpdz(codec); 1301 twl4030_codec_enable(codec, 1);
1073 } 1302 }
1074 return 0; 1303 return 0;
1075} 1304}
@@ -1139,13 +1368,13 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1139 if (format != old_format) { 1368 if (format != old_format) {
1140 1369
1141 /* clear CODECPDZ before changing format (codec requirement) */ 1370 /* clear CODECPDZ before changing format (codec requirement) */
1142 twl4030_clear_codecpdz(codec); 1371 twl4030_codec_enable(codec, 0);
1143 1372
1144 /* change format */ 1373 /* change format */
1145 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); 1374 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1146 1375
1147 /* set CODECPDZ afterwards */ 1376 /* set CODECPDZ afterwards */
1148 twl4030_set_codecpdz(codec); 1377 twl4030_codec_enable(codec, 1);
1149 } 1378 }
1150 1379
1151 return 0; 1380 return 0;
@@ -1154,6 +1383,12 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1154#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) 1383#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
1155#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) 1384#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
1156 1385
1386static struct snd_soc_dai_ops twl4030_dai_ops = {
1387 .hw_params = twl4030_hw_params,
1388 .set_sysclk = twl4030_set_dai_sysclk,
1389 .set_fmt = twl4030_set_dai_fmt,
1390};
1391
1157struct snd_soc_dai twl4030_dai = { 1392struct snd_soc_dai twl4030_dai = {
1158 .name = "twl4030", 1393 .name = "twl4030",
1159 .playback = { 1394 .playback = {
@@ -1168,18 +1403,14 @@ struct snd_soc_dai twl4030_dai = {
1168 .channels_max = 2, 1403 .channels_max = 2,
1169 .rates = TWL4030_RATES, 1404 .rates = TWL4030_RATES,
1170 .formats = TWL4030_FORMATS,}, 1405 .formats = TWL4030_FORMATS,},
1171 .ops = { 1406 .ops = &twl4030_dai_ops,
1172 .hw_params = twl4030_hw_params,
1173 .set_sysclk = twl4030_set_dai_sysclk,
1174 .set_fmt = twl4030_set_dai_fmt,
1175 }
1176}; 1407};
1177EXPORT_SYMBOL_GPL(twl4030_dai); 1408EXPORT_SYMBOL_GPL(twl4030_dai);
1178 1409
1179static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) 1410static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
1180{ 1411{
1181 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1412 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1182 struct snd_soc_codec *codec = socdev->codec; 1413 struct snd_soc_codec *codec = socdev->card->codec;
1183 1414
1184 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 1415 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
1185 1416
@@ -1189,7 +1420,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
1189static int twl4030_resume(struct platform_device *pdev) 1420static int twl4030_resume(struct platform_device *pdev)
1190{ 1421{
1191 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1422 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1192 struct snd_soc_codec *codec = socdev->codec; 1423 struct snd_soc_codec *codec = socdev->card->codec;
1193 1424
1194 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1425 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1195 twl4030_set_bias_level(codec, codec->suspend_bias_level); 1426 twl4030_set_bias_level(codec, codec->suspend_bias_level);
@@ -1203,7 +1434,7 @@ static int twl4030_resume(struct platform_device *pdev)
1203 1434
1204static int twl4030_init(struct snd_soc_device *socdev) 1435static int twl4030_init(struct snd_soc_device *socdev)
1205{ 1436{
1206 struct snd_soc_codec *codec = socdev->codec; 1437 struct snd_soc_codec *codec = socdev->card->codec;
1207 int ret = 0; 1438 int ret = 0;
1208 1439
1209 printk(KERN_INFO "TWL4030 Audio Codec init \n"); 1440 printk(KERN_INFO "TWL4030 Audio Codec init \n");
@@ -1233,7 +1464,8 @@ static int twl4030_init(struct snd_soc_device *socdev)
1233 /* power on device */ 1464 /* power on device */
1234 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1465 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1235 1466
1236 twl4030_add_controls(codec); 1467 snd_soc_add_controls(codec, twl4030_snd_controls,
1468 ARRAY_SIZE(twl4030_snd_controls));
1237 twl4030_add_widgets(codec); 1469 twl4030_add_widgets(codec);
1238 1470
1239 ret = snd_soc_init_card(socdev); 1471 ret = snd_soc_init_card(socdev);
@@ -1258,12 +1490,20 @@ static int twl4030_probe(struct platform_device *pdev)
1258{ 1490{
1259 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1491 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1260 struct snd_soc_codec *codec; 1492 struct snd_soc_codec *codec;
1493 struct twl4030_priv *twl4030;
1261 1494
1262 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1495 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1263 if (codec == NULL) 1496 if (codec == NULL)
1264 return -ENOMEM; 1497 return -ENOMEM;
1265 1498
1266 socdev->codec = codec; 1499 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
1500 if (twl4030 == NULL) {
1501 kfree(codec);
1502 return -ENOMEM;
1503 }
1504
1505 codec->private_data = twl4030;
1506 socdev->card->codec = codec;
1267 mutex_init(&codec->mutex); 1507 mutex_init(&codec->mutex);
1268 INIT_LIST_HEAD(&codec->dapm_widgets); 1508 INIT_LIST_HEAD(&codec->dapm_widgets);
1269 INIT_LIST_HEAD(&codec->dapm_paths); 1509 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -1277,11 +1517,13 @@ static int twl4030_probe(struct platform_device *pdev)
1277static int twl4030_remove(struct platform_device *pdev) 1517static int twl4030_remove(struct platform_device *pdev)
1278{ 1518{
1279 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1519 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1280 struct snd_soc_codec *codec = socdev->codec; 1520 struct snd_soc_codec *codec = socdev->card->codec;
1281 1521
1282 printk(KERN_INFO "TWL4030 Audio Codec remove\n"); 1522 printk(KERN_INFO "TWL4030 Audio Codec remove\n");
1523 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
1283 snd_soc_free_pcms(socdev); 1524 snd_soc_free_pcms(socdev);
1284 snd_soc_dapm_free(socdev); 1525 snd_soc_dapm_free(socdev);
1526 kfree(codec->private_data);
1285 kfree(codec); 1527 kfree(codec);
1286 1528
1287 return 0; 1529 return 0;
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 442e5a828617..33dbb144dad1 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -170,6 +170,9 @@
170#define TWL4030_CLK256FS_EN 0x02 170#define TWL4030_CLK256FS_EN 0x02
171#define TWL4030_AIF_EN 0x01 171#define TWL4030_AIF_EN 0x01
172 172
173/* EAR_CTL (0x21) */
174#define TWL4030_EAR_GAIN 0x30
175
173/* HS_GAIN_SET (0x23) Fields */ 176/* HS_GAIN_SET (0x23) Fields */
174 177
175#define TWL4030_HSR_GAIN 0x0C 178#define TWL4030_HSR_GAIN 0x0C
@@ -198,6 +201,18 @@
198#define TWL4030_RAMP_DELAY_2581MS 0x1C 201#define TWL4030_RAMP_DELAY_2581MS 0x1C
199#define TWL4030_RAMP_EN 0x02 202#define TWL4030_RAMP_EN 0x02
200 203
204/* PREDL_CTL (0x25) */
205#define TWL4030_PREDL_GAIN 0x30
206
207/* PREDR_CTL (0x26) */
208#define TWL4030_PREDR_GAIN 0x30
209
210/* PRECKL_CTL (0x27) */
211#define TWL4030_PRECKL_GAIN 0x30
212
213/* PRECKR_CTL (0x28) */
214#define TWL4030_PRECKR_GAIN 0x30
215
201/* HFL_CTL (0x29, 0x2A) Fields */ 216/* HFL_CTL (0x29, 0x2A) Fields */
202#define TWL4030_HF_CTL_HB_EN 0x04 217#define TWL4030_HF_CTL_HB_EN 0x04
203#define TWL4030_HF_CTL_LOOP_EN 0x08 218#define TWL4030_HF_CTL_LOOP_EN 0x08
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index a2c5064a774b..ddefb8f80145 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -173,7 +173,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
173{ 173{
174 struct snd_soc_pcm_runtime *rtd = substream->private_data; 174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_device *socdev = rtd->socdev; 175 struct snd_soc_device *socdev = rtd->socdev;
176 struct snd_soc_codec *codec = socdev->codec; 176 struct snd_soc_codec *codec = socdev->card->codec;
177 struct uda134x_priv *uda134x = codec->private_data; 177 struct uda134x_priv *uda134x = codec->private_data;
178 struct snd_pcm_runtime *master_runtime; 178 struct snd_pcm_runtime *master_runtime;
179 179
@@ -206,7 +206,7 @@ static void uda134x_shutdown(struct snd_pcm_substream *substream,
206{ 206{
207 struct snd_soc_pcm_runtime *rtd = substream->private_data; 207 struct snd_soc_pcm_runtime *rtd = substream->private_data;
208 struct snd_soc_device *socdev = rtd->socdev; 208 struct snd_soc_device *socdev = rtd->socdev;
209 struct snd_soc_codec *codec = socdev->codec; 209 struct snd_soc_codec *codec = socdev->card->codec;
210 struct uda134x_priv *uda134x = codec->private_data; 210 struct uda134x_priv *uda134x = codec->private_data;
211 211
212 if (uda134x->master_substream == substream) 212 if (uda134x->master_substream == substream)
@@ -221,7 +221,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
221{ 221{
222 struct snd_soc_pcm_runtime *rtd = substream->private_data; 222 struct snd_soc_pcm_runtime *rtd = substream->private_data;
223 struct snd_soc_device *socdev = rtd->socdev; 223 struct snd_soc_device *socdev = rtd->socdev;
224 struct snd_soc_codec *codec = socdev->codec; 224 struct snd_soc_codec *codec = socdev->card->codec;
225 struct uda134x_priv *uda134x = codec->private_data; 225 struct uda134x_priv *uda134x = codec->private_data;
226 u8 hw_params; 226 u8 hw_params;
227 227
@@ -431,38 +431,14 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
431SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), 431SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
432}; 432};
433 433
434static int uda134x_add_controls(struct snd_soc_codec *codec) 434static struct snd_soc_dai_ops uda134x_dai_ops = {
435{ 435 .startup = uda134x_startup,
436 int err, i, n; 436 .shutdown = uda134x_shutdown,
437 const struct snd_kcontrol_new *ctrls; 437 .hw_params = uda134x_hw_params,
438 struct uda134x_platform_data *pd = codec->control_data; 438 .digital_mute = uda134x_mute,
439 439 .set_sysclk = uda134x_set_dai_sysclk,
440 switch (pd->model) { 440 .set_fmt = uda134x_set_dai_fmt,
441 case UDA134X_UDA1340: 441};
442 case UDA134X_UDA1344:
443 n = ARRAY_SIZE(uda1340_snd_controls);
444 ctrls = uda1340_snd_controls;
445 break;
446 case UDA134X_UDA1341:
447 n = ARRAY_SIZE(uda1341_snd_controls);
448 ctrls = uda1341_snd_controls;
449 break;
450 default:
451 printk(KERN_ERR "%s unkown codec type: %d",
452 __func__, pd->model);
453 return -EINVAL;
454 }
455
456 for (i = 0; i < n; i++) {
457 err = snd_ctl_add(codec->card,
458 snd_soc_cnew(&ctrls[i],
459 codec, NULL));
460 if (err < 0)
461 return err;
462 }
463
464 return 0;
465}
466 442
467struct snd_soc_dai uda134x_dai = { 443struct snd_soc_dai uda134x_dai = {
468 .name = "UDA134X", 444 .name = "UDA134X",
@@ -483,14 +459,7 @@ struct snd_soc_dai uda134x_dai = {
483 .formats = UDA134X_FORMATS, 459 .formats = UDA134X_FORMATS,
484 }, 460 },
485 /* pcm operations */ 461 /* pcm operations */
486 .ops = { 462 .ops = &uda134x_dai_ops,
487 .startup = uda134x_startup,
488 .shutdown = uda134x_shutdown,
489 .hw_params = uda134x_hw_params,
490 .digital_mute = uda134x_mute,
491 .set_sysclk = uda134x_set_dai_sysclk,
492 .set_fmt = uda134x_set_dai_fmt,
493 }
494}; 463};
495EXPORT_SYMBOL(uda134x_dai); 464EXPORT_SYMBOL(uda134x_dai);
496 465
@@ -525,11 +494,11 @@ static int uda134x_soc_probe(struct platform_device *pdev)
525 return -EINVAL; 494 return -EINVAL;
526 } 495 }
527 496
528 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 497 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
529 if (socdev->codec == NULL) 498 if (socdev->card->codec == NULL)
530 return ret; 499 return ret;
531 500
532 codec = socdev->codec; 501 codec = socdev->card->codec;
533 502
534 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); 503 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
535 if (uda134x == NULL) 504 if (uda134x == NULL)
@@ -572,7 +541,22 @@ static int uda134x_soc_probe(struct platform_device *pdev)
572 goto pcm_err; 541 goto pcm_err;
573 } 542 }
574 543
575 ret = uda134x_add_controls(codec); 544 switch (pd->model) {
545 case UDA134X_UDA1340:
546 case UDA134X_UDA1344:
547 ret = snd_soc_add_controls(codec, uda1340_snd_controls,
548 ARRAY_SIZE(uda1340_snd_controls));
549 break;
550 case UDA134X_UDA1341:
551 ret = snd_soc_add_controls(codec, uda1341_snd_controls,
552 ARRAY_SIZE(uda1341_snd_controls));
553 break;
554 default:
555 printk(KERN_ERR "%s unkown codec type: %d",
556 __func__, pd->model);
557 return -EINVAL;
558 }
559
576 if (ret < 0) { 560 if (ret < 0) {
577 printk(KERN_ERR "UDA134X: failed to register controls\n"); 561 printk(KERN_ERR "UDA134X: failed to register controls\n");
578 goto pcm_err; 562 goto pcm_err;
@@ -602,7 +586,7 @@ priv_err:
602static int uda134x_soc_remove(struct platform_device *pdev) 586static int uda134x_soc_remove(struct platform_device *pdev)
603{ 587{
604 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 588 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
605 struct snd_soc_codec *codec = socdev->codec; 589 struct snd_soc_codec *codec = socdev->card->codec;
606 590
607 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 591 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
608 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); 592 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -622,7 +606,7 @@ static int uda134x_soc_suspend(struct platform_device *pdev,
622 pm_message_t state) 606 pm_message_t state)
623{ 607{
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 608 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
625 struct snd_soc_codec *codec = socdev->codec; 609 struct snd_soc_codec *codec = socdev->card->codec;
626 610
627 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 611 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
628 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); 612 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -632,7 +616,7 @@ static int uda134x_soc_suspend(struct platform_device *pdev,
632static int uda134x_soc_resume(struct platform_device *pdev) 616static int uda134x_soc_resume(struct platform_device *pdev)
633{ 617{
634 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 618 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
635 struct snd_soc_codec *codec = socdev->codec; 619 struct snd_soc_codec *codec = socdev->card->codec;
636 620
637 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 621 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
638 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); 622 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index e6bf0844fbf3..5b21594e0e58 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -25,6 +25,7 @@
25#include <linux/ioctl.h> 25#include <linux/ioctl.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/workqueue.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/control.h> 30#include <sound/control.h>
30#include <sound/initval.h> 31#include <sound/initval.h>
@@ -35,7 +36,8 @@
35 36
36#include "uda1380.h" 37#include "uda1380.h"
37 38
38#define UDA1380_VERSION "0.6" 39static struct work_struct uda1380_work;
40static struct snd_soc_codec *uda1380_codec;
39 41
40/* 42/*
41 * uda1380 register cache 43 * uda1380 register cache
@@ -52,6 +54,8 @@ static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
52 0x0000, 0x8000, 0x0002, 0x0000, 54 0x0000, 0x8000, 0x0002, 0x0000,
53}; 55};
54 56
57static unsigned long uda1380_cache_dirty;
58
55/* 59/*
56 * read uda1380 register cache 60 * read uda1380 register cache
57 */ 61 */
@@ -73,8 +77,11 @@ static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
73 u16 reg, unsigned int value) 77 u16 reg, unsigned int value)
74{ 78{
75 u16 *cache = codec->reg_cache; 79 u16 *cache = codec->reg_cache;
80
76 if (reg >= UDA1380_CACHEREGNUM) 81 if (reg >= UDA1380_CACHEREGNUM)
77 return; 82 return;
83 if ((reg >= 0x10) && (cache[reg] != value))
84 set_bit(reg - 0x10, &uda1380_cache_dirty);
78 cache[reg] = value; 85 cache[reg] = value;
79} 86}
80 87
@@ -113,6 +120,8 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
113 (data[0]<<8) | data[1]); 120 (data[0]<<8) | data[1]);
114 return -EIO; 121 return -EIO;
115 } 122 }
123 if (reg >= 0x10)
124 clear_bit(reg - 0x10, &uda1380_cache_dirty);
116 return 0; 125 return 0;
117 } else 126 } else
118 return -EIO; 127 return -EIO;
@@ -120,6 +129,20 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
120 129
121#define uda1380_reset(c) uda1380_write(c, UDA1380_RESET, 0) 130#define uda1380_reset(c) uda1380_write(c, UDA1380_RESET, 0)
122 131
132static void uda1380_flush_work(struct work_struct *work)
133{
134 int bit, reg;
135
136 for_each_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
137 reg = 0x10 + bit;
138 pr_debug("uda1380: flush reg %x val %x:\n", reg,
139 uda1380_read_reg_cache(uda1380_codec, reg));
140 uda1380_write(uda1380_codec, reg,
141 uda1380_read_reg_cache(uda1380_codec, reg));
142 clear_bit(bit, &uda1380_cache_dirty);
143 }
144}
145
123/* declarations of ALSA reg_elem_REAL controls */ 146/* declarations of ALSA reg_elem_REAL controls */
124static const char *uda1380_deemp[] = { 147static const char *uda1380_deemp[] = {
125 "None", 148 "None",
@@ -254,7 +277,6 @@ static const struct snd_kcontrol_new uda1380_snd_controls[] = {
254 SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0), /* DA_POL_INV */ 277 SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0), /* DA_POL_INV */
255 SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum), /* SEL_NS */ 278 SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum), /* SEL_NS */
256 SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum), /* MIX_POS, MIX */ 279 SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum), /* MIX_POS, MIX */
257 SOC_SINGLE("Silence Switch", UDA1380_MIXER, 7, 1, 0), /* SILENCE, force DAC output to silence */
258 SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0), /* SDET_ON */ 280 SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0), /* SDET_ON */
259 SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum), /* SD_VALUE */ 281 SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum), /* SD_VALUE */
260 SOC_ENUM("Oversampling Input", uda1380_os_enum), /* OS */ 282 SOC_ENUM("Oversampling Input", uda1380_os_enum), /* OS */
@@ -271,21 +293,6 @@ static const struct snd_kcontrol_new uda1380_snd_controls[] = {
271 SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0), 293 SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
272}; 294};
273 295
274/* add non dapm controls */
275static int uda1380_add_controls(struct snd_soc_codec *codec)
276{
277 int err, i;
278
279 for (i = 0; i < ARRAY_SIZE(uda1380_snd_controls); i++) {
280 err = snd_ctl_add(codec->card,
281 snd_soc_cnew(&uda1380_snd_controls[i], codec, NULL));
282 if (err < 0)
283 return err;
284 }
285
286 return 0;
287}
288
289/* Input mux */ 296/* Input mux */
290static const struct snd_kcontrol_new uda1380_input_mux_control = 297static const struct snd_kcontrol_new uda1380_input_mux_control =
291 SOC_DAPM_ENUM("Route", uda1380_input_sel_enum); 298 SOC_DAPM_ENUM("Route", uda1380_input_sel_enum);
@@ -371,7 +378,7 @@ static int uda1380_add_widgets(struct snd_soc_codec *codec)
371 return 0; 378 return 0;
372} 379}
373 380
374static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai, 381static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
375 unsigned int fmt) 382 unsigned int fmt)
376{ 383{
377 struct snd_soc_codec *codec = codec_dai->codec; 384 struct snd_soc_codec *codec = codec_dai->codec;
@@ -381,61 +388,107 @@ static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai,
381 iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); 388 iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
382 iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK); 389 iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
383 390
384 /* FIXME: how to select I2S for DATAO and MSB for DATAI correctly? */
385 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 391 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
386 case SND_SOC_DAIFMT_I2S: 392 case SND_SOC_DAIFMT_I2S:
387 iface |= R01_SFORI_I2S | R01_SFORO_I2S; 393 iface |= R01_SFORI_I2S | R01_SFORO_I2S;
388 break; 394 break;
389 case SND_SOC_DAIFMT_LSB: 395 case SND_SOC_DAIFMT_LSB:
390 iface |= R01_SFORI_LSB16 | R01_SFORO_I2S; 396 iface |= R01_SFORI_LSB16 | R01_SFORO_LSB16;
391 break; 397 break;
392 case SND_SOC_DAIFMT_MSB: 398 case SND_SOC_DAIFMT_MSB:
393 iface |= R01_SFORI_MSB | R01_SFORO_I2S; 399 iface |= R01_SFORI_MSB | R01_SFORO_MSB;
394 } 400 }
395 401
396 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) 402 /* DATAI is slave only, so in single-link mode, this has to be slave */
397 iface |= R01_SIM; 403 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
404 return -EINVAL;
398 405
399 uda1380_write(codec, UDA1380_IFACE, iface); 406 uda1380_write(codec, UDA1380_IFACE, iface);
400 407
401 return 0; 408 return 0;
402} 409}
403 410
404/* 411static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
405 * Flush reg cache 412 unsigned int fmt)
406 * We can only write the interpolator and decimator registers
407 * when the DAI is being clocked by the CPU DAI. It's up to the
408 * machine and cpu DAI driver to do this before we are called.
409 */
410static int uda1380_pcm_prepare(struct snd_pcm_substream *substream,
411 struct snd_soc_dai *dai)
412{ 413{
413 struct snd_soc_pcm_runtime *rtd = substream->private_data; 414 struct snd_soc_codec *codec = codec_dai->codec;
414 struct snd_soc_device *socdev = rtd->socdev; 415 int iface;
415 struct snd_soc_codec *codec = socdev->codec; 416
416 int reg, reg_start, reg_end, clk; 417 /* set up DAI based upon fmt */
417 418 iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
418 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 419 iface &= ~R01_SFORI_MASK;
419 reg_start = UDA1380_MVOL; 420
420 reg_end = UDA1380_MIXER; 421 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
421 } else { 422 case SND_SOC_DAIFMT_I2S:
422 reg_start = UDA1380_DEC; 423 iface |= R01_SFORI_I2S;
423 reg_end = UDA1380_AGC; 424 break;
425 case SND_SOC_DAIFMT_LSB:
426 iface |= R01_SFORI_LSB16;
427 break;
428 case SND_SOC_DAIFMT_MSB:
429 iface |= R01_SFORI_MSB;
424 } 430 }
425 431
426 /* FIXME disable DAC_CLK */ 432 /* DATAI is slave only, so this has to be slave */
427 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 433 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
428 uda1380_write(codec, UDA1380_CLK, clk & ~R00_DAC_CLK); 434 return -EINVAL;
435
436 uda1380_write(codec, UDA1380_IFACE, iface);
437
438 return 0;
439}
440
441static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
442 unsigned int fmt)
443{
444 struct snd_soc_codec *codec = codec_dai->codec;
445 int iface;
446
447 /* set up DAI based upon fmt */
448 iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
449 iface &= ~(R01_SIM | R01_SFORO_MASK);
429 450
430 for (reg = reg_start; reg <= reg_end; reg++) { 451 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
431 pr_debug("uda1380: flush reg %x val %x:", reg, 452 case SND_SOC_DAIFMT_I2S:
432 uda1380_read_reg_cache(codec, reg)); 453 iface |= R01_SFORO_I2S;
433 uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg)); 454 break;
455 case SND_SOC_DAIFMT_LSB:
456 iface |= R01_SFORO_LSB16;
457 break;
458 case SND_SOC_DAIFMT_MSB:
459 iface |= R01_SFORO_MSB;
434 } 460 }
435 461
436 /* FIXME enable DAC_CLK */ 462 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
437 uda1380_write(codec, UDA1380_CLK, clk | R00_DAC_CLK); 463 iface |= R01_SIM;
438 464
465 uda1380_write(codec, UDA1380_IFACE, iface);
466
467 return 0;
468}
469
470static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
471 struct snd_soc_dai *dai)
472{
473 struct snd_soc_pcm_runtime *rtd = substream->private_data;
474 struct snd_soc_device *socdev = rtd->socdev;
475 struct snd_soc_codec *codec = socdev->card->codec;
476 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
477
478 switch (cmd) {
479 case SNDRV_PCM_TRIGGER_START:
480 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
481 uda1380_write_reg_cache(codec, UDA1380_MIXER,
482 mixer & ~R14_SILENCE);
483 schedule_work(&uda1380_work);
484 break;
485 case SNDRV_PCM_TRIGGER_STOP:
486 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
487 uda1380_write_reg_cache(codec, UDA1380_MIXER,
488 mixer | R14_SILENCE);
489 schedule_work(&uda1380_work);
490 break;
491 }
439 return 0; 492 return 0;
440} 493}
441 494
@@ -445,7 +498,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
445{ 498{
446 struct snd_soc_pcm_runtime *rtd = substream->private_data; 499 struct snd_soc_pcm_runtime *rtd = substream->private_data;
447 struct snd_soc_device *socdev = rtd->socdev; 500 struct snd_soc_device *socdev = rtd->socdev;
448 struct snd_soc_codec *codec = socdev->codec; 501 struct snd_soc_codec *codec = socdev->card->codec;
449 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 502 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
450 503
451 /* set WSPLL power and divider if running from this clock */ 504 /* set WSPLL power and divider if running from this clock */
@@ -484,7 +537,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
484{ 537{
485 struct snd_soc_pcm_runtime *rtd = substream->private_data; 538 struct snd_soc_pcm_runtime *rtd = substream->private_data;
486 struct snd_soc_device *socdev = rtd->socdev; 539 struct snd_soc_device *socdev = rtd->socdev;
487 struct snd_soc_codec *codec = socdev->codec; 540 struct snd_soc_codec *codec = socdev->card->codec;
488 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 541 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
489 542
490 /* shut down WSPLL power if running from this clock */ 543 /* shut down WSPLL power if running from this clock */
@@ -501,24 +554,6 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
501 uda1380_write(codec, UDA1380_CLK, clk); 554 uda1380_write(codec, UDA1380_CLK, clk);
502} 555}
503 556
504static int uda1380_mute(struct snd_soc_dai *codec_dai, int mute)
505{
506 struct snd_soc_codec *codec = codec_dai->codec;
507 u16 mute_reg = uda1380_read_reg_cache(codec, UDA1380_DEEMP) & ~R13_MTM;
508
509 /* FIXME: mute(codec,0) is called when the magician clock is already
510 * set to WSPLL, but for some unknown reason writing to interpolator
511 * registers works only when clocked by SYSCLK */
512 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
513 uda1380_write(codec, UDA1380_CLK, ~R00_DAC_CLK & clk);
514 if (mute)
515 uda1380_write(codec, UDA1380_DEEMP, mute_reg | R13_MTM);
516 else
517 uda1380_write(codec, UDA1380_DEEMP, mute_reg);
518 uda1380_write(codec, UDA1380_CLK, clk);
519 return 0;
520}
521
522static int uda1380_set_bias_level(struct snd_soc_codec *codec, 557static int uda1380_set_bias_level(struct snd_soc_codec *codec,
523 enum snd_soc_bias_level level) 558 enum snd_soc_bias_level level)
524{ 559{
@@ -544,6 +579,27 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
544 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ 579 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
545 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 580 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
546 581
582static struct snd_soc_dai_ops uda1380_dai_ops = {
583 .hw_params = uda1380_pcm_hw_params,
584 .shutdown = uda1380_pcm_shutdown,
585 .trigger = uda1380_trigger,
586 .set_fmt = uda1380_set_dai_fmt_both,
587};
588
589static struct snd_soc_dai_ops uda1380_dai_ops_playback = {
590 .hw_params = uda1380_pcm_hw_params,
591 .shutdown = uda1380_pcm_shutdown,
592 .trigger = uda1380_trigger,
593 .set_fmt = uda1380_set_dai_fmt_playback,
594};
595
596static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
597 .hw_params = uda1380_pcm_hw_params,
598 .shutdown = uda1380_pcm_shutdown,
599 .trigger = uda1380_trigger,
600 .set_fmt = uda1380_set_dai_fmt_capture,
601};
602
547struct snd_soc_dai uda1380_dai[] = { 603struct snd_soc_dai uda1380_dai[] = {
548{ 604{
549 .name = "UDA1380", 605 .name = "UDA1380",
@@ -559,13 +615,7 @@ struct snd_soc_dai uda1380_dai[] = {
559 .channels_max = 2, 615 .channels_max = 2,
560 .rates = UDA1380_RATES, 616 .rates = UDA1380_RATES,
561 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 617 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
562 .ops = { 618 .ops = &uda1380_dai_ops,
563 .hw_params = uda1380_pcm_hw_params,
564 .shutdown = uda1380_pcm_shutdown,
565 .prepare = uda1380_pcm_prepare,
566 .digital_mute = uda1380_mute,
567 .set_fmt = uda1380_set_dai_fmt,
568 },
569}, 619},
570{ /* playback only - dual interface */ 620{ /* playback only - dual interface */
571 .name = "UDA1380", 621 .name = "UDA1380",
@@ -576,13 +626,7 @@ struct snd_soc_dai uda1380_dai[] = {
576 .rates = UDA1380_RATES, 626 .rates = UDA1380_RATES,
577 .formats = SNDRV_PCM_FMTBIT_S16_LE, 627 .formats = SNDRV_PCM_FMTBIT_S16_LE,
578 }, 628 },
579 .ops = { 629 .ops = &uda1380_dai_ops_playback,
580 .hw_params = uda1380_pcm_hw_params,
581 .shutdown = uda1380_pcm_shutdown,
582 .prepare = uda1380_pcm_prepare,
583 .digital_mute = uda1380_mute,
584 .set_fmt = uda1380_set_dai_fmt,
585 },
586}, 630},
587{ /* capture only - dual interface*/ 631{ /* capture only - dual interface*/
588 .name = "UDA1380", 632 .name = "UDA1380",
@@ -593,12 +637,7 @@ struct snd_soc_dai uda1380_dai[] = {
593 .rates = UDA1380_RATES, 637 .rates = UDA1380_RATES,
594 .formats = SNDRV_PCM_FMTBIT_S16_LE, 638 .formats = SNDRV_PCM_FMTBIT_S16_LE,
595 }, 639 },
596 .ops = { 640 .ops = &uda1380_dai_ops_capture,
597 .hw_params = uda1380_pcm_hw_params,
598 .shutdown = uda1380_pcm_shutdown,
599 .prepare = uda1380_pcm_prepare,
600 .set_fmt = uda1380_set_dai_fmt,
601 },
602}, 641},
603}; 642};
604EXPORT_SYMBOL_GPL(uda1380_dai); 643EXPORT_SYMBOL_GPL(uda1380_dai);
@@ -606,7 +645,7 @@ EXPORT_SYMBOL_GPL(uda1380_dai);
606static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) 645static int uda1380_suspend(struct platform_device *pdev, pm_message_t state)
607{ 646{
608 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 647 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
609 struct snd_soc_codec *codec = socdev->codec; 648 struct snd_soc_codec *codec = socdev->card->codec;
610 649
611 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); 650 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
612 return 0; 651 return 0;
@@ -615,7 +654,7 @@ static int uda1380_suspend(struct platform_device *pdev, pm_message_t state)
615static int uda1380_resume(struct platform_device *pdev) 654static int uda1380_resume(struct platform_device *pdev)
616{ 655{
617 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 656 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
618 struct snd_soc_codec *codec = socdev->codec; 657 struct snd_soc_codec *codec = socdev->card->codec;
619 int i; 658 int i;
620 u8 data[2]; 659 u8 data[2];
621 u16 *cache = codec->reg_cache; 660 u16 *cache = codec->reg_cache;
@@ -637,7 +676,7 @@ static int uda1380_resume(struct platform_device *pdev)
637 */ 676 */
638static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) 677static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
639{ 678{
640 struct snd_soc_codec *codec = socdev->codec; 679 struct snd_soc_codec *codec = socdev->card->codec;
641 int ret = 0; 680 int ret = 0;
642 681
643 codec->name = "UDA1380"; 682 codec->name = "UDA1380";
@@ -655,6 +694,9 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
655 codec->reg_cache_step = 1; 694 codec->reg_cache_step = 1;
656 uda1380_reset(codec); 695 uda1380_reset(codec);
657 696
697 uda1380_codec = codec;
698 INIT_WORK(&uda1380_work, uda1380_flush_work);
699
658 /* register pcms */ 700 /* register pcms */
659 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 701 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
660 if (ret < 0) { 702 if (ret < 0) {
@@ -675,7 +717,8 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
675 } 717 }
676 718
677 /* uda1380 init */ 719 /* uda1380 init */
678 uda1380_add_controls(codec); 720 snd_soc_add_controls(codec, uda1380_snd_controls,
721 ARRAY_SIZE(uda1380_snd_controls));
679 uda1380_add_widgets(codec); 722 uda1380_add_widgets(codec);
680 ret = snd_soc_init_card(socdev); 723 ret = snd_soc_init_card(socdev);
681 if (ret < 0) { 724 if (ret < 0) {
@@ -702,7 +745,7 @@ static int uda1380_i2c_probe(struct i2c_client *i2c,
702{ 745{
703 struct snd_soc_device *socdev = uda1380_socdev; 746 struct snd_soc_device *socdev = uda1380_socdev;
704 struct uda1380_setup_data *setup = socdev->codec_data; 747 struct uda1380_setup_data *setup = socdev->codec_data;
705 struct snd_soc_codec *codec = socdev->codec; 748 struct snd_soc_codec *codec = socdev->card->codec;
706 int ret; 749 int ret;
707 750
708 i2c_set_clientdata(i2c, codec); 751 i2c_set_clientdata(i2c, codec);
@@ -786,14 +829,12 @@ static int uda1380_probe(struct platform_device *pdev)
786 struct snd_soc_codec *codec; 829 struct snd_soc_codec *codec;
787 int ret; 830 int ret;
788 831
789 pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION);
790
791 setup = socdev->codec_data; 832 setup = socdev->codec_data;
792 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 833 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
793 if (codec == NULL) 834 if (codec == NULL)
794 return -ENOMEM; 835 return -ENOMEM;
795 836
796 socdev->codec = codec; 837 socdev->card->codec = codec;
797 mutex_init(&codec->mutex); 838 mutex_init(&codec->mutex);
798 INIT_LIST_HEAD(&codec->dapm_widgets); 839 INIT_LIST_HEAD(&codec->dapm_widgets);
799 INIT_LIST_HEAD(&codec->dapm_paths); 840 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -817,7 +858,7 @@ static int uda1380_probe(struct platform_device *pdev)
817static int uda1380_remove(struct platform_device *pdev) 858static int uda1380_remove(struct platform_device *pdev)
818{ 859{
819 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 860 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
820 struct snd_soc_codec *codec = socdev->codec; 861 struct snd_soc_codec *codec = socdev->card->codec;
821 862
822 if (codec->control_data) 863 if (codec->control_data)
823 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); 864 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 35d99750c383..3b1d0993bed9 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -51,10 +51,17 @@ struct wm8350_output {
51 u16 mute; 51 u16 mute;
52}; 52};
53 53
54struct wm8350_jack_data {
55 struct snd_soc_jack *jack;
56 int report;
57};
58
54struct wm8350_data { 59struct wm8350_data {
55 struct snd_soc_codec codec; 60 struct snd_soc_codec codec;
56 struct wm8350_output out1; 61 struct wm8350_output out1;
57 struct wm8350_output out2; 62 struct wm8350_output out2;
63 struct wm8350_jack_data hpl;
64 struct wm8350_jack_data hpr;
58 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 65 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
59}; 66};
60 67
@@ -775,21 +782,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
775 {"Beep", NULL, "IN3R PGA"}, 782 {"Beep", NULL, "IN3R PGA"},
776}; 783};
777 784
778static int wm8350_add_controls(struct snd_soc_codec *codec)
779{
780 int err, i;
781
782 for (i = 0; i < ARRAY_SIZE(wm8350_snd_controls); i++) {
783 err = snd_ctl_add(codec->card,
784 snd_soc_cnew(&wm8350_snd_controls[i],
785 codec, NULL));
786 if (err < 0)
787 return err;
788 }
789
790 return 0;
791}
792
793static int wm8350_add_widgets(struct snd_soc_codec *codec) 785static int wm8350_add_widgets(struct snd_soc_codec *codec)
794{ 786{
795 int ret; 787 int ret;
@@ -1309,7 +1301,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1309static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) 1301static int wm8350_suspend(struct platform_device *pdev, pm_message_t state)
1310{ 1302{
1311 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1303 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1312 struct snd_soc_codec *codec = socdev->codec; 1304 struct snd_soc_codec *codec = socdev->card->codec;
1313 1305
1314 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); 1306 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1315 return 0; 1307 return 0;
@@ -1318,7 +1310,7 @@ static int wm8350_suspend(struct platform_device *pdev, pm_message_t state)
1318static int wm8350_resume(struct platform_device *pdev) 1310static int wm8350_resume(struct platform_device *pdev)
1319{ 1311{
1320 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1312 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1321 struct snd_soc_codec *codec = socdev->codec; 1313 struct snd_soc_codec *codec = socdev->card->codec;
1322 1314
1323 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1315 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1324 1316
@@ -1328,6 +1320,95 @@ static int wm8350_resume(struct platform_device *pdev)
1328 return 0; 1320 return 0;
1329} 1321}
1330 1322
1323static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data)
1324{
1325 struct wm8350_data *priv = data;
1326 u16 reg;
1327 int report;
1328 int mask;
1329 struct wm8350_jack_data *jack = NULL;
1330
1331 switch (irq) {
1332 case WM8350_IRQ_CODEC_JCK_DET_L:
1333 jack = &priv->hpl;
1334 mask = WM8350_JACK_L_LVL;
1335 break;
1336
1337 case WM8350_IRQ_CODEC_JCK_DET_R:
1338 jack = &priv->hpr;
1339 mask = WM8350_JACK_R_LVL;
1340 break;
1341
1342 default:
1343 BUG();
1344 }
1345
1346 if (!jack->jack) {
1347 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n");
1348 return;
1349 }
1350
1351 /* Debounce */
1352 msleep(200);
1353
1354 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1355 if (reg & mask)
1356 report = jack->report;
1357 else
1358 report = 0;
1359
1360 snd_soc_jack_report(jack->jack, report, jack->report);
1361}
1362
1363/**
1364 * wm8350_hp_jack_detect - Enable headphone jack detection.
1365 *
1366 * @codec: WM8350 codec
1367 * @which: left or right jack detect signal
1368 * @jack: jack to report detection events on
1369 * @report: value to report
1370 *
1371 * Enables the headphone jack detection of the WM8350.
1372 */
1373int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1374 struct snd_soc_jack *jack, int report)
1375{
1376 struct wm8350_data *priv = codec->private_data;
1377 struct wm8350 *wm8350 = codec->control_data;
1378 int irq;
1379 int ena;
1380
1381 switch (which) {
1382 case WM8350_JDL:
1383 priv->hpl.jack = jack;
1384 priv->hpl.report = report;
1385 irq = WM8350_IRQ_CODEC_JCK_DET_L;
1386 ena = WM8350_JDL_ENA;
1387 break;
1388
1389 case WM8350_JDR:
1390 priv->hpr.jack = jack;
1391 priv->hpr.report = report;
1392 irq = WM8350_IRQ_CODEC_JCK_DET_R;
1393 ena = WM8350_JDR_ENA;
1394 break;
1395
1396 default:
1397 return -EINVAL;
1398 }
1399
1400 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1401 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
1402
1403 /* Sync status */
1404 wm8350_hp_jack_handler(wm8350, irq, priv);
1405
1406 wm8350_unmask_irq(wm8350, irq);
1407
1408 return 0;
1409}
1410EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect);
1411
1331static struct snd_soc_codec *wm8350_codec; 1412static struct snd_soc_codec *wm8350_codec;
1332 1413
1333static int wm8350_probe(struct platform_device *pdev) 1414static int wm8350_probe(struct platform_device *pdev)
@@ -1342,8 +1423,8 @@ static int wm8350_probe(struct platform_device *pdev)
1342 1423
1343 BUG_ON(!wm8350_codec); 1424 BUG_ON(!wm8350_codec);
1344 1425
1345 socdev->codec = wm8350_codec; 1426 socdev->card->codec = wm8350_codec;
1346 codec = socdev->codec; 1427 codec = socdev->card->codec;
1347 wm8350 = codec->control_data; 1428 wm8350 = codec->control_data;
1348 priv = codec->private_data; 1429 priv = codec->private_data;
1349 1430
@@ -1381,13 +1462,21 @@ static int wm8350_probe(struct platform_device *pdev)
1381 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, 1462 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
1382 WM8350_OUT2_VU | WM8350_OUT2R_MUTE); 1463 WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
1383 1464
1465 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
1466 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
1467 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L,
1468 wm8350_hp_jack_handler, priv);
1469 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
1470 wm8350_hp_jack_handler, priv);
1471
1384 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1472 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1385 if (ret < 0) { 1473 if (ret < 0) {
1386 dev_err(&pdev->dev, "failed to create pcms\n"); 1474 dev_err(&pdev->dev, "failed to create pcms\n");
1387 return ret; 1475 return ret;
1388 } 1476 }
1389 1477
1390 wm8350_add_controls(codec); 1478 snd_soc_add_controls(codec, wm8350_snd_controls,
1479 ARRAY_SIZE(wm8350_snd_controls));
1391 wm8350_add_widgets(codec); 1480 wm8350_add_widgets(codec);
1392 1481
1393 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1482 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1409,10 +1498,23 @@ card_err:
1409static int wm8350_remove(struct platform_device *pdev) 1498static int wm8350_remove(struct platform_device *pdev)
1410{ 1499{
1411 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1500 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1412 struct snd_soc_codec *codec = socdev->codec; 1501 struct snd_soc_codec *codec = socdev->card->codec;
1413 struct wm8350 *wm8350 = codec->control_data; 1502 struct wm8350 *wm8350 = codec->control_data;
1503 struct wm8350_data *priv = codec->private_data;
1414 int ret; 1504 int ret;
1415 1505
1506 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1507 WM8350_JDL_ENA | WM8350_JDR_ENA);
1508 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1509
1510 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
1511 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
1512 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
1513 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
1514
1515 priv->hpl.jack = NULL;
1516 priv->hpr.jack = NULL;
1517
1416 /* cancel any work waiting to be queued. */ 1518 /* cancel any work waiting to be queued. */
1417 ret = cancel_delayed_work(&codec->delayed_work); 1519 ret = cancel_delayed_work(&codec->delayed_work);
1418 1520
@@ -1436,6 +1538,16 @@ static int wm8350_remove(struct platform_device *pdev)
1436 SNDRV_PCM_FMTBIT_S20_3LE |\ 1538 SNDRV_PCM_FMTBIT_S20_3LE |\
1437 SNDRV_PCM_FMTBIT_S24_LE) 1539 SNDRV_PCM_FMTBIT_S24_LE)
1438 1540
1541static struct snd_soc_dai_ops wm8350_dai_ops = {
1542 .hw_params = wm8350_pcm_hw_params,
1543 .digital_mute = wm8350_mute,
1544 .trigger = wm8350_pcm_trigger,
1545 .set_fmt = wm8350_set_dai_fmt,
1546 .set_sysclk = wm8350_set_dai_sysclk,
1547 .set_pll = wm8350_set_fll,
1548 .set_clkdiv = wm8350_set_clkdiv,
1549};
1550
1439struct snd_soc_dai wm8350_dai = { 1551struct snd_soc_dai wm8350_dai = {
1440 .name = "WM8350", 1552 .name = "WM8350",
1441 .playback = { 1553 .playback = {
@@ -1452,15 +1564,7 @@ struct snd_soc_dai wm8350_dai = {
1452 .rates = WM8350_RATES, 1564 .rates = WM8350_RATES,
1453 .formats = WM8350_FORMATS, 1565 .formats = WM8350_FORMATS,
1454 }, 1566 },
1455 .ops = { 1567 .ops = &wm8350_dai_ops,
1456 .hw_params = wm8350_pcm_hw_params,
1457 .digital_mute = wm8350_mute,
1458 .trigger = wm8350_pcm_trigger,
1459 .set_fmt = wm8350_set_dai_fmt,
1460 .set_sysclk = wm8350_set_dai_sysclk,
1461 .set_pll = wm8350_set_fll,
1462 .set_clkdiv = wm8350_set_clkdiv,
1463 },
1464}; 1568};
1465EXPORT_SYMBOL_GPL(wm8350_dai); 1569EXPORT_SYMBOL_GPL(wm8350_dai);
1466 1570
@@ -1472,7 +1576,7 @@ struct snd_soc_codec_device soc_codec_dev_wm8350 = {
1472}; 1576};
1473EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350); 1577EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
1474 1578
1475static int wm8350_codec_probe(struct platform_device *pdev) 1579static __devinit int wm8350_codec_probe(struct platform_device *pdev)
1476{ 1580{
1477 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1581 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1478 struct wm8350_data *priv; 1582 struct wm8350_data *priv;
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
index cc2887aa6c38..d11bd9288cf9 100644
--- a/sound/soc/codecs/wm8350.h
+++ b/sound/soc/codecs/wm8350.h
@@ -17,4 +17,12 @@
17extern struct snd_soc_dai wm8350_dai; 17extern struct snd_soc_dai wm8350_dai;
18extern struct snd_soc_codec_device soc_codec_dev_wm8350; 18extern struct snd_soc_codec_device soc_codec_dev_wm8350;
19 19
20enum wm8350_jack {
21 WM8350_JDL = 1,
22 WM8350_JDR = 2,
23};
24
25int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
26 struct snd_soc_jack *jack, int report);
27
20#endif 28#endif
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
new file mode 100644
index 000000000000..510efa604008
--- /dev/null
+++ b/sound/soc/codecs/wm8400.c
@@ -0,0 +1,1582 @@
1/*
2 * wm8400.c -- WM8400 ALSA Soc Audio driver
3 *
4 * Copyright 2008, 2009 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <linux/mfd/wm8400-audio.h>
23#include <linux/mfd/wm8400-private.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31
32#include "wm8400.h"
33
34/* Fake register for internal state */
35#define WM8400_INTDRIVBITS (WM8400_REGISTER_COUNT + 1)
36#define WM8400_INMIXL_PWR 0
37#define WM8400_AINLMUX_PWR 1
38#define WM8400_INMIXR_PWR 2
39#define WM8400_AINRMUX_PWR 3
40
41static struct regulator_bulk_data power[] = {
42 {
43 .supply = "I2S1VDD",
44 },
45 {
46 .supply = "I2S2VDD",
47 },
48 {
49 .supply = "DCVDD",
50 },
51 {
52 .supply = "AVDD",
53 },
54 {
55 .supply = "FLLVDD",
56 },
57 {
58 .supply = "HPVDD",
59 },
60 {
61 .supply = "SPKVDD",
62 },
63};
64
65/* codec private data */
66struct wm8400_priv {
67 struct snd_soc_codec codec;
68 struct wm8400 *wm8400;
69 u16 fake_register;
70 unsigned int sysclk;
71 unsigned int pcmclk;
72 struct work_struct work;
73 int fll_in, fll_out;
74};
75
76static inline unsigned int wm8400_read(struct snd_soc_codec *codec,
77 unsigned int reg)
78{
79 struct wm8400_priv *wm8400 = codec->private_data;
80
81 if (reg == WM8400_INTDRIVBITS)
82 return wm8400->fake_register;
83 else
84 return wm8400_reg_read(wm8400->wm8400, reg);
85}
86
87/*
88 * write to the wm8400 register space
89 */
90static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg,
91 unsigned int value)
92{
93 struct wm8400_priv *wm8400 = codec->private_data;
94
95 if (reg == WM8400_INTDRIVBITS) {
96 wm8400->fake_register = value;
97 return 0;
98 } else
99 return wm8400_set_bits(wm8400->wm8400, reg, 0xffff, value);
100}
101
102static void wm8400_codec_reset(struct snd_soc_codec *codec)
103{
104 struct wm8400_priv *wm8400 = codec->private_data;
105
106 wm8400_reset_codec_reg_cache(wm8400->wm8400);
107}
108
109static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600);
110
111static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000);
112
113static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, -2100, 0);
114
115static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600);
116
117static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0);
118
119static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0);
120
121static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763);
122
123static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0);
124
125static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_value *ucontrol)
127{
128 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
129 struct soc_mixer_control *mc =
130 (struct soc_mixer_control *)kcontrol->private_value;
131 int reg = mc->reg;
132 int ret;
133 u16 val;
134
135 ret = snd_soc_put_volsw(kcontrol, ucontrol);
136 if (ret < 0)
137 return ret;
138
139 /* now hit the volume update bits (always bit 8) */
140 val = wm8400_read(codec, reg);
141 return wm8400_write(codec, reg, val | 0x0100);
142}
143
144#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
145{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
146 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
147 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
148 .tlv.p = (tlv_array), \
149 .info = snd_soc_info_volsw, \
150 .get = snd_soc_get_volsw, .put = wm8400_outpga_put_volsw_vu, \
151 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
152
153
154static const char *wm8400_digital_sidetone[] =
155 {"None", "Left ADC", "Right ADC", "Reserved"};
156
157static const struct soc_enum wm8400_left_digital_sidetone_enum =
158SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE,
159 WM8400_ADC_TO_DACL_SHIFT, 2, wm8400_digital_sidetone);
160
161static const struct soc_enum wm8400_right_digital_sidetone_enum =
162SOC_ENUM_SINGLE(WM8400_DIGITAL_SIDE_TONE,
163 WM8400_ADC_TO_DACR_SHIFT, 2, wm8400_digital_sidetone);
164
165static const char *wm8400_adcmode[] =
166 {"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
167
168static const struct soc_enum wm8400_right_adcmode_enum =
169SOC_ENUM_SINGLE(WM8400_ADC_CTRL, WM8400_ADC_HPF_CUT_SHIFT, 3, wm8400_adcmode);
170
171static const struct snd_kcontrol_new wm8400_snd_controls[] = {
172/* INMIXL */
173SOC_SINGLE("LIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L12MNBST_SHIFT,
174 1, 0),
175SOC_SINGLE("LIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L34MNBST_SHIFT,
176 1, 0),
177/* INMIXR */
178SOC_SINGLE("RIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R12MNBST_SHIFT,
179 1, 0),
180SOC_SINGLE("RIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R34MNBST_SHIFT,
181 1, 0),
182
183/* LOMIX */
184SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER3,
185 WM8400_LLI3LOVOL_SHIFT, 7, 0, out_mix_tlv),
186SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3,
187 WM8400_LR12LOVOL_SHIFT, 7, 0, out_mix_tlv),
188SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3,
189 WM8400_LL12LOVOL_SHIFT, 7, 0, out_mix_tlv),
190SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER5,
191 WM8400_LRI3LOVOL_SHIFT, 7, 0, out_mix_tlv),
192SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER5,
193 WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv),
194SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER5,
195 WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv),
196
197/* ROMIX */
198SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER4,
199 WM8400_RRI3ROVOL_SHIFT, 7, 0, out_mix_tlv),
200SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4,
201 WM8400_RL12ROVOL_SHIFT, 7, 0, out_mix_tlv),
202SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4,
203 WM8400_RR12ROVOL_SHIFT, 7, 0, out_mix_tlv),
204SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER6,
205 WM8400_RLI3ROVOL_SHIFT, 7, 0, out_mix_tlv),
206SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER6,
207 WM8400_RLBROVOL_SHIFT, 7, 0, out_mix_tlv),
208SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER6,
209 WM8400_RRBROVOL_SHIFT, 7, 0, out_mix_tlv),
210
211/* LOUT */
212WM8400_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8400_LEFT_OUTPUT_VOLUME,
213 WM8400_LOUTVOL_SHIFT, WM8400_LOUTVOL_MASK, 0, out_pga_tlv),
214SOC_SINGLE("LOUT ZC", WM8400_LEFT_OUTPUT_VOLUME, WM8400_LOZC_SHIFT, 1, 0),
215
216/* ROUT */
217WM8400_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8400_RIGHT_OUTPUT_VOLUME,
218 WM8400_ROUTVOL_SHIFT, WM8400_ROUTVOL_MASK, 0, out_pga_tlv),
219SOC_SINGLE("ROUT ZC", WM8400_RIGHT_OUTPUT_VOLUME, WM8400_ROZC_SHIFT, 1, 0),
220
221/* LOPGA */
222WM8400_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8400_LEFT_OPGA_VOLUME,
223 WM8400_LOPGAVOL_SHIFT, WM8400_LOPGAVOL_MASK, 0, out_pga_tlv),
224SOC_SINGLE("LOPGA ZC Switch", WM8400_LEFT_OPGA_VOLUME,
225 WM8400_LOPGAZC_SHIFT, 1, 0),
226
227/* ROPGA */
228WM8400_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8400_RIGHT_OPGA_VOLUME,
229 WM8400_ROPGAVOL_SHIFT, WM8400_ROPGAVOL_MASK, 0, out_pga_tlv),
230SOC_SINGLE("ROPGA ZC Switch", WM8400_RIGHT_OPGA_VOLUME,
231 WM8400_ROPGAZC_SHIFT, 1, 0),
232
233SOC_SINGLE("LON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
234 WM8400_LONMUTE_SHIFT, 1, 0),
235SOC_SINGLE("LOP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
236 WM8400_LOPMUTE_SHIFT, 1, 0),
237SOC_SINGLE("LOP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME,
238 WM8400_LOATTN_SHIFT, 1, 0),
239SOC_SINGLE("RON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
240 WM8400_RONMUTE_SHIFT, 1, 0),
241SOC_SINGLE("ROP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
242 WM8400_ROPMUTE_SHIFT, 1, 0),
243SOC_SINGLE("ROP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME,
244 WM8400_ROATTN_SHIFT, 1, 0),
245
246SOC_SINGLE("OUT3 Mute Switch", WM8400_OUT3_4_VOLUME,
247 WM8400_OUT3MUTE_SHIFT, 1, 0),
248SOC_SINGLE("OUT3 Attenuation Switch", WM8400_OUT3_4_VOLUME,
249 WM8400_OUT3ATTN_SHIFT, 1, 0),
250
251SOC_SINGLE("OUT4 Mute Switch", WM8400_OUT3_4_VOLUME,
252 WM8400_OUT4MUTE_SHIFT, 1, 0),
253SOC_SINGLE("OUT4 Attenuation Switch", WM8400_OUT3_4_VOLUME,
254 WM8400_OUT4ATTN_SHIFT, 1, 0),
255
256SOC_SINGLE("Speaker Mode Switch", WM8400_CLASSD1,
257 WM8400_CDMODE_SHIFT, 1, 0),
258
259SOC_SINGLE("Speaker Output Attenuation Volume", WM8400_SPEAKER_VOLUME,
260 WM8400_SPKATTN_SHIFT, WM8400_SPKATTN_MASK, 0),
261SOC_SINGLE("Speaker DC Boost Volume", WM8400_CLASSD3,
262 WM8400_DCGAIN_SHIFT, 6, 0),
263SOC_SINGLE("Speaker AC Boost Volume", WM8400_CLASSD3,
264 WM8400_ACGAIN_SHIFT, 6, 0),
265
266WM8400_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
267 WM8400_LEFT_DAC_DIGITAL_VOLUME, WM8400_DACL_VOL_SHIFT,
268 127, 0, out_dac_tlv),
269
270WM8400_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
271 WM8400_RIGHT_DAC_DIGITAL_VOLUME, WM8400_DACR_VOL_SHIFT,
272 127, 0, out_dac_tlv),
273
274SOC_ENUM("Left Digital Sidetone", wm8400_left_digital_sidetone_enum),
275SOC_ENUM("Right Digital Sidetone", wm8400_right_digital_sidetone_enum),
276
277SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE,
278 WM8400_ADCL_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv),
279SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE,
280 WM8400_ADCR_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv),
281
282SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8400_ADC_CTRL,
283 WM8400_ADC_HPF_ENA_SHIFT, 1, 0),
284
285SOC_ENUM("ADC HPF Mode", wm8400_right_adcmode_enum),
286
287WM8400_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
288 WM8400_LEFT_ADC_DIGITAL_VOLUME,
289 WM8400_ADCL_VOL_SHIFT,
290 WM8400_ADCL_VOL_MASK,
291 0,
292 in_adc_tlv),
293
294WM8400_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
295 WM8400_RIGHT_ADC_DIGITAL_VOLUME,
296 WM8400_ADCR_VOL_SHIFT,
297 WM8400_ADCR_VOL_MASK,
298 0,
299 in_adc_tlv),
300
301WM8400_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
302 WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
303 WM8400_LIN12VOL_SHIFT,
304 WM8400_LIN12VOL_MASK,
305 0,
306 in_pga_tlv),
307
308SOC_SINGLE("LIN12 ZC Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
309 WM8400_LI12ZC_SHIFT, 1, 0),
310
311SOC_SINGLE("LIN12 Mute Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
312 WM8400_LI12MUTE_SHIFT, 1, 0),
313
314WM8400_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
315 WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
316 WM8400_LIN34VOL_SHIFT,
317 WM8400_LIN34VOL_MASK,
318 0,
319 in_pga_tlv),
320
321SOC_SINGLE("LIN34 ZC Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
322 WM8400_LI34ZC_SHIFT, 1, 0),
323
324SOC_SINGLE("LIN34 Mute Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
325 WM8400_LI34MUTE_SHIFT, 1, 0),
326
327WM8400_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
328 WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
329 WM8400_RIN12VOL_SHIFT,
330 WM8400_RIN12VOL_MASK,
331 0,
332 in_pga_tlv),
333
334SOC_SINGLE("RIN12 ZC Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
335 WM8400_RI12ZC_SHIFT, 1, 0),
336
337SOC_SINGLE("RIN12 Mute Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
338 WM8400_RI12MUTE_SHIFT, 1, 0),
339
340WM8400_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
341 WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
342 WM8400_RIN34VOL_SHIFT,
343 WM8400_RIN34VOL_MASK,
344 0,
345 in_pga_tlv),
346
347SOC_SINGLE("RIN34 ZC Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
348 WM8400_RI34ZC_SHIFT, 1, 0),
349
350SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
351 WM8400_RI34MUTE_SHIFT, 1, 0),
352
353};
354
355/* add non dapm controls */
356static int wm8400_add_controls(struct snd_soc_codec *codec)
357{
358 return snd_soc_add_controls(codec, wm8400_snd_controls,
359 ARRAY_SIZE(wm8400_snd_controls));
360}
361
362/*
363 * _DAPM_ Controls
364 */
365
366static int inmixer_event (struct snd_soc_dapm_widget *w,
367 struct snd_kcontrol *kcontrol, int event)
368{
369 u16 reg, fakepower;
370
371 reg = wm8400_read(w->codec, WM8400_POWER_MANAGEMENT_2);
372 fakepower = wm8400_read(w->codec, WM8400_INTDRIVBITS);
373
374 if (fakepower & ((1 << WM8400_INMIXL_PWR) |
375 (1 << WM8400_AINLMUX_PWR))) {
376 reg |= WM8400_AINL_ENA;
377 } else {
378 reg &= ~WM8400_AINL_ENA;
379 }
380
381 if (fakepower & ((1 << WM8400_INMIXR_PWR) |
382 (1 << WM8400_AINRMUX_PWR))) {
383 reg |= WM8400_AINR_ENA;
384 } else {
385 reg &= ~WM8400_AINL_ENA;
386 }
387 wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg);
388
389 return 0;
390}
391
392static int outmixer_event (struct snd_soc_dapm_widget *w,
393 struct snd_kcontrol * kcontrol, int event)
394{
395 struct soc_mixer_control *mc =
396 (struct soc_mixer_control *)kcontrol->private_value;
397 u32 reg_shift = mc->shift;
398 int ret = 0;
399 u16 reg;
400
401 switch (reg_shift) {
402 case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
403 reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER1);
404 if (reg & WM8400_LDLO) {
405 printk(KERN_WARNING
406 "Cannot set as Output Mixer 1 LDLO Set\n");
407 ret = -1;
408 }
409 break;
410 case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
411 reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER2);
412 if (reg & WM8400_RDRO) {
413 printk(KERN_WARNING
414 "Cannot set as Output Mixer 2 RDRO Set\n");
415 ret = -1;
416 }
417 break;
418 case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
419 reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER);
420 if (reg & WM8400_LDSPK) {
421 printk(KERN_WARNING
422 "Cannot set as Speaker Mixer LDSPK Set\n");
423 ret = -1;
424 }
425 break;
426 case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
427 reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER);
428 if (reg & WM8400_RDSPK) {
429 printk(KERN_WARNING
430 "Cannot set as Speaker Mixer RDSPK Set\n");
431 ret = -1;
432 }
433 break;
434 }
435
436 return ret;
437}
438
439/* INMIX dB values */
440static const unsigned int in_mix_tlv[] = {
441 TLV_DB_RANGE_HEAD(1),
442 0,7, TLV_DB_LINEAR_ITEM(-1200, 600),
443};
444
445/* Left In PGA Connections */
446static const struct snd_kcontrol_new wm8400_dapm_lin12_pga_controls[] = {
447SOC_DAPM_SINGLE("LIN1 Switch", WM8400_INPUT_MIXER2, WM8400_LMN1_SHIFT, 1, 0),
448SOC_DAPM_SINGLE("LIN2 Switch", WM8400_INPUT_MIXER2, WM8400_LMP2_SHIFT, 1, 0),
449};
450
451static const struct snd_kcontrol_new wm8400_dapm_lin34_pga_controls[] = {
452SOC_DAPM_SINGLE("LIN3 Switch", WM8400_INPUT_MIXER2, WM8400_LMN3_SHIFT, 1, 0),
453SOC_DAPM_SINGLE("LIN4 Switch", WM8400_INPUT_MIXER2, WM8400_LMP4_SHIFT, 1, 0),
454};
455
456/* Right In PGA Connections */
457static const struct snd_kcontrol_new wm8400_dapm_rin12_pga_controls[] = {
458SOC_DAPM_SINGLE("RIN1 Switch", WM8400_INPUT_MIXER2, WM8400_RMN1_SHIFT, 1, 0),
459SOC_DAPM_SINGLE("RIN2 Switch", WM8400_INPUT_MIXER2, WM8400_RMP2_SHIFT, 1, 0),
460};
461
462static const struct snd_kcontrol_new wm8400_dapm_rin34_pga_controls[] = {
463SOC_DAPM_SINGLE("RIN3 Switch", WM8400_INPUT_MIXER2, WM8400_RMN3_SHIFT, 1, 0),
464SOC_DAPM_SINGLE("RIN4 Switch", WM8400_INPUT_MIXER2, WM8400_RMP4_SHIFT, 1, 0),
465};
466
467/* INMIXL */
468static const struct snd_kcontrol_new wm8400_dapm_inmixl_controls[] = {
469SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8400_INPUT_MIXER3,
470 WM8400_LDBVOL_SHIFT, WM8400_LDBVOL_MASK, 0, in_mix_tlv),
471SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8400_INPUT_MIXER5, WM8400_LI2BVOL_SHIFT,
472 7, 0, in_mix_tlv),
473SOC_DAPM_SINGLE("LINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT,
474 1, 0),
475SOC_DAPM_SINGLE("LINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
476 1, 0),
477};
478
479/* INMIXR */
480static const struct snd_kcontrol_new wm8400_dapm_inmixr_controls[] = {
481SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8400_INPUT_MIXER4,
482 WM8400_RDBVOL_SHIFT, WM8400_RDBVOL_MASK, 0, in_mix_tlv),
483SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8400_INPUT_MIXER6, WM8400_RI2BVOL_SHIFT,
484 7, 0, in_mix_tlv),
485SOC_DAPM_SINGLE("RINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT,
486 1, 0),
487SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
488 1, 0),
489};
490
491/* AINLMUX */
492static const char *wm8400_ainlmux[] =
493 {"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
494
495static const struct soc_enum wm8400_ainlmux_enum =
496SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINLMODE_SHIFT,
497 ARRAY_SIZE(wm8400_ainlmux), wm8400_ainlmux);
498
499static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls =
500SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
501
502/* DIFFINL */
503
504/* AINRMUX */
505static const char *wm8400_ainrmux[] =
506 {"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
507
508static const struct soc_enum wm8400_ainrmux_enum =
509SOC_ENUM_SINGLE( WM8400_INPUT_MIXER1, WM8400_AINRMODE_SHIFT,
510 ARRAY_SIZE(wm8400_ainrmux), wm8400_ainrmux);
511
512static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls =
513SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum);
514
515/* RXVOICE */
516static const struct snd_kcontrol_new wm8400_dapm_rxvoice_controls[] = {
517SOC_DAPM_SINGLE_TLV("LIN4/RXN", WM8400_INPUT_MIXER5, WM8400_LR4BVOL_SHIFT,
518 WM8400_LR4BVOL_MASK, 0, in_mix_tlv),
519SOC_DAPM_SINGLE_TLV("RIN4/RXP", WM8400_INPUT_MIXER6, WM8400_RL4BVOL_SHIFT,
520 WM8400_RL4BVOL_MASK, 0, in_mix_tlv),
521};
522
523/* LOMIX */
524static const struct snd_kcontrol_new wm8400_dapm_lomix_controls[] = {
525SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER1,
526 WM8400_LRBLO_SHIFT, 1, 0),
527SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER1,
528 WM8400_LLBLO_SHIFT, 1, 0),
529SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER1,
530 WM8400_LRI3LO_SHIFT, 1, 0),
531SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER1,
532 WM8400_LLI3LO_SHIFT, 1, 0),
533SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1,
534 WM8400_LR12LO_SHIFT, 1, 0),
535SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1,
536 WM8400_LL12LO_SHIFT, 1, 0),
537SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8400_OUTPUT_MIXER1,
538 WM8400_LDLO_SHIFT, 1, 0),
539};
540
541/* ROMIX */
542static const struct snd_kcontrol_new wm8400_dapm_romix_controls[] = {
543SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER2,
544 WM8400_RLBRO_SHIFT, 1, 0),
545SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER2,
546 WM8400_RRBRO_SHIFT, 1, 0),
547SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER2,
548 WM8400_RLI3RO_SHIFT, 1, 0),
549SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER2,
550 WM8400_RRI3RO_SHIFT, 1, 0),
551SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2,
552 WM8400_RL12RO_SHIFT, 1, 0),
553SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2,
554 WM8400_RR12RO_SHIFT, 1, 0),
555SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8400_OUTPUT_MIXER2,
556 WM8400_RDRO_SHIFT, 1, 0),
557};
558
559/* LONMIX */
560static const struct snd_kcontrol_new wm8400_dapm_lonmix_controls[] = {
561SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1,
562 WM8400_LLOPGALON_SHIFT, 1, 0),
563SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER1,
564 WM8400_LROPGALON_SHIFT, 1, 0),
565SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8400_LINE_MIXER1,
566 WM8400_LOPLON_SHIFT, 1, 0),
567};
568
569/* LOPMIX */
570static const struct snd_kcontrol_new wm8400_dapm_lopmix_controls[] = {
571SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER1,
572 WM8400_LR12LOP_SHIFT, 1, 0),
573SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER1,
574 WM8400_LL12LOP_SHIFT, 1, 0),
575SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1,
576 WM8400_LLOPGALOP_SHIFT, 1, 0),
577};
578
579/* RONMIX */
580static const struct snd_kcontrol_new wm8400_dapm_ronmix_controls[] = {
581SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2,
582 WM8400_RROPGARON_SHIFT, 1, 0),
583SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER2,
584 WM8400_RLOPGARON_SHIFT, 1, 0),
585SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8400_LINE_MIXER2,
586 WM8400_ROPRON_SHIFT, 1, 0),
587};
588
589/* ROPMIX */
590static const struct snd_kcontrol_new wm8400_dapm_ropmix_controls[] = {
591SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER2,
592 WM8400_RL12ROP_SHIFT, 1, 0),
593SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER2,
594 WM8400_RR12ROP_SHIFT, 1, 0),
595SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2,
596 WM8400_RROPGAROP_SHIFT, 1, 0),
597};
598
599/* OUT3MIX */
600static const struct snd_kcontrol_new wm8400_dapm_out3mix_controls[] = {
601SOC_DAPM_SINGLE("OUT3MIX LIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER,
602 WM8400_LI4O3_SHIFT, 1, 0),
603SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8400_OUT3_4_MIXER,
604 WM8400_LPGAO3_SHIFT, 1, 0),
605};
606
607/* OUT4MIX */
608static const struct snd_kcontrol_new wm8400_dapm_out4mix_controls[] = {
609SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8400_OUT3_4_MIXER,
610 WM8400_RPGAO4_SHIFT, 1, 0),
611SOC_DAPM_SINGLE("OUT4MIX RIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER,
612 WM8400_RI4O4_SHIFT, 1, 0),
613};
614
615/* SPKMIX */
616static const struct snd_kcontrol_new wm8400_dapm_spkmix_controls[] = {
617SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8400_SPEAKER_MIXER,
618 WM8400_LI2SPK_SHIFT, 1, 0),
619SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8400_SPEAKER_MIXER,
620 WM8400_LB2SPK_SHIFT, 1, 0),
621SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8400_SPEAKER_MIXER,
622 WM8400_LOPGASPK_SHIFT, 1, 0),
623SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8400_SPEAKER_MIXER,
624 WM8400_LDSPK_SHIFT, 1, 0),
625SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8400_SPEAKER_MIXER,
626 WM8400_RDSPK_SHIFT, 1, 0),
627SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8400_SPEAKER_MIXER,
628 WM8400_ROPGASPK_SHIFT, 1, 0),
629SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8400_SPEAKER_MIXER,
630 WM8400_RL12ROP_SHIFT, 1, 0),
631SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8400_SPEAKER_MIXER,
632 WM8400_RI2SPK_SHIFT, 1, 0),
633};
634
635static const struct snd_soc_dapm_widget wm8400_dapm_widgets[] = {
636/* Input Side */
637/* Input Lines */
638SND_SOC_DAPM_INPUT("LIN1"),
639SND_SOC_DAPM_INPUT("LIN2"),
640SND_SOC_DAPM_INPUT("LIN3"),
641SND_SOC_DAPM_INPUT("LIN4/RXN"),
642SND_SOC_DAPM_INPUT("RIN3"),
643SND_SOC_DAPM_INPUT("RIN4/RXP"),
644SND_SOC_DAPM_INPUT("RIN1"),
645SND_SOC_DAPM_INPUT("RIN2"),
646SND_SOC_DAPM_INPUT("Internal ADC Source"),
647
648/* DACs */
649SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8400_POWER_MANAGEMENT_2,
650 WM8400_ADCL_ENA_SHIFT, 0),
651SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8400_POWER_MANAGEMENT_2,
652 WM8400_ADCR_ENA_SHIFT, 0),
653
654/* Input PGAs */
655SND_SOC_DAPM_MIXER("LIN12 PGA", WM8400_POWER_MANAGEMENT_2,
656 WM8400_LIN12_ENA_SHIFT,
657 0, &wm8400_dapm_lin12_pga_controls[0],
658 ARRAY_SIZE(wm8400_dapm_lin12_pga_controls)),
659SND_SOC_DAPM_MIXER("LIN34 PGA", WM8400_POWER_MANAGEMENT_2,
660 WM8400_LIN34_ENA_SHIFT,
661 0, &wm8400_dapm_lin34_pga_controls[0],
662 ARRAY_SIZE(wm8400_dapm_lin34_pga_controls)),
663SND_SOC_DAPM_MIXER("RIN12 PGA", WM8400_POWER_MANAGEMENT_2,
664 WM8400_RIN12_ENA_SHIFT,
665 0, &wm8400_dapm_rin12_pga_controls[0],
666 ARRAY_SIZE(wm8400_dapm_rin12_pga_controls)),
667SND_SOC_DAPM_MIXER("RIN34 PGA", WM8400_POWER_MANAGEMENT_2,
668 WM8400_RIN34_ENA_SHIFT,
669 0, &wm8400_dapm_rin34_pga_controls[0],
670 ARRAY_SIZE(wm8400_dapm_rin34_pga_controls)),
671
672/* INMIXL */
673SND_SOC_DAPM_MIXER_E("INMIXL", WM8400_INTDRIVBITS, WM8400_INMIXL_PWR, 0,
674 &wm8400_dapm_inmixl_controls[0],
675 ARRAY_SIZE(wm8400_dapm_inmixl_controls),
676 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
677
678/* AINLMUX */
679SND_SOC_DAPM_MUX_E("AILNMUX", WM8400_INTDRIVBITS, WM8400_AINLMUX_PWR, 0,
680 &wm8400_dapm_ainlmux_controls, inmixer_event,
681 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
682
683/* INMIXR */
684SND_SOC_DAPM_MIXER_E("INMIXR", WM8400_INTDRIVBITS, WM8400_INMIXR_PWR, 0,
685 &wm8400_dapm_inmixr_controls[0],
686 ARRAY_SIZE(wm8400_dapm_inmixr_controls),
687 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
688
689/* AINRMUX */
690SND_SOC_DAPM_MUX_E("AIRNMUX", WM8400_INTDRIVBITS, WM8400_AINRMUX_PWR, 0,
691 &wm8400_dapm_ainrmux_controls, inmixer_event,
692 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
693
694/* Output Side */
695/* DACs */
696SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8400_POWER_MANAGEMENT_3,
697 WM8400_DACL_ENA_SHIFT, 0),
698SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8400_POWER_MANAGEMENT_3,
699 WM8400_DACR_ENA_SHIFT, 0),
700
701/* LOMIX */
702SND_SOC_DAPM_MIXER_E("LOMIX", WM8400_POWER_MANAGEMENT_3,
703 WM8400_LOMIX_ENA_SHIFT,
704 0, &wm8400_dapm_lomix_controls[0],
705 ARRAY_SIZE(wm8400_dapm_lomix_controls),
706 outmixer_event, SND_SOC_DAPM_PRE_REG),
707
708/* LONMIX */
709SND_SOC_DAPM_MIXER("LONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LON_ENA_SHIFT,
710 0, &wm8400_dapm_lonmix_controls[0],
711 ARRAY_SIZE(wm8400_dapm_lonmix_controls)),
712
713/* LOPMIX */
714SND_SOC_DAPM_MIXER("LOPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LOP_ENA_SHIFT,
715 0, &wm8400_dapm_lopmix_controls[0],
716 ARRAY_SIZE(wm8400_dapm_lopmix_controls)),
717
718/* OUT3MIX */
719SND_SOC_DAPM_MIXER("OUT3MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT3_ENA_SHIFT,
720 0, &wm8400_dapm_out3mix_controls[0],
721 ARRAY_SIZE(wm8400_dapm_out3mix_controls)),
722
723/* SPKMIX */
724SND_SOC_DAPM_MIXER_E("SPKMIX", WM8400_POWER_MANAGEMENT_1, WM8400_SPK_ENA_SHIFT,
725 0, &wm8400_dapm_spkmix_controls[0],
726 ARRAY_SIZE(wm8400_dapm_spkmix_controls), outmixer_event,
727 SND_SOC_DAPM_PRE_REG),
728
729/* OUT4MIX */
730SND_SOC_DAPM_MIXER("OUT4MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT4_ENA_SHIFT,
731 0, &wm8400_dapm_out4mix_controls[0],
732 ARRAY_SIZE(wm8400_dapm_out4mix_controls)),
733
734/* ROPMIX */
735SND_SOC_DAPM_MIXER("ROPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_ROP_ENA_SHIFT,
736 0, &wm8400_dapm_ropmix_controls[0],
737 ARRAY_SIZE(wm8400_dapm_ropmix_controls)),
738
739/* RONMIX */
740SND_SOC_DAPM_MIXER("RONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_RON_ENA_SHIFT,
741 0, &wm8400_dapm_ronmix_controls[0],
742 ARRAY_SIZE(wm8400_dapm_ronmix_controls)),
743
744/* ROMIX */
745SND_SOC_DAPM_MIXER_E("ROMIX", WM8400_POWER_MANAGEMENT_3,
746 WM8400_ROMIX_ENA_SHIFT,
747 0, &wm8400_dapm_romix_controls[0],
748 ARRAY_SIZE(wm8400_dapm_romix_controls),
749 outmixer_event, SND_SOC_DAPM_PRE_REG),
750
751/* LOUT PGA */
752SND_SOC_DAPM_PGA("LOUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_LOUT_ENA_SHIFT,
753 0, NULL, 0),
754
755/* ROUT PGA */
756SND_SOC_DAPM_PGA("ROUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_ROUT_ENA_SHIFT,
757 0, NULL, 0),
758
759/* LOPGA */
760SND_SOC_DAPM_PGA("LOPGA", WM8400_POWER_MANAGEMENT_3, WM8400_LOPGA_ENA_SHIFT, 0,
761 NULL, 0),
762
763/* ROPGA */
764SND_SOC_DAPM_PGA("ROPGA", WM8400_POWER_MANAGEMENT_3, WM8400_ROPGA_ENA_SHIFT, 0,
765 NULL, 0),
766
767/* MICBIAS */
768SND_SOC_DAPM_MICBIAS("MICBIAS", WM8400_POWER_MANAGEMENT_1,
769 WM8400_MIC1BIAS_ENA_SHIFT, 0),
770
771SND_SOC_DAPM_OUTPUT("LON"),
772SND_SOC_DAPM_OUTPUT("LOP"),
773SND_SOC_DAPM_OUTPUT("OUT3"),
774SND_SOC_DAPM_OUTPUT("LOUT"),
775SND_SOC_DAPM_OUTPUT("SPKN"),
776SND_SOC_DAPM_OUTPUT("SPKP"),
777SND_SOC_DAPM_OUTPUT("ROUT"),
778SND_SOC_DAPM_OUTPUT("OUT4"),
779SND_SOC_DAPM_OUTPUT("ROP"),
780SND_SOC_DAPM_OUTPUT("RON"),
781
782SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
783};
784
785static const struct snd_soc_dapm_route audio_map[] = {
786 /* Make DACs turn on when playing even if not mixed into any outputs */
787 {"Internal DAC Sink", NULL, "Left DAC"},
788 {"Internal DAC Sink", NULL, "Right DAC"},
789
790 /* Make ADCs turn on when recording
791 * even if not mixed from any inputs */
792 {"Left ADC", NULL, "Internal ADC Source"},
793 {"Right ADC", NULL, "Internal ADC Source"},
794
795 /* Input Side */
796 /* LIN12 PGA */
797 {"LIN12 PGA", "LIN1 Switch", "LIN1"},
798 {"LIN12 PGA", "LIN2 Switch", "LIN2"},
799 /* LIN34 PGA */
800 {"LIN34 PGA", "LIN3 Switch", "LIN3"},
801 {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"},
802 /* INMIXL */
803 {"INMIXL", "Record Left Volume", "LOMIX"},
804 {"INMIXL", "LIN2 Volume", "LIN2"},
805 {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
806 {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
807 /* AILNMUX */
808 {"AILNMUX", "INMIXL Mix", "INMIXL"},
809 {"AILNMUX", "DIFFINL Mix", "LIN12 PGA"},
810 {"AILNMUX", "DIFFINL Mix", "LIN34 PGA"},
811 {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"},
812 {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"},
813 /* ADC */
814 {"Left ADC", NULL, "AILNMUX"},
815
816 /* RIN12 PGA */
817 {"RIN12 PGA", "RIN1 Switch", "RIN1"},
818 {"RIN12 PGA", "RIN2 Switch", "RIN2"},
819 /* RIN34 PGA */
820 {"RIN34 PGA", "RIN3 Switch", "RIN3"},
821 {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"},
822 /* INMIXL */
823 {"INMIXR", "Record Right Volume", "ROMIX"},
824 {"INMIXR", "RIN2 Volume", "RIN2"},
825 {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
826 {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
827 /* AIRNMUX */
828 {"AIRNMUX", "INMIXR Mix", "INMIXR"},
829 {"AIRNMUX", "DIFFINR Mix", "RIN12 PGA"},
830 {"AIRNMUX", "DIFFINR Mix", "RIN34 PGA"},
831 {"AIRNMUX", "RXVOICE Mix", "LIN4/RXN"},
832 {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"},
833 /* ADC */
834 {"Right ADC", NULL, "AIRNMUX"},
835
836 /* LOMIX */
837 {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
838 {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
839 {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
840 {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
841 {"LOMIX", "LOMIX Right ADC Bypass Switch", "AIRNMUX"},
842 {"LOMIX", "LOMIX Left ADC Bypass Switch", "AILNMUX"},
843 {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
844
845 /* ROMIX */
846 {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
847 {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
848 {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
849 {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
850 {"ROMIX", "ROMIX Right ADC Bypass Switch", "AIRNMUX"},
851 {"ROMIX", "ROMIX Left ADC Bypass Switch", "AILNMUX"},
852 {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
853
854 /* SPKMIX */
855 {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
856 {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
857 {"SPKMIX", "SPKMIX LADC Bypass Switch", "AILNMUX"},
858 {"SPKMIX", "SPKMIX RADC Bypass Switch", "AIRNMUX"},
859 {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
860 {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
861 {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
862 {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
863
864 /* LONMIX */
865 {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
866 {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
867 {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
868
869 /* LOPMIX */
870 {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
871 {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
872 {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
873
874 /* OUT3MIX */
875 {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"},
876 {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
877
878 /* OUT4MIX */
879 {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
880 {"OUT4MIX", "OUT4MIX RIN4/RXP Bypass Switch", "RIN4/RXP"},
881
882 /* RONMIX */
883 {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
884 {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
885 {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
886
887 /* ROPMIX */
888 {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
889 {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
890 {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
891
892 /* Out Mixer PGAs */
893 {"LOPGA", NULL, "LOMIX"},
894 {"ROPGA", NULL, "ROMIX"},
895
896 {"LOUT PGA", NULL, "LOMIX"},
897 {"ROUT PGA", NULL, "ROMIX"},
898
899 /* Output Pins */
900 {"LON", NULL, "LONMIX"},
901 {"LOP", NULL, "LOPMIX"},
902 {"OUT3", NULL, "OUT3MIX"},
903 {"LOUT", NULL, "LOUT PGA"},
904 {"SPKN", NULL, "SPKMIX"},
905 {"ROUT", NULL, "ROUT PGA"},
906 {"OUT4", NULL, "OUT4MIX"},
907 {"ROP", NULL, "ROPMIX"},
908 {"RON", NULL, "RONMIX"},
909};
910
911static int wm8400_add_widgets(struct snd_soc_codec *codec)
912{
913 snd_soc_dapm_new_controls(codec, wm8400_dapm_widgets,
914 ARRAY_SIZE(wm8400_dapm_widgets));
915
916 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
917
918 snd_soc_dapm_new_widgets(codec);
919 return 0;
920}
921
922/*
923 * Clock after FLL and dividers
924 */
925static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai,
926 int clk_id, unsigned int freq, int dir)
927{
928 struct snd_soc_codec *codec = codec_dai->codec;
929 struct wm8400_priv *wm8400 = codec->private_data;
930
931 wm8400->sysclk = freq;
932 return 0;
933}
934
935struct fll_factors {
936 u16 n;
937 u16 k;
938 u16 outdiv;
939 u16 fratio;
940 u16 freq_ref;
941};
942
943#define FIXED_FLL_SIZE ((1 << 16) * 10)
944
945static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
946 unsigned int Fref, unsigned int Fout)
947{
948 u64 Kpart;
949 unsigned int K, Nmod, target;
950
951 factors->outdiv = 2;
952 while (Fout * factors->outdiv < 90000000 ||
953 Fout * factors->outdiv > 100000000) {
954 factors->outdiv *= 2;
955 if (factors->outdiv > 32) {
956 dev_err(wm8400->wm8400->dev,
957 "Unsupported FLL output frequency %dHz\n",
958 Fout);
959 return -EINVAL;
960 }
961 }
962 target = Fout * factors->outdiv;
963 factors->outdiv = factors->outdiv >> 2;
964
965 if (Fref < 48000)
966 factors->freq_ref = 1;
967 else
968 factors->freq_ref = 0;
969
970 if (Fref < 1000000)
971 factors->fratio = 9;
972 else
973 factors->fratio = 0;
974
975 /* Ensure we have a fractional part */
976 do {
977 if (Fref < 1000000)
978 factors->fratio--;
979 else
980 factors->fratio++;
981
982 if (factors->fratio < 1 || factors->fratio > 8) {
983 dev_err(wm8400->wm8400->dev,
984 "Unable to calculate FRATIO\n");
985 return -EINVAL;
986 }
987
988 factors->n = target / (Fref * factors->fratio);
989 Nmod = target % (Fref * factors->fratio);
990 } while (Nmod == 0);
991
992 /* Calculate fractional part - scale up so we can round. */
993 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
994
995 do_div(Kpart, (Fref * factors->fratio));
996
997 K = Kpart & 0xFFFFFFFF;
998
999 if ((K % 10) >= 5)
1000 K += 5;
1001
1002 /* Move down to proper range now rounding is done */
1003 factors->k = K / 10;
1004
1005 dev_dbg(wm8400->wm8400->dev,
1006 "FLL: Fref=%d Fout=%d N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
1007 Fref, Fout,
1008 factors->n, factors->k, factors->fratio, factors->outdiv);
1009
1010 return 0;
1011}
1012
1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1014 unsigned int freq_in, unsigned int freq_out)
1015{
1016 struct snd_soc_codec *codec = codec_dai->codec;
1017 struct wm8400_priv *wm8400 = codec->private_data;
1018 struct fll_factors factors;
1019 int ret;
1020 u16 reg;
1021
1022 if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out)
1023 return 0;
1024
1025 if (freq_out != 0) {
1026 ret = fll_factors(wm8400, &factors, freq_in, freq_out);
1027 if (ret != 0)
1028 return ret;
1029 }
1030
1031 wm8400->fll_out = freq_out;
1032 wm8400->fll_in = freq_in;
1033
1034 /* We *must* disable the FLL before any changes */
1035 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_2);
1036 reg &= ~WM8400_FLL_ENA;
1037 wm8400_write(codec, WM8400_POWER_MANAGEMENT_2, reg);
1038
1039 reg = wm8400_read(codec, WM8400_FLL_CONTROL_1);
1040 reg &= ~WM8400_FLL_OSC_ENA;
1041 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg);
1042
1043 if (freq_out == 0)
1044 return 0;
1045
1046 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
1047 reg |= WM8400_FLL_FRAC | factors.fratio;
1048 reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT;
1049 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg);
1050
1051 wm8400_write(codec, WM8400_FLL_CONTROL_2, factors.k);
1052 wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n);
1053
1054 reg = wm8400_read(codec, WM8400_FLL_CONTROL_4);
1055 reg &= WM8400_FLL_OUTDIV_MASK;
1056 reg |= factors.outdiv;
1057 wm8400_write(codec, WM8400_FLL_CONTROL_4, reg);
1058
1059 return 0;
1060}
1061
1062/*
1063 * Sets ADC and Voice DAC format.
1064 */
1065static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
1066 unsigned int fmt)
1067{
1068 struct snd_soc_codec *codec = codec_dai->codec;
1069 u16 audio1, audio3;
1070
1071 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
1072 audio3 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_3);
1073
1074 /* set master/slave audio interface */
1075 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1076 case SND_SOC_DAIFMT_CBS_CFS:
1077 audio3 &= ~WM8400_AIF_MSTR1;
1078 break;
1079 case SND_SOC_DAIFMT_CBM_CFM:
1080 audio3 |= WM8400_AIF_MSTR1;
1081 break;
1082 default:
1083 return -EINVAL;
1084 }
1085
1086 audio1 &= ~WM8400_AIF_FMT_MASK;
1087
1088 /* interface format */
1089 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1090 case SND_SOC_DAIFMT_I2S:
1091 audio1 |= WM8400_AIF_FMT_I2S;
1092 audio1 &= ~WM8400_AIF_LRCLK_INV;
1093 break;
1094 case SND_SOC_DAIFMT_RIGHT_J:
1095 audio1 |= WM8400_AIF_FMT_RIGHTJ;
1096 audio1 &= ~WM8400_AIF_LRCLK_INV;
1097 break;
1098 case SND_SOC_DAIFMT_LEFT_J:
1099 audio1 |= WM8400_AIF_FMT_LEFTJ;
1100 audio1 &= ~WM8400_AIF_LRCLK_INV;
1101 break;
1102 case SND_SOC_DAIFMT_DSP_A:
1103 audio1 |= WM8400_AIF_FMT_DSP;
1104 audio1 &= ~WM8400_AIF_LRCLK_INV;
1105 break;
1106 case SND_SOC_DAIFMT_DSP_B:
1107 audio1 |= WM8400_AIF_FMT_DSP | WM8400_AIF_LRCLK_INV;
1108 break;
1109 default:
1110 return -EINVAL;
1111 }
1112
1113 wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
1114 wm8400_write(codec, WM8400_AUDIO_INTERFACE_3, audio3);
1115 return 0;
1116}
1117
1118static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1119 int div_id, int div)
1120{
1121 struct snd_soc_codec *codec = codec_dai->codec;
1122 u16 reg;
1123
1124 switch (div_id) {
1125 case WM8400_MCLK_DIV:
1126 reg = wm8400_read(codec, WM8400_CLOCKING_2) &
1127 ~WM8400_MCLK_DIV_MASK;
1128 wm8400_write(codec, WM8400_CLOCKING_2, reg | div);
1129 break;
1130 case WM8400_DACCLK_DIV:
1131 reg = wm8400_read(codec, WM8400_CLOCKING_2) &
1132 ~WM8400_DAC_CLKDIV_MASK;
1133 wm8400_write(codec, WM8400_CLOCKING_2, reg | div);
1134 break;
1135 case WM8400_ADCCLK_DIV:
1136 reg = wm8400_read(codec, WM8400_CLOCKING_2) &
1137 ~WM8400_ADC_CLKDIV_MASK;
1138 wm8400_write(codec, WM8400_CLOCKING_2, reg | div);
1139 break;
1140 case WM8400_BCLK_DIV:
1141 reg = wm8400_read(codec, WM8400_CLOCKING_1) &
1142 ~WM8400_BCLK_DIV_MASK;
1143 wm8400_write(codec, WM8400_CLOCKING_1, reg | div);
1144 break;
1145 default:
1146 return -EINVAL;
1147 }
1148
1149 return 0;
1150}
1151
1152/*
1153 * Set PCM DAI bit size and sample rate.
1154 */
1155static int wm8400_hw_params(struct snd_pcm_substream *substream,
1156 struct snd_pcm_hw_params *params,
1157 struct snd_soc_dai *dai)
1158{
1159 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1160 struct snd_soc_device *socdev = rtd->socdev;
1161 struct snd_soc_codec *codec = socdev->card->codec;
1162 u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
1163
1164 audio1 &= ~WM8400_AIF_WL_MASK;
1165 /* bit size */
1166 switch (params_format(params)) {
1167 case SNDRV_PCM_FORMAT_S16_LE:
1168 break;
1169 case SNDRV_PCM_FORMAT_S20_3LE:
1170 audio1 |= WM8400_AIF_WL_20BITS;
1171 break;
1172 case SNDRV_PCM_FORMAT_S24_LE:
1173 audio1 |= WM8400_AIF_WL_24BITS;
1174 break;
1175 case SNDRV_PCM_FORMAT_S32_LE:
1176 audio1 |= WM8400_AIF_WL_32BITS;
1177 break;
1178 }
1179
1180 wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
1181 return 0;
1182}
1183
1184static int wm8400_mute(struct snd_soc_dai *dai, int mute)
1185{
1186 struct snd_soc_codec *codec = dai->codec;
1187 u16 val = wm8400_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
1188
1189 if (mute)
1190 wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
1191 else
1192 wm8400_write(codec, WM8400_DAC_CTRL, val);
1193
1194 return 0;
1195}
1196
1197/* TODO: set bias for best performance at standby */
1198static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1199 enum snd_soc_bias_level level)
1200{
1201 struct wm8400_priv *wm8400 = codec->private_data;
1202 u16 val;
1203 int ret;
1204
1205 switch (level) {
1206 case SND_SOC_BIAS_ON:
1207 break;
1208
1209 case SND_SOC_BIAS_PREPARE:
1210 /* VMID=2*50k */
1211 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) &
1212 ~WM8400_VMID_MODE_MASK;
1213 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2);
1214 break;
1215
1216 case SND_SOC_BIAS_STANDBY:
1217 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1218 ret = regulator_bulk_enable(ARRAY_SIZE(power),
1219 &power[0]);
1220 if (ret != 0) {
1221 dev_err(wm8400->wm8400->dev,
1222 "Failed to enable regulators: %d\n",
1223 ret);
1224 return ret;
1225 }
1226
1227 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1,
1228 WM8400_CODEC_ENA | WM8400_SYSCLK_ENA);
1229
1230 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1231 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1232 WM8400_BUFDCOPEN | WM8400_POBCTRL);
1233
1234 msleep(50);
1235
1236 /* Enable VREF & VMID at 2x50k */
1237 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
1238 val |= 0x2 | WM8400_VREF_ENA;
1239 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1240
1241 /* Enable BUFIOEN */
1242 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1243 WM8400_BUFDCOPEN | WM8400_POBCTRL |
1244 WM8400_BUFIOEN);
1245
1246 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1247 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN);
1248 }
1249
1250 /* VMID=2*300k */
1251 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) &
1252 ~WM8400_VMID_MODE_MASK;
1253 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4);
1254 break;
1255
1256 case SND_SOC_BIAS_OFF:
1257 /* Enable POBCTRL and SOFT_ST */
1258 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1259 WM8400_POBCTRL | WM8400_BUFIOEN);
1260
1261 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1262 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1263 WM8400_BUFDCOPEN | WM8400_POBCTRL |
1264 WM8400_BUFIOEN);
1265
1266 /* mute DAC */
1267 val = wm8400_read(codec, WM8400_DAC_CTRL);
1268 wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
1269
1270 /* Enable any disabled outputs */
1271 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
1272 val |= WM8400_SPK_ENA | WM8400_OUT3_ENA |
1273 WM8400_OUT4_ENA | WM8400_LOUT_ENA |
1274 WM8400_ROUT_ENA;
1275 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1276
1277 /* Disable VMID */
1278 val &= ~WM8400_VMID_MODE_MASK;
1279 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1280
1281 msleep(300);
1282
1283 /* Enable all output discharge bits */
1284 wm8400_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
1285 WM8400_DIS_RLINE | WM8400_DIS_OUT3 |
1286 WM8400_DIS_OUT4 | WM8400_DIS_LOUT |
1287 WM8400_DIS_ROUT);
1288
1289 /* Disable VREF */
1290 val &= ~WM8400_VREF_ENA;
1291 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1292
1293 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1294 wm8400_write(codec, WM8400_ANTIPOP2, 0x0);
1295
1296 ret = regulator_bulk_disable(ARRAY_SIZE(power),
1297 &power[0]);
1298 if (ret != 0)
1299 return ret;
1300
1301 break;
1302 }
1303
1304 codec->bias_level = level;
1305 return 0;
1306}
1307
1308#define WM8400_RATES SNDRV_PCM_RATE_8000_96000
1309
1310#define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1311 SNDRV_PCM_FMTBIT_S24_LE)
1312
1313static struct snd_soc_dai_ops wm8400_dai_ops = {
1314 .hw_params = wm8400_hw_params,
1315 .digital_mute = wm8400_mute,
1316 .set_fmt = wm8400_set_dai_fmt,
1317 .set_clkdiv = wm8400_set_dai_clkdiv,
1318 .set_sysclk = wm8400_set_dai_sysclk,
1319 .set_pll = wm8400_set_dai_pll,
1320};
1321
1322/*
1323 * The WM8400 supports 2 different and mutually exclusive DAI
1324 * configurations.
1325 *
1326 * 1. ADC/DAC on Primary Interface
1327 * 2. ADC on Primary Interface/DAC on secondary
1328 */
1329struct snd_soc_dai wm8400_dai = {
1330/* ADC/DAC on primary */
1331 .name = "WM8400 ADC/DAC Primary",
1332 .id = 1,
1333 .playback = {
1334 .stream_name = "Playback",
1335 .channels_min = 1,
1336 .channels_max = 2,
1337 .rates = WM8400_RATES,
1338 .formats = WM8400_FORMATS,
1339 },
1340 .capture = {
1341 .stream_name = "Capture",
1342 .channels_min = 1,
1343 .channels_max = 2,
1344 .rates = WM8400_RATES,
1345 .formats = WM8400_FORMATS,
1346 },
1347 .ops = &wm8400_dai_ops,
1348};
1349EXPORT_SYMBOL_GPL(wm8400_dai);
1350
1351static int wm8400_suspend(struct platform_device *pdev, pm_message_t state)
1352{
1353 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1354 struct snd_soc_codec *codec = socdev->card->codec;
1355
1356 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
1357
1358 return 0;
1359}
1360
1361static int wm8400_resume(struct platform_device *pdev)
1362{
1363 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1364 struct snd_soc_codec *codec = socdev->card->codec;
1365
1366 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1367
1368 return 0;
1369}
1370
1371static struct snd_soc_codec *wm8400_codec;
1372
1373static int wm8400_probe(struct platform_device *pdev)
1374{
1375 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1376 struct snd_soc_codec *codec;
1377 int ret;
1378
1379 if (!wm8400_codec) {
1380 dev_err(&pdev->dev, "wm8400 not yet discovered\n");
1381 return -ENODEV;
1382 }
1383 codec = wm8400_codec;
1384
1385 socdev->card->codec = codec;
1386
1387 /* register pcms */
1388 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1389 if (ret < 0) {
1390 dev_err(&pdev->dev, "failed to create pcms\n");
1391 goto pcm_err;
1392 }
1393
1394 wm8400_add_controls(codec);
1395 wm8400_add_widgets(codec);
1396
1397 ret = snd_soc_init_card(socdev);
1398 if (ret < 0) {
1399 dev_err(&pdev->dev, "failed to register card\n");
1400 goto card_err;
1401 }
1402
1403 return ret;
1404
1405card_err:
1406 snd_soc_free_pcms(socdev);
1407 snd_soc_dapm_free(socdev);
1408pcm_err:
1409 return ret;
1410}
1411
1412/* power down chip */
1413static int wm8400_remove(struct platform_device *pdev)
1414{
1415 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1416
1417 snd_soc_free_pcms(socdev);
1418 snd_soc_dapm_free(socdev);
1419
1420 return 0;
1421}
1422
1423struct snd_soc_codec_device soc_codec_dev_wm8400 = {
1424 .probe = wm8400_probe,
1425 .remove = wm8400_remove,
1426 .suspend = wm8400_suspend,
1427 .resume = wm8400_resume,
1428};
1429
1430static void wm8400_probe_deferred(struct work_struct *work)
1431{
1432 struct wm8400_priv *priv = container_of(work, struct wm8400_priv,
1433 work);
1434 struct snd_soc_codec *codec = &priv->codec;
1435 int ret;
1436
1437 /* charge output caps */
1438 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1439
1440 /* We're done, tell the subsystem. */
1441 ret = snd_soc_register_codec(codec);
1442 if (ret != 0) {
1443 dev_err(priv->wm8400->dev,
1444 "Failed to register codec: %d\n", ret);
1445 goto err;
1446 }
1447
1448 ret = snd_soc_register_dai(&wm8400_dai);
1449 if (ret != 0) {
1450 dev_err(priv->wm8400->dev,
1451 "Failed to register DAI: %d\n", ret);
1452 goto err_codec;
1453 }
1454
1455 return;
1456
1457err_codec:
1458 snd_soc_unregister_codec(codec);
1459err:
1460 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
1461}
1462
1463static int wm8400_codec_probe(struct platform_device *dev)
1464{
1465 struct wm8400_priv *priv;
1466 int ret;
1467 u16 reg;
1468 struct snd_soc_codec *codec;
1469
1470 priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL);
1471 if (priv == NULL)
1472 return -ENOMEM;
1473
1474 codec = &priv->codec;
1475 codec->private_data = priv;
1476 codec->control_data = dev->dev.driver_data;
1477 priv->wm8400 = dev->dev.driver_data;
1478
1479 ret = regulator_bulk_get(priv->wm8400->dev,
1480 ARRAY_SIZE(power), &power[0]);
1481 if (ret != 0) {
1482 dev_err(&dev->dev, "Failed to get regulators: %d\n", ret);
1483 goto err;
1484 }
1485
1486 codec->dev = &dev->dev;
1487 wm8400_dai.dev = &dev->dev;
1488
1489 codec->name = "WM8400";
1490 codec->owner = THIS_MODULE;
1491 codec->read = wm8400_read;
1492 codec->write = wm8400_write;
1493 codec->bias_level = SND_SOC_BIAS_OFF;
1494 codec->set_bias_level = wm8400_set_bias_level;
1495 codec->dai = &wm8400_dai;
1496 codec->num_dai = 1;
1497 codec->reg_cache_size = WM8400_REGISTER_COUNT;
1498 mutex_init(&codec->mutex);
1499 INIT_LIST_HEAD(&codec->dapm_widgets);
1500 INIT_LIST_HEAD(&codec->dapm_paths);
1501 INIT_WORK(&priv->work, wm8400_probe_deferred);
1502
1503 wm8400_codec_reset(codec);
1504
1505 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
1506 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
1507
1508 /* Latch volume update bits */
1509 reg = wm8400_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
1510 wm8400_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
1511 reg & WM8400_IPVU);
1512 reg = wm8400_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
1513 wm8400_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
1514 reg & WM8400_IPVU);
1515
1516 wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1517 wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1518
1519 wm8400_codec = codec;
1520
1521 if (!schedule_work(&priv->work)) {
1522 ret = -EINVAL;
1523 goto err_regulator;
1524 }
1525
1526 return 0;
1527
1528err_regulator:
1529 wm8400_codec = NULL;
1530 regulator_bulk_free(ARRAY_SIZE(power), power);
1531err:
1532 kfree(priv);
1533 return ret;
1534}
1535
1536static int __exit wm8400_codec_remove(struct platform_device *dev)
1537{
1538 struct wm8400_priv *priv = wm8400_codec->private_data;
1539 u16 reg;
1540
1541 snd_soc_unregister_dai(&wm8400_dai);
1542 snd_soc_unregister_codec(wm8400_codec);
1543
1544 reg = wm8400_read(wm8400_codec, WM8400_POWER_MANAGEMENT_1);
1545 wm8400_write(wm8400_codec, WM8400_POWER_MANAGEMENT_1,
1546 reg & (~WM8400_CODEC_ENA));
1547
1548 regulator_bulk_free(ARRAY_SIZE(power), power);
1549 kfree(priv);
1550
1551 wm8400_codec = NULL;
1552
1553 return 0;
1554}
1555
1556static struct platform_driver wm8400_codec_driver = {
1557 .driver = {
1558 .name = "wm8400-codec",
1559 .owner = THIS_MODULE,
1560 },
1561 .probe = wm8400_codec_probe,
1562 .remove = __exit_p(wm8400_codec_remove),
1563};
1564
1565static int __init wm8400_codec_init(void)
1566{
1567 return platform_driver_register(&wm8400_codec_driver);
1568}
1569module_init(wm8400_codec_init);
1570
1571static void __exit wm8400_codec_exit(void)
1572{
1573 platform_driver_unregister(&wm8400_codec_driver);
1574}
1575module_exit(wm8400_codec_exit);
1576
1577EXPORT_SYMBOL_GPL(soc_codec_dev_wm8400);
1578
1579MODULE_DESCRIPTION("ASoC WM8400 driver");
1580MODULE_AUTHOR("Mark Brown");
1581MODULE_LICENSE("GPL");
1582MODULE_ALIAS("platform:wm8400-codec");
diff --git a/sound/soc/codecs/wm8400.h b/sound/soc/codecs/wm8400.h
new file mode 100644
index 000000000000..79c5934d4776
--- /dev/null
+++ b/sound/soc/codecs/wm8400.h
@@ -0,0 +1,62 @@
1/*
2 * wm8400.h -- audio driver for WM8400
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef _WM8400_CODEC_H
15#define _WM8400_CODEC_H
16
17#define WM8400_MCLK_DIV 0
18#define WM8400_DACCLK_DIV 1
19#define WM8400_ADCCLK_DIV 2
20#define WM8400_BCLK_DIV 3
21
22#define WM8400_MCLK_DIV_1 0x400
23#define WM8400_MCLK_DIV_2 0x800
24
25#define WM8400_DAC_CLKDIV_1 0x00
26#define WM8400_DAC_CLKDIV_1_5 0x04
27#define WM8400_DAC_CLKDIV_2 0x08
28#define WM8400_DAC_CLKDIV_3 0x0c
29#define WM8400_DAC_CLKDIV_4 0x10
30#define WM8400_DAC_CLKDIV_5_5 0x14
31#define WM8400_DAC_CLKDIV_6 0x18
32
33#define WM8400_ADC_CLKDIV_1 0x00
34#define WM8400_ADC_CLKDIV_1_5 0x20
35#define WM8400_ADC_CLKDIV_2 0x40
36#define WM8400_ADC_CLKDIV_3 0x60
37#define WM8400_ADC_CLKDIV_4 0x80
38#define WM8400_ADC_CLKDIV_5_5 0xa0
39#define WM8400_ADC_CLKDIV_6 0xc0
40
41
42#define WM8400_BCLK_DIV_1 (0x0 << 1)
43#define WM8400_BCLK_DIV_1_5 (0x1 << 1)
44#define WM8400_BCLK_DIV_2 (0x2 << 1)
45#define WM8400_BCLK_DIV_3 (0x3 << 1)
46#define WM8400_BCLK_DIV_4 (0x4 << 1)
47#define WM8400_BCLK_DIV_5_5 (0x5 << 1)
48#define WM8400_BCLK_DIV_6 (0x6 << 1)
49#define WM8400_BCLK_DIV_8 (0x7 << 1)
50#define WM8400_BCLK_DIV_11 (0x8 << 1)
51#define WM8400_BCLK_DIV_12 (0x9 << 1)
52#define WM8400_BCLK_DIV_16 (0xA << 1)
53#define WM8400_BCLK_DIV_22 (0xB << 1)
54#define WM8400_BCLK_DIV_24 (0xC << 1)
55#define WM8400_BCLK_DIV_32 (0xD << 1)
56#define WM8400_BCLK_DIV_44 (0xE << 1)
57#define WM8400_BCLK_DIV_48 (0xF << 1)
58
59extern struct snd_soc_dai wm8400_dai;
60extern struct snd_soc_codec_device soc_codec_dev_wm8400;
61
62#endif
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 40f8238df717..6a4cea09c45d 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -171,22 +171,6 @@ SOC_SINGLE("Capture Boost(+20dB)", WM8510_ADCBOOST, 8, 1, 0),
171SOC_SINGLE("Mono Playback Switch", WM8510_MONOMIX, 6, 1, 1), 171SOC_SINGLE("Mono Playback Switch", WM8510_MONOMIX, 6, 1, 1),
172}; 172};
173 173
174/* add non dapm controls */
175static int wm8510_add_controls(struct snd_soc_codec *codec)
176{
177 int err, i;
178
179 for (i = 0; i < ARRAY_SIZE(wm8510_snd_controls); i++) {
180 err = snd_ctl_add(codec->card,
181 snd_soc_cnew(&wm8510_snd_controls[i], codec,
182 NULL));
183 if (err < 0)
184 return err;
185 }
186
187 return 0;
188}
189
190/* Speaker Output Mixer */ 174/* Speaker Output Mixer */
191static const struct snd_kcontrol_new wm8510_speaker_mixer_controls[] = { 175static const struct snd_kcontrol_new wm8510_speaker_mixer_controls[] = {
192SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_SPKMIX, 1, 1, 0), 176SOC_DAPM_SINGLE("Line Bypass Switch", WM8510_SPKMIX, 1, 1, 0),
@@ -352,7 +336,7 @@ static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai,
352 return 0; 336 return 0;
353 } 337 }
354 338
355 pll_factors(freq_out*8, freq_in); 339 pll_factors(freq_out*4, freq_in);
356 340
357 wm8510_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n); 341 wm8510_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
358 wm8510_write(codec, WM8510_PLLK1, pll_div.k >> 18); 342 wm8510_write(codec, WM8510_PLLK1, pll_div.k >> 18);
@@ -383,7 +367,7 @@ static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
383 wm8510_write(codec, WM8510_GPIO, reg | div); 367 wm8510_write(codec, WM8510_GPIO, reg | div);
384 break; 368 break;
385 case WM8510_MCLKDIV: 369 case WM8510_MCLKDIV:
386 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1f; 370 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x11f;
387 wm8510_write(codec, WM8510_CLOCK, reg | div); 371 wm8510_write(codec, WM8510_CLOCK, reg | div);
388 break; 372 break;
389 case WM8510_ADCCLK: 373 case WM8510_ADCCLK:
@@ -468,7 +452,7 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
468{ 452{
469 struct snd_soc_pcm_runtime *rtd = substream->private_data; 453 struct snd_soc_pcm_runtime *rtd = substream->private_data;
470 struct snd_soc_device *socdev = rtd->socdev; 454 struct snd_soc_device *socdev = rtd->socdev;
471 struct snd_soc_codec *codec = socdev->codec; 455 struct snd_soc_codec *codec = socdev->card->codec;
472 u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f; 456 u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f;
473 u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1; 457 u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1;
474 458
@@ -570,6 +554,14 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
570#define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 554#define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
571 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 555 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
572 556
557static struct snd_soc_dai_ops wm8510_dai_ops = {
558 .hw_params = wm8510_pcm_hw_params,
559 .digital_mute = wm8510_mute,
560 .set_fmt = wm8510_set_dai_fmt,
561 .set_clkdiv = wm8510_set_dai_clkdiv,
562 .set_pll = wm8510_set_dai_pll,
563};
564
573struct snd_soc_dai wm8510_dai = { 565struct snd_soc_dai wm8510_dai = {
574 .name = "WM8510 HiFi", 566 .name = "WM8510 HiFi",
575 .playback = { 567 .playback = {
@@ -584,20 +576,14 @@ struct snd_soc_dai wm8510_dai = {
584 .channels_max = 2, 576 .channels_max = 2,
585 .rates = WM8510_RATES, 577 .rates = WM8510_RATES,
586 .formats = WM8510_FORMATS,}, 578 .formats = WM8510_FORMATS,},
587 .ops = { 579 .ops = &wm8510_dai_ops,
588 .hw_params = wm8510_pcm_hw_params,
589 .digital_mute = wm8510_mute,
590 .set_fmt = wm8510_set_dai_fmt,
591 .set_clkdiv = wm8510_set_dai_clkdiv,
592 .set_pll = wm8510_set_dai_pll,
593 },
594}; 580};
595EXPORT_SYMBOL_GPL(wm8510_dai); 581EXPORT_SYMBOL_GPL(wm8510_dai);
596 582
597static int wm8510_suspend(struct platform_device *pdev, pm_message_t state) 583static int wm8510_suspend(struct platform_device *pdev, pm_message_t state)
598{ 584{
599 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 585 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
600 struct snd_soc_codec *codec = socdev->codec; 586 struct snd_soc_codec *codec = socdev->card->codec;
601 587
602 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); 588 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
603 return 0; 589 return 0;
@@ -606,7 +592,7 @@ static int wm8510_suspend(struct platform_device *pdev, pm_message_t state)
606static int wm8510_resume(struct platform_device *pdev) 592static int wm8510_resume(struct platform_device *pdev)
607{ 593{
608 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 594 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
609 struct snd_soc_codec *codec = socdev->codec; 595 struct snd_soc_codec *codec = socdev->card->codec;
610 int i; 596 int i;
611 u8 data[2]; 597 u8 data[2];
612 u16 *cache = codec->reg_cache; 598 u16 *cache = codec->reg_cache;
@@ -628,7 +614,7 @@ static int wm8510_resume(struct platform_device *pdev)
628 */ 614 */
629static int wm8510_init(struct snd_soc_device *socdev) 615static int wm8510_init(struct snd_soc_device *socdev)
630{ 616{
631 struct snd_soc_codec *codec = socdev->codec; 617 struct snd_soc_codec *codec = socdev->card->codec;
632 int ret = 0; 618 int ret = 0;
633 619
634 codec->name = "WM8510"; 620 codec->name = "WM8510";
@@ -656,7 +642,8 @@ static int wm8510_init(struct snd_soc_device *socdev)
656 /* power on device */ 642 /* power on device */
657 codec->bias_level = SND_SOC_BIAS_OFF; 643 codec->bias_level = SND_SOC_BIAS_OFF;
658 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 644 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
659 wm8510_add_controls(codec); 645 snd_soc_add_controls(codec, wm8510_snd_controls,
646 ARRAY_SIZE(wm8510_snd_controls));
660 wm8510_add_widgets(codec); 647 wm8510_add_widgets(codec);
661 ret = snd_soc_init_card(socdev); 648 ret = snd_soc_init_card(socdev);
662 if (ret < 0) { 649 if (ret < 0) {
@@ -685,7 +672,7 @@ static int wm8510_i2c_probe(struct i2c_client *i2c,
685 const struct i2c_device_id *id) 672 const struct i2c_device_id *id)
686{ 673{
687 struct snd_soc_device *socdev = wm8510_socdev; 674 struct snd_soc_device *socdev = wm8510_socdev;
688 struct snd_soc_codec *codec = socdev->codec; 675 struct snd_soc_codec *codec = socdev->card->codec;
689 int ret; 676 int ret;
690 677
691 i2c_set_clientdata(i2c, codec); 678 i2c_set_clientdata(i2c, codec);
@@ -766,7 +753,7 @@ err_driver:
766static int __devinit wm8510_spi_probe(struct spi_device *spi) 753static int __devinit wm8510_spi_probe(struct spi_device *spi)
767{ 754{
768 struct snd_soc_device *socdev = wm8510_socdev; 755 struct snd_soc_device *socdev = wm8510_socdev;
769 struct snd_soc_codec *codec = socdev->codec; 756 struct snd_soc_codec *codec = socdev->card->codec;
770 int ret; 757 int ret;
771 758
772 codec->control_data = spi; 759 codec->control_data = spi;
@@ -832,7 +819,7 @@ static int wm8510_probe(struct platform_device *pdev)
832 if (codec == NULL) 819 if (codec == NULL)
833 return -ENOMEM; 820 return -ENOMEM;
834 821
835 socdev->codec = codec; 822 socdev->card->codec = codec;
836 mutex_init(&codec->mutex); 823 mutex_init(&codec->mutex);
837 INIT_LIST_HEAD(&codec->dapm_widgets); 824 INIT_LIST_HEAD(&codec->dapm_widgets);
838 INIT_LIST_HEAD(&codec->dapm_paths); 825 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -862,7 +849,7 @@ static int wm8510_probe(struct platform_device *pdev)
862static int wm8510_remove(struct platform_device *pdev) 849static int wm8510_remove(struct platform_device *pdev)
863{ 850{
864 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 851 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
865 struct snd_soc_codec *codec = socdev->codec; 852 struct snd_soc_codec *codec = socdev->card->codec;
866 853
867 if (codec->control_data) 854 if (codec->control_data)
868 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); 855 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index d004e5845298..442ea6f160fc 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8580.c -- WM8580 ALSA Soc Audio driver 2 * wm8580.c -- WM8580 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2008 Wolfson Microelectronics PLC. 4 * Copyright 2008, 2009 Wolfson Microelectronics PLC.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
@@ -35,19 +35,6 @@
35 35
36#include "wm8580.h" 36#include "wm8580.h"
37 37
38#define WM8580_VERSION "0.1"
39
40struct pll_state {
41 unsigned int in;
42 unsigned int out;
43};
44
45/* codec private data */
46struct wm8580_priv {
47 struct pll_state a;
48 struct pll_state b;
49};
50
51/* WM8580 register space */ 38/* WM8580 register space */
52#define WM8580_PLLA1 0x00 39#define WM8580_PLLA1 0x00
53#define WM8580_PLLA2 0x01 40#define WM8580_PLLA2 0x01
@@ -102,6 +89,8 @@ struct wm8580_priv {
102#define WM8580_READBACK 0x34 89#define WM8580_READBACK 0x34
103#define WM8580_RESET 0x35 90#define WM8580_RESET 0x35
104 91
92#define WM8580_MAX_REGISTER 0x35
93
105/* PLLB4 (register 7h) */ 94/* PLLB4 (register 7h) */
106#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60 95#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
107#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20 96#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
@@ -193,6 +182,20 @@ static const u16 wm8580_reg[] = {
193 0x0000, 0x0000 /*R53*/ 182 0x0000, 0x0000 /*R53*/
194}; 183};
195 184
185struct pll_state {
186 unsigned int in;
187 unsigned int out;
188};
189
190/* codec private data */
191struct wm8580_priv {
192 struct snd_soc_codec codec;
193 u16 reg_cache[WM8580_MAX_REGISTER + 1];
194 struct pll_state a;
195 struct pll_state b;
196};
197
198
196/* 199/*
197 * read wm8580 register cache 200 * read wm8580 register cache
198 */ 201 */
@@ -200,7 +203,7 @@ static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
200 unsigned int reg) 203 unsigned int reg)
201{ 204{
202 u16 *cache = codec->reg_cache; 205 u16 *cache = codec->reg_cache;
203 BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); 206 BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
204 return cache[reg]; 207 return cache[reg];
205} 208}
206 209
@@ -223,7 +226,7 @@ static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
223{ 226{
224 u8 data[2]; 227 u8 data[2];
225 228
226 BUG_ON(reg > ARRAY_SIZE(wm8580_reg)); 229 BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
227 230
228 /* Registers are 9 bits wide */ 231 /* Registers are 9 bits wide */
229 value &= 0x1ff; 232 value &= 0x1ff;
@@ -330,20 +333,6 @@ SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
330SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), 333SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
331}; 334};
332 335
333/* Add non-DAPM controls */
334static int wm8580_add_controls(struct snd_soc_codec *codec)
335{
336 int err, i;
337
338 for (i = 0; i < ARRAY_SIZE(wm8580_snd_controls); i++) {
339 err = snd_ctl_add(codec->card,
340 snd_soc_cnew(&wm8580_snd_controls[i],
341 codec, NULL));
342 if (err < 0)
343 return err;
344 }
345 return 0;
346}
347static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { 336static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
348SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1), 337SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),
349SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1), 338SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),
@@ -553,7 +542,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
553{ 542{
554 struct snd_soc_pcm_runtime *rtd = substream->private_data; 543 struct snd_soc_pcm_runtime *rtd = substream->private_data;
555 struct snd_soc_device *socdev = rtd->socdev; 544 struct snd_soc_device *socdev = rtd->socdev;
556 struct snd_soc_codec *codec = socdev->codec; 545 struct snd_soc_codec *codec = socdev->card->codec;
557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id); 546 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id);
558 547
559 paifb &= ~WM8580_AIF_LENGTH_MASK; 548 paifb &= ~WM8580_AIF_LENGTH_MASK;
@@ -771,8 +760,22 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
771 switch (level) { 760 switch (level) {
772 case SND_SOC_BIAS_ON: 761 case SND_SOC_BIAS_ON:
773 case SND_SOC_BIAS_PREPARE: 762 case SND_SOC_BIAS_PREPARE:
763 break;
764
774 case SND_SOC_BIAS_STANDBY: 765 case SND_SOC_BIAS_STANDBY:
766 if (codec->bias_level == SND_SOC_BIAS_OFF) {
767 /* Power up and get individual control of the DACs */
768 reg = wm8580_read(codec, WM8580_PWRDN1);
769 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
770 wm8580_write(codec, WM8580_PWRDN1, reg);
771
772 /* Make VMID high impedence */
773 reg = wm8580_read(codec, WM8580_ADC_CONTROL1);
774 reg &= ~0x100;
775 wm8580_write(codec, WM8580_ADC_CONTROL1, reg);
776 }
775 break; 777 break;
778
776 case SND_SOC_BIAS_OFF: 779 case SND_SOC_BIAS_OFF:
777 reg = wm8580_read(codec, WM8580_PWRDN1); 780 reg = wm8580_read(codec, WM8580_PWRDN1);
778 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 781 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
@@ -785,6 +788,21 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
785#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 788#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
786 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 789 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
787 790
791static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
792 .hw_params = wm8580_paif_hw_params,
793 .set_fmt = wm8580_set_paif_dai_fmt,
794 .set_clkdiv = wm8580_set_dai_clkdiv,
795 .set_pll = wm8580_set_dai_pll,
796 .digital_mute = wm8580_digital_mute,
797};
798
799static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
800 .hw_params = wm8580_paif_hw_params,
801 .set_fmt = wm8580_set_paif_dai_fmt,
802 .set_clkdiv = wm8580_set_dai_clkdiv,
803 .set_pll = wm8580_set_dai_pll,
804};
805
788struct snd_soc_dai wm8580_dai[] = { 806struct snd_soc_dai wm8580_dai[] = {
789 { 807 {
790 .name = "WM8580 PAIFRX", 808 .name = "WM8580 PAIFRX",
@@ -796,13 +814,7 @@ struct snd_soc_dai wm8580_dai[] = {
796 .rates = SNDRV_PCM_RATE_8000_192000, 814 .rates = SNDRV_PCM_RATE_8000_192000,
797 .formats = WM8580_FORMATS, 815 .formats = WM8580_FORMATS,
798 }, 816 },
799 .ops = { 817 .ops = &wm8580_dai_ops_playback,
800 .hw_params = wm8580_paif_hw_params,
801 .set_fmt = wm8580_set_paif_dai_fmt,
802 .set_clkdiv = wm8580_set_dai_clkdiv,
803 .set_pll = wm8580_set_dai_pll,
804 .digital_mute = wm8580_digital_mute,
805 },
806 }, 818 },
807 { 819 {
808 .name = "WM8580 PAIFTX", 820 .name = "WM8580 PAIFTX",
@@ -814,109 +826,168 @@ struct snd_soc_dai wm8580_dai[] = {
814 .rates = SNDRV_PCM_RATE_8000_192000, 826 .rates = SNDRV_PCM_RATE_8000_192000,
815 .formats = WM8580_FORMATS, 827 .formats = WM8580_FORMATS,
816 }, 828 },
817 .ops = { 829 .ops = &wm8580_dai_ops_capture,
818 .hw_params = wm8580_paif_hw_params,
819 .set_fmt = wm8580_set_paif_dai_fmt,
820 .set_clkdiv = wm8580_set_dai_clkdiv,
821 .set_pll = wm8580_set_dai_pll,
822 },
823 }, 830 },
824}; 831};
825EXPORT_SYMBOL_GPL(wm8580_dai); 832EXPORT_SYMBOL_GPL(wm8580_dai);
826 833
827/* 834static struct snd_soc_codec *wm8580_codec;
828 * initialise the WM8580 driver 835
829 * register the mixer and dsp interfaces with the kernel 836static int wm8580_probe(struct platform_device *pdev)
830 */
831static int wm8580_init(struct snd_soc_device *socdev)
832{ 837{
833 struct snd_soc_codec *codec = socdev->codec; 838 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
839 struct snd_soc_codec *codec;
834 int ret = 0; 840 int ret = 0;
835 841
836 codec->name = "WM8580"; 842 if (wm8580_codec == NULL) {
837 codec->owner = THIS_MODULE; 843 dev_err(&pdev->dev, "Codec device not registered\n");
838 codec->read = wm8580_read_reg_cache; 844 return -ENODEV;
839 codec->write = wm8580_write; 845 }
840 codec->set_bias_level = wm8580_set_bias_level;
841 codec->dai = wm8580_dai;
842 codec->num_dai = ARRAY_SIZE(wm8580_dai);
843 codec->reg_cache_size = ARRAY_SIZE(wm8580_reg);
844 codec->reg_cache = kmemdup(wm8580_reg, sizeof(wm8580_reg),
845 GFP_KERNEL);
846
847 if (codec->reg_cache == NULL)
848 return -ENOMEM;
849
850 /* Get the codec into a known state */
851 wm8580_write(codec, WM8580_RESET, 0);
852
853 /* Power up and get individual control of the DACs */
854 wm8580_write(codec, WM8580_PWRDN1, wm8580_read(codec, WM8580_PWRDN1) &
855 ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD));
856 846
857 /* Make VMID high impedence */ 847 socdev->card->codec = wm8580_codec;
858 wm8580_write(codec, WM8580_ADC_CONTROL1, 848 codec = wm8580_codec;
859 wm8580_read(codec, WM8580_ADC_CONTROL1) & ~0x100);
860 849
861 /* register pcms */ 850 /* register pcms */
862 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, 851 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
863 SNDRV_DEFAULT_STR1);
864 if (ret < 0) { 852 if (ret < 0) {
865 printk(KERN_ERR "wm8580: failed to create pcms\n"); 853 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
866 goto pcm_err; 854 goto pcm_err;
867 } 855 }
868 856
869 wm8580_add_controls(codec); 857 snd_soc_add_controls(codec, wm8580_snd_controls,
858 ARRAY_SIZE(wm8580_snd_controls));
870 wm8580_add_widgets(codec); 859 wm8580_add_widgets(codec);
871
872 ret = snd_soc_init_card(socdev); 860 ret = snd_soc_init_card(socdev);
873 if (ret < 0) { 861 if (ret < 0) {
874 printk(KERN_ERR "wm8580: failed to register card\n"); 862 dev_err(codec->dev, "failed to register card: %d\n", ret);
875 goto card_err; 863 goto card_err;
876 } 864 }
865
877 return ret; 866 return ret;
878 867
879card_err: 868card_err:
880 snd_soc_free_pcms(socdev); 869 snd_soc_free_pcms(socdev);
881 snd_soc_dapm_free(socdev); 870 snd_soc_dapm_free(socdev);
882pcm_err: 871pcm_err:
883 kfree(codec->reg_cache);
884 return ret; 872 return ret;
885} 873}
886 874
887/* If the i2c layer weren't so broken, we could pass this kind of data 875/* power down chip */
888 around */ 876static int wm8580_remove(struct platform_device *pdev)
889static struct snd_soc_device *wm8580_socdev; 877{
878 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
879
880 snd_soc_free_pcms(socdev);
881 snd_soc_dapm_free(socdev);
890 882
891#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 883 return 0;
884}
892 885
893/* 886struct snd_soc_codec_device soc_codec_dev_wm8580 = {
894 * WM8580 2 wire address is determined by GPIO5 887 .probe = wm8580_probe,
895 * state during powerup. 888 .remove = wm8580_remove,
896 * low = 0x1a 889};
897 * high = 0x1b 890EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
898 */ 891
892static int wm8580_register(struct wm8580_priv *wm8580)
893{
894 int ret, i;
895 struct snd_soc_codec *codec = &wm8580->codec;
896
897 if (wm8580_codec) {
898 dev_err(codec->dev, "Another WM8580 is registered\n");
899 ret = -EINVAL;
900 goto err;
901 }
902
903 mutex_init(&codec->mutex);
904 INIT_LIST_HEAD(&codec->dapm_widgets);
905 INIT_LIST_HEAD(&codec->dapm_paths);
899 906
907 codec->private_data = wm8580;
908 codec->name = "WM8580";
909 codec->owner = THIS_MODULE;
910 codec->read = wm8580_read_reg_cache;
911 codec->write = wm8580_write;
912 codec->bias_level = SND_SOC_BIAS_OFF;
913 codec->set_bias_level = wm8580_set_bias_level;
914 codec->dai = wm8580_dai;
915 codec->num_dai = ARRAY_SIZE(wm8580_dai);
916 codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache);
917 codec->reg_cache = &wm8580->reg_cache;
918
919 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
920
921 /* Get the codec into a known state */
922 ret = wm8580_write(codec, WM8580_RESET, 0);
923 if (ret != 0) {
924 dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
925 goto err;
926 }
927
928 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
929 wm8580_dai[i].dev = codec->dev;
930
931 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
932
933 wm8580_codec = codec;
934
935 ret = snd_soc_register_codec(codec);
936 if (ret != 0) {
937 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
938 goto err;
939 }
940
941 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
942 if (ret != 0) {
943 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
944 goto err_codec;
945 }
946
947 return 0;
948
949err_codec:
950 snd_soc_unregister_codec(codec);
951err:
952 kfree(wm8580);
953 return ret;
954}
955
956static void wm8580_unregister(struct wm8580_priv *wm8580)
957{
958 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF);
959 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
960 snd_soc_unregister_codec(&wm8580->codec);
961 kfree(wm8580);
962 wm8580_codec = NULL;
963}
964
965#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
900static int wm8580_i2c_probe(struct i2c_client *i2c, 966static int wm8580_i2c_probe(struct i2c_client *i2c,
901 const struct i2c_device_id *id) 967 const struct i2c_device_id *id)
902{ 968{
903 struct snd_soc_device *socdev = wm8580_socdev; 969 struct wm8580_priv *wm8580;
904 struct snd_soc_codec *codec = socdev->codec; 970 struct snd_soc_codec *codec;
905 int ret;
906 971
907 i2c_set_clientdata(i2c, codec); 972 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
973 if (wm8580 == NULL)
974 return -ENOMEM;
975
976 codec = &wm8580->codec;
977 codec->hw_write = (hw_write_t)i2c_master_send;
978
979 i2c_set_clientdata(i2c, wm8580);
908 codec->control_data = i2c; 980 codec->control_data = i2c;
909 981
910 ret = wm8580_init(socdev); 982 codec->dev = &i2c->dev;
911 if (ret < 0) 983
912 dev_err(&i2c->dev, "failed to initialise WM8580\n"); 984 return wm8580_register(wm8580);
913 return ret;
914} 985}
915 986
916static int wm8580_i2c_remove(struct i2c_client *client) 987static int wm8580_i2c_remove(struct i2c_client *client)
917{ 988{
918 struct snd_soc_codec *codec = i2c_get_clientdata(client); 989 struct wm8580_priv *wm8580 = i2c_get_clientdata(client);
919 kfree(codec->reg_cache); 990 wm8580_unregister(wm8580);
920 return 0; 991 return 0;
921} 992}
922 993
@@ -928,129 +999,35 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
928 999
929static struct i2c_driver wm8580_i2c_driver = { 1000static struct i2c_driver wm8580_i2c_driver = {
930 .driver = { 1001 .driver = {
931 .name = "WM8580 I2C Codec", 1002 .name = "wm8580",
932 .owner = THIS_MODULE, 1003 .owner = THIS_MODULE,
933 }, 1004 },
934 .probe = wm8580_i2c_probe, 1005 .probe = wm8580_i2c_probe,
935 .remove = wm8580_i2c_remove, 1006 .remove = wm8580_i2c_remove,
936 .id_table = wm8580_i2c_id, 1007 .id_table = wm8580_i2c_id,
937}; 1008};
1009#endif
938 1010
939static int wm8580_add_i2c_device(struct platform_device *pdev, 1011static int __init wm8580_modinit(void)
940 const struct wm8580_setup_data *setup)
941{ 1012{
942 struct i2c_board_info info;
943 struct i2c_adapter *adapter;
944 struct i2c_client *client;
945 int ret; 1013 int ret;
946 1014
1015#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
947 ret = i2c_add_driver(&wm8580_i2c_driver); 1016 ret = i2c_add_driver(&wm8580_i2c_driver);
948 if (ret != 0) { 1017 if (ret != 0) {
949 dev_err(&pdev->dev, "can't add i2c driver\n"); 1018 pr_err("Failed to register WM8580 I2C driver: %d\n", ret);
950 return ret;
951 }
952
953 memset(&info, 0, sizeof(struct i2c_board_info));
954 info.addr = setup->i2c_address;
955 strlcpy(info.type, "wm8580", I2C_NAME_SIZE);
956
957 adapter = i2c_get_adapter(setup->i2c_bus);
958 if (!adapter) {
959 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
960 setup->i2c_bus);
961 goto err_driver;
962 }
963
964 client = i2c_new_device(adapter, &info);
965 i2c_put_adapter(adapter);
966 if (!client) {
967 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
968 (unsigned int)info.addr);
969 goto err_driver;
970 } 1019 }
971
972 return 0;
973
974err_driver:
975 i2c_del_driver(&wm8580_i2c_driver);
976 return -ENODEV;
977}
978#endif 1020#endif
979 1021
980static int wm8580_probe(struct platform_device *pdev)
981{
982 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
983 struct wm8580_setup_data *setup;
984 struct snd_soc_codec *codec;
985 struct wm8580_priv *wm8580;
986 int ret = 0;
987
988 pr_info("WM8580 Audio Codec %s\n", WM8580_VERSION);
989
990 setup = socdev->codec_data;
991 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
992 if (codec == NULL)
993 return -ENOMEM;
994
995 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
996 if (wm8580 == NULL) {
997 kfree(codec);
998 return -ENOMEM;
999 }
1000
1001 codec->private_data = wm8580;
1002 socdev->codec = codec;
1003 mutex_init(&codec->mutex);
1004 INIT_LIST_HEAD(&codec->dapm_widgets);
1005 INIT_LIST_HEAD(&codec->dapm_paths);
1006 wm8580_socdev = socdev;
1007
1008#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1009 if (setup->i2c_address) {
1010 codec->hw_write = (hw_write_t)i2c_master_send;
1011 ret = wm8580_add_i2c_device(pdev, setup);
1012 }
1013#else
1014 /* Add other interfaces here */
1015#endif
1016 return ret;
1017}
1018
1019/* power down chip */
1020static int wm8580_remove(struct platform_device *pdev)
1021{
1022 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1023 struct snd_soc_codec *codec = socdev->codec;
1024
1025 if (codec->control_data)
1026 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
1027 snd_soc_free_pcms(socdev);
1028 snd_soc_dapm_free(socdev);
1029#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1030 i2c_unregister_device(codec->control_data);
1031 i2c_del_driver(&wm8580_i2c_driver);
1032#endif
1033 kfree(codec->private_data);
1034 kfree(codec);
1035
1036 return 0; 1022 return 0;
1037} 1023}
1038
1039struct snd_soc_codec_device soc_codec_dev_wm8580 = {
1040 .probe = wm8580_probe,
1041 .remove = wm8580_remove,
1042};
1043EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
1044
1045static int __init wm8580_modinit(void)
1046{
1047 return snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
1048}
1049module_init(wm8580_modinit); 1024module_init(wm8580_modinit);
1050 1025
1051static void __exit wm8580_exit(void) 1026static void __exit wm8580_exit(void)
1052{ 1027{
1053 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 1028#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1029 i2c_del_driver(&wm8580_i2c_driver);
1030#endif
1054} 1031}
1055module_exit(wm8580_exit); 1032module_exit(wm8580_exit);
1056 1033
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
index 09e4422f6f2f..0dfb5ddde6a2 100644
--- a/sound/soc/codecs/wm8580.h
+++ b/sound/soc/codecs/wm8580.h
@@ -28,11 +28,6 @@
28#define WM8580_CLKSRC_OSC 4 28#define WM8580_CLKSRC_OSC 4
29#define WM8580_CLKSRC_NONE 5 29#define WM8580_CLKSRC_NONE 5
30 30
31struct wm8580_setup_data {
32 int i2c_bus;
33 unsigned short i2c_address;
34};
35
36#define WM8580_DAI_PAIFRX 0 31#define WM8580_DAI_PAIFRX 0
37#define WM8580_DAI_PAIFTX 1 32#define WM8580_DAI_PAIFTX 1
38 33
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 80b11983e137..e7ff2121ede9 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -47,7 +47,7 @@ static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec,
47 unsigned int reg) 47 unsigned int reg)
48{ 48{
49 u16 *cache = codec->reg_cache; 49 u16 *cache = codec->reg_cache;
50 BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults)); 50 BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults));
51 return cache[reg]; 51 return cache[reg];
52} 52}
53 53
@@ -55,7 +55,7 @@ static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec,
55 u16 reg, unsigned int value) 55 u16 reg, unsigned int value)
56{ 56{
57 u16 *cache = codec->reg_cache; 57 u16 *cache = codec->reg_cache;
58 BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults)); 58 BUG_ON(reg >= ARRAY_SIZE(wm8728_reg_defaults));
59 cache[reg] = value; 59 cache[reg] = value;
60} 60}
61 61
@@ -92,21 +92,6 @@ SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8728_DACLVOL, WM8728_DACRVOL,
92SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0), 92SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0),
93}; 93};
94 94
95static int wm8728_add_controls(struct snd_soc_codec *codec)
96{
97 int err, i;
98
99 for (i = 0; i < ARRAY_SIZE(wm8728_snd_controls); i++) {
100 err = snd_ctl_add(codec->card,
101 snd_soc_cnew(&wm8728_snd_controls[i],
102 codec, NULL));
103 if (err < 0)
104 return err;
105 }
106
107 return 0;
108}
109
110/* 95/*
111 * DAPM controls. 96 * DAPM controls.
112 */ 97 */
@@ -152,7 +137,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
152{ 137{
153 struct snd_soc_pcm_runtime *rtd = substream->private_data; 138 struct snd_soc_pcm_runtime *rtd = substream->private_data;
154 struct snd_soc_device *socdev = rtd->socdev; 139 struct snd_soc_device *socdev = rtd->socdev;
155 struct snd_soc_codec *codec = socdev->codec; 140 struct snd_soc_codec *codec = socdev->card->codec;
156 u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL); 141 u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL);
157 142
158 dac &= ~0x18; 143 dac &= ~0x18;
@@ -259,6 +244,12 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
259#define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 244#define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
260 SNDRV_PCM_FMTBIT_S24_LE) 245 SNDRV_PCM_FMTBIT_S24_LE)
261 246
247static struct snd_soc_dai_ops wm8728_dai_ops = {
248 .hw_params = wm8728_hw_params,
249 .digital_mute = wm8728_mute,
250 .set_fmt = wm8728_set_dai_fmt,
251};
252
262struct snd_soc_dai wm8728_dai = { 253struct snd_soc_dai wm8728_dai = {
263 .name = "WM8728", 254 .name = "WM8728",
264 .playback = { 255 .playback = {
@@ -268,18 +259,14 @@ struct snd_soc_dai wm8728_dai = {
268 .rates = WM8728_RATES, 259 .rates = WM8728_RATES,
269 .formats = WM8728_FORMATS, 260 .formats = WM8728_FORMATS,
270 }, 261 },
271 .ops = { 262 .ops = &wm8728_dai_ops,
272 .hw_params = wm8728_hw_params,
273 .digital_mute = wm8728_mute,
274 .set_fmt = wm8728_set_dai_fmt,
275 }
276}; 263};
277EXPORT_SYMBOL_GPL(wm8728_dai); 264EXPORT_SYMBOL_GPL(wm8728_dai);
278 265
279static int wm8728_suspend(struct platform_device *pdev, pm_message_t state) 266static int wm8728_suspend(struct platform_device *pdev, pm_message_t state)
280{ 267{
281 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 268 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
282 struct snd_soc_codec *codec = socdev->codec; 269 struct snd_soc_codec *codec = socdev->card->codec;
283 270
284 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); 271 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
285 272
@@ -289,7 +276,7 @@ static int wm8728_suspend(struct platform_device *pdev, pm_message_t state)
289static int wm8728_resume(struct platform_device *pdev) 276static int wm8728_resume(struct platform_device *pdev)
290{ 277{
291 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 278 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
292 struct snd_soc_codec *codec = socdev->codec; 279 struct snd_soc_codec *codec = socdev->card->codec;
293 280
294 wm8728_set_bias_level(codec, codec->suspend_bias_level); 281 wm8728_set_bias_level(codec, codec->suspend_bias_level);
295 282
@@ -302,7 +289,7 @@ static int wm8728_resume(struct platform_device *pdev)
302 */ 289 */
303static int wm8728_init(struct snd_soc_device *socdev) 290static int wm8728_init(struct snd_soc_device *socdev)
304{ 291{
305 struct snd_soc_codec *codec = socdev->codec; 292 struct snd_soc_codec *codec = socdev->card->codec;
306 int ret = 0; 293 int ret = 0;
307 294
308 codec->name = "WM8728"; 295 codec->name = "WM8728";
@@ -330,7 +317,8 @@ static int wm8728_init(struct snd_soc_device *socdev)
330 /* power on device */ 317 /* power on device */
331 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 318 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
332 319
333 wm8728_add_controls(codec); 320 snd_soc_add_controls(codec, wm8728_snd_controls,
321 ARRAY_SIZE(wm8728_snd_controls));
334 wm8728_add_widgets(codec); 322 wm8728_add_widgets(codec);
335 ret = snd_soc_init_card(socdev); 323 ret = snd_soc_init_card(socdev);
336 if (ret < 0) { 324 if (ret < 0) {
@@ -363,7 +351,7 @@ static int wm8728_i2c_probe(struct i2c_client *i2c,
363 const struct i2c_device_id *id) 351 const struct i2c_device_id *id)
364{ 352{
365 struct snd_soc_device *socdev = wm8728_socdev; 353 struct snd_soc_device *socdev = wm8728_socdev;
366 struct snd_soc_codec *codec = socdev->codec; 354 struct snd_soc_codec *codec = socdev->card->codec;
367 int ret; 355 int ret;
368 356
369 i2c_set_clientdata(i2c, codec); 357 i2c_set_clientdata(i2c, codec);
@@ -444,7 +432,7 @@ err_driver:
444static int __devinit wm8728_spi_probe(struct spi_device *spi) 432static int __devinit wm8728_spi_probe(struct spi_device *spi)
445{ 433{
446 struct snd_soc_device *socdev = wm8728_socdev; 434 struct snd_soc_device *socdev = wm8728_socdev;
447 struct snd_soc_codec *codec = socdev->codec; 435 struct snd_soc_codec *codec = socdev->card->codec;
448 int ret; 436 int ret;
449 437
450 codec->control_data = spi; 438 codec->control_data = spi;
@@ -508,7 +496,7 @@ static int wm8728_probe(struct platform_device *pdev)
508 if (codec == NULL) 496 if (codec == NULL)
509 return -ENOMEM; 497 return -ENOMEM;
510 498
511 socdev->codec = codec; 499 socdev->card->codec = codec;
512 mutex_init(&codec->mutex); 500 mutex_init(&codec->mutex);
513 INIT_LIST_HEAD(&codec->dapm_widgets); 501 INIT_LIST_HEAD(&codec->dapm_widgets);
514 INIT_LIST_HEAD(&codec->dapm_paths); 502 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -541,7 +529,7 @@ static int wm8728_probe(struct platform_device *pdev)
541static int wm8728_remove(struct platform_device *pdev) 529static int wm8728_remove(struct platform_device *pdev)
542{ 530{
543 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 531 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
544 struct snd_soc_codec *codec = socdev->codec; 532 struct snd_soc_codec *codec = socdev->card->codec;
545 533
546 if (codec->control_data) 534 if (codec->control_data)
547 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); 535 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index c444b9f2701e..e043e3f60008 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -29,15 +29,20 @@
29 29
30#include "wm8731.h" 30#include "wm8731.h"
31 31
32#define WM8731_VERSION "0.13" 32static struct snd_soc_codec *wm8731_codec;
33
34struct snd_soc_codec_device soc_codec_dev_wm8731; 33struct snd_soc_codec_device soc_codec_dev_wm8731;
35 34
36/* codec private data */ 35/* codec private data */
37struct wm8731_priv { 36struct wm8731_priv {
37 struct snd_soc_codec codec;
38 u16 reg_cache[WM8731_CACHEREGNUM];
38 unsigned int sysclk; 39 unsigned int sysclk;
39}; 40};
40 41
42#ifdef CONFIG_SPI_MASTER
43static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
44#endif
45
41/* 46/*
42 * wm8731 register cache 47 * wm8731 register cache
43 * We can't read the WM8731 register space when we are 48 * We can't read the WM8731 register space when we are
@@ -129,22 +134,6 @@ SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
129SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), 134SOC_ENUM("Playback De-emphasis", wm8731_enum[1]),
130}; 135};
131 136
132/* add non dapm controls */
133static int wm8731_add_controls(struct snd_soc_codec *codec)
134{
135 int err, i;
136
137 for (i = 0; i < ARRAY_SIZE(wm8731_snd_controls); i++) {
138 err = snd_ctl_add(codec->card,
139 snd_soc_cnew(&wm8731_snd_controls[i],
140 codec, NULL));
141 if (err < 0)
142 return err;
143 }
144
145 return 0;
146}
147
148/* Output Mixer */ 137/* Output Mixer */
149static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { 138static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = {
150SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), 139SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
@@ -269,7 +258,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
269{ 258{
270 struct snd_soc_pcm_runtime *rtd = substream->private_data; 259 struct snd_soc_pcm_runtime *rtd = substream->private_data;
271 struct snd_soc_device *socdev = rtd->socdev; 260 struct snd_soc_device *socdev = rtd->socdev;
272 struct snd_soc_codec *codec = socdev->codec; 261 struct snd_soc_codec *codec = socdev->card->codec;
273 struct wm8731_priv *wm8731 = codec->private_data; 262 struct wm8731_priv *wm8731 = codec->private_data;
274 u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3; 263 u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3;
275 int i = get_coeff(wm8731->sysclk, params_rate(params)); 264 int i = get_coeff(wm8731->sysclk, params_rate(params));
@@ -299,7 +288,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
299{ 288{
300 struct snd_soc_pcm_runtime *rtd = substream->private_data; 289 struct snd_soc_pcm_runtime *rtd = substream->private_data;
301 struct snd_soc_device *socdev = rtd->socdev; 290 struct snd_soc_device *socdev = rtd->socdev;
302 struct snd_soc_codec *codec = socdev->codec; 291 struct snd_soc_codec *codec = socdev->card->codec;
303 292
304 /* set active */ 293 /* set active */
305 wm8731_write(codec, WM8731_ACTIVE, 0x0001); 294 wm8731_write(codec, WM8731_ACTIVE, 0x0001);
@@ -312,7 +301,7 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream,
312{ 301{
313 struct snd_soc_pcm_runtime *rtd = substream->private_data; 302 struct snd_soc_pcm_runtime *rtd = substream->private_data;
314 struct snd_soc_device *socdev = rtd->socdev; 303 struct snd_soc_device *socdev = rtd->socdev;
315 struct snd_soc_codec *codec = socdev->codec; 304 struct snd_soc_codec *codec = socdev->card->codec;
316 305
317 /* deactivate */ 306 /* deactivate */
318 if (!codec->active) { 307 if (!codec->active) {
@@ -414,21 +403,19 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
414static int wm8731_set_bias_level(struct snd_soc_codec *codec, 403static int wm8731_set_bias_level(struct snd_soc_codec *codec,
415 enum snd_soc_bias_level level) 404 enum snd_soc_bias_level level)
416{ 405{
417 u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; 406 u16 reg;
418 407
419 switch (level) { 408 switch (level) {
420 case SND_SOC_BIAS_ON: 409 case SND_SOC_BIAS_ON:
421 /* vref/mid, osc on, dac unmute */
422 wm8731_write(codec, WM8731_PWR, reg);
423 break; 410 break;
424 case SND_SOC_BIAS_PREPARE: 411 case SND_SOC_BIAS_PREPARE:
425 break; 412 break;
426 case SND_SOC_BIAS_STANDBY: 413 case SND_SOC_BIAS_STANDBY:
427 /* everything off except vref/vmid, */ 414 /* Clear PWROFF, gate CLKOUT, everything else as-is */
415 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f;
428 wm8731_write(codec, WM8731_PWR, reg | 0x0040); 416 wm8731_write(codec, WM8731_PWR, reg | 0x0040);
429 break; 417 break;
430 case SND_SOC_BIAS_OFF: 418 case SND_SOC_BIAS_OFF:
431 /* everything off, dac mute, inactive */
432 wm8731_write(codec, WM8731_ACTIVE, 0x0); 419 wm8731_write(codec, WM8731_ACTIVE, 0x0);
433 wm8731_write(codec, WM8731_PWR, 0xffff); 420 wm8731_write(codec, WM8731_PWR, 0xffff);
434 break; 421 break;
@@ -446,6 +433,15 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
446#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 433#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
447 SNDRV_PCM_FMTBIT_S24_LE) 434 SNDRV_PCM_FMTBIT_S24_LE)
448 435
436static struct snd_soc_dai_ops wm8731_dai_ops = {
437 .prepare = wm8731_pcm_prepare,
438 .hw_params = wm8731_hw_params,
439 .shutdown = wm8731_shutdown,
440 .digital_mute = wm8731_mute,
441 .set_sysclk = wm8731_set_dai_sysclk,
442 .set_fmt = wm8731_set_dai_fmt,
443};
444
449struct snd_soc_dai wm8731_dai = { 445struct snd_soc_dai wm8731_dai = {
450 .name = "WM8731", 446 .name = "WM8731",
451 .playback = { 447 .playback = {
@@ -460,21 +456,14 @@ struct snd_soc_dai wm8731_dai = {
460 .channels_max = 2, 456 .channels_max = 2,
461 .rates = WM8731_RATES, 457 .rates = WM8731_RATES,
462 .formats = WM8731_FORMATS,}, 458 .formats = WM8731_FORMATS,},
463 .ops = { 459 .ops = &wm8731_dai_ops,
464 .prepare = wm8731_pcm_prepare,
465 .hw_params = wm8731_hw_params,
466 .shutdown = wm8731_shutdown,
467 .digital_mute = wm8731_mute,
468 .set_sysclk = wm8731_set_dai_sysclk,
469 .set_fmt = wm8731_set_dai_fmt,
470 }
471}; 460};
472EXPORT_SYMBOL_GPL(wm8731_dai); 461EXPORT_SYMBOL_GPL(wm8731_dai);
473 462
474static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 463static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
475{ 464{
476 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 465 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
477 struct snd_soc_codec *codec = socdev->codec; 466 struct snd_soc_codec *codec = socdev->card->codec;
478 467
479 wm8731_write(codec, WM8731_ACTIVE, 0x0); 468 wm8731_write(codec, WM8731_ACTIVE, 0x0);
480 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 469 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -484,7 +473,7 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
484static int wm8731_resume(struct platform_device *pdev) 473static int wm8731_resume(struct platform_device *pdev)
485{ 474{
486 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 475 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
487 struct snd_soc_codec *codec = socdev->codec; 476 struct snd_soc_codec *codec = socdev->card->codec;
488 int i; 477 int i;
489 u8 data[2]; 478 u8 data[2];
490 u16 *cache = codec->reg_cache; 479 u16 *cache = codec->reg_cache;
@@ -500,54 +489,33 @@ static int wm8731_resume(struct platform_device *pdev)
500 return 0; 489 return 0;
501} 490}
502 491
503/* 492static int wm8731_probe(struct platform_device *pdev)
504 * initialise the WM8731 driver
505 * register the mixer and dsp interfaces with the kernel
506 */
507static int wm8731_init(struct snd_soc_device *socdev)
508{ 493{
509 struct snd_soc_codec *codec = socdev->codec; 494 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
510 int reg, ret = 0; 495 struct snd_soc_codec *codec;
496 int ret = 0;
511 497
512 codec->name = "WM8731"; 498 if (wm8731_codec == NULL) {
513 codec->owner = THIS_MODULE; 499 dev_err(&pdev->dev, "Codec device not registered\n");
514 codec->read = wm8731_read_reg_cache; 500 return -ENODEV;
515 codec->write = wm8731_write; 501 }
516 codec->set_bias_level = wm8731_set_bias_level;
517 codec->dai = &wm8731_dai;
518 codec->num_dai = 1;
519 codec->reg_cache_size = ARRAY_SIZE(wm8731_reg);
520 codec->reg_cache = kmemdup(wm8731_reg, sizeof(wm8731_reg), GFP_KERNEL);
521 if (codec->reg_cache == NULL)
522 return -ENOMEM;
523 502
524 wm8731_reset(codec); 503 socdev->card->codec = wm8731_codec;
504 codec = wm8731_codec;
525 505
526 /* register pcms */ 506 /* register pcms */
527 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 507 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
528 if (ret < 0) { 508 if (ret < 0) {
529 printk(KERN_ERR "wm8731: failed to create pcms\n"); 509 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
530 goto pcm_err; 510 goto pcm_err;
531 } 511 }
532 512
533 /* power on device */ 513 snd_soc_add_controls(codec, wm8731_snd_controls,
534 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 514 ARRAY_SIZE(wm8731_snd_controls));
535
536 /* set the update bits */
537 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
538 wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100);
539 reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V);
540 wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100);
541 reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
542 wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
543 reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
544 wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
545
546 wm8731_add_controls(codec);
547 wm8731_add_widgets(codec); 515 wm8731_add_widgets(codec);
548 ret = snd_soc_init_card(socdev); 516 ret = snd_soc_init_card(socdev);
549 if (ret < 0) { 517 if (ret < 0) {
550 printk(KERN_ERR "wm8731: failed to register card\n"); 518 dev_err(codec->dev, "failed to register card: %d\n", ret);
551 goto card_err; 519 goto card_err;
552 } 520 }
553 521
@@ -557,133 +525,109 @@ card_err:
557 snd_soc_free_pcms(socdev); 525 snd_soc_free_pcms(socdev);
558 snd_soc_dapm_free(socdev); 526 snd_soc_dapm_free(socdev);
559pcm_err: 527pcm_err:
560 kfree(codec->reg_cache);
561 return ret; 528 return ret;
562} 529}
563 530
564static struct snd_soc_device *wm8731_socdev; 531/* power down chip */
565 532static int wm8731_remove(struct platform_device *pdev)
566#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
567
568/*
569 * WM8731 2 wire address is determined by GPIO5
570 * state during powerup.
571 * low = 0x1a
572 * high = 0x1b
573 */
574
575static int wm8731_i2c_probe(struct i2c_client *i2c,
576 const struct i2c_device_id *id)
577{ 533{
578 struct snd_soc_device *socdev = wm8731_socdev; 534 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
579 struct snd_soc_codec *codec = socdev->codec;
580 int ret;
581
582 i2c_set_clientdata(i2c, codec);
583 codec->control_data = i2c;
584
585 ret = wm8731_init(socdev);
586 if (ret < 0)
587 pr_err("failed to initialise WM8731\n");
588 535
589 return ret; 536 snd_soc_free_pcms(socdev);
590} 537 snd_soc_dapm_free(socdev);
591 538
592static int wm8731_i2c_remove(struct i2c_client *client)
593{
594 struct snd_soc_codec *codec = i2c_get_clientdata(client);
595 kfree(codec->reg_cache);
596 return 0; 539 return 0;
597} 540}
598 541
599static const struct i2c_device_id wm8731_i2c_id[] = { 542struct snd_soc_codec_device soc_codec_dev_wm8731 = {
600 { "wm8731", 0 }, 543 .probe = wm8731_probe,
601 { } 544 .remove = wm8731_remove,
602}; 545 .suspend = wm8731_suspend,
603MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); 546 .resume = wm8731_resume,
604
605static struct i2c_driver wm8731_i2c_driver = {
606 .driver = {
607 .name = "WM8731 I2C Codec",
608 .owner = THIS_MODULE,
609 },
610 .probe = wm8731_i2c_probe,
611 .remove = wm8731_i2c_remove,
612 .id_table = wm8731_i2c_id,
613}; 547};
548EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
614 549
615static int wm8731_add_i2c_device(struct platform_device *pdev, 550static int wm8731_register(struct wm8731_priv *wm8731)
616 const struct wm8731_setup_data *setup)
617{ 551{
618 struct i2c_board_info info;
619 struct i2c_adapter *adapter;
620 struct i2c_client *client;
621 int ret; 552 int ret;
553 struct snd_soc_codec *codec = &wm8731->codec;
554 u16 reg;
622 555
623 ret = i2c_add_driver(&wm8731_i2c_driver); 556 if (wm8731_codec) {
624 if (ret != 0) { 557 dev_err(codec->dev, "Another WM8731 is registered\n");
625 dev_err(&pdev->dev, "can't add i2c driver\n"); 558 return -EINVAL;
626 return ret;
627 } 559 }
628 560
629 memset(&info, 0, sizeof(struct i2c_board_info)); 561 mutex_init(&codec->mutex);
630 info.addr = setup->i2c_address; 562 INIT_LIST_HEAD(&codec->dapm_widgets);
631 strlcpy(info.type, "wm8731", I2C_NAME_SIZE); 563 INIT_LIST_HEAD(&codec->dapm_paths);
632 564
633 adapter = i2c_get_adapter(setup->i2c_bus); 565 codec->private_data = wm8731;
634 if (!adapter) { 566 codec->name = "WM8731";
635 dev_err(&pdev->dev, "can't get i2c adapter %d\n", 567 codec->owner = THIS_MODULE;
636 setup->i2c_bus); 568 codec->read = wm8731_read_reg_cache;
637 goto err_driver; 569 codec->write = wm8731_write;
638 } 570 codec->bias_level = SND_SOC_BIAS_OFF;
571 codec->set_bias_level = wm8731_set_bias_level;
572 codec->dai = &wm8731_dai;
573 codec->num_dai = 1;
574 codec->reg_cache_size = WM8731_CACHEREGNUM;
575 codec->reg_cache = &wm8731->reg_cache;
639 576
640 client = i2c_new_device(adapter, &info); 577 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
641 i2c_put_adapter(adapter); 578
642 if (!client) { 579 ret = wm8731_reset(codec);
643 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", 580 if (ret < 0) {
644 (unsigned int)info.addr); 581 dev_err(codec->dev, "Failed to issue reset\n");
645 goto err_driver; 582 return ret;
646 } 583 }
647 584
648 return 0; 585 wm8731_dai.dev = codec->dev;
649 586
650err_driver: 587 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
651 i2c_del_driver(&wm8731_i2c_driver);
652 return -ENODEV;
653}
654#endif
655 588
656#if defined(CONFIG_SPI_MASTER) 589 /* Latch the update bits */
657static int __devinit wm8731_spi_probe(struct spi_device *spi) 590 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
658{ 591 wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100);
659 struct snd_soc_device *socdev = wm8731_socdev; 592 reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V);
660 struct snd_soc_codec *codec = socdev->codec; 593 wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100);
661 int ret; 594 reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
595 wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
596 reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
597 wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
662 598
663 codec->control_data = spi; 599 /* Disable bypass path by default */
600 reg = wm8731_read_reg_cache(codec, WM8731_APANA);
601 wm8731_write(codec, WM8731_APANA, reg & ~0x4);
664 602
665 ret = wm8731_init(socdev); 603 wm8731_codec = codec;
666 if (ret < 0)
667 dev_err(&spi->dev, "failed to initialise WM8731\n");
668 604
669 return ret; 605 ret = snd_soc_register_codec(codec);
670} 606 if (ret != 0) {
607 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
608 return ret;
609 }
610
611 ret = snd_soc_register_dai(&wm8731_dai);
612 if (ret != 0) {
613 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
614 snd_soc_unregister_codec(codec);
615 return ret;
616 }
671 617
672static int __devexit wm8731_spi_remove(struct spi_device *spi)
673{
674 return 0; 618 return 0;
675} 619}
676 620
677static struct spi_driver wm8731_spi_driver = { 621static void wm8731_unregister(struct wm8731_priv *wm8731)
678 .driver = { 622{
679 .name = "wm8731", 623 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
680 .bus = &spi_bus_type, 624 snd_soc_unregister_dai(&wm8731_dai);
681 .owner = THIS_MODULE, 625 snd_soc_unregister_codec(&wm8731->codec);
682 }, 626 kfree(wm8731);
683 .probe = wm8731_spi_probe, 627 wm8731_codec = NULL;
684 .remove = __devexit_p(wm8731_spi_remove), 628}
685};
686 629
630#if defined(CONFIG_SPI_MASTER)
687static int wm8731_spi_write(struct spi_device *spi, const char *data, int len) 631static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
688{ 632{
689 struct spi_transfer t; 633 struct spi_transfer t;
@@ -707,101 +651,121 @@ static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
707 651
708 return len; 652 return len;
709} 653}
710#endif /* CONFIG_SPI_MASTER */
711 654
712static int wm8731_probe(struct platform_device *pdev) 655static int __devinit wm8731_spi_probe(struct spi_device *spi)
713{ 656{
714 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
715 struct wm8731_setup_data *setup;
716 struct snd_soc_codec *codec; 657 struct snd_soc_codec *codec;
717 struct wm8731_priv *wm8731; 658 struct wm8731_priv *wm8731;
718 int ret = 0;
719
720 pr_info("WM8731 Audio Codec %s", WM8731_VERSION);
721
722 setup = socdev->codec_data;
723 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
724 if (codec == NULL)
725 return -ENOMEM;
726 659
727 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 660 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
728 if (wm8731 == NULL) { 661 if (wm8731 == NULL)
729 kfree(codec);
730 return -ENOMEM; 662 return -ENOMEM;
731 }
732 663
733 codec->private_data = wm8731; 664 codec = &wm8731->codec;
734 socdev->codec = codec; 665 codec->control_data = spi;
735 mutex_init(&codec->mutex); 666 codec->hw_write = (hw_write_t)wm8731_spi_write;
736 INIT_LIST_HEAD(&codec->dapm_widgets); 667 codec->dev = &spi->dev;
737 INIT_LIST_HEAD(&codec->dapm_paths);
738 668
739 wm8731_socdev = socdev; 669 spi->dev.driver_data = wm8731;
740 ret = -ENODEV;
741 670
742#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 671 return wm8731_register(wm8731);
743 if (setup->i2c_address) {
744 codec->hw_write = (hw_write_t)i2c_master_send;
745 ret = wm8731_add_i2c_device(pdev, setup);
746 }
747#endif
748#if defined(CONFIG_SPI_MASTER)
749 if (setup->spi) {
750 codec->hw_write = (hw_write_t)wm8731_spi_write;
751 ret = spi_register_driver(&wm8731_spi_driver);
752 if (ret != 0)
753 printk(KERN_ERR "can't add spi driver");
754 }
755#endif
756
757 if (ret != 0) {
758 kfree(codec->private_data);
759 kfree(codec);
760 }
761 return ret;
762} 672}
763 673
764/* power down chip */ 674static int __devexit wm8731_spi_remove(struct spi_device *spi)
765static int wm8731_remove(struct platform_device *pdev)
766{ 675{
767 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 676 struct wm8731_priv *wm8731 = spi->dev.driver_data;
768 struct snd_soc_codec *codec = socdev->codec;
769 677
770 if (codec->control_data) 678 wm8731_unregister(wm8731);
771 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 679
680 return 0;
681}
682
683static struct spi_driver wm8731_spi_driver = {
684 .driver = {
685 .name = "wm8731",
686 .bus = &spi_bus_type,
687 .owner = THIS_MODULE,
688 },
689 .probe = wm8731_spi_probe,
690 .remove = __devexit_p(wm8731_spi_remove),
691};
692#endif /* CONFIG_SPI_MASTER */
772 693
773 snd_soc_free_pcms(socdev);
774 snd_soc_dapm_free(socdev);
775#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 694#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
776 i2c_unregister_device(codec->control_data); 695static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
777 i2c_del_driver(&wm8731_i2c_driver); 696 const struct i2c_device_id *id)
778#endif 697{
779#if defined(CONFIG_SPI_MASTER) 698 struct wm8731_priv *wm8731;
780 spi_unregister_driver(&wm8731_spi_driver); 699 struct snd_soc_codec *codec;
781#endif 700
782 kfree(codec->private_data); 701 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
783 kfree(codec); 702 if (wm8731 == NULL)
703 return -ENOMEM;
704
705 codec = &wm8731->codec;
706 codec->hw_write = (hw_write_t)i2c_master_send;
784 707
708 i2c_set_clientdata(i2c, wm8731);
709 codec->control_data = i2c;
710
711 codec->dev = &i2c->dev;
712
713 return wm8731_register(wm8731);
714}
715
716static __devexit int wm8731_i2c_remove(struct i2c_client *client)
717{
718 struct wm8731_priv *wm8731 = i2c_get_clientdata(client);
719 wm8731_unregister(wm8731);
785 return 0; 720 return 0;
786} 721}
787 722
788struct snd_soc_codec_device soc_codec_dev_wm8731 = { 723static const struct i2c_device_id wm8731_i2c_id[] = {
789 .probe = wm8731_probe, 724 { "wm8731", 0 },
790 .remove = wm8731_remove, 725 { }
791 .suspend = wm8731_suspend,
792 .resume = wm8731_resume,
793}; 726};
794EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 727MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
728
729static struct i2c_driver wm8731_i2c_driver = {
730 .driver = {
731 .name = "WM8731 I2C Codec",
732 .owner = THIS_MODULE,
733 },
734 .probe = wm8731_i2c_probe,
735 .remove = __devexit_p(wm8731_i2c_remove),
736 .id_table = wm8731_i2c_id,
737};
738#endif
795 739
796static int __init wm8731_modinit(void) 740static int __init wm8731_modinit(void)
797{ 741{
798 return snd_soc_register_dai(&wm8731_dai); 742 int ret;
743#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
744 ret = i2c_add_driver(&wm8731_i2c_driver);
745 if (ret != 0) {
746 printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n",
747 ret);
748 }
749#endif
750#if defined(CONFIG_SPI_MASTER)
751 ret = spi_register_driver(&wm8731_spi_driver);
752 if (ret != 0) {
753 printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n",
754 ret);
755 }
756#endif
757 return 0;
799} 758}
800module_init(wm8731_modinit); 759module_init(wm8731_modinit);
801 760
802static void __exit wm8731_exit(void) 761static void __exit wm8731_exit(void)
803{ 762{
804 snd_soc_unregister_dai(&wm8731_dai); 763#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
764 i2c_del_driver(&wm8731_i2c_driver);
765#endif
766#if defined(CONFIG_SPI_MASTER)
767 spi_unregister_driver(&wm8731_spi_driver);
768#endif
805} 769}
806module_exit(wm8731_exit); 770module_exit(wm8731_exit);
807 771
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index 95190e9c0c14..cd7b806e8ad0 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -34,12 +34,6 @@
34#define WM8731_SYSCLK 0 34#define WM8731_SYSCLK 0
35#define WM8731_DAI 0 35#define WM8731_DAI 0
36 36
37struct wm8731_setup_data {
38 int spi;
39 int i2c_bus;
40 unsigned short i2c_address;
41};
42
43extern struct snd_soc_dai wm8731_dai; 37extern struct snd_soc_dai wm8731_dai;
44extern struct snd_soc_codec_device soc_codec_dev_wm8731; 38extern struct snd_soc_codec_device soc_codec_dev_wm8731;
45 39
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 5997fa68e0d5..b64509b01a49 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -231,21 +231,6 @@ SOC_SINGLE("Mono Playback Volume", WM8750_MOUTV, 0, 127, 0),
231 231
232}; 232};
233 233
234/* add non dapm controls */
235static int wm8750_add_controls(struct snd_soc_codec *codec)
236{
237 int err, i;
238
239 for (i = 0; i < ARRAY_SIZE(wm8750_snd_controls); i++) {
240 err = snd_ctl_add(codec->card,
241 snd_soc_cnew(&wm8750_snd_controls[i],
242 codec, NULL));
243 if (err < 0)
244 return err;
245 }
246 return 0;
247}
248
249/* 234/*
250 * DAPM Controls 235 * DAPM Controls
251 */ 236 */
@@ -619,7 +604,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
619{ 604{
620 struct snd_soc_pcm_runtime *rtd = substream->private_data; 605 struct snd_soc_pcm_runtime *rtd = substream->private_data;
621 struct snd_soc_device *socdev = rtd->socdev; 606 struct snd_soc_device *socdev = rtd->socdev;
622 struct snd_soc_codec *codec = socdev->codec; 607 struct snd_soc_codec *codec = socdev->card->codec;
623 struct wm8750_priv *wm8750 = codec->private_data; 608 struct wm8750_priv *wm8750 = codec->private_data;
624 u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; 609 u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3;
625 u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; 610 u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0;
@@ -694,6 +679,13 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
694#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 679#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
695 SNDRV_PCM_FMTBIT_S24_LE) 680 SNDRV_PCM_FMTBIT_S24_LE)
696 681
682static struct snd_soc_dai_ops wm8750_dai_ops = {
683 .hw_params = wm8750_pcm_hw_params,
684 .digital_mute = wm8750_mute,
685 .set_fmt = wm8750_set_dai_fmt,
686 .set_sysclk = wm8750_set_dai_sysclk,
687};
688
697struct snd_soc_dai wm8750_dai = { 689struct snd_soc_dai wm8750_dai = {
698 .name = "WM8750", 690 .name = "WM8750",
699 .playback = { 691 .playback = {
@@ -708,12 +700,7 @@ struct snd_soc_dai wm8750_dai = {
708 .channels_max = 2, 700 .channels_max = 2,
709 .rates = WM8750_RATES, 701 .rates = WM8750_RATES,
710 .formats = WM8750_FORMATS,}, 702 .formats = WM8750_FORMATS,},
711 .ops = { 703 .ops = &wm8750_dai_ops,
712 .hw_params = wm8750_pcm_hw_params,
713 .digital_mute = wm8750_mute,
714 .set_fmt = wm8750_set_dai_fmt,
715 .set_sysclk = wm8750_set_dai_sysclk,
716 },
717}; 704};
718EXPORT_SYMBOL_GPL(wm8750_dai); 705EXPORT_SYMBOL_GPL(wm8750_dai);
719 706
@@ -727,7 +714,7 @@ static void wm8750_work(struct work_struct *work)
727static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 714static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
728{ 715{
729 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 716 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
730 struct snd_soc_codec *codec = socdev->codec; 717 struct snd_soc_codec *codec = socdev->card->codec;
731 718
732 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); 719 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
733 return 0; 720 return 0;
@@ -736,7 +723,7 @@ static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
736static int wm8750_resume(struct platform_device *pdev) 723static int wm8750_resume(struct platform_device *pdev)
737{ 724{
738 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 725 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
739 struct snd_soc_codec *codec = socdev->codec; 726 struct snd_soc_codec *codec = socdev->card->codec;
740 int i; 727 int i;
741 u8 data[2]; 728 u8 data[2];
742 u16 *cache = codec->reg_cache; 729 u16 *cache = codec->reg_cache;
@@ -769,7 +756,7 @@ static int wm8750_resume(struct platform_device *pdev)
769 */ 756 */
770static int wm8750_init(struct snd_soc_device *socdev) 757static int wm8750_init(struct snd_soc_device *socdev)
771{ 758{
772 struct snd_soc_codec *codec = socdev->codec; 759 struct snd_soc_codec *codec = socdev->card->codec;
773 int reg, ret = 0; 760 int reg, ret = 0;
774 761
775 codec->name = "WM8750"; 762 codec->name = "WM8750";
@@ -816,7 +803,8 @@ static int wm8750_init(struct snd_soc_device *socdev)
816 reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); 803 reg = wm8750_read_reg_cache(codec, WM8750_RINVOL);
817 wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); 804 wm8750_write(codec, WM8750_RINVOL, reg | 0x0100);
818 805
819 wm8750_add_controls(codec); 806 snd_soc_add_controls(codec, wm8750_snd_controls,
807 ARRAY_SIZE(wm8750_snd_controls));
820 wm8750_add_widgets(codec); 808 wm8750_add_widgets(codec);
821 ret = snd_soc_init_card(socdev); 809 ret = snd_soc_init_card(socdev);
822 if (ret < 0) { 810 if (ret < 0) {
@@ -850,7 +838,7 @@ static int wm8750_i2c_probe(struct i2c_client *i2c,
850 const struct i2c_device_id *id) 838 const struct i2c_device_id *id)
851{ 839{
852 struct snd_soc_device *socdev = wm8750_socdev; 840 struct snd_soc_device *socdev = wm8750_socdev;
853 struct snd_soc_codec *codec = socdev->codec; 841 struct snd_soc_codec *codec = socdev->card->codec;
854 int ret; 842 int ret;
855 843
856 i2c_set_clientdata(i2c, codec); 844 i2c_set_clientdata(i2c, codec);
@@ -931,7 +919,7 @@ err_driver:
931static int __devinit wm8750_spi_probe(struct spi_device *spi) 919static int __devinit wm8750_spi_probe(struct spi_device *spi)
932{ 920{
933 struct snd_soc_device *socdev = wm8750_socdev; 921 struct snd_soc_device *socdev = wm8750_socdev;
934 struct snd_soc_codec *codec = socdev->codec; 922 struct snd_soc_codec *codec = socdev->card->codec;
935 int ret; 923 int ret;
936 924
937 codec->control_data = spi; 925 codec->control_data = spi;
@@ -1003,7 +991,7 @@ static int wm8750_probe(struct platform_device *pdev)
1003 } 991 }
1004 992
1005 codec->private_data = wm8750; 993 codec->private_data = wm8750;
1006 socdev->codec = codec; 994 socdev->card->codec = codec;
1007 mutex_init(&codec->mutex); 995 mutex_init(&codec->mutex);
1008 INIT_LIST_HEAD(&codec->dapm_widgets); 996 INIT_LIST_HEAD(&codec->dapm_widgets);
1009 INIT_LIST_HEAD(&codec->dapm_paths); 997 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -1057,7 +1045,7 @@ static int run_delayed_work(struct delayed_work *dwork)
1057static int wm8750_remove(struct platform_device *pdev) 1045static int wm8750_remove(struct platform_device *pdev)
1058{ 1046{
1059 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1047 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1060 struct snd_soc_codec *codec = socdev->codec; 1048 struct snd_soc_codec *codec = socdev->card->codec;
1061 1049
1062 if (codec->control_data) 1050 if (codec->control_data)
1063 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); 1051 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 77620ab98756..a6e8f3f7f052 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -51,8 +51,6 @@
51 51
52#include "wm8753.h" 52#include "wm8753.h"
53 53
54#define WM8753_VERSION "0.16"
55
56static int caps_charge = 2000; 54static int caps_charge = 2000;
57module_param(caps_charge, int, 0); 55module_param(caps_charge, int, 0);
58MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); 56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
@@ -60,12 +58,6 @@ MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
60static void wm8753_set_dai_mode(struct snd_soc_codec *codec, 58static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
61 unsigned int mode); 59 unsigned int mode);
62 60
63/* codec private data */
64struct wm8753_priv {
65 unsigned int sysclk;
66 unsigned int pcmclk;
67};
68
69/* 61/*
70 * wm8753 register cache 62 * wm8753 register cache
71 * We can't read the WM8753 register space when we 63 * We can't read the WM8753 register space when we
@@ -90,6 +82,14 @@ static const u16 wm8753_reg[] = {
90 0x0000, 0x0000 82 0x0000, 0x0000
91}; 83};
92 84
85/* codec private data */
86struct wm8753_priv {
87 unsigned int sysclk;
88 unsigned int pcmclk;
89 struct snd_soc_codec codec;
90 u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
91};
92
93/* 93/*
94 * read wm8753 register cache 94 * read wm8753 register cache
95 */ 95 */
@@ -97,7 +97,7 @@ static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
97 unsigned int reg) 97 unsigned int reg)
98{ 98{
99 u16 *cache = codec->reg_cache; 99 u16 *cache = codec->reg_cache;
100 if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1)) 100 if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
101 return -1; 101 return -1;
102 return cache[reg - 1]; 102 return cache[reg - 1];
103} 103}
@@ -109,7 +109,7 @@ static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
109 unsigned int reg, unsigned int value) 109 unsigned int reg, unsigned int value)
110{ 110{
111 u16 *cache = codec->reg_cache; 111 u16 *cache = codec->reg_cache;
112 if (reg < 1 || reg > 0x3f) 112 if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
113 return; 113 return;
114 cache[reg - 1] = value; 114 cache[reg - 1] = value;
115} 115}
@@ -339,21 +339,6 @@ SOC_ENUM("ADC Data Select", wm8753_enum[27]),
339SOC_ENUM("ROUT2 Phase", wm8753_enum[28]), 339SOC_ENUM("ROUT2 Phase", wm8753_enum[28]),
340}; 340};
341 341
342/* add non dapm controls */
343static int wm8753_add_controls(struct snd_soc_codec *codec)
344{
345 int err, i;
346
347 for (i = 0; i < ARRAY_SIZE(wm8753_snd_controls); i++) {
348 err = snd_ctl_add(codec->card,
349 snd_soc_cnew(&wm8753_snd_controls[i],
350 codec, NULL));
351 if (err < 0)
352 return err;
353 }
354 return 0;
355}
356
357/* 342/*
358 * _DAPM_ Controls 343 * _DAPM_ Controls
359 */ 344 */
@@ -927,7 +912,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
927{ 912{
928 struct snd_soc_pcm_runtime *rtd = substream->private_data; 913 struct snd_soc_pcm_runtime *rtd = substream->private_data;
929 struct snd_soc_device *socdev = rtd->socdev; 914 struct snd_soc_device *socdev = rtd->socdev;
930 struct snd_soc_codec *codec = socdev->codec; 915 struct snd_soc_codec *codec = socdev->card->codec;
931 struct wm8753_priv *wm8753 = codec->private_data; 916 struct wm8753_priv *wm8753 = codec->private_data;
932 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; 917 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
933 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; 918 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
@@ -1161,7 +1146,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1161{ 1146{
1162 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1147 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1163 struct snd_soc_device *socdev = rtd->socdev; 1148 struct snd_soc_device *socdev = rtd->socdev;
1164 struct snd_soc_codec *codec = socdev->codec; 1149 struct snd_soc_codec *codec = socdev->card->codec;
1165 struct wm8753_priv *wm8753 = codec->private_data; 1150 struct wm8753_priv *wm8753 = codec->private_data;
1166 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; 1151 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
1167 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; 1152 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
@@ -1316,6 +1301,51 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1316 * 3. Voice disabled - HIFI over HIFI 1301 * 3. Voice disabled - HIFI over HIFI
1317 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture 1302 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1318 */ 1303 */
1304static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = {
1305 .hw_params = wm8753_i2s_hw_params,
1306 .digital_mute = wm8753_mute,
1307 .set_fmt = wm8753_mode1h_set_dai_fmt,
1308 .set_clkdiv = wm8753_set_dai_clkdiv,
1309 .set_pll = wm8753_set_dai_pll,
1310 .set_sysclk = wm8753_set_dai_sysclk,
1311};
1312
1313static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1314 .hw_params = wm8753_pcm_hw_params,
1315 .digital_mute = wm8753_mute,
1316 .set_fmt = wm8753_mode1v_set_dai_fmt,
1317 .set_clkdiv = wm8753_set_dai_clkdiv,
1318 .set_pll = wm8753_set_dai_pll,
1319 .set_sysclk = wm8753_set_dai_sysclk,
1320};
1321
1322static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = {
1323 .hw_params = wm8753_pcm_hw_params,
1324 .digital_mute = wm8753_mute,
1325 .set_fmt = wm8753_mode2_set_dai_fmt,
1326 .set_clkdiv = wm8753_set_dai_clkdiv,
1327 .set_pll = wm8753_set_dai_pll,
1328 .set_sysclk = wm8753_set_dai_sysclk,
1329};
1330
1331static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
1332 .hw_params = wm8753_i2s_hw_params,
1333 .digital_mute = wm8753_mute,
1334 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1335 .set_clkdiv = wm8753_set_dai_clkdiv,
1336 .set_pll = wm8753_set_dai_pll,
1337 .set_sysclk = wm8753_set_dai_sysclk,
1338};
1339
1340static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1341 .hw_params = wm8753_i2s_hw_params,
1342 .digital_mute = wm8753_mute,
1343 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1344 .set_clkdiv = wm8753_set_dai_clkdiv,
1345 .set_pll = wm8753_set_dai_pll,
1346 .set_sysclk = wm8753_set_dai_sysclk,
1347};
1348
1319static const struct snd_soc_dai wm8753_all_dai[] = { 1349static const struct snd_soc_dai wm8753_all_dai[] = {
1320/* DAI HiFi mode 1 */ 1350/* DAI HiFi mode 1 */
1321{ .name = "WM8753 HiFi", 1351{ .name = "WM8753 HiFi",
@@ -1332,14 +1362,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1332 .channels_max = 2, 1362 .channels_max = 2,
1333 .rates = WM8753_RATES, 1363 .rates = WM8753_RATES,
1334 .formats = WM8753_FORMATS}, 1364 .formats = WM8753_FORMATS},
1335 .ops = { 1365 .ops = &wm8753_dai_ops_hifi_mode1,
1336 .hw_params = wm8753_i2s_hw_params,
1337 .digital_mute = wm8753_mute,
1338 .set_fmt = wm8753_mode1h_set_dai_fmt,
1339 .set_clkdiv = wm8753_set_dai_clkdiv,
1340 .set_pll = wm8753_set_dai_pll,
1341 .set_sysclk = wm8753_set_dai_sysclk,
1342 },
1343}, 1366},
1344/* DAI Voice mode 1 */ 1367/* DAI Voice mode 1 */
1345{ .name = "WM8753 Voice", 1368{ .name = "WM8753 Voice",
@@ -1356,14 +1379,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1356 .channels_max = 2, 1379 .channels_max = 2,
1357 .rates = WM8753_RATES, 1380 .rates = WM8753_RATES,
1358 .formats = WM8753_FORMATS,}, 1381 .formats = WM8753_FORMATS,},
1359 .ops = { 1382 .ops = &wm8753_dai_ops_voice_mode1,
1360 .hw_params = wm8753_pcm_hw_params,
1361 .digital_mute = wm8753_mute,
1362 .set_fmt = wm8753_mode1v_set_dai_fmt,
1363 .set_clkdiv = wm8753_set_dai_clkdiv,
1364 .set_pll = wm8753_set_dai_pll,
1365 .set_sysclk = wm8753_set_dai_sysclk,
1366 },
1367}, 1383},
1368/* DAI HiFi mode 2 - dummy */ 1384/* DAI HiFi mode 2 - dummy */
1369{ .name = "WM8753 HiFi", 1385{ .name = "WM8753 HiFi",
@@ -1384,14 +1400,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1384 .channels_max = 2, 1400 .channels_max = 2,
1385 .rates = WM8753_RATES, 1401 .rates = WM8753_RATES,
1386 .formats = WM8753_FORMATS,}, 1402 .formats = WM8753_FORMATS,},
1387 .ops = { 1403 .ops = &wm8753_dai_ops_voice_mode2,
1388 .hw_params = wm8753_pcm_hw_params,
1389 .digital_mute = wm8753_mute,
1390 .set_fmt = wm8753_mode2_set_dai_fmt,
1391 .set_clkdiv = wm8753_set_dai_clkdiv,
1392 .set_pll = wm8753_set_dai_pll,
1393 .set_sysclk = wm8753_set_dai_sysclk,
1394 },
1395}, 1404},
1396/* DAI HiFi mode 3 */ 1405/* DAI HiFi mode 3 */
1397{ .name = "WM8753 HiFi", 1406{ .name = "WM8753 HiFi",
@@ -1408,14 +1417,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1408 .channels_max = 2, 1417 .channels_max = 2,
1409 .rates = WM8753_RATES, 1418 .rates = WM8753_RATES,
1410 .formats = WM8753_FORMATS,}, 1419 .formats = WM8753_FORMATS,},
1411 .ops = { 1420 .ops = &wm8753_dai_ops_hifi_mode3,
1412 .hw_params = wm8753_i2s_hw_params,
1413 .digital_mute = wm8753_mute,
1414 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1415 .set_clkdiv = wm8753_set_dai_clkdiv,
1416 .set_pll = wm8753_set_dai_pll,
1417 .set_sysclk = wm8753_set_dai_sysclk,
1418 },
1419}, 1421},
1420/* DAI Voice mode 3 - dummy */ 1422/* DAI Voice mode 3 - dummy */
1421{ .name = "WM8753 Voice", 1423{ .name = "WM8753 Voice",
@@ -1436,14 +1438,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1436 .channels_max = 2, 1438 .channels_max = 2,
1437 .rates = WM8753_RATES, 1439 .rates = WM8753_RATES,
1438 .formats = WM8753_FORMATS,}, 1440 .formats = WM8753_FORMATS,},
1439 .ops = { 1441 .ops = &wm8753_dai_ops_hifi_mode4,
1440 .hw_params = wm8753_i2s_hw_params,
1441 .digital_mute = wm8753_mute,
1442 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1443 .set_clkdiv = wm8753_set_dai_clkdiv,
1444 .set_pll = wm8753_set_dai_pll,
1445 .set_sysclk = wm8753_set_dai_sysclk,
1446 },
1447}, 1442},
1448/* DAI Voice mode 4 - dummy */ 1443/* DAI Voice mode 4 - dummy */
1449{ .name = "WM8753 Voice", 1444{ .name = "WM8753 Voice",
@@ -1466,30 +1461,35 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode)
1466 if (mode < 4) { 1461 if (mode < 4) {
1467 int playback_active, capture_active, codec_active, pop_wait; 1462 int playback_active, capture_active, codec_active, pop_wait;
1468 void *private_data; 1463 void *private_data;
1464 struct list_head list;
1469 1465
1470 playback_active = wm8753_dai[0].playback.active; 1466 playback_active = wm8753_dai[0].playback.active;
1471 capture_active = wm8753_dai[0].capture.active; 1467 capture_active = wm8753_dai[0].capture.active;
1472 codec_active = wm8753_dai[0].active; 1468 codec_active = wm8753_dai[0].active;
1473 private_data = wm8753_dai[0].private_data; 1469 private_data = wm8753_dai[0].private_data;
1474 pop_wait = wm8753_dai[0].pop_wait; 1470 pop_wait = wm8753_dai[0].pop_wait;
1471 list = wm8753_dai[0].list;
1475 wm8753_dai[0] = wm8753_all_dai[mode << 1]; 1472 wm8753_dai[0] = wm8753_all_dai[mode << 1];
1476 wm8753_dai[0].playback.active = playback_active; 1473 wm8753_dai[0].playback.active = playback_active;
1477 wm8753_dai[0].capture.active = capture_active; 1474 wm8753_dai[0].capture.active = capture_active;
1478 wm8753_dai[0].active = codec_active; 1475 wm8753_dai[0].active = codec_active;
1479 wm8753_dai[0].private_data = private_data; 1476 wm8753_dai[0].private_data = private_data;
1480 wm8753_dai[0].pop_wait = pop_wait; 1477 wm8753_dai[0].pop_wait = pop_wait;
1478 wm8753_dai[0].list = list;
1481 1479
1482 playback_active = wm8753_dai[1].playback.active; 1480 playback_active = wm8753_dai[1].playback.active;
1483 capture_active = wm8753_dai[1].capture.active; 1481 capture_active = wm8753_dai[1].capture.active;
1484 codec_active = wm8753_dai[1].active; 1482 codec_active = wm8753_dai[1].active;
1485 private_data = wm8753_dai[1].private_data; 1483 private_data = wm8753_dai[1].private_data;
1486 pop_wait = wm8753_dai[1].pop_wait; 1484 pop_wait = wm8753_dai[1].pop_wait;
1485 list = wm8753_dai[1].list;
1487 wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1]; 1486 wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1];
1488 wm8753_dai[1].playback.active = playback_active; 1487 wm8753_dai[1].playback.active = playback_active;
1489 wm8753_dai[1].capture.active = capture_active; 1488 wm8753_dai[1].capture.active = capture_active;
1490 wm8753_dai[1].active = codec_active; 1489 wm8753_dai[1].active = codec_active;
1491 wm8753_dai[1].private_data = private_data; 1490 wm8753_dai[1].private_data = private_data;
1492 wm8753_dai[1].pop_wait = pop_wait; 1491 wm8753_dai[1].pop_wait = pop_wait;
1492 wm8753_dai[1].list = list;
1493 } 1493 }
1494 wm8753_dai[0].codec = codec; 1494 wm8753_dai[0].codec = codec;
1495 wm8753_dai[1].codec = codec; 1495 wm8753_dai[1].codec = codec;
@@ -1505,7 +1505,7 @@ static void wm8753_work(struct work_struct *work)
1505static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) 1505static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
1506{ 1506{
1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1508 struct snd_soc_codec *codec = socdev->codec; 1508 struct snd_soc_codec *codec = socdev->card->codec;
1509 1509
1510 /* we only need to suspend if we are a valid card */ 1510 /* we only need to suspend if we are a valid card */
1511 if (!codec->card) 1511 if (!codec->card)
@@ -1518,7 +1518,7 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
1518static int wm8753_resume(struct platform_device *pdev) 1518static int wm8753_resume(struct platform_device *pdev)
1519{ 1519{
1520 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1520 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1521 struct snd_soc_codec *codec = socdev->codec; 1521 struct snd_soc_codec *codec = socdev->card->codec;
1522 int i; 1522 int i;
1523 u8 data[2]; 1523 u8 data[2];
1524 u16 *cache = codec->reg_cache; 1524 u16 *cache = codec->reg_cache;
@@ -1531,6 +1531,11 @@ static int wm8753_resume(struct platform_device *pdev)
1531 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { 1531 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
1532 if (i + 1 == WM8753_RESET) 1532 if (i + 1 == WM8753_RESET)
1533 continue; 1533 continue;
1534
1535 /* No point in writing hardware default values back */
1536 if (cache[i] == wm8753_reg[i])
1537 continue;
1538
1534 data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); 1539 data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
1535 data[1] = cache[i] & 0x00ff; 1540 data[1] = cache[i] & 0x00ff;
1536 codec->hw_write(codec->control_data, data, 2); 1541 codec->hw_write(codec->control_data, data, 2);
@@ -1549,44 +1554,129 @@ static int wm8753_resume(struct platform_device *pdev)
1549 return 0; 1554 return 0;
1550} 1555}
1551 1556
1557static struct snd_soc_codec *wm8753_codec;
1558
1559static int wm8753_probe(struct platform_device *pdev)
1560{
1561 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1562 struct snd_soc_codec *codec;
1563 int ret = 0;
1564
1565 if (!wm8753_codec) {
1566 dev_err(&pdev->dev, "WM8753 codec not yet registered\n");
1567 return -EINVAL;
1568 }
1569
1570 socdev->card->codec = wm8753_codec;
1571 codec = wm8753_codec;
1572
1573 wm8753_set_dai_mode(codec, 0);
1574
1575 /* register pcms */
1576 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1577 if (ret < 0) {
1578 printk(KERN_ERR "wm8753: failed to create pcms\n");
1579 goto pcm_err;
1580 }
1581
1582 snd_soc_add_controls(codec, wm8753_snd_controls,
1583 ARRAY_SIZE(wm8753_snd_controls));
1584 wm8753_add_widgets(codec);
1585 ret = snd_soc_init_card(socdev);
1586 if (ret < 0) {
1587 printk(KERN_ERR "wm8753: failed to register card\n");
1588 goto card_err;
1589 }
1590
1591 return 0;
1592
1593card_err:
1594 snd_soc_free_pcms(socdev);
1595 snd_soc_dapm_free(socdev);
1596
1597pcm_err:
1598 return ret;
1599}
1600
1552/* 1601/*
1553 * initialise the WM8753 driver 1602 * This function forces any delayed work to be queued and run.
1554 * register the mixer and dsp interfaces with the kernel
1555 */ 1603 */
1556static int wm8753_init(struct snd_soc_device *socdev) 1604static int run_delayed_work(struct delayed_work *dwork)
1605{
1606 int ret;
1607
1608 /* cancel any work waiting to be queued. */
1609 ret = cancel_delayed_work(dwork);
1610
1611 /* if there was any work waiting then we run it now and
1612 * wait for it's completion */
1613 if (ret) {
1614 schedule_delayed_work(dwork, 0);
1615 flush_scheduled_work();
1616 }
1617 return ret;
1618}
1619
1620/* power down chip */
1621static int wm8753_remove(struct platform_device *pdev)
1557{ 1622{
1558 struct snd_soc_codec *codec = socdev->codec; 1623 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1559 int reg, ret = 0; 1624
1625 snd_soc_free_pcms(socdev);
1626 snd_soc_dapm_free(socdev);
1627
1628 return 0;
1629}
1630
1631struct snd_soc_codec_device soc_codec_dev_wm8753 = {
1632 .probe = wm8753_probe,
1633 .remove = wm8753_remove,
1634 .suspend = wm8753_suspend,
1635 .resume = wm8753_resume,
1636};
1637EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
1638
1639static int wm8753_register(struct wm8753_priv *wm8753)
1640{
1641 int ret, i;
1642 struct snd_soc_codec *codec = &wm8753->codec;
1643 u16 reg;
1644
1645 if (wm8753_codec) {
1646 dev_err(codec->dev, "Multiple WM8753 devices not supported\n");
1647 ret = -EINVAL;
1648 goto err;
1649 }
1650
1651 mutex_init(&codec->mutex);
1652 INIT_LIST_HEAD(&codec->dapm_widgets);
1653 INIT_LIST_HEAD(&codec->dapm_paths);
1560 1654
1561 codec->name = "WM8753"; 1655 codec->name = "WM8753";
1562 codec->owner = THIS_MODULE; 1656 codec->owner = THIS_MODULE;
1563 codec->read = wm8753_read_reg_cache; 1657 codec->read = wm8753_read_reg_cache;
1564 codec->write = wm8753_write; 1658 codec->write = wm8753_write;
1659 codec->bias_level = SND_SOC_BIAS_STANDBY;
1565 codec->set_bias_level = wm8753_set_bias_level; 1660 codec->set_bias_level = wm8753_set_bias_level;
1566 codec->dai = wm8753_dai; 1661 codec->dai = wm8753_dai;
1567 codec->num_dai = 2; 1662 codec->num_dai = 2;
1568 codec->reg_cache_size = ARRAY_SIZE(wm8753_reg); 1663 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache);
1569 codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL); 1664 codec->reg_cache = &wm8753->reg_cache;
1570 1665 codec->private_data = wm8753;
1571 if (codec->reg_cache == NULL)
1572 return -ENOMEM;
1573
1574 wm8753_set_dai_mode(codec, 0);
1575 1666
1576 wm8753_reset(codec); 1667 memcpy(codec->reg_cache, wm8753_reg, sizeof(codec->reg_cache));
1668 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1577 1669
1578 /* register pcms */ 1670 ret = wm8753_reset(codec);
1579 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1580 if (ret < 0) { 1671 if (ret < 0) {
1581 printk(KERN_ERR "wm8753: failed to create pcms\n"); 1672 dev_err(codec->dev, "Failed to issue reset\n");
1582 goto pcm_err; 1673 goto err;
1583 } 1674 }
1584 1675
1585 /* charge output caps */ 1676 /* charge output caps */
1586 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 1677 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1587 codec->bias_level = SND_SOC_BIAS_STANDBY;
1588 schedule_delayed_work(&codec->delayed_work, 1678 schedule_delayed_work(&codec->delayed_work,
1589 msecs_to_jiffies(caps_charge)); 1679 msecs_to_jiffies(caps_charge));
1590 1680
1591 /* set the update bits */ 1681 /* set the update bits */
1592 reg = wm8753_read_reg_cache(codec, WM8753_LDAC); 1682 reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
@@ -1610,59 +1700,70 @@ static int wm8753_init(struct snd_soc_device *socdev)
1610 reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); 1700 reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
1611 wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); 1701 wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
1612 1702
1613 wm8753_add_controls(codec); 1703 wm8753_codec = codec;
1614 wm8753_add_widgets(codec); 1704
1615 ret = snd_soc_init_card(socdev); 1705 for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++)
1616 if (ret < 0) { 1706 wm8753_dai[i].dev = codec->dev;
1617 printk(KERN_ERR "wm8753: failed to register card\n"); 1707
1618 goto card_err; 1708 ret = snd_soc_register_codec(codec);
1709 if (ret != 0) {
1710 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1711 goto err;
1619 } 1712 }
1620 1713
1621 return ret; 1714 ret = snd_soc_register_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai));
1715 if (ret != 0) {
1716 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
1717 goto err_codec;
1718 }
1622 1719
1623card_err: 1720 return 0;
1624 snd_soc_free_pcms(socdev); 1721
1625 snd_soc_dapm_free(socdev); 1722err_codec:
1626pcm_err: 1723 run_delayed_work(&codec->delayed_work);
1627 kfree(codec->reg_cache); 1724 snd_soc_unregister_codec(codec);
1725err:
1726 kfree(wm8753);
1628 return ret; 1727 return ret;
1629} 1728}
1630 1729
1631/* If the i2c layer weren't so broken, we could pass this kind of data 1730static void wm8753_unregister(struct wm8753_priv *wm8753)
1632 around */ 1731{
1633static struct snd_soc_device *wm8753_socdev; 1732 wm8753_set_bias_level(&wm8753->codec, SND_SOC_BIAS_OFF);
1733 run_delayed_work(&wm8753->codec.delayed_work);
1734 snd_soc_unregister_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai));
1735 snd_soc_unregister_codec(&wm8753->codec);
1736 kfree(wm8753);
1737 wm8753_codec = NULL;
1738}
1634 1739
1635#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1740#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1636 1741
1637/*
1638 * WM8753 2 wire address is determined by GPIO5
1639 * state during powerup.
1640 * low = 0x1a
1641 * high = 0x1b
1642 */
1643
1644static int wm8753_i2c_probe(struct i2c_client *i2c, 1742static int wm8753_i2c_probe(struct i2c_client *i2c,
1645 const struct i2c_device_id *id) 1743 const struct i2c_device_id *id)
1646{ 1744{
1647 struct snd_soc_device *socdev = wm8753_socdev; 1745 struct snd_soc_codec *codec;
1648 struct snd_soc_codec *codec = socdev->codec; 1746 struct wm8753_priv *wm8753;
1649 int ret;
1650 1747
1651 i2c_set_clientdata(i2c, codec); 1748 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1652 codec->control_data = i2c; 1749 if (wm8753 == NULL)
1750 return -ENOMEM;
1653 1751
1654 ret = wm8753_init(socdev); 1752 codec = &wm8753->codec;
1655 if (ret < 0) 1753 codec->hw_write = (hw_write_t)i2c_master_send;
1656 pr_err("failed to initialise WM8753\n"); 1754 codec->control_data = i2c;
1755 i2c_set_clientdata(i2c, wm8753);
1657 1756
1658 return ret; 1757 codec->dev = &i2c->dev;
1758
1759 return wm8753_register(wm8753);
1659} 1760}
1660 1761
1661static int wm8753_i2c_remove(struct i2c_client *client) 1762static int wm8753_i2c_remove(struct i2c_client *client)
1662{ 1763{
1663 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1764 struct wm8753_priv *wm8753 = i2c_get_clientdata(client);
1664 kfree(codec->reg_cache); 1765 wm8753_unregister(wm8753);
1665 return 0; 1766 return 0;
1666} 1767}
1667 1768
1668static const struct i2c_device_id wm8753_i2c_id[] = { 1769static const struct i2c_device_id wm8753_i2c_id[] = {
@@ -1673,86 +1774,16 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1673 1774
1674static struct i2c_driver wm8753_i2c_driver = { 1775static struct i2c_driver wm8753_i2c_driver = {
1675 .driver = { 1776 .driver = {
1676 .name = "WM8753 I2C Codec", 1777 .name = "wm8753",
1677 .owner = THIS_MODULE, 1778 .owner = THIS_MODULE,
1678 }, 1779 },
1679 .probe = wm8753_i2c_probe, 1780 .probe = wm8753_i2c_probe,
1680 .remove = wm8753_i2c_remove, 1781 .remove = wm8753_i2c_remove,
1681 .id_table = wm8753_i2c_id, 1782 .id_table = wm8753_i2c_id,
1682}; 1783};
1683
1684static int wm8753_add_i2c_device(struct platform_device *pdev,
1685 const struct wm8753_setup_data *setup)
1686{
1687 struct i2c_board_info info;
1688 struct i2c_adapter *adapter;
1689 struct i2c_client *client;
1690 int ret;
1691
1692 ret = i2c_add_driver(&wm8753_i2c_driver);
1693 if (ret != 0) {
1694 dev_err(&pdev->dev, "can't add i2c driver\n");
1695 return ret;
1696 }
1697
1698 memset(&info, 0, sizeof(struct i2c_board_info));
1699 info.addr = setup->i2c_address;
1700 strlcpy(info.type, "wm8753", I2C_NAME_SIZE);
1701
1702 adapter = i2c_get_adapter(setup->i2c_bus);
1703 if (!adapter) {
1704 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1705 setup->i2c_bus);
1706 goto err_driver;
1707 }
1708
1709 client = i2c_new_device(adapter, &info);
1710 i2c_put_adapter(adapter);
1711 if (!client) {
1712 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1713 (unsigned int)info.addr);
1714 goto err_driver;
1715 }
1716
1717 return 0;
1718
1719err_driver:
1720 i2c_del_driver(&wm8753_i2c_driver);
1721 return -ENODEV;
1722}
1723#endif 1784#endif
1724 1785
1725#if defined(CONFIG_SPI_MASTER) 1786#if defined(CONFIG_SPI_MASTER)
1726static int __devinit wm8753_spi_probe(struct spi_device *spi)
1727{
1728 struct snd_soc_device *socdev = wm8753_socdev;
1729 struct snd_soc_codec *codec = socdev->codec;
1730 int ret;
1731
1732 codec->control_data = spi;
1733
1734 ret = wm8753_init(socdev);
1735 if (ret < 0)
1736 dev_err(&spi->dev, "failed to initialise WM8753\n");
1737
1738 return ret;
1739}
1740
1741static int __devexit wm8753_spi_remove(struct spi_device *spi)
1742{
1743 return 0;
1744}
1745
1746static struct spi_driver wm8753_spi_driver = {
1747 .driver = {
1748 .name = "wm8753",
1749 .bus = &spi_bus_type,
1750 .owner = THIS_MODULE,
1751 },
1752 .probe = wm8753_spi_probe,
1753 .remove = __devexit_p(wm8753_spi_remove),
1754};
1755
1756static int wm8753_spi_write(struct spi_device *spi, const char *data, int len) 1787static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1757{ 1788{
1758 struct spi_transfer t; 1789 struct spi_transfer t;
@@ -1776,120 +1807,69 @@ static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1776 1807
1777 return len; 1808 return len;
1778} 1809}
1779#endif
1780 1810
1781 1811static int __devinit wm8753_spi_probe(struct spi_device *spi)
1782static int wm8753_probe(struct platform_device *pdev)
1783{ 1812{
1784 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1785 struct wm8753_setup_data *setup;
1786 struct snd_soc_codec *codec; 1813 struct snd_soc_codec *codec;
1787 struct wm8753_priv *wm8753; 1814 struct wm8753_priv *wm8753;
1788 int ret = 0;
1789
1790 pr_info("WM8753 Audio Codec %s", WM8753_VERSION);
1791
1792 setup = socdev->codec_data;
1793 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1794 if (codec == NULL)
1795 return -ENOMEM;
1796 1815
1797 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1816 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1798 if (wm8753 == NULL) { 1817 if (wm8753 == NULL)
1799 kfree(codec);
1800 return -ENOMEM; 1818 return -ENOMEM;
1801 }
1802 1819
1803 codec->private_data = wm8753; 1820 codec = &wm8753->codec;
1804 socdev->codec = codec; 1821 codec->control_data = spi;
1805 mutex_init(&codec->mutex); 1822 codec->hw_write = (hw_write_t)wm8753_spi_write;
1806 INIT_LIST_HEAD(&codec->dapm_widgets); 1823 codec->dev = &spi->dev;
1807 INIT_LIST_HEAD(&codec->dapm_paths);
1808 wm8753_socdev = socdev;
1809 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1810 1824
1811#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1825 spi->dev.driver_data = wm8753;
1812 if (setup->i2c_address) {
1813 codec->hw_write = (hw_write_t)i2c_master_send;
1814 ret = wm8753_add_i2c_device(pdev, setup);
1815 }
1816#endif
1817#if defined(CONFIG_SPI_MASTER)
1818 if (setup->spi) {
1819 codec->hw_write = (hw_write_t)wm8753_spi_write;
1820 ret = spi_register_driver(&wm8753_spi_driver);
1821 if (ret != 0)
1822 printk(KERN_ERR "can't add spi driver");
1823 }
1824#endif
1825 1826
1826 if (ret != 0) { 1827 return wm8753_register(wm8753);
1827 kfree(codec->private_data);
1828 kfree(codec);
1829 }
1830 return ret;
1831} 1828}
1832 1829
1833/* 1830static int __devexit wm8753_spi_remove(struct spi_device *spi)
1834 * This function forces any delayed work to be queued and run.
1835 */
1836static int run_delayed_work(struct delayed_work *dwork)
1837{ 1831{
1838 int ret; 1832 struct wm8753_priv *wm8753 = spi->dev.driver_data;
1839 1833 wm8753_unregister(wm8753);
1840 /* cancel any work waiting to be queued. */ 1834 return 0;
1841 ret = cancel_delayed_work(dwork);
1842
1843 /* if there was any work waiting then we run it now and
1844 * wait for it's completion */
1845 if (ret) {
1846 schedule_delayed_work(dwork, 0);
1847 flush_scheduled_work();
1848 }
1849 return ret;
1850} 1835}
1851 1836
1852/* power down chip */ 1837static struct spi_driver wm8753_spi_driver = {
1853static int wm8753_remove(struct platform_device *pdev) 1838 .driver = {
1854{ 1839 .name = "wm8753",
1855 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1840 .bus = &spi_bus_type,
1856 struct snd_soc_codec *codec = socdev->codec; 1841 .owner = THIS_MODULE,
1842 },
1843 .probe = wm8753_spi_probe,
1844 .remove = __devexit_p(wm8753_spi_remove),
1845};
1846#endif
1857 1847
1858 if (codec->control_data) 1848static int __init wm8753_modinit(void)
1859 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1849{
1860 run_delayed_work(&codec->delayed_work); 1850 int ret;
1861 snd_soc_free_pcms(socdev);
1862 snd_soc_dapm_free(socdev);
1863#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1851#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1864 i2c_unregister_device(codec->control_data); 1852 ret = i2c_add_driver(&wm8753_i2c_driver);
1865 i2c_del_driver(&wm8753_i2c_driver); 1853 if (ret != 0)
1854 pr_err("Failed to register WM8753 I2C driver: %d\n", ret);
1866#endif 1855#endif
1867#if defined(CONFIG_SPI_MASTER) 1856#if defined(CONFIG_SPI_MASTER)
1868 spi_unregister_driver(&wm8753_spi_driver); 1857 ret = spi_register_driver(&wm8753_spi_driver);
1858 if (ret != 0)
1859 pr_err("Failed to register WM8753 SPI driver: %d\n", ret);
1869#endif 1860#endif
1870 kfree(codec->private_data);
1871 kfree(codec);
1872
1873 return 0; 1861 return 0;
1874} 1862}
1875
1876struct snd_soc_codec_device soc_codec_dev_wm8753 = {
1877 .probe = wm8753_probe,
1878 .remove = wm8753_remove,
1879 .suspend = wm8753_suspend,
1880 .resume = wm8753_resume,
1881};
1882EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
1883
1884static int __init wm8753_modinit(void)
1885{
1886 return snd_soc_register_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
1887}
1888module_init(wm8753_modinit); 1863module_init(wm8753_modinit);
1889 1864
1890static void __exit wm8753_exit(void) 1865static void __exit wm8753_exit(void)
1891{ 1866{
1892 snd_soc_unregister_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai)); 1867#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1868 i2c_del_driver(&wm8753_i2c_driver);
1869#endif
1870#if defined(CONFIG_SPI_MASTER)
1871 spi_unregister_driver(&wm8753_spi_driver);
1872#endif
1893} 1873}
1894module_exit(wm8753_exit); 1874module_exit(wm8753_exit);
1895 1875
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index f55704ce931b..57b2ba244040 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -77,12 +77,6 @@
77#define WM8753_BIASCTL 0x3d 77#define WM8753_BIASCTL 0x3d
78#define WM8753_ADCTL2 0x3f 78#define WM8753_ADCTL2 0x3f
79 79
80struct wm8753_setup_data {
81 int spi;
82 int i2c_bus;
83 unsigned short i2c_address;
84};
85
86#define WM8753_PLL1 0 80#define WM8753_PLL1 0
87#define WM8753_PLL2 1 81#define WM8753_PLL2 1
88 82
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 6767de10ded0..46c5ea1ff921 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -517,22 +517,6 @@ SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1,
517 517
518}; 518};
519 519
520/* add non dapm controls */
521static int wm8900_add_controls(struct snd_soc_codec *codec)
522{
523 int err, i;
524
525 for (i = 0; i < ARRAY_SIZE(wm8900_snd_controls); i++) {
526 err = snd_ctl_add(codec->card,
527 snd_soc_cnew(&wm8900_snd_controls[i],
528 codec, NULL));
529 if (err < 0)
530 return err;
531 }
532
533 return 0;
534}
535
536static const struct snd_kcontrol_new wm8900_dapm_loutput2_control = 520static const struct snd_kcontrol_new wm8900_dapm_loutput2_control =
537SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0); 521SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0);
538 522
@@ -736,7 +720,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
736{ 720{
737 struct snd_soc_pcm_runtime *rtd = substream->private_data; 721 struct snd_soc_pcm_runtime *rtd = substream->private_data;
738 struct snd_soc_device *socdev = rtd->socdev; 722 struct snd_soc_device *socdev = rtd->socdev;
739 struct snd_soc_codec *codec = socdev->codec; 723 struct snd_soc_codec *codec = socdev->card->codec;
740 u16 reg; 724 u16 reg;
741 725
742 reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60; 726 reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60;
@@ -1104,6 +1088,14 @@ static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1104 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ 1088 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
1105 SNDRV_PCM_FORMAT_S24_LE) 1089 SNDRV_PCM_FORMAT_S24_LE)
1106 1090
1091static struct snd_soc_dai_ops wm8900_dai_ops = {
1092 .hw_params = wm8900_hw_params,
1093 .set_clkdiv = wm8900_set_dai_clkdiv,
1094 .set_pll = wm8900_set_dai_pll,
1095 .set_fmt = wm8900_set_dai_fmt,
1096 .digital_mute = wm8900_digital_mute,
1097};
1098
1107struct snd_soc_dai wm8900_dai = { 1099struct snd_soc_dai wm8900_dai = {
1108 .name = "WM8900 HiFi", 1100 .name = "WM8900 HiFi",
1109 .playback = { 1101 .playback = {
@@ -1120,13 +1112,7 @@ struct snd_soc_dai wm8900_dai = {
1120 .rates = WM8900_RATES, 1112 .rates = WM8900_RATES,
1121 .formats = WM8900_PCM_FORMATS, 1113 .formats = WM8900_PCM_FORMATS,
1122 }, 1114 },
1123 .ops = { 1115 .ops = &wm8900_dai_ops,
1124 .hw_params = wm8900_hw_params,
1125 .set_clkdiv = wm8900_set_dai_clkdiv,
1126 .set_pll = wm8900_set_dai_pll,
1127 .set_fmt = wm8900_set_dai_fmt,
1128 .digital_mute = wm8900_digital_mute,
1129 },
1130}; 1116};
1131EXPORT_SYMBOL_GPL(wm8900_dai); 1117EXPORT_SYMBOL_GPL(wm8900_dai);
1132 1118
@@ -1226,7 +1212,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1226static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) 1212static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1227{ 1213{
1228 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1214 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1229 struct snd_soc_codec *codec = socdev->codec; 1215 struct snd_soc_codec *codec = socdev->card->codec;
1230 struct wm8900_priv *wm8900 = codec->private_data; 1216 struct wm8900_priv *wm8900 = codec->private_data;
1231 int fll_out = wm8900->fll_out; 1217 int fll_out = wm8900->fll_out;
1232 int fll_in = wm8900->fll_in; 1218 int fll_in = wm8900->fll_in;
@@ -1250,7 +1236,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1250static int wm8900_resume(struct platform_device *pdev) 1236static int wm8900_resume(struct platform_device *pdev)
1251{ 1237{
1252 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1238 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1253 struct snd_soc_codec *codec = socdev->codec; 1239 struct snd_soc_codec *codec = socdev->card->codec;
1254 struct wm8900_priv *wm8900 = codec->private_data; 1240 struct wm8900_priv *wm8900 = codec->private_data;
1255 u16 *cache; 1241 u16 *cache;
1256 int i, ret; 1242 int i, ret;
@@ -1288,8 +1274,8 @@ static int wm8900_resume(struct platform_device *pdev)
1288 1274
1289static struct snd_soc_codec *wm8900_codec; 1275static struct snd_soc_codec *wm8900_codec;
1290 1276
1291static int wm8900_i2c_probe(struct i2c_client *i2c, 1277static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1292 const struct i2c_device_id *id) 1278 const struct i2c_device_id *id)
1293{ 1279{
1294 struct wm8900_priv *wm8900; 1280 struct wm8900_priv *wm8900;
1295 struct snd_soc_codec *codec; 1281 struct snd_soc_codec *codec;
@@ -1388,7 +1374,7 @@ err:
1388 return ret; 1374 return ret;
1389} 1375}
1390 1376
1391static int wm8900_i2c_remove(struct i2c_client *client) 1377static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1392{ 1378{
1393 snd_soc_unregister_dai(&wm8900_dai); 1379 snd_soc_unregister_dai(&wm8900_dai);
1394 snd_soc_unregister_codec(wm8900_codec); 1380 snd_soc_unregister_codec(wm8900_codec);
@@ -1414,7 +1400,7 @@ static struct i2c_driver wm8900_i2c_driver = {
1414 .owner = THIS_MODULE, 1400 .owner = THIS_MODULE,
1415 }, 1401 },
1416 .probe = wm8900_i2c_probe, 1402 .probe = wm8900_i2c_probe,
1417 .remove = wm8900_i2c_remove, 1403 .remove = __devexit_p(wm8900_i2c_remove),
1418 .id_table = wm8900_i2c_id, 1404 .id_table = wm8900_i2c_id,
1419}; 1405};
1420 1406
@@ -1430,7 +1416,7 @@ static int wm8900_probe(struct platform_device *pdev)
1430 } 1416 }
1431 1417
1432 codec = wm8900_codec; 1418 codec = wm8900_codec;
1433 socdev->codec = codec; 1419 socdev->card->codec = codec;
1434 1420
1435 /* Register pcms */ 1421 /* Register pcms */
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1422 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -1439,7 +1425,8 @@ static int wm8900_probe(struct platform_device *pdev)
1439 goto pcm_err; 1425 goto pcm_err;
1440 } 1426 }
1441 1427
1442 wm8900_add_controls(codec); 1428 snd_soc_add_controls(codec, wm8900_snd_controls,
1429 ARRAY_SIZE(wm8900_snd_controls));
1443 wm8900_add_widgets(codec); 1430 wm8900_add_widgets(codec);
1444 1431
1445 ret = snd_soc_init_card(socdev); 1432 ret = snd_soc_init_card(socdev);
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index bde74546db4a..8cf571f1a803 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -744,21 +744,6 @@ SOC_DOUBLE_R_TLV("Speaker Volume",
744 0, 63, 0, out_tlv), 744 0, 63, 0, out_tlv),
745}; 745};
746 746
747static int wm8903_add_controls(struct snd_soc_codec *codec)
748{
749 int err, i;
750
751 for (i = 0; i < ARRAY_SIZE(wm8903_snd_controls); i++) {
752 err = snd_ctl_add(codec->card,
753 snd_soc_cnew(&wm8903_snd_controls[i],
754 codec, NULL));
755 if (err < 0)
756 return err;
757 }
758
759 return 0;
760}
761
762static const struct snd_kcontrol_new linput_mode_mux = 747static const struct snd_kcontrol_new linput_mode_mux =
763 SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum); 748 SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum);
764 749
@@ -1276,7 +1261,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
1276{ 1261{
1277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1262 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1278 struct snd_soc_device *socdev = rtd->socdev; 1263 struct snd_soc_device *socdev = rtd->socdev;
1279 struct snd_soc_codec *codec = socdev->codec; 1264 struct snd_soc_codec *codec = socdev->card->codec;
1280 struct wm8903_priv *wm8903 = codec->private_data; 1265 struct wm8903_priv *wm8903 = codec->private_data;
1281 struct i2c_client *i2c = codec->control_data; 1266 struct i2c_client *i2c = codec->control_data;
1282 struct snd_pcm_runtime *master_runtime; 1267 struct snd_pcm_runtime *master_runtime;
@@ -1318,7 +1303,7 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream,
1318{ 1303{
1319 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1304 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1320 struct snd_soc_device *socdev = rtd->socdev; 1305 struct snd_soc_device *socdev = rtd->socdev;
1321 struct snd_soc_codec *codec = socdev->codec; 1306 struct snd_soc_codec *codec = socdev->card->codec;
1322 struct wm8903_priv *wm8903 = codec->private_data; 1307 struct wm8903_priv *wm8903 = codec->private_data;
1323 1308
1324 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1309 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1338,7 +1323,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1338{ 1323{
1339 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1324 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1340 struct snd_soc_device *socdev = rtd->socdev; 1325 struct snd_soc_device *socdev = rtd->socdev;
1341 struct snd_soc_codec *codec = socdev->codec; 1326 struct snd_soc_codec *codec = socdev->card->codec;
1342 struct wm8903_priv *wm8903 = codec->private_data; 1327 struct wm8903_priv *wm8903 = codec->private_data;
1343 struct i2c_client *i2c = codec->control_data; 1328 struct i2c_client *i2c = codec->control_data;
1344 int fs = params_rate(params); 1329 int fs = params_rate(params);
@@ -1512,6 +1497,15 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1512 SNDRV_PCM_FMTBIT_S20_3LE |\ 1497 SNDRV_PCM_FMTBIT_S20_3LE |\
1513 SNDRV_PCM_FMTBIT_S24_LE) 1498 SNDRV_PCM_FMTBIT_S24_LE)
1514 1499
1500static struct snd_soc_dai_ops wm8903_dai_ops = {
1501 .startup = wm8903_startup,
1502 .shutdown = wm8903_shutdown,
1503 .hw_params = wm8903_hw_params,
1504 .digital_mute = wm8903_digital_mute,
1505 .set_fmt = wm8903_set_dai_fmt,
1506 .set_sysclk = wm8903_set_dai_sysclk,
1507};
1508
1515struct snd_soc_dai wm8903_dai = { 1509struct snd_soc_dai wm8903_dai = {
1516 .name = "WM8903", 1510 .name = "WM8903",
1517 .playback = { 1511 .playback = {
@@ -1528,21 +1522,14 @@ struct snd_soc_dai wm8903_dai = {
1528 .rates = WM8903_CAPTURE_RATES, 1522 .rates = WM8903_CAPTURE_RATES,
1529 .formats = WM8903_FORMATS, 1523 .formats = WM8903_FORMATS,
1530 }, 1524 },
1531 .ops = { 1525 .ops = &wm8903_dai_ops,
1532 .startup = wm8903_startup,
1533 .shutdown = wm8903_shutdown,
1534 .hw_params = wm8903_hw_params,
1535 .digital_mute = wm8903_digital_mute,
1536 .set_fmt = wm8903_set_dai_fmt,
1537 .set_sysclk = wm8903_set_dai_sysclk
1538 }
1539}; 1526};
1540EXPORT_SYMBOL_GPL(wm8903_dai); 1527EXPORT_SYMBOL_GPL(wm8903_dai);
1541 1528
1542static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) 1529static int wm8903_suspend(struct platform_device *pdev, pm_message_t state)
1543{ 1530{
1544 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1531 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1545 struct snd_soc_codec *codec = socdev->codec; 1532 struct snd_soc_codec *codec = socdev->card->codec;
1546 1533
1547 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1534 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1548 1535
@@ -1552,7 +1539,7 @@ static int wm8903_suspend(struct platform_device *pdev, pm_message_t state)
1552static int wm8903_resume(struct platform_device *pdev) 1539static int wm8903_resume(struct platform_device *pdev)
1553{ 1540{
1554 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1541 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1555 struct snd_soc_codec *codec = socdev->codec; 1542 struct snd_soc_codec *codec = socdev->card->codec;
1556 struct i2c_client *i2c = codec->control_data; 1543 struct i2c_client *i2c = codec->control_data;
1557 int i; 1544 int i;
1558 u16 *reg_cache = codec->reg_cache; 1545 u16 *reg_cache = codec->reg_cache;
@@ -1577,8 +1564,8 @@ static int wm8903_resume(struct platform_device *pdev)
1577 1564
1578static struct snd_soc_codec *wm8903_codec; 1565static struct snd_soc_codec *wm8903_codec;
1579 1566
1580static int wm8903_i2c_probe(struct i2c_client *i2c, 1567static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1581 const struct i2c_device_id *id) 1568 const struct i2c_device_id *id)
1582{ 1569{
1583 struct wm8903_priv *wm8903; 1570 struct wm8903_priv *wm8903;
1584 struct snd_soc_codec *codec; 1571 struct snd_soc_codec *codec;
@@ -1684,7 +1671,7 @@ err:
1684 return ret; 1671 return ret;
1685} 1672}
1686 1673
1687static int wm8903_i2c_remove(struct i2c_client *client) 1674static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1688{ 1675{
1689 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1676 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1690 1677
@@ -1714,7 +1701,7 @@ static struct i2c_driver wm8903_i2c_driver = {
1714 .owner = THIS_MODULE, 1701 .owner = THIS_MODULE,
1715 }, 1702 },
1716 .probe = wm8903_i2c_probe, 1703 .probe = wm8903_i2c_probe,
1717 .remove = wm8903_i2c_remove, 1704 .remove = __devexit_p(wm8903_i2c_remove),
1718 .id_table = wm8903_i2c_id, 1705 .id_table = wm8903_i2c_id,
1719}; 1706};
1720 1707
@@ -1728,7 +1715,7 @@ static int wm8903_probe(struct platform_device *pdev)
1728 goto err; 1715 goto err;
1729 } 1716 }
1730 1717
1731 socdev->codec = wm8903_codec; 1718 socdev->card->codec = wm8903_codec;
1732 1719
1733 /* register pcms */ 1720 /* register pcms */
1734 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1721 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -1737,8 +1724,9 @@ static int wm8903_probe(struct platform_device *pdev)
1737 goto err; 1724 goto err;
1738 } 1725 }
1739 1726
1740 wm8903_add_controls(socdev->codec); 1727 snd_soc_add_controls(socdev->card->codec, wm8903_snd_controls,
1741 wm8903_add_widgets(socdev->codec); 1728 ARRAY_SIZE(wm8903_snd_controls));
1729 wm8903_add_widgets(socdev->card->codec);
1742 1730
1743 ret = snd_soc_init_card(socdev); 1731 ret = snd_soc_init_card(socdev);
1744 if (ret < 0) { 1732 if (ret < 0) {
@@ -1759,7 +1747,7 @@ err:
1759static int wm8903_remove(struct platform_device *pdev) 1747static int wm8903_remove(struct platform_device *pdev)
1760{ 1748{
1761 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1749 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1762 struct snd_soc_codec *codec = socdev->codec; 1750 struct snd_soc_codec *codec = socdev->card->codec;
1763 1751
1764 if (codec->control_data) 1752 if (codec->control_data)
1765 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1753 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 88ead7f8dd98..032dca22dbd3 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -195,21 +195,6 @@ static const struct snd_kcontrol_new wm8971_snd_controls[] = {
195 SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0), 195 SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0),
196}; 196};
197 197
198/* add non-DAPM controls */
199static int wm8971_add_controls(struct snd_soc_codec *codec)
200{
201 int err, i;
202
203 for (i = 0; i < ARRAY_SIZE(wm8971_snd_controls); i++) {
204 err = snd_ctl_add(codec->card,
205 snd_soc_cnew(&wm8971_snd_controls[i],
206 codec, NULL));
207 if (err < 0)
208 return err;
209 }
210 return 0;
211}
212
213/* 198/*
214 * DAPM Controls 199 * DAPM Controls
215 */ 200 */
@@ -546,7 +531,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
546{ 531{
547 struct snd_soc_pcm_runtime *rtd = substream->private_data; 532 struct snd_soc_pcm_runtime *rtd = substream->private_data;
548 struct snd_soc_device *socdev = rtd->socdev; 533 struct snd_soc_device *socdev = rtd->socdev;
549 struct snd_soc_codec *codec = socdev->codec; 534 struct snd_soc_codec *codec = socdev->card->codec;
550 struct wm8971_priv *wm8971 = codec->private_data; 535 struct wm8971_priv *wm8971 = codec->private_data;
551 u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3; 536 u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3;
552 u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0; 537 u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0;
@@ -619,6 +604,13 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
619#define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 604#define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
620 SNDRV_PCM_FMTBIT_S24_LE) 605 SNDRV_PCM_FMTBIT_S24_LE)
621 606
607static struct snd_soc_dai_ops wm8971_dai_ops = {
608 .hw_params = wm8971_pcm_hw_params,
609 .digital_mute = wm8971_mute,
610 .set_fmt = wm8971_set_dai_fmt,
611 .set_sysclk = wm8971_set_dai_sysclk,
612};
613
622struct snd_soc_dai wm8971_dai = { 614struct snd_soc_dai wm8971_dai = {
623 .name = "WM8971", 615 .name = "WM8971",
624 .playback = { 616 .playback = {
@@ -633,12 +625,7 @@ struct snd_soc_dai wm8971_dai = {
633 .channels_max = 2, 625 .channels_max = 2,
634 .rates = WM8971_RATES, 626 .rates = WM8971_RATES,
635 .formats = WM8971_FORMATS,}, 627 .formats = WM8971_FORMATS,},
636 .ops = { 628 .ops = &wm8971_dai_ops,
637 .hw_params = wm8971_pcm_hw_params,
638 .digital_mute = wm8971_mute,
639 .set_fmt = wm8971_set_dai_fmt,
640 .set_sysclk = wm8971_set_dai_sysclk,
641 },
642}; 629};
643EXPORT_SYMBOL_GPL(wm8971_dai); 630EXPORT_SYMBOL_GPL(wm8971_dai);
644 631
@@ -652,7 +639,7 @@ static void wm8971_work(struct work_struct *work)
652static int wm8971_suspend(struct platform_device *pdev, pm_message_t state) 639static int wm8971_suspend(struct platform_device *pdev, pm_message_t state)
653{ 640{
654 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 641 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
655 struct snd_soc_codec *codec = socdev->codec; 642 struct snd_soc_codec *codec = socdev->card->codec;
656 643
657 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); 644 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
658 return 0; 645 return 0;
@@ -661,7 +648,7 @@ static int wm8971_suspend(struct platform_device *pdev, pm_message_t state)
661static int wm8971_resume(struct platform_device *pdev) 648static int wm8971_resume(struct platform_device *pdev)
662{ 649{
663 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 650 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
664 struct snd_soc_codec *codec = socdev->codec; 651 struct snd_soc_codec *codec = socdev->card->codec;
665 int i; 652 int i;
666 u8 data[2]; 653 u8 data[2];
667 u16 *cache = codec->reg_cache; 654 u16 *cache = codec->reg_cache;
@@ -692,7 +679,7 @@ static int wm8971_resume(struct platform_device *pdev)
692 679
693static int wm8971_init(struct snd_soc_device *socdev) 680static int wm8971_init(struct snd_soc_device *socdev)
694{ 681{
695 struct snd_soc_codec *codec = socdev->codec; 682 struct snd_soc_codec *codec = socdev->card->codec;
696 int reg, ret = 0; 683 int reg, ret = 0;
697 684
698 codec->name = "WM8971"; 685 codec->name = "WM8971";
@@ -745,7 +732,8 @@ static int wm8971_init(struct snd_soc_device *socdev)
745 reg = wm8971_read_reg_cache(codec, WM8971_RINVOL); 732 reg = wm8971_read_reg_cache(codec, WM8971_RINVOL);
746 wm8971_write(codec, WM8971_RINVOL, reg | 0x0100); 733 wm8971_write(codec, WM8971_RINVOL, reg | 0x0100);
747 734
748 wm8971_add_controls(codec); 735 snd_soc_add_controls(codec, wm8971_snd_controls,
736 ARRAY_SIZE(wm8971_snd_controls));
749 wm8971_add_widgets(codec); 737 wm8971_add_widgets(codec);
750 ret = snd_soc_init_card(socdev); 738 ret = snd_soc_init_card(socdev);
751 if (ret < 0) { 739 if (ret < 0) {
@@ -772,7 +760,7 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
772 const struct i2c_device_id *id) 760 const struct i2c_device_id *id)
773{ 761{
774 struct snd_soc_device *socdev = wm8971_socdev; 762 struct snd_soc_device *socdev = wm8971_socdev;
775 struct snd_soc_codec *codec = socdev->codec; 763 struct snd_soc_codec *codec = socdev->card->codec;
776 int ret; 764 int ret;
777 765
778 i2c_set_clientdata(i2c, codec); 766 i2c_set_clientdata(i2c, codec);
@@ -873,7 +861,7 @@ static int wm8971_probe(struct platform_device *pdev)
873 } 861 }
874 862
875 codec->private_data = wm8971; 863 codec->private_data = wm8971;
876 socdev->codec = codec; 864 socdev->card->codec = codec;
877 mutex_init(&codec->mutex); 865 mutex_init(&codec->mutex);
878 INIT_LIST_HEAD(&codec->dapm_widgets); 866 INIT_LIST_HEAD(&codec->dapm_widgets);
879 INIT_LIST_HEAD(&codec->dapm_paths); 867 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -908,7 +896,7 @@ static int wm8971_probe(struct platform_device *pdev)
908static int wm8971_remove(struct platform_device *pdev) 896static int wm8971_remove(struct platform_device *pdev)
909{ 897{
910 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 898 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
911 struct snd_soc_codec *codec = socdev->codec; 899 struct snd_soc_codec *codec = socdev->card->codec;
912 900
913 if (codec->control_data) 901 if (codec->control_data)
914 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); 902 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index a5731faa150c..c518c3e5aa3f 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -115,7 +115,7 @@ static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec,
115 unsigned int reg) 115 unsigned int reg)
116{ 116{
117 u16 *cache = codec->reg_cache; 117 u16 *cache = codec->reg_cache;
118 BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1); 118 BUG_ON(reg >= ARRAY_SIZE(wm8990_reg));
119 return cache[reg]; 119 return cache[reg];
120} 120}
121 121
@@ -128,7 +128,7 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
128 u16 *cache = codec->reg_cache; 128 u16 *cache = codec->reg_cache;
129 129
130 /* Reset register and reserved registers are uncached */ 130 /* Reset register and reserved registers are uncached */
131 if (reg == 0 || reg > ARRAY_SIZE(wm8990_reg) - 1) 131 if (reg == 0 || reg >= ARRAY_SIZE(wm8990_reg))
132 return; 132 return;
133 133
134 cache[reg] = value; 134 cache[reg] = value;
@@ -418,21 +418,6 @@ SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
418 418
419}; 419};
420 420
421/* add non dapm controls */
422static int wm8990_add_controls(struct snd_soc_codec *codec)
423{
424 int err, i;
425
426 for (i = 0; i < ARRAY_SIZE(wm8990_snd_controls); i++) {
427 err = snd_ctl_add(codec->card,
428 snd_soc_cnew(&wm8990_snd_controls[i], codec,
429 NULL));
430 if (err < 0)
431 return err;
432 }
433 return 0;
434}
435
436/* 421/*
437 * _DAPM_ Controls 422 * _DAPM_ Controls
438 */ 423 */
@@ -1178,7 +1163,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1178{ 1163{
1179 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1164 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1180 struct snd_soc_device *socdev = rtd->socdev; 1165 struct snd_soc_device *socdev = rtd->socdev;
1181 struct snd_soc_codec *codec = socdev->codec; 1166 struct snd_soc_codec *codec = socdev->card->codec;
1182 u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1); 1167 u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1);
1183 1168
1184 audio1 &= ~WM8990_AIF_WL_MASK; 1169 audio1 &= ~WM8990_AIF_WL_MASK;
@@ -1347,6 +1332,15 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1347 * 1. ADC/DAC on Primary Interface 1332 * 1. ADC/DAC on Primary Interface
1348 * 2. ADC on Primary Interface/DAC on secondary 1333 * 2. ADC on Primary Interface/DAC on secondary
1349 */ 1334 */
1335static struct snd_soc_dai_ops wm8990_dai_ops = {
1336 .hw_params = wm8990_hw_params,
1337 .digital_mute = wm8990_mute,
1338 .set_fmt = wm8990_set_dai_fmt,
1339 .set_clkdiv = wm8990_set_dai_clkdiv,
1340 .set_pll = wm8990_set_dai_pll,
1341 .set_sysclk = wm8990_set_dai_sysclk,
1342};
1343
1350struct snd_soc_dai wm8990_dai = { 1344struct snd_soc_dai wm8990_dai = {
1351/* ADC/DAC on primary */ 1345/* ADC/DAC on primary */
1352 .name = "WM8990 ADC/DAC Primary", 1346 .name = "WM8990 ADC/DAC Primary",
@@ -1363,21 +1357,14 @@ struct snd_soc_dai wm8990_dai = {
1363 .channels_max = 2, 1357 .channels_max = 2,
1364 .rates = WM8990_RATES, 1358 .rates = WM8990_RATES,
1365 .formats = WM8990_FORMATS,}, 1359 .formats = WM8990_FORMATS,},
1366 .ops = { 1360 .ops = &wm8990_dai_ops,
1367 .hw_params = wm8990_hw_params,
1368 .digital_mute = wm8990_mute,
1369 .set_fmt = wm8990_set_dai_fmt,
1370 .set_clkdiv = wm8990_set_dai_clkdiv,
1371 .set_pll = wm8990_set_dai_pll,
1372 .set_sysclk = wm8990_set_dai_sysclk,
1373 },
1374}; 1361};
1375EXPORT_SYMBOL_GPL(wm8990_dai); 1362EXPORT_SYMBOL_GPL(wm8990_dai);
1376 1363
1377static int wm8990_suspend(struct platform_device *pdev, pm_message_t state) 1364static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
1378{ 1365{
1379 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1366 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1380 struct snd_soc_codec *codec = socdev->codec; 1367 struct snd_soc_codec *codec = socdev->card->codec;
1381 1368
1382 /* we only need to suspend if we are a valid card */ 1369 /* we only need to suspend if we are a valid card */
1383 if (!codec->card) 1370 if (!codec->card)
@@ -1390,7 +1377,7 @@ static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
1390static int wm8990_resume(struct platform_device *pdev) 1377static int wm8990_resume(struct platform_device *pdev)
1391{ 1378{
1392 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1379 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1393 struct snd_soc_codec *codec = socdev->codec; 1380 struct snd_soc_codec *codec = socdev->card->codec;
1394 int i; 1381 int i;
1395 u8 data[2]; 1382 u8 data[2];
1396 u16 *cache = codec->reg_cache; 1383 u16 *cache = codec->reg_cache;
@@ -1418,7 +1405,7 @@ static int wm8990_resume(struct platform_device *pdev)
1418 */ 1405 */
1419static int wm8990_init(struct snd_soc_device *socdev) 1406static int wm8990_init(struct snd_soc_device *socdev)
1420{ 1407{
1421 struct snd_soc_codec *codec = socdev->codec; 1408 struct snd_soc_codec *codec = socdev->card->codec;
1422 u16 reg; 1409 u16 reg;
1423 int ret = 0; 1410 int ret = 0;
1424 1411
@@ -1461,7 +1448,8 @@ static int wm8990_init(struct snd_soc_device *socdev)
1461 wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1448 wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1462 wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1449 wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1463 1450
1464 wm8990_add_controls(codec); 1451 snd_soc_add_controls(codec, wm8990_snd_controls,
1452 ARRAY_SIZE(wm8990_snd_controls));
1465 wm8990_add_widgets(codec); 1453 wm8990_add_widgets(codec);
1466 ret = snd_soc_init_card(socdev); 1454 ret = snd_soc_init_card(socdev);
1467 if (ret < 0) { 1455 if (ret < 0) {
@@ -1495,7 +1483,7 @@ static int wm8990_i2c_probe(struct i2c_client *i2c,
1495 const struct i2c_device_id *id) 1483 const struct i2c_device_id *id)
1496{ 1484{
1497 struct snd_soc_device *socdev = wm8990_socdev; 1485 struct snd_soc_device *socdev = wm8990_socdev;
1498 struct snd_soc_codec *codec = socdev->codec; 1486 struct snd_soc_codec *codec = socdev->card->codec;
1499 int ret; 1487 int ret;
1500 1488
1501 i2c_set_clientdata(i2c, codec); 1489 i2c_set_clientdata(i2c, codec);
@@ -1594,7 +1582,7 @@ static int wm8990_probe(struct platform_device *pdev)
1594 } 1582 }
1595 1583
1596 codec->private_data = wm8990; 1584 codec->private_data = wm8990;
1597 socdev->codec = codec; 1585 socdev->card->codec = codec;
1598 mutex_init(&codec->mutex); 1586 mutex_init(&codec->mutex);
1599 INIT_LIST_HEAD(&codec->dapm_widgets); 1587 INIT_LIST_HEAD(&codec->dapm_widgets);
1600 INIT_LIST_HEAD(&codec->dapm_paths); 1588 INIT_LIST_HEAD(&codec->dapm_paths);
@@ -1620,7 +1608,7 @@ static int wm8990_probe(struct platform_device *pdev)
1620static int wm8990_remove(struct platform_device *pdev) 1608static int wm8990_remove(struct platform_device *pdev)
1621{ 1609{
1622 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1610 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1623 struct snd_soc_codec *codec = socdev->codec; 1611 struct snd_soc_codec *codec = socdev->card->codec;
1624 1612
1625 if (codec->control_data) 1613 if (codec->control_data)
1626 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); 1614 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
new file mode 100644
index 000000000000..3265817c5c26
--- /dev/null
+++ b/sound/soc/codecs/wm9705.c
@@ -0,0 +1,415 @@
1/*
2 * wm9705.c -- ALSA Soc WM9705 codec support
3 *
4 * Copyright 2008 Ian Molton <spyro@f2s.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; Version 2 of the License only.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/device.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/ac97_codec.h>
19#include <sound/initval.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22
23#include "wm9705.h"
24
25/*
26 * WM9705 register cache
27 */
28static const u16 wm9705_reg[] = {
29 0x6150, 0x8000, 0x8000, 0x8000, /* 0x0 */
30 0x0000, 0x8000, 0x8008, 0x8008, /* 0x8 */
31 0x8808, 0x8808, 0x8808, 0x8808, /* 0x10 */
32 0x8808, 0x0000, 0x8000, 0x0000, /* 0x18 */
33 0x0000, 0x0000, 0x0000, 0x000f, /* 0x20 */
34 0x0605, 0x0000, 0xbb80, 0x0000, /* 0x28 */
35 0x0000, 0xbb80, 0x0000, 0x0000, /* 0x30 */
36 0x0000, 0x2000, 0x0000, 0x0000, /* 0x38 */
37 0x0000, 0x0000, 0x0000, 0x0000, /* 0x40 */
38 0x0000, 0x0000, 0x0000, 0x0000, /* 0x48 */
39 0x0000, 0x0000, 0x0000, 0x0000, /* 0x50 */
40 0x0000, 0x0000, 0x0000, 0x0000, /* 0x58 */
41 0x0000, 0x0000, 0x0000, 0x0000, /* 0x60 */
42 0x0000, 0x0000, 0x0000, 0x0000, /* 0x68 */
43 0x0000, 0x0808, 0x0000, 0x0006, /* 0x70 */
44 0x0000, 0x0000, 0x574d, 0x4c05, /* 0x78 */
45};
46
47static const struct snd_kcontrol_new wm9705_snd_ac97_controls[] = {
48 SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),
49 SOC_SINGLE("Master Playback Switch", AC97_MASTER, 15, 1, 1),
50 SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
51 SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
52 SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1),
53 SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1),
54 SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1),
55 SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
56 SOC_SINGLE("PCBeep Playback Volume", AC97_PC_BEEP, 1, 15, 1),
57 SOC_SINGLE("Phone Playback Volume", AC97_PHONE, 0, 31, 1),
58 SOC_DOUBLE("Line Playback Volume", AC97_LINE, 8, 0, 31, 1),
59 SOC_DOUBLE("CD Playback Volume", AC97_CD, 8, 0, 31, 1),
60 SOC_SINGLE("Mic Playback Volume", AC97_MIC, 0, 31, 1),
61 SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 6, 1, 0),
62 SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0),
63 SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),
64};
65
66static const char *wm9705_mic[] = {"Mic 1", "Mic 2"};
67static const char *wm9705_rec_sel[] = {"Mic", "CD", "NC", "NC",
68 "Line", "Stereo Mix", "Mono Mix", "Phone"};
69
70static const struct soc_enum wm9705_enum_mic =
71 SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, wm9705_mic);
72static const struct soc_enum wm9705_enum_rec_l =
73 SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9705_rec_sel);
74static const struct soc_enum wm9705_enum_rec_r =
75 SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9705_rec_sel);
76
77/* Headphone Mixer */
78static const struct snd_kcontrol_new wm9705_hp_mixer_controls[] = {
79 SOC_DAPM_SINGLE("PCBeep Playback Switch", AC97_PC_BEEP, 15, 1, 1),
80 SOC_DAPM_SINGLE("CD Playback Switch", AC97_CD, 15, 1, 1),
81 SOC_DAPM_SINGLE("Mic Playback Switch", AC97_MIC, 15, 1, 1),
82 SOC_DAPM_SINGLE("Phone Playback Switch", AC97_PHONE, 15, 1, 1),
83 SOC_DAPM_SINGLE("Line Playback Switch", AC97_LINE, 15, 1, 1),
84};
85
86/* Mic source */
87static const struct snd_kcontrol_new wm9705_mic_src_controls =
88 SOC_DAPM_ENUM("Route", wm9705_enum_mic);
89
90/* Capture source */
91static const struct snd_kcontrol_new wm9705_capture_selectl_controls =
92 SOC_DAPM_ENUM("Route", wm9705_enum_rec_l);
93static const struct snd_kcontrol_new wm9705_capture_selectr_controls =
94 SOC_DAPM_ENUM("Route", wm9705_enum_rec_r);
95
96/* DAPM widgets */
97static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = {
98 SND_SOC_DAPM_MUX("Mic Source", SND_SOC_NOPM, 0, 0,
99 &wm9705_mic_src_controls),
100 SND_SOC_DAPM_MUX("Left Capture Source", SND_SOC_NOPM, 0, 0,
101 &wm9705_capture_selectl_controls),
102 SND_SOC_DAPM_MUX("Right Capture Source", SND_SOC_NOPM, 0, 0,
103 &wm9705_capture_selectr_controls),
104 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
105 SND_SOC_NOPM, 0, 0),
106 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
107 SND_SOC_NOPM, 0, 0),
108 SND_SOC_DAPM_MIXER_NAMED_CTL("HP Mixer", SND_SOC_NOPM, 0, 0,
109 &wm9705_hp_mixer_controls[0],
110 ARRAY_SIZE(wm9705_hp_mixer_controls)),
111 SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
112 SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0),
113 SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0),
114 SND_SOC_DAPM_PGA("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
115 SND_SOC_DAPM_PGA("Speaker PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
116 SND_SOC_DAPM_PGA("Line PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
117 SND_SOC_DAPM_PGA("Line out PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
118 SND_SOC_DAPM_PGA("Mono PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
119 SND_SOC_DAPM_PGA("Phone PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
120 SND_SOC_DAPM_PGA("Mic PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
121 SND_SOC_DAPM_PGA("PCBEEP PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
122 SND_SOC_DAPM_PGA("CD PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
123 SND_SOC_DAPM_PGA("ADC PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
124 SND_SOC_DAPM_OUTPUT("HPOUTL"),
125 SND_SOC_DAPM_OUTPUT("HPOUTR"),
126 SND_SOC_DAPM_OUTPUT("LOUT"),
127 SND_SOC_DAPM_OUTPUT("ROUT"),
128 SND_SOC_DAPM_OUTPUT("MONOOUT"),
129 SND_SOC_DAPM_INPUT("PHONE"),
130 SND_SOC_DAPM_INPUT("LINEINL"),
131 SND_SOC_DAPM_INPUT("LINEINR"),
132 SND_SOC_DAPM_INPUT("CDINL"),
133 SND_SOC_DAPM_INPUT("CDINR"),
134 SND_SOC_DAPM_INPUT("PCBEEP"),
135 SND_SOC_DAPM_INPUT("MIC1"),
136 SND_SOC_DAPM_INPUT("MIC2"),
137};
138
139/* Audio map
140 * WM9705 has no switches to disable the route from the inputs to the HP mixer
141 * so in order to prevent active inputs from forcing the audio outputs to be
142 * constantly enabled, we use the mutes on those inputs to simulate such
143 * controls.
144 */
145static const struct snd_soc_dapm_route audio_map[] = {
146 /* HP mixer */
147 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"},
148 {"HP Mixer", "CD Playback Switch", "CD PGA"},
149 {"HP Mixer", "Mic Playback Switch", "Mic PGA"},
150 {"HP Mixer", "Phone Playback Switch", "Phone PGA"},
151 {"HP Mixer", "Line Playback Switch", "Line PGA"},
152 {"HP Mixer", NULL, "Left DAC"},
153 {"HP Mixer", NULL, "Right DAC"},
154
155 /* mono mixer */
156 {"Mono Mixer", NULL, "HP Mixer"},
157
158 /* outputs */
159 {"Headphone PGA", NULL, "HP Mixer"},
160 {"HPOUTL", NULL, "Headphone PGA"},
161 {"HPOUTR", NULL, "Headphone PGA"},
162 {"Line out PGA", NULL, "HP Mixer"},
163 {"LOUT", NULL, "Line out PGA"},
164 {"ROUT", NULL, "Line out PGA"},
165 {"Mono PGA", NULL, "Mono Mixer"},
166 {"MONOOUT", NULL, "Mono PGA"},
167
168 /* inputs */
169 {"CD PGA", NULL, "CDINL"},
170 {"CD PGA", NULL, "CDINR"},
171 {"Line PGA", NULL, "LINEINL"},
172 {"Line PGA", NULL, "LINEINR"},
173 {"Phone PGA", NULL, "PHONE"},
174 {"Mic Source", "Mic 1", "MIC1"},
175 {"Mic Source", "Mic 2", "MIC2"},
176 {"Mic PGA", NULL, "Mic Source"},
177 {"PCBEEP PGA", NULL, "PCBEEP"},
178
179 /* Left capture selector */
180 {"Left Capture Source", "Mic", "Mic Source"},
181 {"Left Capture Source", "CD", "CDINL"},
182 {"Left Capture Source", "Line", "LINEINL"},
183 {"Left Capture Source", "Stereo Mix", "HP Mixer"},
184 {"Left Capture Source", "Mono Mix", "HP Mixer"},
185 {"Left Capture Source", "Phone", "PHONE"},
186
187 /* Right capture source */
188 {"Right Capture Source", "Mic", "Mic Source"},
189 {"Right Capture Source", "CD", "CDINR"},
190 {"Right Capture Source", "Line", "LINEINR"},
191 {"Right Capture Source", "Stereo Mix", "HP Mixer"},
192 {"Right Capture Source", "Mono Mix", "HP Mixer"},
193 {"Right Capture Source", "Phone", "PHONE"},
194
195 {"ADC PGA", NULL, "Left Capture Source"},
196 {"ADC PGA", NULL, "Right Capture Source"},
197
198 /* ADC's */
199 {"Left ADC", NULL, "ADC PGA"},
200 {"Right ADC", NULL, "ADC PGA"},
201};
202
203static int wm9705_add_widgets(struct snd_soc_codec *codec)
204{
205 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets,
206 ARRAY_SIZE(wm9705_dapm_widgets));
207 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
208 snd_soc_dapm_new_widgets(codec);
209
210 return 0;
211}
212
213/* We use a register cache to enhance read performance. */
214static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
215{
216 u16 *cache = codec->reg_cache;
217
218 switch (reg) {
219 case AC97_RESET:
220 case AC97_VENDOR_ID1:
221 case AC97_VENDOR_ID2:
222 return soc_ac97_ops.read(codec->ac97, reg);
223 default:
224 reg = reg >> 1;
225
226 if (reg >= (ARRAY_SIZE(wm9705_reg)))
227 return -EIO;
228
229 return cache[reg];
230 }
231}
232
233static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
234 unsigned int val)
235{
236 u16 *cache = codec->reg_cache;
237
238 soc_ac97_ops.write(codec->ac97, reg, val);
239 reg = reg >> 1;
240 if (reg < (ARRAY_SIZE(wm9705_reg)))
241 cache[reg] = val;
242
243 return 0;
244}
245
246static int ac97_prepare(struct snd_pcm_substream *substream,
247 struct snd_soc_dai *dai)
248{
249 struct snd_pcm_runtime *runtime = substream->runtime;
250 struct snd_soc_pcm_runtime *rtd = substream->private_data;
251 struct snd_soc_device *socdev = rtd->socdev;
252 struct snd_soc_codec *codec = socdev->card->codec;
253 int reg;
254 u16 vra;
255
256 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
257 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
258
259 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
260 reg = AC97_PCM_FRONT_DAC_RATE;
261 else
262 reg = AC97_PCM_LR_ADC_RATE;
263
264 return ac97_write(codec, reg, runtime->rate);
265}
266
267#define WM9705_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
268 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
269 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
270 SNDRV_PCM_RATE_48000)
271
272static struct snd_soc_dai_ops wm9705_dai_ops = {
273 .prepare = ac97_prepare,
274};
275
276struct snd_soc_dai wm9705_dai[] = {
277 {
278 .name = "AC97 HiFi",
279 .ac97_control = 1,
280 .playback = {
281 .stream_name = "HiFi Playback",
282 .channels_min = 1,
283 .channels_max = 2,
284 .rates = WM9705_AC97_RATES,
285 .formats = SNDRV_PCM_FMTBIT_S16_LE,
286 },
287 .capture = {
288 .stream_name = "HiFi Capture",
289 .channels_min = 1,
290 .channels_max = 2,
291 .rates = WM9705_AC97_RATES,
292 .formats = SNDRV_PCM_FMTBIT_S16_LE,
293 },
294 .ops = &wm9705_dai_ops,
295 },
296 {
297 .name = "AC97 Aux",
298 .playback = {
299 .stream_name = "Aux Playback",
300 .channels_min = 1,
301 .channels_max = 1,
302 .rates = WM9705_AC97_RATES,
303 .formats = SNDRV_PCM_FMTBIT_S16_LE,
304 },
305 }
306};
307EXPORT_SYMBOL_GPL(wm9705_dai);
308
309static int wm9705_reset(struct snd_soc_codec *codec)
310{
311 if (soc_ac97_ops.reset) {
312 soc_ac97_ops.reset(codec->ac97);
313 if (ac97_read(codec, 0) == wm9705_reg[0])
314 return 0; /* Success */
315 }
316
317 return -EIO;
318}
319
320static int wm9705_soc_probe(struct platform_device *pdev)
321{
322 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
323 struct snd_soc_codec *codec;
324 int ret = 0;
325
326 printk(KERN_INFO "WM9705 SoC Audio Codec\n");
327
328 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
329 GFP_KERNEL);
330 if (socdev->card->codec == NULL)
331 return -ENOMEM;
332 codec = socdev->card->codec;
333 mutex_init(&codec->mutex);
334
335 codec->reg_cache = kmemdup(wm9705_reg, sizeof(wm9705_reg), GFP_KERNEL);
336 if (codec->reg_cache == NULL) {
337 ret = -ENOMEM;
338 goto cache_err;
339 }
340 codec->reg_cache_size = sizeof(wm9705_reg);
341 codec->reg_cache_step = 2;
342
343 codec->name = "WM9705";
344 codec->owner = THIS_MODULE;
345 codec->dai = wm9705_dai;
346 codec->num_dai = ARRAY_SIZE(wm9705_dai);
347 codec->write = ac97_write;
348 codec->read = ac97_read;
349 INIT_LIST_HEAD(&codec->dapm_widgets);
350 INIT_LIST_HEAD(&codec->dapm_paths);
351
352 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
353 if (ret < 0) {
354 printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
355 goto codec_err;
356 }
357
358 /* register pcms */
359 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
360 if (ret < 0)
361 goto pcm_err;
362
363 ret = wm9705_reset(codec);
364 if (ret)
365 goto reset_err;
366
367 snd_soc_add_controls(codec, wm9705_snd_ac97_controls,
368 ARRAY_SIZE(wm9705_snd_ac97_controls));
369 wm9705_add_widgets(codec);
370
371 ret = snd_soc_init_card(socdev);
372 if (ret < 0) {
373 printk(KERN_ERR "wm9705: failed to register card\n");
374 goto pcm_err;
375 }
376
377 return 0;
378
379reset_err:
380 snd_soc_free_pcms(socdev);
381pcm_err:
382 snd_soc_free_ac97_codec(codec);
383codec_err:
384 kfree(codec->reg_cache);
385cache_err:
386 kfree(socdev->card->codec);
387 socdev->card->codec = NULL;
388 return ret;
389}
390
391static int wm9705_soc_remove(struct platform_device *pdev)
392{
393 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
394 struct snd_soc_codec *codec = socdev->card->codec;
395
396 if (codec == NULL)
397 return 0;
398
399 snd_soc_dapm_free(socdev);
400 snd_soc_free_pcms(socdev);
401 snd_soc_free_ac97_codec(codec);
402 kfree(codec->reg_cache);
403 kfree(codec);
404 return 0;
405}
406
407struct snd_soc_codec_device soc_codec_dev_wm9705 = {
408 .probe = wm9705_soc_probe,
409 .remove = wm9705_soc_remove,
410};
411EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705);
412
413MODULE_DESCRIPTION("ASoC WM9705 driver");
414MODULE_AUTHOR("Ian Molton");
415MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wm9705.h b/sound/soc/codecs/wm9705.h
new file mode 100644
index 000000000000..d380f110f9e2
--- /dev/null
+++ b/sound/soc/codecs/wm9705.h
@@ -0,0 +1,14 @@
1/*
2 * wm9705.h -- WM9705 Soc Audio driver
3 */
4
5#ifndef _WM9705_H
6#define _WM9705_H
7
8#define WM9705_DAI_AC97_HIFI 0
9#define WM9705_DAI_AC97_AUX 1
10
11extern struct snd_soc_dai wm9705_dai[2];
12extern struct snd_soc_codec_device soc_codec_dev_wm9705;
13
14#endif
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index af83d629078a..765cf1e7369e 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -154,21 +154,6 @@ SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
154SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), 154SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
155}; 155};
156 156
157/* add non dapm controls */
158static int wm9712_add_controls(struct snd_soc_codec *codec)
159{
160 int err, i;
161
162 for (i = 0; i < ARRAY_SIZE(wm9712_snd_ac97_controls); i++) {
163 err = snd_ctl_add(codec->card,
164 snd_soc_cnew(&wm9712_snd_ac97_controls[i],
165 codec, NULL));
166 if (err < 0)
167 return err;
168 }
169 return 0;
170}
171
172/* We have to create a fake left and right HP mixers because 157/* We have to create a fake left and right HP mixers because
173 * the codec only has a single control that is shared by both channels. 158 * the codec only has a single control that is shared by both channels.
174 * This makes it impossible to determine the audio path. 159 * This makes it impossible to determine the audio path.
@@ -467,7 +452,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
467 else { 452 else {
468 reg = reg >> 1; 453 reg = reg >> 1;
469 454
470 if (reg > (ARRAY_SIZE(wm9712_reg))) 455 if (reg >= (ARRAY_SIZE(wm9712_reg)))
471 return -EIO; 456 return -EIO;
472 457
473 return cache[reg]; 458 return cache[reg];
@@ -481,7 +466,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
481 466
482 soc_ac97_ops.write(codec->ac97, reg, val); 467 soc_ac97_ops.write(codec->ac97, reg, val);
483 reg = reg >> 1; 468 reg = reg >> 1;
484 if (reg <= (ARRAY_SIZE(wm9712_reg))) 469 if (reg < (ARRAY_SIZE(wm9712_reg)))
485 cache[reg] = val; 470 cache[reg] = val;
486 471
487 return 0; 472 return 0;
@@ -493,7 +478,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
493 struct snd_pcm_runtime *runtime = substream->runtime; 478 struct snd_pcm_runtime *runtime = substream->runtime;
494 struct snd_soc_pcm_runtime *rtd = substream->private_data; 479 struct snd_soc_pcm_runtime *rtd = substream->private_data;
495 struct snd_soc_device *socdev = rtd->socdev; 480 struct snd_soc_device *socdev = rtd->socdev;
496 struct snd_soc_codec *codec = socdev->codec; 481 struct snd_soc_codec *codec = socdev->card->codec;
497 int reg; 482 int reg;
498 u16 vra; 483 u16 vra;
499 484
@@ -514,7 +499,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
514 struct snd_pcm_runtime *runtime = substream->runtime; 499 struct snd_pcm_runtime *runtime = substream->runtime;
515 struct snd_soc_pcm_runtime *rtd = substream->private_data; 500 struct snd_soc_pcm_runtime *rtd = substream->private_data;
516 struct snd_soc_device *socdev = rtd->socdev; 501 struct snd_soc_device *socdev = rtd->socdev;
517 struct snd_soc_codec *codec = socdev->codec; 502 struct snd_soc_codec *codec = socdev->card->codec;
518 u16 vra, xsle; 503 u16 vra, xsle;
519 504
520 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 505 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -532,6 +517,14 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
532 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ 517 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
533 SNDRV_PCM_RATE_48000) 518 SNDRV_PCM_RATE_48000)
534 519
520static struct snd_soc_dai_ops wm9712_dai_ops_hifi = {
521 .prepare = ac97_prepare,
522};
523
524static struct snd_soc_dai_ops wm9712_dai_ops_aux = {
525 .prepare = ac97_aux_prepare,
526};
527
535struct snd_soc_dai wm9712_dai[] = { 528struct snd_soc_dai wm9712_dai[] = {
536{ 529{
537 .name = "AC97 HiFi", 530 .name = "AC97 HiFi",
@@ -548,8 +541,7 @@ struct snd_soc_dai wm9712_dai[] = {
548 .channels_max = 2, 541 .channels_max = 2,
549 .rates = WM9712_AC97_RATES, 542 .rates = WM9712_AC97_RATES,
550 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 543 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
551 .ops = { 544 .ops = &wm9712_dai_ops_hifi,
552 .prepare = ac97_prepare,},
553}, 545},
554{ 546{
555 .name = "AC97 Aux", 547 .name = "AC97 Aux",
@@ -559,8 +551,7 @@ struct snd_soc_dai wm9712_dai[] = {
559 .channels_max = 1, 551 .channels_max = 1,
560 .rates = WM9712_AC97_RATES, 552 .rates = WM9712_AC97_RATES,
561 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 553 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
562 .ops = { 554 .ops = &wm9712_dai_ops_aux,
563 .prepare = ac97_aux_prepare,},
564} 555}
565}; 556};
566EXPORT_SYMBOL_GPL(wm9712_dai); 557EXPORT_SYMBOL_GPL(wm9712_dai);
@@ -607,7 +598,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev,
607 pm_message_t state) 598 pm_message_t state)
608{ 599{
609 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 600 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
610 struct snd_soc_codec *codec = socdev->codec; 601 struct snd_soc_codec *codec = socdev->card->codec;
611 602
612 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); 603 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
613 return 0; 604 return 0;
@@ -616,7 +607,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev,
616static int wm9712_soc_resume(struct platform_device *pdev) 607static int wm9712_soc_resume(struct platform_device *pdev)
617{ 608{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 609 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
619 struct snd_soc_codec *codec = socdev->codec; 610 struct snd_soc_codec *codec = socdev->card->codec;
620 int i, ret; 611 int i, ret;
621 u16 *cache = codec->reg_cache; 612 u16 *cache = codec->reg_cache;
622 613
@@ -652,10 +643,11 @@ static int wm9712_soc_probe(struct platform_device *pdev)
652 643
653 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); 644 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
654 645
655 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 646 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
656 if (socdev->codec == NULL) 647 GFP_KERNEL);
648 if (socdev->card->codec == NULL)
657 return -ENOMEM; 649 return -ENOMEM;
658 codec = socdev->codec; 650 codec = socdev->card->codec;
659 mutex_init(&codec->mutex); 651 mutex_init(&codec->mutex);
660 652
661 codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); 653 codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL);
@@ -698,7 +690,8 @@ static int wm9712_soc_probe(struct platform_device *pdev)
698 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); 690 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
699 691
700 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 692 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
701 wm9712_add_controls(codec); 693 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
694 ARRAY_SIZE(wm9712_snd_ac97_controls));
702 wm9712_add_widgets(codec); 695 wm9712_add_widgets(codec);
703 ret = snd_soc_init_card(socdev); 696 ret = snd_soc_init_card(socdev);
704 if (ret < 0) { 697 if (ret < 0) {
@@ -718,15 +711,15 @@ codec_err:
718 kfree(codec->reg_cache); 711 kfree(codec->reg_cache);
719 712
720cache_err: 713cache_err:
721 kfree(socdev->codec); 714 kfree(socdev->card->codec);
722 socdev->codec = NULL; 715 socdev->card->codec = NULL;
723 return ret; 716 return ret;
724} 717}
725 718
726static int wm9712_soc_remove(struct platform_device *pdev) 719static int wm9712_soc_remove(struct platform_device *pdev)
727{ 720{
728 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 721 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
729 struct snd_soc_codec *codec = socdev->codec; 722 struct snd_soc_codec *codec = socdev->card->codec;
730 723
731 if (codec == NULL) 724 if (codec == NULL)
732 return 0; 725 return 0;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index f3ca8aaf0139..523bad077fa0 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -32,7 +32,6 @@
32 32
33struct wm9713_priv { 33struct wm9713_priv {
34 u32 pll_in; /* PLL input frequency */ 34 u32 pll_in; /* PLL input frequency */
35 u32 pll_out; /* PLL output frequency */
36}; 35};
37 36
38static unsigned int ac97_read(struct snd_soc_codec *codec, 37static unsigned int ac97_read(struct snd_soc_codec *codec,
@@ -190,21 +189,6 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
190SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), 189SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
191}; 190};
192 191
193/* add non dapm controls */
194static int wm9713_add_controls(struct snd_soc_codec *codec)
195{
196 int err, i;
197
198 for (i = 0; i < ARRAY_SIZE(wm9713_snd_ac97_controls); i++) {
199 err = snd_ctl_add(codec->card,
200 snd_soc_cnew(&wm9713_snd_ac97_controls[i],
201 codec, NULL));
202 if (err < 0)
203 return err;
204 }
205 return 0;
206}
207
208/* We have to create a fake left and right HP mixers because 192/* We have to create a fake left and right HP mixers because
209 * the codec only has a single control that is shared by both channels. 193 * the codec only has a single control that is shared by both channels.
210 * This makes it impossible to determine the audio path using the current 194 * This makes it impossible to determine the audio path using the current
@@ -636,7 +620,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
636 else { 620 else {
637 reg = reg >> 1; 621 reg = reg >> 1;
638 622
639 if (reg > (ARRAY_SIZE(wm9713_reg))) 623 if (reg >= (ARRAY_SIZE(wm9713_reg)))
640 return -EIO; 624 return -EIO;
641 625
642 return cache[reg]; 626 return cache[reg];
@@ -650,7 +634,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
650 if (reg < 0x7c) 634 if (reg < 0x7c)
651 soc_ac97_ops.write(codec->ac97, reg, val); 635 soc_ac97_ops.write(codec->ac97, reg, val);
652 reg = reg >> 1; 636 reg = reg >> 1;
653 if (reg <= (ARRAY_SIZE(wm9713_reg))) 637 if (reg < (ARRAY_SIZE(wm9713_reg)))
654 cache[reg] = val; 638 cache[reg] = val;
655 639
656 return 0; 640 return 0;
@@ -738,13 +722,13 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
738 struct _pll_div pll_div; 722 struct _pll_div pll_div;
739 723
740 /* turn PLL off ? */ 724 /* turn PLL off ? */
741 if (freq_in == 0 || freq_out == 0) { 725 if (freq_in == 0) {
742 /* disable PLL power and select ext source */ 726 /* disable PLL power and select ext source */
743 reg = ac97_read(codec, AC97_HANDSET_RATE); 727 reg = ac97_read(codec, AC97_HANDSET_RATE);
744 ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080); 728 ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080);
745 reg = ac97_read(codec, AC97_EXTENDED_MID); 729 reg = ac97_read(codec, AC97_EXTENDED_MID);
746 ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200); 730 ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200);
747 wm9713->pll_out = 0; 731 wm9713->pll_in = 0;
748 return 0; 732 return 0;
749 } 733 }
750 734
@@ -788,7 +772,6 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
788 ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff); 772 ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff);
789 reg = ac97_read(codec, AC97_HANDSET_RATE); 773 reg = ac97_read(codec, AC97_HANDSET_RATE);
790 ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f); 774 ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f);
791 wm9713->pll_out = freq_out;
792 wm9713->pll_in = freq_in; 775 wm9713->pll_in = freq_in;
793 776
794 /* wait 10ms AC97 link frames for the link to stabilise */ 777 /* wait 10ms AC97 link frames for the link to stabilise */
@@ -957,13 +940,14 @@ static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
957 struct snd_soc_dai *dai) 940 struct snd_soc_dai *dai)
958{ 941{
959 struct snd_soc_codec *codec = dai->codec; 942 struct snd_soc_codec *codec = dai->codec;
960 u16 status; 943 u16 status, rate;
961 944
962 /* Gracefully shut down the voice interface. */ 945 /* Gracefully shut down the voice interface. */
963 status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000; 946 status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
964 ac97_write(codec, AC97_HANDSET_RATE, 0x0280); 947 rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
948 ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
965 schedule_timeout_interruptible(msecs_to_jiffies(1)); 949 schedule_timeout_interruptible(msecs_to_jiffies(1));
966 ac97_write(codec, AC97_HANDSET_RATE, 0x0F80); 950 ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00);
967 ac97_write(codec, AC97_EXTENDED_MID, status); 951 ac97_write(codec, AC97_EXTENDED_MID, status);
968} 952}
969 953
@@ -1021,6 +1005,27 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
1021 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ 1005 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
1022 SNDRV_PCM_FORMAT_S24_LE) 1006 SNDRV_PCM_FORMAT_S24_LE)
1023 1007
1008static struct snd_soc_dai_ops wm9713_dai_ops_hifi = {
1009 .prepare = ac97_hifi_prepare,
1010 .set_clkdiv = wm9713_set_dai_clkdiv,
1011 .set_pll = wm9713_set_dai_pll,
1012};
1013
1014static struct snd_soc_dai_ops wm9713_dai_ops_aux = {
1015 .prepare = ac97_aux_prepare,
1016 .set_clkdiv = wm9713_set_dai_clkdiv,
1017 .set_pll = wm9713_set_dai_pll,
1018};
1019
1020static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
1021 .hw_params = wm9713_pcm_hw_params,
1022 .shutdown = wm9713_voiceshutdown,
1023 .set_clkdiv = wm9713_set_dai_clkdiv,
1024 .set_pll = wm9713_set_dai_pll,
1025 .set_fmt = wm9713_set_dai_fmt,
1026 .set_tristate = wm9713_set_dai_tristate,
1027};
1028
1024struct snd_soc_dai wm9713_dai[] = { 1029struct snd_soc_dai wm9713_dai[] = {
1025{ 1030{
1026 .name = "AC97 HiFi", 1031 .name = "AC97 HiFi",
@@ -1037,10 +1042,7 @@ struct snd_soc_dai wm9713_dai[] = {
1037 .channels_max = 2, 1042 .channels_max = 2,
1038 .rates = WM9713_RATES, 1043 .rates = WM9713_RATES,
1039 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1044 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
1040 .ops = { 1045 .ops = &wm9713_dai_ops_hifi,
1041 .prepare = ac97_hifi_prepare,
1042 .set_clkdiv = wm9713_set_dai_clkdiv,
1043 .set_pll = wm9713_set_dai_pll,},
1044 }, 1046 },
1045 { 1047 {
1046 .name = "AC97 Aux", 1048 .name = "AC97 Aux",
@@ -1050,10 +1052,7 @@ struct snd_soc_dai wm9713_dai[] = {
1050 .channels_max = 1, 1052 .channels_max = 1,
1051 .rates = WM9713_RATES, 1053 .rates = WM9713_RATES,
1052 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1054 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
1053 .ops = { 1055 .ops = &wm9713_dai_ops_aux,
1054 .prepare = ac97_aux_prepare,
1055 .set_clkdiv = wm9713_set_dai_clkdiv,
1056 .set_pll = wm9713_set_dai_pll,},
1057 }, 1056 },
1058 { 1057 {
1059 .name = "WM9713 Voice", 1058 .name = "WM9713 Voice",
@@ -1069,14 +1068,7 @@ struct snd_soc_dai wm9713_dai[] = {
1069 .channels_max = 2, 1068 .channels_max = 2,
1070 .rates = WM9713_PCM_RATES, 1069 .rates = WM9713_PCM_RATES,
1071 .formats = WM9713_PCM_FORMATS,}, 1070 .formats = WM9713_PCM_FORMATS,},
1072 .ops = { 1071 .ops = &wm9713_dai_ops_voice,
1073 .hw_params = wm9713_pcm_hw_params,
1074 .shutdown = wm9713_voiceshutdown,
1075 .set_clkdiv = wm9713_set_dai_clkdiv,
1076 .set_pll = wm9713_set_dai_pll,
1077 .set_fmt = wm9713_set_dai_fmt,
1078 .set_tristate = wm9713_set_dai_tristate,
1079 },
1080 }, 1072 },
1081}; 1073};
1082EXPORT_SYMBOL_GPL(wm9713_dai); 1074EXPORT_SYMBOL_GPL(wm9713_dai);
@@ -1132,7 +1124,7 @@ static int wm9713_soc_suspend(struct platform_device *pdev,
1132 pm_message_t state) 1124 pm_message_t state)
1133{ 1125{
1134 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1126 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1135 struct snd_soc_codec *codec = socdev->codec; 1127 struct snd_soc_codec *codec = socdev->card->codec;
1136 u16 reg; 1128 u16 reg;
1137 1129
1138 /* Disable everything except touchpanel - that will be handled 1130 /* Disable everything except touchpanel - that will be handled
@@ -1150,7 +1142,7 @@ static int wm9713_soc_suspend(struct platform_device *pdev,
1150static int wm9713_soc_resume(struct platform_device *pdev) 1142static int wm9713_soc_resume(struct platform_device *pdev)
1151{ 1143{
1152 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1144 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1153 struct snd_soc_codec *codec = socdev->codec; 1145 struct snd_soc_codec *codec = socdev->card->codec;
1154 struct wm9713_priv *wm9713 = codec->private_data; 1146 struct wm9713_priv *wm9713 = codec->private_data;
1155 int i, ret; 1147 int i, ret;
1156 u16 *cache = codec->reg_cache; 1148 u16 *cache = codec->reg_cache;
@@ -1164,8 +1156,8 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1164 wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1156 wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1165 1157
1166 /* do we need to re-start the PLL ? */ 1158 /* do we need to re-start the PLL ? */
1167 if (wm9713->pll_out) 1159 if (wm9713->pll_in)
1168 wm9713_set_pll(codec, 0, wm9713->pll_in, wm9713->pll_out); 1160 wm9713_set_pll(codec, 0, wm9713->pll_in, 0);
1169 1161
1170 /* only synchronise the codec if warm reset failed */ 1162 /* only synchronise the codec if warm reset failed */
1171 if (ret == 0) { 1163 if (ret == 0) {
@@ -1191,10 +1183,11 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1191 1183
1192 printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION); 1184 printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION);
1193 1185
1194 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1186 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
1195 if (socdev->codec == NULL) 1187 GFP_KERNEL);
1188 if (socdev->card->codec == NULL)
1196 return -ENOMEM; 1189 return -ENOMEM;
1197 codec = socdev->codec; 1190 codec = socdev->card->codec;
1198 mutex_init(&codec->mutex); 1191 mutex_init(&codec->mutex);
1199 1192
1200 codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL); 1193 codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL);
@@ -1245,7 +1238,8 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1245 reg = ac97_read(codec, AC97_CD) & 0x7fff; 1238 reg = ac97_read(codec, AC97_CD) & 0x7fff;
1246 ac97_write(codec, AC97_CD, reg); 1239 ac97_write(codec, AC97_CD, reg);
1247 1240
1248 wm9713_add_controls(codec); 1241 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1242 ARRAY_SIZE(wm9713_snd_ac97_controls));
1249 wm9713_add_widgets(codec); 1243 wm9713_add_widgets(codec);
1250 ret = snd_soc_init_card(socdev); 1244 ret = snd_soc_init_card(socdev);
1251 if (ret < 0) 1245 if (ret < 0)
@@ -1265,15 +1259,15 @@ priv_err:
1265 kfree(codec->reg_cache); 1259 kfree(codec->reg_cache);
1266 1260
1267cache_err: 1261cache_err:
1268 kfree(socdev->codec); 1262 kfree(socdev->card->codec);
1269 socdev->codec = NULL; 1263 socdev->card->codec = NULL;
1270 return ret; 1264 return ret;
1271} 1265}
1272 1266
1273static int wm9713_soc_remove(struct platform_device *pdev) 1267static int wm9713_soc_remove(struct platform_device *pdev)
1274{ 1268{
1275 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1269 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1276 struct snd_soc_codec *codec = socdev->codec; 1270 struct snd_soc_codec *codec = socdev->card->codec;
1277 1271
1278 if (codec == NULL) 1272 if (codec == NULL)
1279 return 0; 1273 return 0;
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index b502741692d6..bd7392c9657e 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -20,7 +20,7 @@ config SND_DAVINCI_SOC_EVM
20 20
21config SND_DAVINCI_SOC_SFFSDR 21config SND_DAVINCI_SOC_SFFSDR
22 tristate "SoC Audio support for SFFSDR" 22 tristate "SoC Audio support for SFFSDR"
23 depends on SND_DAVINCI_SOC && MACH_DAVINCI_SFFSDR 23 depends on SND_DAVINCI_SOC && MACH_SFFSDR
24 select SND_DAVINCI_SOC_I2S 24 select SND_DAVINCI_SOC_I2S
25 select SND_SOC_PCM3008 25 select SND_SOC_PCM3008
26 select SFFSDR_FPGA 26 select SFFSDR_FPGA
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 54851f318568..9b90b347007c 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -186,7 +186,8 @@ static int __init evm_init(void)
186 186
187 platform_set_drvdata(evm_snd_device, &evm_snd_devdata); 187 platform_set_drvdata(evm_snd_device, &evm_snd_devdata);
188 evm_snd_devdata.dev = &evm_snd_device->dev; 188 evm_snd_devdata.dev = &evm_snd_device->dev;
189 evm_snd_device->dev.platform_data = &evm_snd_data; 189 platform_device_add_data(evm_snd_device, &evm_snd_data,
190 sizeof(evm_snd_data));
190 191
191 ret = platform_device_add_resources(evm_snd_device, evm_snd_resources, 192 ret = platform_device_add_resources(evm_snd_device, evm_snd_resources,
192 ARRAY_SIZE(evm_snd_resources)); 193 ARRAY_SIZE(evm_snd_resources));
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 0fee779e3c76..ffdb9439d3d8 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -499,6 +499,13 @@ static void davinci_i2s_remove(struct platform_device *pdev,
499 499
500#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 500#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
501 501
502static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
503 .startup = davinci_i2s_startup,
504 .trigger = davinci_i2s_trigger,
505 .hw_params = davinci_i2s_hw_params,
506 .set_fmt = davinci_i2s_set_dai_fmt,
507};
508
502struct snd_soc_dai davinci_i2s_dai = { 509struct snd_soc_dai davinci_i2s_dai = {
503 .name = "davinci-i2s", 510 .name = "davinci-i2s",
504 .id = 0, 511 .id = 0,
@@ -514,12 +521,7 @@ struct snd_soc_dai davinci_i2s_dai = {
514 .channels_max = 2, 521 .channels_max = 2,
515 .rates = DAVINCI_I2S_RATES, 522 .rates = DAVINCI_I2S_RATES,
516 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 523 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
517 .ops = { 524 .ops = &davinci_i2s_dai_ops,
518 .startup = davinci_i2s_startup,
519 .trigger = davinci_i2s_trigger,
520 .hw_params = davinci_i2s_hw_params,
521 .set_fmt = davinci_i2s_set_dai_fmt,
522 },
523}; 525};
524EXPORT_SYMBOL_GPL(davinci_i2s_dai); 526EXPORT_SYMBOL_GPL(davinci_i2s_dai);
525 527
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 366049d8578c..7af3b5b3a53d 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -286,7 +286,7 @@ static int davinci_pcm_mmap(struct snd_pcm_substream *substream,
286 runtime->dma_bytes); 286 runtime->dma_bytes);
287} 287}
288 288
289struct snd_pcm_ops davinci_pcm_ops = { 289static struct snd_pcm_ops davinci_pcm_ops = {
290 .open = davinci_pcm_open, 290 .open = davinci_pcm_open,
291 .close = davinci_pcm_close, 291 .close = davinci_pcm_close,
292 .ioctl = snd_pcm_lib_ioctl, 292 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 4935d1bcbd8d..40eccfe9e358 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -25,7 +25,9 @@
25 25
26#include <asm/dma.h> 26#include <asm/dma.h>
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28#ifdef CONFIG_SFFSDR_FPGA
28#include <asm/plat-sffsdr/sffsdr-fpga.h> 29#include <asm/plat-sffsdr/sffsdr-fpga.h>
30#endif
29 31
30#include <mach/mcbsp.h> 32#include <mach/mcbsp.h>
31#include <mach/edma.h> 33#include <mach/edma.h>
@@ -34,31 +36,45 @@
34#include "davinci-pcm.h" 36#include "davinci-pcm.h"
35#include "davinci-i2s.h" 37#include "davinci-i2s.h"
36 38
39/*
40 * CLKX and CLKR are the inputs for the Sample Rate Generator.
41 * FSX and FSR are outputs, driven by the sample Rate Generator.
42 */
43#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
44 SND_SOC_DAIFMT_CBM_CFS | \
45 SND_SOC_DAIFMT_IB_NF)
46
37static int sffsdr_hw_params(struct snd_pcm_substream *substream, 47static int sffsdr_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params, 48 struct snd_pcm_hw_params *params)
39 struct snd_soc_dai *dai)
40{ 49{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
43 int fs; 52 int fs;
44 int ret = 0; 53 int ret = 0;
45 54
46 /* Set cpu DAI configuration:
47 * CLKX and CLKR are the inputs for the Sample Rate Generator.
48 * FSX and FSR are outputs, driven by the sample Rate Generator. */
49 ret = snd_soc_dai_set_fmt(cpu_dai,
50 SND_SOC_DAIFMT_RIGHT_J |
51 SND_SOC_DAIFMT_CBM_CFS |
52 SND_SOC_DAIFMT_IB_NF);
53 if (ret < 0)
54 return ret;
55
56 /* Fsref can be 32000, 44100 or 48000. */ 55 /* Fsref can be 32000, 44100 or 48000. */
57 fs = params_rate(params); 56 fs = params_rate(params);
58 57
58#ifndef CONFIG_SFFSDR_FPGA
59 /* Without the FPGA module, the Fs is fixed at 44100 Hz */
60 if (fs != 44100) {
61 pr_debug("warning: only 44.1 kHz is supported without SFFSDR FPGA module\n");
62 return -EINVAL;
63 }
64#endif
65
66 /* set cpu DAI configuration */
67 ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
68 if (ret < 0)
69 return ret;
70
59 pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs); 71 pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs);
60 72
73#ifndef CONFIG_SFFSDR_FPGA
74 return 0;
75#else
61 return sffsdr_fpga_set_codec_fs(fs); 76 return sffsdr_fpga_set_codec_fs(fs);
77#endif
62} 78}
63 79
64static struct snd_soc_ops sffsdr_ops = { 80static struct snd_soc_ops sffsdr_ops = {
@@ -127,7 +143,8 @@ static int __init sffsdr_init(void)
127 143
128 platform_set_drvdata(sffsdr_snd_device, &sffsdr_snd_devdata); 144 platform_set_drvdata(sffsdr_snd_device, &sffsdr_snd_devdata);
129 sffsdr_snd_devdata.dev = &sffsdr_snd_device->dev; 145 sffsdr_snd_devdata.dev = &sffsdr_snd_device->dev;
130 sffsdr_snd_device->dev.platform_data = &sffsdr_snd_data; 146 platform_device_add_data(sffsdr_snd_device, &sffsdr_snd_data,
147 sizeof(sffsdr_snd_data));
131 148
132 ret = platform_device_add_resources(sffsdr_snd_device, 149 ret = platform_device_add_resources(sffsdr_snd_device,
133 sffsdr_snd_resources, 150 sffsdr_snd_resources,
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 95c12b26fe37..9fc908283371 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,17 +1,18 @@
1config SND_SOC_OF_SIMPLE 1config SND_SOC_OF_SIMPLE
2 tristate 2 tristate
3 3
4# ASoC platform support for the Freescale MPC8610 SOC. This compiles drivers
5# for the SSI and the Elo DMA controller. You will still need to select
6# a platform driver and a codec driver.
4config SND_SOC_MPC8610 7config SND_SOC_MPC8610
5 bool "ALSA SoC support for the MPC8610 SOC" 8 tristate
6 depends on MPC8610_HPCD 9 depends on MPC8610
7 default y if MPC8610
8 help
9 Say Y if you want to add support for codecs attached to the SSI
10 device on an MPC8610.
11 10
12config SND_SOC_MPC8610_HPCD 11config SND_SOC_MPC8610_HPCD
13 bool "ALSA SoC support for the Freescale MPC8610 HPCD board" 12 tristate "ALSA SoC support for the Freescale MPC8610 HPCD board"
14 depends on SND_SOC_MPC8610 13 # I2C is necessary for the CS4270 driver
14 depends on MPC8610_HPCD && I2C
15 select SND_SOC_MPC8610
15 select SND_SOC_CS4270 16 select SND_SOC_CS4270
16 select SND_SOC_CS4270_VD33_ERRATA 17 select SND_SOC_CS4270_VD33_ERRATA
17 default y if MPC8610_HPCD 18 default y if MPC8610_HPCD
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 035da4afec34..f85134c86387 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -2,10 +2,13 @@
2obj-$(CONFIG_SND_SOC_OF_SIMPLE) += soc-of-simple.o 2obj-$(CONFIG_SND_SOC_OF_SIMPLE) += soc-of-simple.o
3 3
4# MPC8610 HPCD Machine Support 4# MPC8610 HPCD Machine Support
5obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += mpc8610_hpcd.o 5snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o
6obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o
6 7
7# MPC8610 Platform Support 8# MPC8610 Platform Support
8obj-$(CONFIG_SND_SOC_MPC8610) += fsl_ssi.o fsl_dma.o 9snd-soc-fsl-ssi-objs := fsl_ssi.o
10snd-soc-fsl-dma-objs := fsl_dma.o
11obj-$(CONFIG_SND_SOC_MPC8610) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o
9 12
10obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o 13obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o
11 14
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 64993eda5679..b3eb8570cd7b 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -142,7 +142,8 @@ static const struct snd_pcm_hardware fsl_dma_hardware = {
142 .info = SNDRV_PCM_INFO_INTERLEAVED | 142 .info = SNDRV_PCM_INFO_INTERLEAVED |
143 SNDRV_PCM_INFO_MMAP | 143 SNDRV_PCM_INFO_MMAP |
144 SNDRV_PCM_INFO_MMAP_VALID | 144 SNDRV_PCM_INFO_MMAP_VALID |
145 SNDRV_PCM_INFO_JOINT_DUPLEX, 145 SNDRV_PCM_INFO_JOINT_DUPLEX |
146 SNDRV_PCM_INFO_PAUSE,
146 .formats = FSLDMA_PCM_FORMATS, 147 .formats = FSLDMA_PCM_FORMATS,
147 .rates = FSLDMA_PCM_RATES, 148 .rates = FSLDMA_PCM_RATES,
148 .rate_min = 5512, 149 .rate_min = 5512,
@@ -464,11 +465,7 @@ static int fsl_dma_open(struct snd_pcm_substream *substream)
464 sizeof(struct fsl_dma_link_descriptor); 465 sizeof(struct fsl_dma_link_descriptor);
465 466
466 for (i = 0; i < NUM_DMA_LINKS; i++) { 467 for (i = 0; i < NUM_DMA_LINKS; i++) {
467 struct fsl_dma_link_descriptor *link = &dma_private->link[i]; 468 dma_private->link[i].next = cpu_to_be64(temp_link);
468
469 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
470 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
471 link->next = cpu_to_be64(temp_link);
472 469
473 temp_link += sizeof(struct fsl_dma_link_descriptor); 470 temp_link += sizeof(struct fsl_dma_link_descriptor);
474 } 471 }
@@ -525,79 +522,9 @@ static int fsl_dma_open(struct snd_pcm_substream *substream)
525 * This function obtains hardware parameters about the opened stream and 522 * This function obtains hardware parameters about the opened stream and
526 * programs the DMA controller accordingly. 523 * programs the DMA controller accordingly.
527 * 524 *
528 * Note that due to a quirk of the SSI's STX register, the target address 525 * One drawback of big-endian is that when copying integers of different
529 * for the DMA operations depends on the sample size. So we don't program 526 * sizes to a fixed-sized register, the address to which the integer must be
530 * the dest_addr (for playback -- source_addr for capture) fields in the 527 * copied is dependent on the size of the integer.
531 * link descriptors here. We do that in fsl_dma_prepare()
532 */
533static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
534 struct snd_pcm_hw_params *hw_params)
535{
536 struct snd_pcm_runtime *runtime = substream->runtime;
537 struct fsl_dma_private *dma_private = runtime->private_data;
538
539 dma_addr_t temp_addr; /* Pointer to next period */
540
541 unsigned int i;
542
543 /* Get all the parameters we need */
544 size_t buffer_size = params_buffer_bytes(hw_params);
545 size_t period_size = params_period_bytes(hw_params);
546
547 /* Initialize our DMA tracking variables */
548 dma_private->period_size = period_size;
549 dma_private->num_periods = params_periods(hw_params);
550 dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size;
551 dma_private->dma_buf_next = dma_private->dma_buf_phys +
552 (NUM_DMA_LINKS * period_size);
553 if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
554 dma_private->dma_buf_next = dma_private->dma_buf_phys;
555
556 /*
557 * The actual address in STX0 (destination for playback, source for
558 * capture) is based on the sample size, but we don't know the sample
559 * size in this function, so we'll have to adjust that later. See
560 * comments in fsl_dma_prepare().
561 *
562 * The DMA controller does not have a cache, so the CPU does not
563 * need to tell it to flush its cache. However, the DMA
564 * controller does need to tell the CPU to flush its cache.
565 * That's what the SNOOP bit does.
566 *
567 * Also, even though the DMA controller supports 36-bit addressing, for
568 * simplicity we currently support only 32-bit addresses for the audio
569 * buffer itself.
570 */
571 temp_addr = substream->dma_buffer.addr;
572
573 for (i = 0; i < NUM_DMA_LINKS; i++) {
574 struct fsl_dma_link_descriptor *link = &dma_private->link[i];
575
576 link->count = cpu_to_be32(period_size);
577
578 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
579 link->source_addr = cpu_to_be32(temp_addr);
580 else
581 link->dest_addr = cpu_to_be32(temp_addr);
582
583 temp_addr += period_size;
584 }
585
586 return 0;
587}
588
589/**
590 * fsl_dma_prepare - prepare the DMA registers for playback.
591 *
592 * This function is called after the specifics of the audio data are known,
593 * i.e. snd_pcm_runtime is initialized.
594 *
595 * In this function, we finish programming the registers of the DMA
596 * controller that are dependent on the sample size.
597 *
598 * One of the drawbacks with big-endian is that when copying integers of
599 * different sizes to a fixed-sized register, the address to which the
600 * integer must be copied is dependent on the size of the integer.
601 * 528 *
602 * For example, if P is the address of a 32-bit register, and X is a 32-bit 529 * For example, if P is the address of a 32-bit register, and X is a 32-bit
603 * integer, then X should be copied to address P. However, if X is a 16-bit 530 * integer, then X should be copied to address P. However, if X is a 16-bit
@@ -613,22 +540,58 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
613 * and 8 bytes at a time). So we do not support packed 24-bit samples. 540 * and 8 bytes at a time). So we do not support packed 24-bit samples.
614 * 24-bit data must be padded to 32 bits. 541 * 24-bit data must be padded to 32 bits.
615 */ 542 */
616static int fsl_dma_prepare(struct snd_pcm_substream *substream) 543static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
544 struct snd_pcm_hw_params *hw_params)
617{ 545{
618 struct snd_pcm_runtime *runtime = substream->runtime; 546 struct snd_pcm_runtime *runtime = substream->runtime;
619 struct fsl_dma_private *dma_private = runtime->private_data; 547 struct fsl_dma_private *dma_private = runtime->private_data;
548
549 /* Number of bits per sample */
550 unsigned int sample_size =
551 snd_pcm_format_physical_width(params_format(hw_params));
552
553 /* Number of bytes per frame */
554 unsigned int frame_size = 2 * (sample_size / 8);
555
556 /* Bus address of SSI STX register */
557 dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys;
558
559 /* Size of the DMA buffer, in bytes */
560 size_t buffer_size = params_buffer_bytes(hw_params);
561
562 /* Number of bytes per period */
563 size_t period_size = params_period_bytes(hw_params);
564
565 /* Pointer to next period */
566 dma_addr_t temp_addr = substream->dma_buffer.addr;
567
568 /* Pointer to DMA controller */
620 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; 569 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
621 u32 mr; 570
571 u32 mr; /* DMA Mode Register */
572
622 unsigned int i; 573 unsigned int i;
623 dma_addr_t ssi_sxx_phys; /* Bus address of SSI STX register */
624 unsigned int frame_size; /* Number of bytes per frame */
625 574
626 ssi_sxx_phys = dma_private->ssi_sxx_phys; 575 /* Initialize our DMA tracking variables */
576 dma_private->period_size = period_size;
577 dma_private->num_periods = params_periods(hw_params);
578 dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size;
579 dma_private->dma_buf_next = dma_private->dma_buf_phys +
580 (NUM_DMA_LINKS * period_size);
581
582 if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
583 /* This happens if the number of periods == NUM_DMA_LINKS */
584 dma_private->dma_buf_next = dma_private->dma_buf_phys;
627 585
628 mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK | 586 mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK |
629 CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK); 587 CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK);
630 588
631 switch (runtime->sample_bits) { 589 /* Due to a quirk of the SSI's STX register, the target address
590 * for the DMA operations depends on the sample size. So we calculate
591 * that offset here. While we're at it, also tell the DMA controller
592 * how much data to transfer per sample.
593 */
594 switch (sample_size) {
632 case 8: 595 case 8:
633 mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1; 596 mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1;
634 ssi_sxx_phys += 3; 597 ssi_sxx_phys += 3;
@@ -641,12 +604,12 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream)
641 mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4; 604 mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4;
642 break; 605 break;
643 default: 606 default:
607 /* We should never get here */
644 dev_err(substream->pcm->card->dev, 608 dev_err(substream->pcm->card->dev,
645 "unsupported sample size %u\n", runtime->sample_bits); 609 "unsupported sample size %u\n", sample_size);
646 return -EINVAL; 610 return -EINVAL;
647 } 611 }
648 612
649 frame_size = runtime->frame_bits / 8;
650 /* 613 /*
651 * BWC should always be a multiple of the frame size. BWC determines 614 * BWC should always be a multiple of the frame size. BWC determines
652 * how many bytes are sent/received before the DMA controller checks the 615 * how many bytes are sent/received before the DMA controller checks the
@@ -655,7 +618,6 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream)
655 * capture, the receive FIFO is triggered when it contains one frame, so 618 * capture, the receive FIFO is triggered when it contains one frame, so
656 * we want to receive one frame at a time. 619 * we want to receive one frame at a time.
657 */ 620 */
658
659 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 621 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
660 mr |= CCSR_DMA_MR_BWC(2 * frame_size); 622 mr |= CCSR_DMA_MR_BWC(2 * frame_size);
661 else 623 else
@@ -663,16 +625,48 @@ static int fsl_dma_prepare(struct snd_pcm_substream *substream)
663 625
664 out_be32(&dma_channel->mr, mr); 626 out_be32(&dma_channel->mr, mr);
665 627
666 /*
667 * Program the address of the DMA transfer to/from the SSI.
668 */
669 for (i = 0; i < NUM_DMA_LINKS; i++) { 628 for (i = 0; i < NUM_DMA_LINKS; i++) {
670 struct fsl_dma_link_descriptor *link = &dma_private->link[i]; 629 struct fsl_dma_link_descriptor *link = &dma_private->link[i];
671 630
672 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 631 link->count = cpu_to_be32(period_size);
632
633 /* Even though the DMA controller supports 36-bit addressing,
634 * for simplicity we allow only 32-bit addresses for the audio
635 * buffer itself. This was enforced in fsl_dma_new() with the
636 * DMA mask.
637 *
638 * The snoop bit tells the DMA controller whether it should tell
639 * the ECM to snoop during a read or write to an address. For
640 * audio, we use DMA to transfer data between memory and an I/O
641 * device (the SSI's STX0 or SRX0 register). Snooping is only
642 * needed if there is a cache, so we need to snoop memory
643 * addresses only. For playback, that means we snoop the source
644 * but not the destination. For capture, we snoop the
645 * destination but not the source.
646 *
647 * Note that failing to snoop properly is unlikely to cause
648 * cache incoherency if the period size is larger than the
649 * size of L1 cache. This is because filling in one period will
650 * flush out the data for the previous period. So if you
651 * increased period_bytes_min to a large enough size, you might
652 * get more performance by not snooping, and you'll still be
653 * okay.
654 */
655 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
656 link->source_addr = cpu_to_be32(temp_addr);
657 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
658
673 link->dest_addr = cpu_to_be32(ssi_sxx_phys); 659 link->dest_addr = cpu_to_be32(ssi_sxx_phys);
674 else 660 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP);
661 } else {
675 link->source_addr = cpu_to_be32(ssi_sxx_phys); 662 link->source_addr = cpu_to_be32(ssi_sxx_phys);
663 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP);
664
665 link->dest_addr = cpu_to_be32(temp_addr);
666 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
667 }
668
669 temp_addr += period_size;
676 } 670 }
677 671
678 return 0; 672 return 0;
@@ -808,7 +802,6 @@ static struct snd_pcm_ops fsl_dma_ops = {
808 .ioctl = snd_pcm_lib_ioctl, 802 .ioctl = snd_pcm_lib_ioctl,
809 .hw_params = fsl_dma_hw_params, 803 .hw_params = fsl_dma_hw_params,
810 .hw_free = fsl_dma_hw_free, 804 .hw_free = fsl_dma_hw_free,
811 .prepare = fsl_dma_prepare,
812 .pointer = fsl_dma_pointer, 805 .pointer = fsl_dma_pointer,
813}; 806};
814 807
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index c6d6eb71dc1d..169bca295b78 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -72,6 +72,7 @@
72 * @dev: struct device pointer 72 * @dev: struct device pointer
73 * @playback: the number of playback streams opened 73 * @playback: the number of playback streams opened
74 * @capture: the number of capture streams opened 74 * @capture: the number of capture streams opened
75 * @asynchronous: 0=synchronous mode, 1=asynchronous mode
75 * @cpu_dai: the CPU DAI for this device 76 * @cpu_dai: the CPU DAI for this device
76 * @dev_attr: the sysfs device attribute structure 77 * @dev_attr: the sysfs device attribute structure
77 * @stats: SSI statistics 78 * @stats: SSI statistics
@@ -86,6 +87,7 @@ struct fsl_ssi_private {
86 struct device *dev; 87 struct device *dev;
87 unsigned int playback; 88 unsigned int playback;
88 unsigned int capture; 89 unsigned int capture;
90 int asynchronous;
89 struct snd_soc_dai cpu_dai; 91 struct snd_soc_dai cpu_dai;
90 struct device_attribute dev_attr; 92 struct device_attribute dev_attr;
91 93
@@ -301,9 +303,10 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
301 * 303 *
302 * FIXME: Little-endian samples require a different shift dir 304 * FIXME: Little-endian samples require a different shift dir
303 */ 305 */
304 clrsetbits_be32(&ssi->scr, CCSR_SSI_SCR_I2S_MODE_MASK, 306 clrsetbits_be32(&ssi->scr,
305 CCSR_SSI_SCR_TFR_CLK_DIS | 307 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
306 CCSR_SSI_SCR_I2S_MODE_SLAVE | CCSR_SSI_SCR_SYN); 308 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
309 | (ssi_private->asynchronous ? 0 : CCSR_SSI_SCR_SYN));
307 310
308 out_be32(&ssi->stcr, 311 out_be32(&ssi->stcr,
309 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 312 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
@@ -382,10 +385,15 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
382 SNDRV_PCM_HW_PARAM_RATE, 385 SNDRV_PCM_HW_PARAM_RATE,
383 first_runtime->rate, first_runtime->rate); 386 first_runtime->rate, first_runtime->rate);
384 387
385 snd_pcm_hw_constraint_minmax(substream->runtime, 388 /* If we're in synchronous mode, then we need to constrain
386 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 389 * the sample size as well. We don't support independent sample
387 first_runtime->sample_bits, 390 * rates in asynchronous mode.
388 first_runtime->sample_bits); 391 */
392 if (!ssi_private->asynchronous)
393 snd_pcm_hw_constraint_minmax(substream->runtime,
394 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
395 first_runtime->sample_bits,
396 first_runtime->sample_bits);
389 397
390 ssi_private->second_stream = substream; 398 ssi_private->second_stream = substream;
391 } 399 }
@@ -400,7 +408,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
400} 408}
401 409
402/** 410/**
403 * fsl_ssi_prepare: prepare the SSI. 411 * fsl_ssi_hw_params - program the sample size
404 * 412 *
405 * Most of the SSI registers have been programmed in the startup function, 413 * Most of the SSI registers have been programmed in the startup function,
406 * but the word length must be programmed here. Unfortunately, programming 414 * but the word length must be programmed here. Unfortunately, programming
@@ -412,23 +420,27 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
412 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the 420 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
413 * clock master. 421 * clock master.
414 */ 422 */
415static int fsl_ssi_prepare(struct snd_pcm_substream *substream, 423static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
416 struct snd_soc_dai *dai) 424 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
417{ 425{
418 struct snd_pcm_runtime *runtime = substream->runtime; 426 struct fsl_ssi_private *ssi_private = cpu_dai->private_data;
419 struct snd_soc_pcm_runtime *rtd = substream->private_data;
420 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
421
422 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
423 427
424 if (substream == ssi_private->first_stream) { 428 if (substream == ssi_private->first_stream) {
425 u32 wl; 429 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
430 unsigned int sample_size =
431 snd_pcm_format_width(params_format(hw_params));
432 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
426 433
427 /* The SSI should always be disabled at this points (SSIEN=0) */ 434 /* The SSI should always be disabled at this points (SSIEN=0) */
428 wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format));
429 435
430 /* In synchronous mode, the SSI uses STCCR for capture */ 436 /* In synchronous mode, the SSI uses STCCR for capture */
431 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); 437 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
438 !ssi_private->asynchronous)
439 clrsetbits_be32(&ssi->stccr,
440 CCSR_SSI_SxCCR_WL_MASK, wl);
441 else
442 clrsetbits_be32(&ssi->srccr,
443 CCSR_SSI_SxCCR_WL_MASK, wl);
432 } 444 }
433 445
434 return 0; 446 return 0;
@@ -452,28 +464,33 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
452 464
453 switch (cmd) { 465 switch (cmd) {
454 case SNDRV_PCM_TRIGGER_START: 466 case SNDRV_PCM_TRIGGER_START:
455 case SNDRV_PCM_TRIGGER_RESUME: 467 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
456 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 468 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
457 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 469 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
458 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
459 setbits32(&ssi->scr, 470 setbits32(&ssi->scr,
460 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); 471 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
461 } else { 472 } else {
462 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 473 long timeout = jiffies + 10;
474
463 setbits32(&ssi->scr, 475 setbits32(&ssi->scr,
464 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); 476 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
465 477
466 /* 478 /* Wait until the SSI has filled its FIFO. Without this
467 * I think we need this delay to allow time for the SSI 479 * delay, ALSA complains about overruns. When the FIFO
468 * to put data into its FIFO. Without it, ALSA starts 480 * is full, the DMA controller initiates its first
469 * to complain about overruns. 481 * transfer. Until then, however, the DMA's DAR
482 * register is zero, which translates to an
483 * out-of-bounds pointer. This makes ALSA think an
484 * overrun has occurred.
470 */ 485 */
471 mdelay(1); 486 while (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0) &&
487 (jiffies < timeout));
488 if (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0))
489 return -EIO;
472 } 490 }
473 break; 491 break;
474 492
475 case SNDRV_PCM_TRIGGER_STOP: 493 case SNDRV_PCM_TRIGGER_STOP:
476 case SNDRV_PCM_TRIGGER_SUSPEND:
477 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 494 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
478 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 495 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
479 clrbits32(&ssi->scr, CCSR_SSI_SCR_TE); 496 clrbits32(&ssi->scr, CCSR_SSI_SCR_TE);
@@ -563,6 +580,15 @@ static int fsl_ssi_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
563/** 580/**
564 * fsl_ssi_dai_template: template CPU DAI for the SSI 581 * fsl_ssi_dai_template: template CPU DAI for the SSI
565 */ 582 */
583static struct snd_soc_dai_ops fsl_ssi_dai_ops = {
584 .startup = fsl_ssi_startup,
585 .hw_params = fsl_ssi_hw_params,
586 .shutdown = fsl_ssi_shutdown,
587 .trigger = fsl_ssi_trigger,
588 .set_sysclk = fsl_ssi_set_sysclk,
589 .set_fmt = fsl_ssi_set_fmt,
590};
591
566static struct snd_soc_dai fsl_ssi_dai_template = { 592static struct snd_soc_dai fsl_ssi_dai_template = {
567 .playback = { 593 .playback = {
568 /* The SSI does not support monaural audio. */ 594 /* The SSI does not support monaural audio. */
@@ -577,14 +603,7 @@ static struct snd_soc_dai fsl_ssi_dai_template = {
577 .rates = FSLSSI_I2S_RATES, 603 .rates = FSLSSI_I2S_RATES,
578 .formats = FSLSSI_I2S_FORMATS, 604 .formats = FSLSSI_I2S_FORMATS,
579 }, 605 },
580 .ops = { 606 .ops = &fsl_ssi_dai_ops,
581 .startup = fsl_ssi_startup,
582 .prepare = fsl_ssi_prepare,
583 .shutdown = fsl_ssi_shutdown,
584 .trigger = fsl_ssi_trigger,
585 .set_sysclk = fsl_ssi_set_sysclk,
586 .set_fmt = fsl_ssi_set_fmt,
587 },
588}; 607};
589 608
590/** 609/**
@@ -654,6 +673,7 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
654 ssi_private->ssi_phys = ssi_info->ssi_phys; 673 ssi_private->ssi_phys = ssi_info->ssi_phys;
655 ssi_private->irq = ssi_info->irq; 674 ssi_private->irq = ssi_info->irq;
656 ssi_private->dev = ssi_info->dev; 675 ssi_private->dev = ssi_info->dev;
676 ssi_private->asynchronous = ssi_info->asynchronous;
657 677
658 ssi_private->dev->driver_data = fsl_ssi_dai; 678 ssi_private->dev->driver_data = fsl_ssi_dai;
659 679
@@ -704,6 +724,14 @@ void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai)
704} 724}
705EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai); 725EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai);
706 726
727static int __init fsl_ssi_init(void)
728{
729 printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n");
730
731 return 0;
732}
733module_init(fsl_ssi_init);
734
707MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 735MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
708MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver"); 736MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
709MODULE_LICENSE("GPL"); 737MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index 83b44d700e33..eade01feaab6 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -208,6 +208,7 @@ struct ccsr_ssi {
208 * ssi_phys: physical address of the SSI registers 208 * ssi_phys: physical address of the SSI registers
209 * irq: IRQ of this SSI 209 * irq: IRQ of this SSI
210 * dev: struct device, used to create the sysfs statistics file 210 * dev: struct device, used to create the sysfs statistics file
211 * asynchronous: 0=synchronous mode, 1=asynchronous mode
211*/ 212*/
212struct fsl_ssi_info { 213struct fsl_ssi_info {
213 unsigned int id; 214 unsigned int id;
@@ -215,6 +216,7 @@ struct fsl_ssi_info {
215 dma_addr_t ssi_phys; 216 dma_addr_t ssi_phys;
216 unsigned int irq; 217 unsigned int irq;
217 struct device *dev; 218 struct device *dev;
219 int asynchronous;
218}; 220};
219 221
220struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info); 222struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info);
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 9eb1ce185bd0..3aa729df27b5 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -468,6 +468,16 @@ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
468/** 468/**
469 * psc_i2s_dai_template: template CPU Digital Audio Interface 469 * psc_i2s_dai_template: template CPU Digital Audio Interface
470 */ 470 */
471static struct snd_soc_dai_ops psc_i2s_dai_ops = {
472 .startup = psc_i2s_startup,
473 .hw_params = psc_i2s_hw_params,
474 .hw_free = psc_i2s_hw_free,
475 .shutdown = psc_i2s_shutdown,
476 .trigger = psc_i2s_trigger,
477 .set_sysclk = psc_i2s_set_sysclk,
478 .set_fmt = psc_i2s_set_fmt,
479};
480
471static struct snd_soc_dai psc_i2s_dai_template = { 481static struct snd_soc_dai psc_i2s_dai_template = {
472 .playback = { 482 .playback = {
473 .channels_min = 2, 483 .channels_min = 2,
@@ -481,15 +491,7 @@ static struct snd_soc_dai psc_i2s_dai_template = {
481 .rates = PSC_I2S_RATES, 491 .rates = PSC_I2S_RATES,
482 .formats = PSC_I2S_FORMATS, 492 .formats = PSC_I2S_FORMATS,
483 }, 493 },
484 .ops = { 494 .ops = &psc_i2s_dai_ops,
485 .startup = psc_i2s_startup,
486 .hw_params = psc_i2s_hw_params,
487 .hw_free = psc_i2s_hw_free,
488 .shutdown = psc_i2s_shutdown,
489 .trigger = psc_i2s_trigger,
490 .set_sysclk = psc_i2s_set_sysclk,
491 .set_fmt = psc_i2s_set_fmt,
492 },
493}; 495};
494 496
495/* --------------------------------------------------------------------- 497/* ---------------------------------------------------------------------
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index acf39a646b2f..ef67d1cdffe7 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -353,6 +353,11 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
353 } 353 }
354 ssi_info.irq = machine_data->ssi_irq; 354 ssi_info.irq = machine_data->ssi_irq;
355 355
356 /* Do we want to use asynchronous mode? */
357 ssi_info.asynchronous =
358 of_find_property(np, "fsl,ssi-asynchronous", NULL) ? 1 : 0;
359 if (ssi_info.asynchronous)
360 dev_info(&ofdev->dev, "using asynchronous mode\n");
356 361
357 /* Map the global utilities registers. */ 362 /* Map the global utilities registers. */
358 guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts"); 363 guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 4f7f04014585..675732e724d5 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -8,7 +8,7 @@ config SND_OMAP_SOC_MCBSP
8 8
9config SND_OMAP_SOC_N810 9config SND_OMAP_SOC_N810
10 tristate "SoC Audio support for Nokia N810" 10 tristate "SoC Audio support for Nokia N810"
11 depends on SND_OMAP_SOC && MACH_NOKIA_N810 11 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
12 select SND_OMAP_SOC_MCBSP 12 select SND_OMAP_SOC_MCBSP
13 select OMAP_MUX 13 select OMAP_MUX
14 select SND_SOC_TLV320AIC3X 14 select SND_SOC_TLV320AIC3X
@@ -17,7 +17,7 @@ config SND_OMAP_SOC_N810
17 17
18config SND_OMAP_SOC_OSK5912 18config SND_OMAP_SOC_OSK5912
19 tristate "SoC Audio support for omap osk5912" 19 tristate "SoC Audio support for omap osk5912"
20 depends on SND_OMAP_SOC && MACH_OMAP_OSK 20 depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C
21 select SND_OMAP_SOC_MCBSP 21 select SND_OMAP_SOC_MCBSP
22 select SND_SOC_TLV320AIC23 22 select SND_SOC_TLV320AIC23
23 help 23 help
@@ -55,3 +55,13 @@ config SND_OMAP_SOC_OMAP3_PANDORA
55 select SND_SOC_TWL4030 55 select SND_SOC_TWL4030
56 help 56 help
57 Say Y if you want to add support for SoC audio on the OMAP3 Pandora. 57 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
58
59config SND_OMAP_SOC_OMAP3_BEAGLE
60 tristate "SoC Audio support for OMAP3 Beagle"
61 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE
62 select SND_OMAP_SOC_MCBSP
63 select SND_SOC_TWL4030
64 help
65 Say Y if you want to add support for SoC audio on the Beagleboard.
66
67
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 76fedd96e365..0c9e4ac37660 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -12,6 +12,7 @@ snd-soc-overo-objs := overo.o
12snd-soc-omap2evm-objs := omap2evm.o 12snd-soc-omap2evm-objs := omap2evm.o
13snd-soc-sdp3430-objs := sdp3430.o 13snd-soc-sdp3430-objs := sdp3430.o
14snd-soc-omap3pandora-objs := omap3pandora.o 14snd-soc-omap3pandora-objs := omap3pandora.o
15snd-soc-omap3beagle-objs := omap3beagle.o
15 16
16obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 17obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
17obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 18obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
@@ -19,3 +20,4 @@ obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
19obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o 20obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
20obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 21obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
21obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 22obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
23obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 25593fee9121..a6d1178ce128 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -40,6 +40,13 @@
40#define N810_HEADSET_AMP_GPIO 10 40#define N810_HEADSET_AMP_GPIO 10
41#define N810_SPEAKER_AMP_GPIO 101 41#define N810_SPEAKER_AMP_GPIO 101
42 42
43enum {
44 N810_JACK_DISABLED,
45 N810_JACK_HP,
46 N810_JACK_HS,
47 N810_JACK_MIC,
48};
49
43static struct clk *sys_clkout2; 50static struct clk *sys_clkout2;
44static struct clk *sys_clkout2_src; 51static struct clk *sys_clkout2_src;
45static struct clk *func96m_clk; 52static struct clk *func96m_clk;
@@ -50,15 +57,32 @@ static int n810_dmic_func;
50 57
51static void n810_ext_control(struct snd_soc_codec *codec) 58static void n810_ext_control(struct snd_soc_codec *codec)
52{ 59{
60 int hp = 0, line1l = 0;
61
62 switch (n810_jack_func) {
63 case N810_JACK_HS:
64 line1l = 1;
65 case N810_JACK_HP:
66 hp = 1;
67 break;
68 case N810_JACK_MIC:
69 line1l = 1;
70 break;
71 }
72
53 if (n810_spk_func) 73 if (n810_spk_func)
54 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 74 snd_soc_dapm_enable_pin(codec, "Ext Spk");
55 else 75 else
56 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 76 snd_soc_dapm_disable_pin(codec, "Ext Spk");
57 77
58 if (n810_jack_func) 78 if (hp)
59 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 79 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
60 else 80 else
61 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 81 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
82 if (line1l)
83 snd_soc_dapm_enable_pin(codec, "LINE1L");
84 else
85 snd_soc_dapm_disable_pin(codec, "LINE1L");
62 86
63 if (n810_dmic_func) 87 if (n810_dmic_func)
64 snd_soc_dapm_enable_pin(codec, "DMic"); 88 snd_soc_dapm_enable_pin(codec, "DMic");
@@ -72,7 +96,7 @@ static int n810_startup(struct snd_pcm_substream *substream)
72{ 96{
73 struct snd_pcm_runtime *runtime = substream->runtime; 97 struct snd_pcm_runtime *runtime = substream->runtime;
74 struct snd_soc_pcm_runtime *rtd = substream->private_data; 98 struct snd_soc_pcm_runtime *rtd = substream->private_data;
75 struct snd_soc_codec *codec = rtd->socdev->codec; 99 struct snd_soc_codec *codec = rtd->socdev->card->codec;
76 100
77 snd_pcm_hw_constraint_minmax(runtime, 101 snd_pcm_hw_constraint_minmax(runtime,
78 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 102 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
@@ -229,7 +253,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
229}; 253};
230 254
231static const char *spk_function[] = {"Off", "On"}; 255static const char *spk_function[] = {"Off", "On"};
232static const char *jack_function[] = {"Off", "Headphone"}; 256static const char *jack_function[] = {"Off", "Headphone", "Headset", "Mic"};
233static const char *input_function[] = {"ADC", "Digital Mic"}; 257static const char *input_function[] = {"ADC", "Digital Mic"};
234static const struct soc_enum n810_enum[] = { 258static const struct soc_enum n810_enum[] = {
235 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), 259 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
@@ -248,20 +272,23 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
248 272
249static int n810_aic33_init(struct snd_soc_codec *codec) 273static int n810_aic33_init(struct snd_soc_codec *codec)
250{ 274{
251 int i, err; 275 int err;
252 276
253 /* Not connected */ 277 /* Not connected */
254 snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); 278 snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
255 snd_soc_dapm_nc_pin(codec, "HPLCOM"); 279 snd_soc_dapm_nc_pin(codec, "HPLCOM");
256 snd_soc_dapm_nc_pin(codec, "HPRCOM"); 280 snd_soc_dapm_nc_pin(codec, "HPRCOM");
281 snd_soc_dapm_nc_pin(codec, "MIC3L");
282 snd_soc_dapm_nc_pin(codec, "MIC3R");
283 snd_soc_dapm_nc_pin(codec, "LINE1R");
284 snd_soc_dapm_nc_pin(codec, "LINE2L");
285 snd_soc_dapm_nc_pin(codec, "LINE2R");
257 286
258 /* Add N810 specific controls */ 287 /* Add N810 specific controls */
259 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { 288 err = snd_soc_add_controls(codec, aic33_n810_controls,
260 err = snd_ctl_add(codec->card, 289 ARRAY_SIZE(aic33_n810_controls));
261 snd_soc_cnew(&aic33_n810_controls[i], codec, NULL)); 290 if (err < 0)
262 if (err < 0) 291 return err;
263 return err;
264 }
265 292
266 /* Add N810 specific widgets */ 293 /* Add N810 specific widgets */
267 snd_soc_dapm_new_controls(codec, aic33_dapm_widgets, 294 snd_soc_dapm_new_controls(codec, aic33_dapm_widgets,
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 05dd5abcddf4..d6882be33452 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -461,6 +461,16 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
461 return err; 461 return err;
462} 462}
463 463
464static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
465 .startup = omap_mcbsp_dai_startup,
466 .shutdown = omap_mcbsp_dai_shutdown,
467 .trigger = omap_mcbsp_dai_trigger,
468 .hw_params = omap_mcbsp_dai_hw_params,
469 .set_fmt = omap_mcbsp_dai_set_dai_fmt,
470 .set_clkdiv = omap_mcbsp_dai_set_clkdiv,
471 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk,
472};
473
464#define OMAP_MCBSP_DAI_BUILDER(link_id) \ 474#define OMAP_MCBSP_DAI_BUILDER(link_id) \
465{ \ 475{ \
466 .name = "omap-mcbsp-dai-"#link_id, \ 476 .name = "omap-mcbsp-dai-"#link_id, \
@@ -477,15 +487,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
477 .rates = OMAP_MCBSP_RATES, \ 487 .rates = OMAP_MCBSP_RATES, \
478 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 488 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
479 }, \ 489 }, \
480 .ops = { \ 490 .ops = &omap_mcbsp_dai_ops, \
481 .startup = omap_mcbsp_dai_startup, \
482 .shutdown = omap_mcbsp_dai_shutdown, \
483 .trigger = omap_mcbsp_dai_trigger, \
484 .hw_params = omap_mcbsp_dai_hw_params, \
485 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \
486 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \
487 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \
488 }, \
489 .private_data = &mcbsp_data[(link_id)].bus_id, \ 491 .private_data = &mcbsp_data[(link_id)].bus_id, \
490} 492}
491 493
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index dd3bb2933762..8e1431cb46bb 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -265,7 +265,7 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream,
265 runtime->dma_bytes); 265 runtime->dma_bytes);
266} 266}
267 267
268struct snd_pcm_ops omap_pcm_ops = { 268static struct snd_pcm_ops omap_pcm_ops = {
269 .open = omap_pcm_open, 269 .open = omap_pcm_open,
270 .close = omap_pcm_close, 270 .close = omap_pcm_close,
271 .ioctl = snd_pcm_lib_ioctl, 271 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index fcc2f5d9a878..fe282d4ef422 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -143,7 +143,7 @@ static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
143}; 143};
144 144
145static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = { 145static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = {
146 SND_SOC_DAPM_MIC("Mic (Internal)", NULL), 146 SND_SOC_DAPM_MIC("Mic (internal)", NULL),
147 SND_SOC_DAPM_MIC("Mic (external)", NULL), 147 SND_SOC_DAPM_MIC("Mic (external)", NULL),
148 SND_SOC_DAPM_LINE("Line In", NULL), 148 SND_SOC_DAPM_LINE("Line In", NULL),
149}; 149};
@@ -155,16 +155,33 @@ static const struct snd_soc_dapm_route omap3pandora_out_map[] = {
155}; 155};
156 156
157static const struct snd_soc_dapm_route omap3pandora_in_map[] = { 157static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
158 {"INL", NULL, "Line In"}, 158 {"AUXL", NULL, "Line In"},
159 {"INR", NULL, "Line In"}, 159 {"AUXR", NULL, "Line In"},
160 {"INL", NULL, "Mic (Internal)"}, 160
161 {"INR", NULL, "Mic (external)"}, 161 {"MAINMIC", NULL, "Mic Bias 1"},
162 {"Mic Bias 1", NULL, "Mic (internal)"},
163
164 {"SUBMIC", NULL, "Mic Bias 2"},
165 {"Mic Bias 2", NULL, "Mic (external)"},
162}; 166};
163 167
164static int omap3pandora_out_init(struct snd_soc_codec *codec) 168static int omap3pandora_out_init(struct snd_soc_codec *codec)
165{ 169{
166 int ret; 170 int ret;
167 171
172 /* All TWL4030 output pins are floating */
173 snd_soc_dapm_nc_pin(codec, "OUTL");
174 snd_soc_dapm_nc_pin(codec, "OUTR");
175 snd_soc_dapm_nc_pin(codec, "EARPIECE");
176 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
177 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
178 snd_soc_dapm_nc_pin(codec, "HSOL");
179 snd_soc_dapm_nc_pin(codec, "HSOR");
180 snd_soc_dapm_nc_pin(codec, "CARKITL");
181 snd_soc_dapm_nc_pin(codec, "CARKITR");
182 snd_soc_dapm_nc_pin(codec, "HFL");
183 snd_soc_dapm_nc_pin(codec, "HFR");
184
168 ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, 185 ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
169 ARRAY_SIZE(omap3pandora_out_dapm_widgets)); 186 ARRAY_SIZE(omap3pandora_out_dapm_widgets));
170 if (ret < 0) 187 if (ret < 0)
@@ -180,18 +197,11 @@ static int omap3pandora_in_init(struct snd_soc_codec *codec)
180{ 197{
181 int ret; 198 int ret;
182 199
183 /* All TWL4030 output pins are floating */ 200 /* Not comnnected */
184 snd_soc_dapm_nc_pin(codec, "OUTL"), 201 snd_soc_dapm_nc_pin(codec, "HSMIC");
185 snd_soc_dapm_nc_pin(codec, "OUTR"), 202 snd_soc_dapm_nc_pin(codec, "CARKITMIC");
186 snd_soc_dapm_nc_pin(codec, "EARPIECE"), 203 snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
187 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"), 204 snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
188 snd_soc_dapm_nc_pin(codec, "PREDRIVER"),
189 snd_soc_dapm_nc_pin(codec, "HSOL"),
190 snd_soc_dapm_nc_pin(codec, "HSOR"),
191 snd_soc_dapm_nc_pin(codec, "CARKITL"),
192 snd_soc_dapm_nc_pin(codec, "CARKITR"),
193 snd_soc_dapm_nc_pin(codec, "HFL"),
194 snd_soc_dapm_nc_pin(codec, "HFR"),
195 205
196 ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets, 206 ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets,
197 ARRAY_SIZE(omap3pandora_in_dapm_widgets)); 207 ARRAY_SIZE(omap3pandora_in_dapm_widgets));
@@ -251,10 +261,9 @@ static int __init omap3pandora_soc_init(void)
251{ 261{
252 int ret; 262 int ret;
253 263
254 if (!machine_is_omap3_pandora()) { 264 if (!machine_is_omap3_pandora())
255 pr_debug(PREFIX "Not OMAP3 Pandora\n");
256 return -ENODEV; 265 return -ENODEV;
257 } 266
258 pr_info("OMAP3 Pandora SoC init\n"); 267 pr_info("OMAP3 Pandora SoC init\n");
259 268
260 ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power"); 269 ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power");
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index cd41a948df7b..a952a4eb3361 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -186,13 +186,6 @@ static int __init osk_soc_init(void)
186 return -ENODEV; 186 return -ENODEV;
187 } 187 }
188 188
189 if (clk_get_usecount(tlv320aic23_mclk) > 0) {
190 /* MCLK is already in use */
191 printk(KERN_WARNING
192 "MCLK in use at %d Hz. We change it to %d Hz\n",
193 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
194 }
195
196 /* 189 /*
197 * Configure 12 MHz output on MCLK. 190 * Configure 12 MHz output on MCLK.
198 */ 191 */
@@ -205,9 +198,8 @@ static int __init osk_soc_init(void)
205 } 198 }
206 } 199 }
207 200
208 printk(KERN_INFO "MCLK = %d [%d], usecount = %d\n", 201 printk(KERN_INFO "MCLK = %d [%d]\n",
209 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK, 202 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
210 clk_get_usecount(tlv320aic23_mclk));
211 203
212 return 0; 204 return 0;
213err1: 205err1:
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index e226fa75669c..10f1c867f11d 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -28,6 +28,7 @@
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/soc-dapm.h> 30#include <sound/soc-dapm.h>
31#include <sound/jack.h>
31 32
32#include <asm/mach-types.h> 33#include <asm/mach-types.h>
33#include <mach/hardware.h> 34#include <mach/hardware.h>
@@ -38,6 +39,8 @@
38#include "omap-pcm.h" 39#include "omap-pcm.h"
39#include "../codecs/twl4030.h" 40#include "../codecs/twl4030.h"
40 41
42static struct snd_soc_card snd_soc_sdp3430;
43
41static int sdp3430_hw_params(struct snd_pcm_substream *substream, 44static int sdp3430_hw_params(struct snd_pcm_substream *substream,
42 struct snd_pcm_hw_params *params) 45 struct snd_pcm_hw_params *params)
43{ 46{
@@ -81,12 +84,121 @@ static struct snd_soc_ops sdp3430_ops = {
81 .hw_params = sdp3430_hw_params, 84 .hw_params = sdp3430_hw_params,
82}; 85};
83 86
87/* Headset jack */
88static struct snd_soc_jack hs_jack;
89
90/* Headset jack detection DAPM pins */
91static struct snd_soc_jack_pin hs_jack_pins[] = {
92 {
93 .pin = "Headset Mic",
94 .mask = SND_JACK_MICROPHONE,
95 },
96 {
97 .pin = "Headset Stereophone",
98 .mask = SND_JACK_HEADPHONE,
99 },
100};
101
102/* Headset jack detection gpios */
103static struct snd_soc_jack_gpio hs_jack_gpios[] = {
104 {
105 .gpio = (OMAP_MAX_GPIO_LINES + 2),
106 .name = "hsdet-gpio",
107 .report = SND_JACK_HEADSET,
108 .debounce_time = 200,
109 },
110};
111
112/* SDP3430 machine DAPM */
113static const struct snd_soc_dapm_widget sdp3430_twl4030_dapm_widgets[] = {
114 SND_SOC_DAPM_MIC("Ext Mic", NULL),
115 SND_SOC_DAPM_SPK("Ext Spk", NULL),
116 SND_SOC_DAPM_MIC("Headset Mic", NULL),
117 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
118};
119
120static const struct snd_soc_dapm_route audio_map[] = {
121 /* External Mics: MAINMIC, SUBMIC with bias*/
122 {"MAINMIC", NULL, "Mic Bias 1"},
123 {"SUBMIC", NULL, "Mic Bias 2"},
124 {"Mic Bias 1", NULL, "Ext Mic"},
125 {"Mic Bias 2", NULL, "Ext Mic"},
126
127 /* External Speakers: HFL, HFR */
128 {"Ext Spk", NULL, "HFL"},
129 {"Ext Spk", NULL, "HFR"},
130
131 /* Headset Mic: HSMIC with bias */
132 {"HSMIC", NULL, "Headset Mic Bias"},
133 {"Headset Mic Bias", NULL, "Headset Mic"},
134
135 /* Headset Stereophone (Headphone): HSOL, HSOR */
136 {"Headset Stereophone", NULL, "HSOL"},
137 {"Headset Stereophone", NULL, "HSOR"},
138};
139
140static int sdp3430_twl4030_init(struct snd_soc_codec *codec)
141{
142 int ret;
143
144 /* Add SDP3430 specific widgets */
145 ret = snd_soc_dapm_new_controls(codec, sdp3430_twl4030_dapm_widgets,
146 ARRAY_SIZE(sdp3430_twl4030_dapm_widgets));
147 if (ret)
148 return ret;
149
150 /* Set up SDP3430 specific audio path audio_map */
151 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
152
153 /* SDP3430 connected pins */
154 snd_soc_dapm_enable_pin(codec, "Ext Mic");
155 snd_soc_dapm_enable_pin(codec, "Ext Spk");
156 snd_soc_dapm_disable_pin(codec, "Headset Mic");
157 snd_soc_dapm_disable_pin(codec, "Headset Stereophone");
158
159 /* TWL4030 not connected pins */
160 snd_soc_dapm_nc_pin(codec, "AUXL");
161 snd_soc_dapm_nc_pin(codec, "AUXR");
162 snd_soc_dapm_nc_pin(codec, "CARKITMIC");
163 snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
164 snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
165
166 snd_soc_dapm_nc_pin(codec, "OUTL");
167 snd_soc_dapm_nc_pin(codec, "OUTR");
168 snd_soc_dapm_nc_pin(codec, "EARPIECE");
169 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
170 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
171 snd_soc_dapm_nc_pin(codec, "CARKITL");
172 snd_soc_dapm_nc_pin(codec, "CARKITR");
173
174 ret = snd_soc_dapm_sync(codec);
175 if (ret)
176 return ret;
177
178 /* Headset jack detection */
179 ret = snd_soc_jack_new(&snd_soc_sdp3430, "Headset Jack",
180 SND_JACK_HEADSET, &hs_jack);
181 if (ret)
182 return ret;
183
184 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
185 hs_jack_pins);
186 if (ret)
187 return ret;
188
189 ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
190 hs_jack_gpios);
191
192 return ret;
193}
194
84/* Digital audio interface glue - connects codec <--> CPU */ 195/* Digital audio interface glue - connects codec <--> CPU */
85static struct snd_soc_dai_link sdp3430_dai = { 196static struct snd_soc_dai_link sdp3430_dai = {
86 .name = "TWL4030", 197 .name = "TWL4030",
87 .stream_name = "TWL4030", 198 .stream_name = "TWL4030",
88 .cpu_dai = &omap_mcbsp_dai[0], 199 .cpu_dai = &omap_mcbsp_dai[0],
89 .codec_dai = &twl4030_dai, 200 .codec_dai = &twl4030_dai,
201 .init = sdp3430_twl4030_init,
90 .ops = &sdp3430_ops, 202 .ops = &sdp3430_ops,
91}; 203};
92 204
@@ -142,6 +254,9 @@ module_init(sdp3430_soc_init);
142 254
143static void __exit sdp3430_soc_exit(void) 255static void __exit sdp3430_soc_exit(void)
144{ 256{
257 snd_soc_jack_free_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
258 hs_jack_gpios);
259
145 platform_device_unregister(sdp3430_snd_device); 260 platform_device_unregister(sdp3430_snd_device);
146} 261}
147module_exit(sdp3430_soc_exit); 262module_exit(sdp3430_soc_exit);
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f82e10699471..5998ab366e83 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -61,6 +61,24 @@ config SND_PXA2XX_SOC_TOSA
61 Say Y if you want to add support for SoC audio on Sharp 61 Say Y if you want to add support for SoC audio on Sharp
62 Zaurus SL-C6000x models (Tosa). 62 Zaurus SL-C6000x models (Tosa).
63 63
64config SND_PXA2XX_SOC_E740
65 tristate "SoC AC97 Audio support for e740"
66 depends on SND_PXA2XX_SOC && MACH_E740
67 select SND_SOC_WM9705
68 select SND_PXA2XX_SOC_AC97
69 help
70 Say Y if you want to add support for SoC audio on the
71 toshiba e740 PDA
72
73config SND_PXA2XX_SOC_E750
74 tristate "SoC AC97 Audio support for e750"
75 depends on SND_PXA2XX_SOC && MACH_E750
76 select SND_SOC_WM9705
77 select SND_PXA2XX_SOC_AC97
78 help
79 Say Y if you want to add support for SoC audio on the
80 toshiba e750 PDA
81
64config SND_PXA2XX_SOC_E800 82config SND_PXA2XX_SOC_E800
65 tristate "SoC AC97 Audio support for e800" 83 tristate "SoC AC97 Audio support for e800"
66 depends on SND_PXA2XX_SOC && MACH_E800 84 depends on SND_PXA2XX_SOC && MACH_E800
@@ -97,3 +115,12 @@ config SND_SOC_ZYLONITE
97 help 115 help
98 Say Y if you want to add support for SoC audio on the 116 Say Y if you want to add support for SoC audio on the
99 Marvell Zylonite reference platform. 117 Marvell Zylonite reference platform.
118
119config SND_PXA2XX_SOC_MIOA701
120 tristate "SoC Audio support for MIO A701"
121 depends on SND_PXA2XX_SOC && MACH_MIOA701
122 select SND_PXA2XX_SOC_AC97
123 select SND_SOC_WM9713
124 help
125 Say Y if you want to add support for SoC audio on the
126 MIO A701.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 08a9f2797729..8ed881c5e5cc 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -13,17 +13,23 @@ obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
13snd-soc-corgi-objs := corgi.o 13snd-soc-corgi-objs := corgi.o
14snd-soc-poodle-objs := poodle.o 14snd-soc-poodle-objs := poodle.o
15snd-soc-tosa-objs := tosa.o 15snd-soc-tosa-objs := tosa.o
16snd-soc-e740-objs := e740_wm9705.o
17snd-soc-e750-objs := e750_wm9705.o
16snd-soc-e800-objs := e800_wm9712.o 18snd-soc-e800-objs := e800_wm9712.o
17snd-soc-spitz-objs := spitz.o 19snd-soc-spitz-objs := spitz.o
18snd-soc-em-x270-objs := em-x270.o 20snd-soc-em-x270-objs := em-x270.o
19snd-soc-palm27x-objs := palm27x.o 21snd-soc-palm27x-objs := palm27x.o
20snd-soc-zylonite-objs := zylonite.o 22snd-soc-zylonite-objs := zylonite.o
23snd-soc-mioa701-objs := mioa701_wm9713.o
21 24
22obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 25obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
23obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 26obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
24obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o 27obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o
28obj-$(CONFIG_SND_PXA2XX_SOC_E740) += snd-soc-e740.o
29obj-$(CONFIG_SND_PXA2XX_SOC_E750) += snd-soc-e750.o
25obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o 30obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
26obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o 31obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
27obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o 32obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
28obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o 33obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
34obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
29obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 35obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 1ba25a559524..02263e5d8f03 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -16,6 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/timer.h> 18#include <linux/timer.h>
19#include <linux/i2c.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <linux/gpio.h> 22#include <linux/gpio.h>
@@ -100,7 +101,7 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
100static int corgi_startup(struct snd_pcm_substream *substream) 101static int corgi_startup(struct snd_pcm_substream *substream)
101{ 102{
102 struct snd_soc_pcm_runtime *rtd = substream->private_data; 103 struct snd_soc_pcm_runtime *rtd = substream->private_data;
103 struct snd_soc_codec *codec = rtd->socdev->codec; 104 struct snd_soc_codec *codec = rtd->socdev->card->codec;
104 105
105 /* check the jack status at stream startup */ 106 /* check the jack status at stream startup */
106 corgi_ext_control(codec); 107 corgi_ext_control(codec);
@@ -275,18 +276,16 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
275 */ 276 */
276static int corgi_wm8731_init(struct snd_soc_codec *codec) 277static int corgi_wm8731_init(struct snd_soc_codec *codec)
277{ 278{
278 int i, err; 279 int err;
279 280
280 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 281 snd_soc_dapm_nc_pin(codec, "LLINEIN");
281 snd_soc_dapm_nc_pin(codec, "RLINEIN"); 282 snd_soc_dapm_nc_pin(codec, "RLINEIN");
282 283
283 /* Add corgi specific controls */ 284 /* Add corgi specific controls */
284 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { 285 err = snd_soc_add_controls(codec, wm8731_corgi_controls,
285 err = snd_ctl_add(codec->card, 286 ARRAY_SIZE(wm8731_corgi_controls));
286 snd_soc_cnew(&wm8731_corgi_controls[i], codec, NULL)); 287 if (err < 0)
287 if (err < 0) 288 return err;
288 return err;
289 }
290 289
291 /* Add corgi specific widgets */ 290 /* Add corgi specific widgets */
292 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, 291 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
@@ -317,19 +316,44 @@ static struct snd_soc_card snd_soc_corgi = {
317 .num_links = 1, 316 .num_links = 1,
318}; 317};
319 318
320/* corgi audio private data */
321static struct wm8731_setup_data corgi_wm8731_setup = {
322 .i2c_bus = 0,
323 .i2c_address = 0x1b,
324};
325
326/* corgi audio subsystem */ 319/* corgi audio subsystem */
327static struct snd_soc_device corgi_snd_devdata = { 320static struct snd_soc_device corgi_snd_devdata = {
328 .card = &snd_soc_corgi, 321 .card = &snd_soc_corgi,
329 .codec_dev = &soc_codec_dev_wm8731, 322 .codec_dev = &soc_codec_dev_wm8731,
330 .codec_data = &corgi_wm8731_setup,
331}; 323};
332 324
325/*
326 * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
327 * New drivers should register the wm8731 I2C device in the machine
328 * setup code (under arch/arm for ARM systems).
329 */
330static int wm8731_i2c_register(void)
331{
332 struct i2c_board_info info;
333 struct i2c_adapter *adapter;
334 struct i2c_client *client;
335
336 memset(&info, 0, sizeof(struct i2c_board_info));
337 info.addr = 0x1b;
338 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
339
340 adapter = i2c_get_adapter(0);
341 if (!adapter) {
342 printk(KERN_ERR "can't get i2c adapter 0\n");
343 return -ENODEV;
344 }
345
346 client = i2c_new_device(adapter, &info);
347 i2c_put_adapter(adapter);
348 if (!client) {
349 printk(KERN_ERR "can't add i2c device at 0x%x\n",
350 (unsigned int)info.addr);
351 return -ENODEV;
352 }
353
354 return 0;
355}
356
333static struct platform_device *corgi_snd_device; 357static struct platform_device *corgi_snd_device;
334 358
335static int __init corgi_init(void) 359static int __init corgi_init(void)
@@ -340,6 +364,10 @@ static int __init corgi_init(void)
340 machine_is_husky())) 364 machine_is_husky()))
341 return -ENODEV; 365 return -ENODEV;
342 366
367 ret = wm8731_i2c_register();
368 if (ret != 0)
369 return ret;
370
343 corgi_snd_device = platform_device_alloc("soc-audio", -1); 371 corgi_snd_device = platform_device_alloc("soc-audio", -1);
344 if (!corgi_snd_device) 372 if (!corgi_snd_device)
345 return -ENOMEM; 373 return -ENOMEM;
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
new file mode 100644
index 000000000000..7cd2f89d7b10
--- /dev/null
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -0,0 +1,211 @@
1/*
2 * e740-wm9705.c -- SoC audio for e740
3 *
4 * Copyright 2007 (c) Ian Molton <spyro@f2s.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 ONLY.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/gpio.h>
15
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20
21#include <mach/audio.h>
22#include <mach/eseries-gpio.h>
23
24#include <asm/mach-types.h>
25
26#include "../codecs/wm9705.h"
27#include "pxa2xx-pcm.h"
28#include "pxa2xx-ac97.h"
29
30
31#define E740_AUDIO_OUT 1
32#define E740_AUDIO_IN 2
33
34static int e740_audio_power;
35
36static void e740_sync_audio_power(int status)
37{
38 gpio_set_value(GPIO_E740_WM9705_nAVDD2, !status);
39 gpio_set_value(GPIO_E740_AMP_ON, (status & E740_AUDIO_OUT) ? 1 : 0);
40 gpio_set_value(GPIO_E740_MIC_ON, (status & E740_AUDIO_IN) ? 1 : 0);
41}
42
43static int e740_mic_amp_event(struct snd_soc_dapm_widget *w,
44 struct snd_kcontrol *kcontrol, int event)
45{
46 if (event & SND_SOC_DAPM_PRE_PMU)
47 e740_audio_power |= E740_AUDIO_IN;
48 else if (event & SND_SOC_DAPM_POST_PMD)
49 e740_audio_power &= ~E740_AUDIO_IN;
50
51 e740_sync_audio_power(e740_audio_power);
52
53 return 0;
54}
55
56static int e740_output_amp_event(struct snd_soc_dapm_widget *w,
57 struct snd_kcontrol *kcontrol, int event)
58{
59 if (event & SND_SOC_DAPM_PRE_PMU)
60 e740_audio_power |= E740_AUDIO_OUT;
61 else if (event & SND_SOC_DAPM_POST_PMD)
62 e740_audio_power &= ~E740_AUDIO_OUT;
63
64 e740_sync_audio_power(e740_audio_power);
65
66 return 0;
67}
68
69static const struct snd_soc_dapm_widget e740_dapm_widgets[] = {
70 SND_SOC_DAPM_HP("Headphone Jack", NULL),
71 SND_SOC_DAPM_SPK("Speaker", NULL),
72 SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
73 SND_SOC_DAPM_PGA_E("Output Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
74 e740_output_amp_event, SND_SOC_DAPM_PRE_PMU |
75 SND_SOC_DAPM_POST_PMD),
76 SND_SOC_DAPM_PGA_E("Mic Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
77 e740_mic_amp_event, SND_SOC_DAPM_PRE_PMU |
78 SND_SOC_DAPM_POST_PMD),
79};
80
81static const struct snd_soc_dapm_route audio_map[] = {
82 {"Output Amp", NULL, "LOUT"},
83 {"Output Amp", NULL, "ROUT"},
84 {"Output Amp", NULL, "MONOOUT"},
85
86 {"Speaker", NULL, "Output Amp"},
87 {"Headphone Jack", NULL, "Output Amp"},
88
89 {"MIC1", NULL, "Mic Amp"},
90 {"Mic Amp", NULL, "Mic (Internal)"},
91};
92
93static int e740_ac97_init(struct snd_soc_codec *codec)
94{
95 snd_soc_dapm_nc_pin(codec, "HPOUTL");
96 snd_soc_dapm_nc_pin(codec, "HPOUTR");
97 snd_soc_dapm_nc_pin(codec, "PHONE");
98 snd_soc_dapm_nc_pin(codec, "LINEINL");
99 snd_soc_dapm_nc_pin(codec, "LINEINR");
100 snd_soc_dapm_nc_pin(codec, "CDINL");
101 snd_soc_dapm_nc_pin(codec, "CDINR");
102 snd_soc_dapm_nc_pin(codec, "PCBEEP");
103 snd_soc_dapm_nc_pin(codec, "MIC2");
104
105 snd_soc_dapm_new_controls(codec, e740_dapm_widgets,
106 ARRAY_SIZE(e740_dapm_widgets));
107
108 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
109
110 snd_soc_dapm_sync(codec);
111
112 return 0;
113}
114
115static struct snd_soc_dai_link e740_dai[] = {
116 {
117 .name = "AC97",
118 .stream_name = "AC97 HiFi",
119 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
120 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI],
121 .init = e740_ac97_init,
122 },
123 {
124 .name = "AC97 Aux",
125 .stream_name = "AC97 Aux",
126 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
127 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX],
128 },
129};
130
131static struct snd_soc_card e740 = {
132 .name = "Toshiba e740",
133 .platform = &pxa2xx_soc_platform,
134 .dai_link = e740_dai,
135 .num_links = ARRAY_SIZE(e740_dai),
136};
137
138static struct snd_soc_device e740_snd_devdata = {
139 .card = &e740,
140 .codec_dev = &soc_codec_dev_wm9705,
141};
142
143static struct platform_device *e740_snd_device;
144
145static int __init e740_init(void)
146{
147 int ret;
148
149 if (!machine_is_e740())
150 return -ENODEV;
151
152 ret = gpio_request(GPIO_E740_MIC_ON, "Mic amp");
153 if (ret)
154 return ret;
155
156 ret = gpio_request(GPIO_E740_AMP_ON, "Output amp");
157 if (ret)
158 goto free_mic_amp_gpio;
159
160 ret = gpio_request(GPIO_E740_WM9705_nAVDD2, "Audio power");
161 if (ret)
162 goto free_op_amp_gpio;
163
164 /* Disable audio */
165 ret = gpio_direction_output(GPIO_E740_MIC_ON, 0);
166 if (ret)
167 goto free_apwr_gpio;
168 ret = gpio_direction_output(GPIO_E740_AMP_ON, 0);
169 if (ret)
170 goto free_apwr_gpio;
171 ret = gpio_direction_output(GPIO_E740_WM9705_nAVDD2, 1);
172 if (ret)
173 goto free_apwr_gpio;
174
175 e740_snd_device = platform_device_alloc("soc-audio", -1);
176 if (!e740_snd_device) {
177 ret = -ENOMEM;
178 goto free_apwr_gpio;
179 }
180
181 platform_set_drvdata(e740_snd_device, &e740_snd_devdata);
182 e740_snd_devdata.dev = &e740_snd_device->dev;
183 ret = platform_device_add(e740_snd_device);
184
185 if (!ret)
186 return 0;
187
188/* Fail gracefully */
189 platform_device_put(e740_snd_device);
190free_apwr_gpio:
191 gpio_free(GPIO_E740_WM9705_nAVDD2);
192free_op_amp_gpio:
193 gpio_free(GPIO_E740_AMP_ON);
194free_mic_amp_gpio:
195 gpio_free(GPIO_E740_MIC_ON);
196
197 return ret;
198}
199
200static void __exit e740_exit(void)
201{
202 platform_device_unregister(e740_snd_device);
203}
204
205module_init(e740_init);
206module_exit(e740_exit);
207
208/* Module information */
209MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
210MODULE_DESCRIPTION("ALSA SoC driver for e740");
211MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
new file mode 100644
index 000000000000..8dceccc5e059
--- /dev/null
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -0,0 +1,187 @@
1/*
2 * e750-wm9705.c -- SoC audio for e750
3 *
4 * Copyright 2007 (c) Ian Molton <spyro@f2s.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 ONLY.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/gpio.h>
15
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20
21#include <mach/audio.h>
22#include <mach/eseries-gpio.h>
23
24#include <asm/mach-types.h>
25
26#include "../codecs/wm9705.h"
27#include "pxa2xx-pcm.h"
28#include "pxa2xx-ac97.h"
29
30static int e750_spk_amp_event(struct snd_soc_dapm_widget *w,
31 struct snd_kcontrol *kcontrol, int event)
32{
33 if (event & SND_SOC_DAPM_PRE_PMU)
34 gpio_set_value(GPIO_E750_SPK_AMP_OFF, 0);
35 else if (event & SND_SOC_DAPM_POST_PMD)
36 gpio_set_value(GPIO_E750_SPK_AMP_OFF, 1);
37
38 return 0;
39}
40
41static int e750_hp_amp_event(struct snd_soc_dapm_widget *w,
42 struct snd_kcontrol *kcontrol, int event)
43{
44 if (event & SND_SOC_DAPM_PRE_PMU)
45 gpio_set_value(GPIO_E750_HP_AMP_OFF, 0);
46 else if (event & SND_SOC_DAPM_POST_PMD)
47 gpio_set_value(GPIO_E750_HP_AMP_OFF, 1);
48
49 return 0;
50}
51
52static const struct snd_soc_dapm_widget e750_dapm_widgets[] = {
53 SND_SOC_DAPM_HP("Headphone Jack", NULL),
54 SND_SOC_DAPM_SPK("Speaker", NULL),
55 SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
56 SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
57 e750_hp_amp_event, SND_SOC_DAPM_PRE_PMU |
58 SND_SOC_DAPM_POST_PMD),
59 SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
60 e750_spk_amp_event, SND_SOC_DAPM_PRE_PMU |
61 SND_SOC_DAPM_POST_PMD),
62};
63
64static const struct snd_soc_dapm_route audio_map[] = {
65 {"Headphone Amp", NULL, "HPOUTL"},
66 {"Headphone Amp", NULL, "HPOUTR"},
67 {"Headphone Jack", NULL, "Headphone Amp"},
68
69 {"Speaker Amp", NULL, "MONOOUT"},
70 {"Speaker", NULL, "Speaker Amp"},
71
72 {"MIC1", NULL, "Mic (Internal)"},
73};
74
75static int e750_ac97_init(struct snd_soc_codec *codec)
76{
77 snd_soc_dapm_nc_pin(codec, "LOUT");
78 snd_soc_dapm_nc_pin(codec, "ROUT");
79 snd_soc_dapm_nc_pin(codec, "PHONE");
80 snd_soc_dapm_nc_pin(codec, "LINEINL");
81 snd_soc_dapm_nc_pin(codec, "LINEINR");
82 snd_soc_dapm_nc_pin(codec, "CDINL");
83 snd_soc_dapm_nc_pin(codec, "CDINR");
84 snd_soc_dapm_nc_pin(codec, "PCBEEP");
85 snd_soc_dapm_nc_pin(codec, "MIC2");
86
87 snd_soc_dapm_new_controls(codec, e750_dapm_widgets,
88 ARRAY_SIZE(e750_dapm_widgets));
89
90 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
91
92 snd_soc_dapm_sync(codec);
93
94 return 0;
95}
96
97static struct snd_soc_dai_link e750_dai[] = {
98 {
99 .name = "AC97",
100 .stream_name = "AC97 HiFi",
101 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
102 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI],
103 .init = e750_ac97_init,
104 /* use ops to check startup state */
105 },
106 {
107 .name = "AC97 Aux",
108 .stream_name = "AC97 Aux",
109 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
110 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX],
111 },
112};
113
114static struct snd_soc_card e750 = {
115 .name = "Toshiba e750",
116 .platform = &pxa2xx_soc_platform,
117 .dai_link = e750_dai,
118 .num_links = ARRAY_SIZE(e750_dai),
119};
120
121static struct snd_soc_device e750_snd_devdata = {
122 .card = &e750,
123 .codec_dev = &soc_codec_dev_wm9705,
124};
125
126static struct platform_device *e750_snd_device;
127
128static int __init e750_init(void)
129{
130 int ret;
131
132 if (!machine_is_e750())
133 return -ENODEV;
134
135 ret = gpio_request(GPIO_E750_HP_AMP_OFF, "Headphone amp");
136 if (ret)
137 return ret;
138
139 ret = gpio_request(GPIO_E750_SPK_AMP_OFF, "Speaker amp");
140 if (ret)
141 goto free_hp_amp_gpio;
142
143 ret = gpio_direction_output(GPIO_E750_HP_AMP_OFF, 1);
144 if (ret)
145 goto free_spk_amp_gpio;
146
147 ret = gpio_direction_output(GPIO_E750_SPK_AMP_OFF, 1);
148 if (ret)
149 goto free_spk_amp_gpio;
150
151 e750_snd_device = platform_device_alloc("soc-audio", -1);
152 if (!e750_snd_device) {
153 ret = -ENOMEM;
154 goto free_spk_amp_gpio;
155 }
156
157 platform_set_drvdata(e750_snd_device, &e750_snd_devdata);
158 e750_snd_devdata.dev = &e750_snd_device->dev;
159 ret = platform_device_add(e750_snd_device);
160
161 if (!ret)
162 return 0;
163
164/* Fail gracefully */
165 platform_device_put(e750_snd_device);
166free_spk_amp_gpio:
167 gpio_free(GPIO_E750_SPK_AMP_OFF);
168free_hp_amp_gpio:
169 gpio_free(GPIO_E750_HP_AMP_OFF);
170
171 return ret;
172}
173
174static void __exit e750_exit(void)
175{
176 platform_device_unregister(e750_snd_device);
177 gpio_free(GPIO_E750_SPK_AMP_OFF);
178 gpio_free(GPIO_E750_HP_AMP_OFF);
179}
180
181module_init(e750_init);
182module_exit(e750_exit);
183
184/* Module information */
185MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
186MODULE_DESCRIPTION("ALSA SoC driver for e750");
187MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 2e3386dfa0f0..bc019cdce429 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -1,8 +1,6 @@
1/* 1/*
2 * e800-wm9712.c -- SoC audio for e800 2 * e800-wm9712.c -- SoC audio for e800
3 * 3 *
4 * Based on tosa.c
5 *
6 * Copyright 2007 (c) Ian Molton <spyro@f2s.com> 4 * Copyright 2007 (c) Ian Molton <spyro@f2s.com>
7 * 5 *
8 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
@@ -13,7 +11,7 @@
13 11
14#include <linux/module.h> 12#include <linux/module.h>
15#include <linux/moduleparam.h> 13#include <linux/moduleparam.h>
16#include <linux/device.h> 14#include <linux/gpio.h>
17 15
18#include <sound/core.h> 16#include <sound/core.h>
19#include <sound/pcm.h> 17#include <sound/pcm.h>
@@ -21,23 +19,85 @@
21#include <sound/soc-dapm.h> 19#include <sound/soc-dapm.h>
22 20
23#include <asm/mach-types.h> 21#include <asm/mach-types.h>
24#include <mach/pxa-regs.h>
25#include <mach/hardware.h>
26#include <mach/audio.h> 22#include <mach/audio.h>
23#include <mach/eseries-gpio.h>
27 24
28#include "../codecs/wm9712.h" 25#include "../codecs/wm9712.h"
29#include "pxa2xx-pcm.h" 26#include "pxa2xx-pcm.h"
30#include "pxa2xx-ac97.h" 27#include "pxa2xx-ac97.h"
31 28
32static struct snd_soc_card e800; 29static int e800_spk_amp_event(struct snd_soc_dapm_widget *w,
30 struct snd_kcontrol *kcontrol, int event)
31{
32 if (event & SND_SOC_DAPM_PRE_PMU)
33 gpio_set_value(GPIO_E800_SPK_AMP_ON, 1);
34 else if (event & SND_SOC_DAPM_POST_PMD)
35 gpio_set_value(GPIO_E800_SPK_AMP_ON, 0);
33 36
34static struct snd_soc_dai_link e800_dai[] = { 37 return 0;
38}
39
40static int e800_hp_amp_event(struct snd_soc_dapm_widget *w,
41 struct snd_kcontrol *kcontrol, int event)
42{
43 if (event & SND_SOC_DAPM_PRE_PMU)
44 gpio_set_value(GPIO_E800_HP_AMP_OFF, 0);
45 else if (event & SND_SOC_DAPM_POST_PMD)
46 gpio_set_value(GPIO_E800_HP_AMP_OFF, 1);
47
48 return 0;
49}
50
51static const struct snd_soc_dapm_widget e800_dapm_widgets[] = {
52 SND_SOC_DAPM_HP("Headphone Jack", NULL),
53 SND_SOC_DAPM_MIC("Mic (Internal1)", NULL),
54 SND_SOC_DAPM_MIC("Mic (Internal2)", NULL),
55 SND_SOC_DAPM_SPK("Speaker", NULL),
56 SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
57 e800_hp_amp_event, SND_SOC_DAPM_PRE_PMU |
58 SND_SOC_DAPM_POST_PMD),
59 SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
60 e800_spk_amp_event, SND_SOC_DAPM_PRE_PMU |
61 SND_SOC_DAPM_POST_PMD),
62};
63
64static const struct snd_soc_dapm_route audio_map[] = {
65 {"Headphone Jack", NULL, "HPOUTL"},
66 {"Headphone Jack", NULL, "HPOUTR"},
67 {"Headphone Jack", NULL, "Headphone Amp"},
68
69 {"Speaker Amp", NULL, "MONOOUT"},
70 {"Speaker", NULL, "Speaker Amp"},
71
72 {"MIC1", NULL, "Mic (Internal1)"},
73 {"MIC2", NULL, "Mic (Internal2)"},
74};
75
76static int e800_ac97_init(struct snd_soc_codec *codec)
35{ 77{
36 .name = "AC97 Aux", 78 snd_soc_dapm_new_controls(codec, e800_dapm_widgets,
37 .stream_name = "AC97 Aux", 79 ARRAY_SIZE(e800_dapm_widgets));
38 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 80
39 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 81 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
40}, 82 snd_soc_dapm_sync(codec);
83
84 return 0;
85}
86
87static struct snd_soc_dai_link e800_dai[] = {
88 {
89 .name = "AC97",
90 .stream_name = "AC97 HiFi",
91 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
92 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
93 .init = e800_ac97_init,
94 },
95 {
96 .name = "AC97 Aux",
97 .stream_name = "AC97 Aux",
98 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
99 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
100 },
41}; 101};
42 102
43static struct snd_soc_card e800 = { 103static struct snd_soc_card e800 = {
@@ -61,6 +121,22 @@ static int __init e800_init(void)
61 if (!machine_is_e800()) 121 if (!machine_is_e800())
62 return -ENODEV; 122 return -ENODEV;
63 123
124 ret = gpio_request(GPIO_E800_HP_AMP_OFF, "Headphone amp");
125 if (ret)
126 return ret;
127
128 ret = gpio_request(GPIO_E800_SPK_AMP_ON, "Speaker amp");
129 if (ret)
130 goto free_hp_amp_gpio;
131
132 ret = gpio_direction_output(GPIO_E800_HP_AMP_OFF, 1);
133 if (ret)
134 goto free_spk_amp_gpio;
135
136 ret = gpio_direction_output(GPIO_E800_SPK_AMP_ON, 1);
137 if (ret)
138 goto free_spk_amp_gpio;
139
64 e800_snd_device = platform_device_alloc("soc-audio", -1); 140 e800_snd_device = platform_device_alloc("soc-audio", -1);
65 if (!e800_snd_device) 141 if (!e800_snd_device)
66 return -ENOMEM; 142 return -ENOMEM;
@@ -69,8 +145,15 @@ static int __init e800_init(void)
69 e800_snd_devdata.dev = &e800_snd_device->dev; 145 e800_snd_devdata.dev = &e800_snd_device->dev;
70 ret = platform_device_add(e800_snd_device); 146 ret = platform_device_add(e800_snd_device);
71 147
72 if (ret) 148 if (!ret)
73 platform_device_put(e800_snd_device); 149 return 0;
150
151/* Fail gracefully */
152 platform_device_put(e800_snd_device);
153free_spk_amp_gpio:
154 gpio_free(GPIO_E800_SPK_AMP_ON);
155free_hp_amp_gpio:
156 gpio_free(GPIO_E800_HP_AMP_OFF);
74 157
75 return ret; 158 return ret;
76} 159}
@@ -78,6 +161,8 @@ static int __init e800_init(void)
78static void __exit e800_exit(void) 161static void __exit e800_exit(void)
79{ 162{
80 platform_device_unregister(e800_snd_device); 163 platform_device_unregister(e800_snd_device);
164 gpio_free(GPIO_E800_SPK_AMP_ON);
165 gpio_free(GPIO_E800_HP_AMP_OFF);
81} 166}
82 167
83module_init(e800_init); 168module_init(e800_init);
@@ -86,4 +171,4 @@ module_exit(e800_exit);
86/* Module information */ 171/* Module information */
87MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); 172MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
88MODULE_DESCRIPTION("ALSA SoC driver for e800"); 173MODULE_DESCRIPTION("ALSA SoC driver for e800");
89MODULE_LICENSE("GPL"); 174MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
new file mode 100644
index 000000000000..19eda8bbfdaf
--- /dev/null
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -0,0 +1,250 @@
1/*
2 * Handles the Mitac mioa701 SoC system
3 *
4 * Copyright (C) 2008 Robert Jarzmik
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation in version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * This is a little schema of the sound interconnections :
20 *
21 * Sagem X200 Wolfson WM9713
22 * +--------+ +-------------------+ Rear Speaker
23 * | | | | /-+
24 * | +--->----->---+MONOIN SPKL+--->----+-+ |
25 * | GSM | | | | | |
26 * | +--->----->---+PCBEEP SPKR+--->----+-+ |
27 * | CHIP | | | \-+
28 * | +---<-----<---+MONO |
29 * | | | | Front Speaker
30 * +--------+ | | /-+
31 * | HPL+--->----+-+ |
32 * | | | | |
33 * | OUT3+--->----+-+ |
34 * | | \-+
35 * | |
36 * | | Front Micro
37 * | | +
38 * | MIC1+-----<--+o+
39 * | | +
40 * +-------------------+ ---
41 */
42
43#include <linux/module.h>
44#include <linux/moduleparam.h>
45#include <linux/platform_device.h>
46
47#include <asm/mach-types.h>
48#include <mach/audio.h>
49
50#include <sound/core.h>
51#include <sound/pcm.h>
52#include <sound/soc.h>
53#include <sound/soc-dapm.h>
54#include <sound/initval.h>
55#include <sound/ac97_codec.h>
56
57#include "pxa2xx-pcm.h"
58#include "pxa2xx-ac97.h"
59#include "../codecs/wm9713.h"
60
61#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
62
63#define AC97_GPIO_PULL 0x58
64
65/* Use GPIO8 for rear speaker amplifier */
66static int rear_amp_power(struct snd_soc_codec *codec, int power)
67{
68 unsigned short reg;
69
70 if (power) {
71 reg = snd_soc_read(codec, AC97_GPIO_CFG);
72 snd_soc_write(codec, AC97_GPIO_CFG, reg | 0x0100);
73 reg = snd_soc_read(codec, AC97_GPIO_PULL);
74 snd_soc_write(codec, AC97_GPIO_PULL, reg | (1<<15));
75 } else {
76 reg = snd_soc_read(codec, AC97_GPIO_CFG);
77 snd_soc_write(codec, AC97_GPIO_CFG, reg & ~0x0100);
78 reg = snd_soc_read(codec, AC97_GPIO_PULL);
79 snd_soc_write(codec, AC97_GPIO_PULL, reg & ~(1<<15));
80 }
81
82 return 0;
83}
84
85static int rear_amp_event(struct snd_soc_dapm_widget *widget,
86 struct snd_kcontrol *kctl, int event)
87{
88 struct snd_soc_codec *codec = widget->codec;
89
90 return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event));
91}
92
93/* mioa701 machine dapm widgets */
94static const struct snd_soc_dapm_widget mioa701_dapm_widgets[] = {
95 SND_SOC_DAPM_SPK("Front Speaker", NULL),
96 SND_SOC_DAPM_SPK("Rear Speaker", rear_amp_event),
97 SND_SOC_DAPM_MIC("Headset", NULL),
98 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
99 SND_SOC_DAPM_LINE("GSM Line In", NULL),
100 SND_SOC_DAPM_MIC("Headset Mic", NULL),
101 SND_SOC_DAPM_MIC("Front Mic", NULL),
102};
103
104static const struct snd_soc_dapm_route audio_map[] = {
105 /* Call Mic */
106 {"Mic Bias", NULL, "Front Mic"},
107 {"MIC1", NULL, "Mic Bias"},
108
109 /* Headset Mic */
110 {"LINEL", NULL, "Headset Mic"},
111 {"LINER", NULL, "Headset Mic"},
112
113 /* GSM Module */
114 {"MONOIN", NULL, "GSM Line Out"},
115 {"PCBEEP", NULL, "GSM Line Out"},
116 {"GSM Line In", NULL, "MONO"},
117
118 /* headphone connected to HPL, HPR */
119 {"Headset", NULL, "HPL"},
120 {"Headset", NULL, "HPR"},
121
122 /* front speaker connected to HPL, OUT3 */
123 {"Front Speaker", NULL, "HPL"},
124 {"Front Speaker", NULL, "OUT3"},
125
126 /* rear speaker connected to SPKL, SPKR */
127 {"Rear Speaker", NULL, "SPKL"},
128 {"Rear Speaker", NULL, "SPKR"},
129};
130
131static int mioa701_wm9713_init(struct snd_soc_codec *codec)
132{
133 unsigned short reg;
134
135 /* Add mioa701 specific widgets */
136 snd_soc_dapm_new_controls(codec, ARRAY_AND_SIZE(mioa701_dapm_widgets));
137
138 /* Set up mioa701 specific audio path audio_mapnects */
139 snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map));
140
141 /* Prepare GPIO8 for rear speaker amplifier */
142 reg = codec->read(codec, AC97_GPIO_CFG);
143 codec->write(codec, AC97_GPIO_CFG, reg | 0x0100);
144
145 /* Prepare MIC input */
146 reg = codec->read(codec, AC97_3D_CONTROL);
147 codec->write(codec, AC97_3D_CONTROL, reg | 0xc000);
148
149 snd_soc_dapm_enable_pin(codec, "Front Speaker");
150 snd_soc_dapm_enable_pin(codec, "Rear Speaker");
151 snd_soc_dapm_enable_pin(codec, "Front Mic");
152 snd_soc_dapm_enable_pin(codec, "GSM Line In");
153 snd_soc_dapm_enable_pin(codec, "GSM Line Out");
154 snd_soc_dapm_sync(codec);
155
156 return 0;
157}
158
159static struct snd_soc_ops mioa701_ops;
160
161static struct snd_soc_dai_link mioa701_dai[] = {
162 {
163 .name = "AC97",
164 .stream_name = "AC97 HiFi",
165 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
166 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
167 .init = mioa701_wm9713_init,
168 .ops = &mioa701_ops,
169 },
170 {
171 .name = "AC97 Aux",
172 .stream_name = "AC97 Aux",
173 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
174 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX],
175 .ops = &mioa701_ops,
176 },
177};
178
179static struct snd_soc_card mioa701 = {
180 .name = "MioA701",
181 .platform = &pxa2xx_soc_platform,
182 .dai_link = mioa701_dai,
183 .num_links = ARRAY_SIZE(mioa701_dai),
184};
185
186static struct snd_soc_device mioa701_snd_devdata = {
187 .card = &mioa701,
188 .codec_dev = &soc_codec_dev_wm9713,
189};
190
191static struct platform_device *mioa701_snd_device;
192
193static int mioa701_wm9713_probe(struct platform_device *pdev)
194{
195 int ret;
196
197 if (!machine_is_mioa701())
198 return -ENODEV;
199
200 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will"
201 "lead to overheating and possible destruction of your device."
202 "Do not use without a good knowledge of mio's board design!\n");
203
204 mioa701_snd_device = platform_device_alloc("soc-audio", -1);
205 if (!mioa701_snd_device)
206 return -ENOMEM;
207
208 platform_set_drvdata(mioa701_snd_device, &mioa701_snd_devdata);
209 mioa701_snd_devdata.dev = &mioa701_snd_device->dev;
210
211 ret = platform_device_add(mioa701_snd_device);
212 if (!ret)
213 return 0;
214
215 platform_device_put(mioa701_snd_device);
216 return ret;
217}
218
219static int __devexit mioa701_wm9713_remove(struct platform_device *pdev)
220{
221 platform_device_unregister(mioa701_snd_device);
222 return 0;
223}
224
225static struct platform_driver mioa701_wm9713_driver = {
226 .probe = mioa701_wm9713_probe,
227 .remove = __devexit_p(mioa701_wm9713_remove),
228 .driver = {
229 .name = "mioa701-wm9713",
230 .owner = THIS_MODULE,
231 },
232};
233
234static int __init mioa701_asoc_init(void)
235{
236 return platform_driver_register(&mioa701_wm9713_driver);
237}
238
239static void __exit mioa701_asoc_exit(void)
240{
241 platform_driver_unregister(&mioa701_wm9713_driver);
242}
243
244module_init(mioa701_asoc_init);
245module_exit(mioa701_asoc_exit);
246
247/* Module information */
248MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)");
249MODULE_DESCRIPTION("ALSA SoC WM9713 MIO A701");
250MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 4a9cf3083af0..48a73f64500b 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -55,7 +55,7 @@ static void palm27x_ext_control(struct snd_soc_codec *codec)
55static int palm27x_startup(struct snd_pcm_substream *substream) 55static int palm27x_startup(struct snd_pcm_substream *substream)
56{ 56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data; 57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_codec *codec = rtd->socdev->codec; 58 struct snd_soc_codec *codec = rtd->socdev->card->codec;
59 59
60 /* check the jack status at stream startup */ 60 /* check the jack status at stream startup */
61 palm27x_ext_control(codec); 61 palm27x_ext_control(codec);
@@ -146,19 +146,16 @@ static const struct snd_kcontrol_new palm27x_controls[] = {
146 146
147static int palm27x_ac97_init(struct snd_soc_codec *codec) 147static int palm27x_ac97_init(struct snd_soc_codec *codec)
148{ 148{
149 int i, err; 149 int err;
150 150
151 snd_soc_dapm_nc_pin(codec, "OUT3"); 151 snd_soc_dapm_nc_pin(codec, "OUT3");
152 snd_soc_dapm_nc_pin(codec, "MONOOUT"); 152 snd_soc_dapm_nc_pin(codec, "MONOOUT");
153 153
154 /* add palm27x specific controls */ 154 /* add palm27x specific controls */
155 for (i = 0; i < ARRAY_SIZE(palm27x_controls); i++) { 155 err = snd_soc_add_controls(codec, palm27x_controls,
156 err = snd_ctl_add(codec->card, 156 ARRAY_SIZE(palm27x_controls));
157 snd_soc_cnew(&palm27x_controls[i], 157 if (err < 0)
158 codec, NULL)); 158 return err;
159 if (err < 0)
160 return err;
161 }
162 159
163 /* add palm27x specific widgets */ 160 /* add palm27x specific widgets */
164 snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, 161 snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 6e9827189fff..ef7c6c8dc8f1 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
19#include <linux/timer.h> 19#include <linux/timer.h>
20#include <linux/i2c.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <sound/core.h> 23#include <sound/core.h>
@@ -77,7 +78,7 @@ static void poodle_ext_control(struct snd_soc_codec *codec)
77static int poodle_startup(struct snd_pcm_substream *substream) 78static int poodle_startup(struct snd_pcm_substream *substream)
78{ 79{
79 struct snd_soc_pcm_runtime *rtd = substream->private_data; 80 struct snd_soc_pcm_runtime *rtd = substream->private_data;
80 struct snd_soc_codec *codec = rtd->socdev->codec; 81 struct snd_soc_codec *codec = rtd->socdev->card->codec;
81 82
82 /* check the jack status at stream startup */ 83 /* check the jack status at stream startup */
83 poodle_ext_control(codec); 84 poodle_ext_control(codec);
@@ -240,19 +241,17 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = {
240 */ 241 */
241static int poodle_wm8731_init(struct snd_soc_codec *codec) 242static int poodle_wm8731_init(struct snd_soc_codec *codec)
242{ 243{
243 int i, err; 244 int err;
244 245
245 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 246 snd_soc_dapm_nc_pin(codec, "LLINEIN");
246 snd_soc_dapm_nc_pin(codec, "RLINEIN"); 247 snd_soc_dapm_nc_pin(codec, "RLINEIN");
247 snd_soc_dapm_enable_pin(codec, "MICIN"); 248 snd_soc_dapm_enable_pin(codec, "MICIN");
248 249
249 /* Add poodle specific controls */ 250 /* Add poodle specific controls */
250 for (i = 0; i < ARRAY_SIZE(wm8731_poodle_controls); i++) { 251 err = snd_soc_add_controls(codec, wm8731_poodle_controls,
251 err = snd_ctl_add(codec->card, 252 ARRAY_SIZE(wm8731_poodle_controls));
252 snd_soc_cnew(&wm8731_poodle_controls[i], codec, NULL)); 253 if (err < 0)
253 if (err < 0) 254 return err;
254 return err;
255 }
256 255
257 /* Add poodle specific widgets */ 256 /* Add poodle specific widgets */
258 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, 257 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
@@ -283,17 +282,42 @@ static struct snd_soc_card snd_soc_poodle = {
283 .num_links = 1, 282 .num_links = 1,
284}; 283};
285 284
286/* poodle audio private data */ 285/*
287static struct wm8731_setup_data poodle_wm8731_setup = { 286 * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
288 .i2c_bus = 0, 287 * New drivers should register the wm8731 I2C device in the machine
289 .i2c_address = 0x1b, 288 * setup code (under arch/arm for ARM systems).
290}; 289 */
290static int wm8731_i2c_register(void)
291{
292 struct i2c_board_info info;
293 struct i2c_adapter *adapter;
294 struct i2c_client *client;
295
296 memset(&info, 0, sizeof(struct i2c_board_info));
297 info.addr = 0x1b;
298 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
299
300 adapter = i2c_get_adapter(0);
301 if (!adapter) {
302 printk(KERN_ERR "can't get i2c adapter 0\n");
303 return -ENODEV;
304 }
305
306 client = i2c_new_device(adapter, &info);
307 i2c_put_adapter(adapter);
308 if (!client) {
309 printk(KERN_ERR "can't add i2c device at 0x%x\n",
310 (unsigned int)info.addr);
311 return -ENODEV;
312 }
313
314 return 0;
315}
291 316
292/* poodle audio subsystem */ 317/* poodle audio subsystem */
293static struct snd_soc_device poodle_snd_devdata = { 318static struct snd_soc_device poodle_snd_devdata = {
294 .card = &snd_soc_poodle, 319 .card = &snd_soc_poodle,
295 .codec_dev = &soc_codec_dev_wm8731, 320 .codec_dev = &soc_codec_dev_wm8731,
296 .codec_data = &poodle_wm8731_setup,
297}; 321};
298 322
299static struct platform_device *poodle_snd_device; 323static struct platform_device *poodle_snd_device;
@@ -305,6 +329,10 @@ static int __init poodle_init(void)
305 if (!machine_is_poodle()) 329 if (!machine_is_poodle())
306 return -ENODEV; 330 return -ENODEV;
307 331
332 ret = wm8731_i2c_register();
333 if (ret != 0)
334 return ret;
335
308 locomo_gpio_set_dir(&poodle_locomo_device.dev, 336 locomo_gpio_set_dir(&poodle_locomo_device.dev,
309 POODLE_LOCOMO_GPIO_AMP_ON, 0); 337 POODLE_LOCOMO_GPIO_AMP_ON, 0);
310 /* should we mute HP at startup - burning power ?*/ 338 /* should we mute HP at startup - burning power ?*/
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 73cb6b4c2f2d..b0bf40973d5b 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -1,4 +1,3 @@
1#define DEBUG
2/* 1/*
3 * pxa-ssp.c -- ALSA Soc Audio Layer 2 * pxa-ssp.c -- ALSA Soc Audio Layer
4 * 3 *
@@ -21,6 +20,8 @@
21#include <linux/clk.h> 20#include <linux/clk.h>
22#include <linux/io.h> 21#include <linux/io.h>
23 22
23#include <asm/irq.h>
24
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/initval.h> 27#include <sound/initval.h>
@@ -221,9 +222,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
221 int ret = 0; 222 int ret = 0;
222 223
223 if (!cpu_dai->active) { 224 if (!cpu_dai->active) {
224 ret = ssp_init(&priv->dev, cpu_dai->id + 1, SSP_NO_IRQ); 225 priv->dev.port = cpu_dai->id + 1;
225 if (ret < 0) 226 priv->dev.irq = NO_IRQ;
226 return ret; 227 clk_enable(priv->dev.ssp->clk);
227 ssp_disable(&priv->dev); 228 ssp_disable(&priv->dev);
228 } 229 }
229 return ret; 230 return ret;
@@ -238,7 +239,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
238 239
239 if (!cpu_dai->active) { 240 if (!cpu_dai->active) {
240 ssp_disable(&priv->dev); 241 ssp_disable(&priv->dev);
241 ssp_exit(&priv->dev); 242 clk_disable(priv->dev.ssp->clk);
242 } 243 }
243} 244}
244 245
@@ -298,7 +299,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
298 int val; 299 int val;
299 300
300 u32 sscr0 = ssp_read_reg(ssp, SSCR0) & 301 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
301 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC); 302 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
302 303
303 dev_dbg(&ssp->pdev->dev, 304 dev_dbg(&ssp->pdev->dev,
304 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n", 305 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n",
@@ -326,7 +327,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
326 case PXA_SSP_CLK_AUDIO: 327 case PXA_SSP_CLK_AUDIO:
327 priv->sysclk = 0; 328 priv->sysclk = 0;
328 ssp_set_scr(&priv->dev, 1); 329 ssp_set_scr(&priv->dev, 1);
329 sscr0 |= SSCR0_ADC; 330 sscr0 |= SSCR0_ACS;
330 break; 331 break;
331 default: 332 default:
332 return -ENODEV; 333 return -ENODEV;
@@ -520,9 +521,20 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
520 u32 sscr1; 521 u32 sscr1;
521 u32 sspsp; 522 u32 sspsp;
522 523
524 /* check if we need to change anything at all */
525 if (priv->dai_fmt == fmt)
526 return 0;
527
528 /* we can only change the settings if the port is not in use */
529 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
530 dev_err(&ssp->pdev->dev,
531 "can't change hardware dai format: stream is in use");
532 return -EINVAL;
533 }
534
523 /* reset port settings */ 535 /* reset port settings */
524 sscr0 = ssp_read_reg(ssp, SSCR0) & 536 sscr0 = ssp_read_reg(ssp, SSCR0) &
525 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC); 537 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
526 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); 538 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
527 sspsp = 0; 539 sspsp = 0;
528 540
@@ -545,18 +557,18 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
545 557
546 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 558 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
547 case SND_SOC_DAIFMT_I2S: 559 case SND_SOC_DAIFMT_I2S:
548 sscr0 |= SSCR0_MOD | SSCR0_PSP; 560 sscr0 |= SSCR0_PSP;
549 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; 561 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
550 562
563 /* See hw_params() */
551 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 564 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
552 case SND_SOC_DAIFMT_NB_NF: 565 case SND_SOC_DAIFMT_NB_NF:
553 sspsp |= SSPSP_FSRT; 566 sspsp |= SSPSP_SFRMP;
554 break; 567 break;
555 case SND_SOC_DAIFMT_NB_IF: 568 case SND_SOC_DAIFMT_NB_IF:
556 sspsp |= SSPSP_SFRMP | SSPSP_FSRT;
557 break; 569 break;
558 case SND_SOC_DAIFMT_IB_IF: 570 case SND_SOC_DAIFMT_IB_IF:
559 sspsp |= SSPSP_SFRMP; 571 sspsp |= SSPSP_SCMODE(3);
560 break; 572 break;
561 default: 573 default:
562 return -EINVAL; 574 return -EINVAL;
@@ -642,34 +654,65 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
642 sscr0 |= SSCR0_FPCKE; 654 sscr0 |= SSCR0_FPCKE;
643#endif 655#endif
644 sscr0 |= SSCR0_DataSize(16); 656 sscr0 |= SSCR0_DataSize(16);
645 if (params_channels(params) > 1)
646 sscr0 |= SSCR0_EDSS;
647 break; 657 break;
648 case SNDRV_PCM_FORMAT_S24_LE: 658 case SNDRV_PCM_FORMAT_S24_LE:
649 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8)); 659 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
650 /* we must be in network mode (2 slots) for 24 bit stereo */
651 break; 660 break;
652 case SNDRV_PCM_FORMAT_S32_LE: 661 case SNDRV_PCM_FORMAT_S32_LE:
653 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); 662 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
654 /* we must be in network mode (2 slots) for 32 bit stereo */
655 break; 663 break;
656 } 664 }
657 ssp_write_reg(ssp, SSCR0, sscr0); 665 ssp_write_reg(ssp, SSCR0, sscr0);
658 666
659 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 667 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
660 case SND_SOC_DAIFMT_I2S: 668 case SND_SOC_DAIFMT_I2S:
661 /* Cleared when the DAI format is set */ 669 sspsp = ssp_read_reg(ssp, SSPSP);
662 sspsp = ssp_read_reg(ssp, SSPSP) | SSPSP_SFRMWDTH(width); 670
671 if (((sscr0 & SSCR0_SCR) == SSCR0_SerClkDiv(4)) &&
672 (width == 16)) {
673 /* This is a special case where the bitclk is 64fs
674 * and we're not dealing with 2*32 bits of audio
675 * samples.
676 *
677 * The SSP values used for that are all found out by
678 * trying and failing a lot; some of the registers
679 * needed for that mode are only available on PXA3xx.
680 */
681
682#ifdef CONFIG_PXA3xx
683 if (!cpu_is_pxa3xx())
684 return -EINVAL;
685
686 sspsp |= SSPSP_SFRMWDTH(width * 2);
687 sspsp |= SSPSP_SFRMDLY(width * 4);
688 sspsp |= SSPSP_EDMYSTOP(3);
689 sspsp |= SSPSP_DMYSTOP(3);
690 sspsp |= SSPSP_DMYSTRT(1);
691#else
692 return -EINVAL;
693#endif
694 } else {
695 /* The frame width is the width the LRCLK is
696 * asserted for; the delay is expressed in
697 * half cycle units. We need the extra cycle
698 * because the data starts clocking out one BCLK
699 * after LRCLK changes polarity.
700 */
701 sspsp |= SSPSP_SFRMWDTH(width + 1);
702 sspsp |= SSPSP_SFRMDLY((width + 1) * 2);
703 sspsp |= SSPSP_DMYSTRT(1);
704 }
705
663 ssp_write_reg(ssp, SSPSP, sspsp); 706 ssp_write_reg(ssp, SSPSP, sspsp);
664 break; 707 break;
665 default: 708 default:
666 break; 709 break;
667 } 710 }
668 711
669 /* We always use a network mode so we always require TDM slots 712 /* When we use a network mode, we always require TDM slots
670 * - complain loudly and fail if they've not been set up yet. 713 * - complain loudly and fail if they've not been set up yet.
671 */ 714 */
672 if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) { 715 if ((sscr0 & SSCR0_MOD) && !(ssp_read_reg(ssp, SSTSA) & 0xf)) {
673 dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n"); 716 dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
674 return -EINVAL; 717 return -EINVAL;
675 } 718 }
@@ -751,7 +794,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
751 if (!priv) 794 if (!priv)
752 return -ENOMEM; 795 return -ENOMEM;
753 796
754 priv->dev.ssp = ssp_request(dai->id, "SoC audio"); 797 priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio");
755 if (priv->dev.ssp == NULL) { 798 if (priv->dev.ssp == NULL) {
756 ret = -ENODEV; 799 ret = -ENODEV;
757 goto err_priv; 800 goto err_priv;
@@ -782,6 +825,19 @@ static void pxa_ssp_remove(struct platform_device *pdev,
782 SNDRV_PCM_FMTBIT_S24_LE | \ 825 SNDRV_PCM_FMTBIT_S24_LE | \
783 SNDRV_PCM_FMTBIT_S32_LE) 826 SNDRV_PCM_FMTBIT_S32_LE)
784 827
828static struct snd_soc_dai_ops pxa_ssp_dai_ops = {
829 .startup = pxa_ssp_startup,
830 .shutdown = pxa_ssp_shutdown,
831 .trigger = pxa_ssp_trigger,
832 .hw_params = pxa_ssp_hw_params,
833 .set_sysclk = pxa_ssp_set_dai_sysclk,
834 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
835 .set_pll = pxa_ssp_set_dai_pll,
836 .set_fmt = pxa_ssp_set_dai_fmt,
837 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
838 .set_tristate = pxa_ssp_set_dai_tristate,
839};
840
785struct snd_soc_dai pxa_ssp_dai[] = { 841struct snd_soc_dai pxa_ssp_dai[] = {
786 { 842 {
787 .name = "pxa2xx-ssp1", 843 .name = "pxa2xx-ssp1",
@@ -802,18 +858,7 @@ struct snd_soc_dai pxa_ssp_dai[] = {
802 .rates = PXA_SSP_RATES, 858 .rates = PXA_SSP_RATES,
803 .formats = PXA_SSP_FORMATS, 859 .formats = PXA_SSP_FORMATS,
804 }, 860 },
805 .ops = { 861 .ops = &pxa_ssp_dai_ops,
806 .startup = pxa_ssp_startup,
807 .shutdown = pxa_ssp_shutdown,
808 .trigger = pxa_ssp_trigger,
809 .hw_params = pxa_ssp_hw_params,
810 .set_sysclk = pxa_ssp_set_dai_sysclk,
811 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
812 .set_pll = pxa_ssp_set_dai_pll,
813 .set_fmt = pxa_ssp_set_dai_fmt,
814 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
815 .set_tristate = pxa_ssp_set_dai_tristate,
816 },
817 }, 862 },
818 { .name = "pxa2xx-ssp2", 863 { .name = "pxa2xx-ssp2",
819 .id = 1, 864 .id = 1,
@@ -833,18 +878,7 @@ struct snd_soc_dai pxa_ssp_dai[] = {
833 .rates = PXA_SSP_RATES, 878 .rates = PXA_SSP_RATES,
834 .formats = PXA_SSP_FORMATS, 879 .formats = PXA_SSP_FORMATS,
835 }, 880 },
836 .ops = { 881 .ops = &pxa_ssp_dai_ops,
837 .startup = pxa_ssp_startup,
838 .shutdown = pxa_ssp_shutdown,
839 .trigger = pxa_ssp_trigger,
840 .hw_params = pxa_ssp_hw_params,
841 .set_sysclk = pxa_ssp_set_dai_sysclk,
842 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
843 .set_pll = pxa_ssp_set_dai_pll,
844 .set_fmt = pxa_ssp_set_dai_fmt,
845 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
846 .set_tristate = pxa_ssp_set_dai_tristate,
847 },
848 }, 882 },
849 { 883 {
850 .name = "pxa2xx-ssp3", 884 .name = "pxa2xx-ssp3",
@@ -865,18 +899,7 @@ struct snd_soc_dai pxa_ssp_dai[] = {
865 .rates = PXA_SSP_RATES, 899 .rates = PXA_SSP_RATES,
866 .formats = PXA_SSP_FORMATS, 900 .formats = PXA_SSP_FORMATS,
867 }, 901 },
868 .ops = { 902 .ops = &pxa_ssp_dai_ops,
869 .startup = pxa_ssp_startup,
870 .shutdown = pxa_ssp_shutdown,
871 .trigger = pxa_ssp_trigger,
872 .hw_params = pxa_ssp_hw_params,
873 .set_sysclk = pxa_ssp_set_dai_sysclk,
874 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
875 .set_pll = pxa_ssp_set_dai_pll,
876 .set_fmt = pxa_ssp_set_dai_fmt,
877 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
878 .set_tristate = pxa_ssp_set_dai_tristate,
879 },
880 }, 903 },
881 { 904 {
882 .name = "pxa2xx-ssp4", 905 .name = "pxa2xx-ssp4",
@@ -897,18 +920,7 @@ struct snd_soc_dai pxa_ssp_dai[] = {
897 .rates = PXA_SSP_RATES, 920 .rates = PXA_SSP_RATES,
898 .formats = PXA_SSP_FORMATS, 921 .formats = PXA_SSP_FORMATS,
899 }, 922 },
900 .ops = { 923 .ops = &pxa_ssp_dai_ops,
901 .startup = pxa_ssp_startup,
902 .shutdown = pxa_ssp_shutdown,
903 .trigger = pxa_ssp_trigger,
904 .hw_params = pxa_ssp_hw_params,
905 .set_sysclk = pxa_ssp_set_dai_sysclk,
906 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
907 .set_pll = pxa_ssp_set_dai_pll,
908 .set_fmt = pxa_ssp_set_dai_fmt,
909 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
910 .set_tristate = pxa_ssp_set_dai_tristate,
911 },
912 }, 924 },
913}; 925};
914EXPORT_SYMBOL_GPL(pxa_ssp_dai); 926EXPORT_SYMBOL_GPL(pxa_ssp_dai);
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 812c2b4d3e07..01c21c6cdbbc 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -106,13 +106,13 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
106static int pxa2xx_ac97_probe(struct platform_device *pdev, 106static int pxa2xx_ac97_probe(struct platform_device *pdev,
107 struct snd_soc_dai *dai) 107 struct snd_soc_dai *dai)
108{ 108{
109 return pxa2xx_ac97_hw_probe(pdev); 109 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
110} 110}
111 111
112static void pxa2xx_ac97_remove(struct platform_device *pdev, 112static void pxa2xx_ac97_remove(struct platform_device *pdev,
113 struct snd_soc_dai *dai) 113 struct snd_soc_dai *dai)
114{ 114{
115 pxa2xx_ac97_hw_remove(pdev); 115 pxa2xx_ac97_hw_remove(to_platform_device(dai->dev));
116} 116}
117 117
118static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 118static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
@@ -164,6 +164,18 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
164 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ 164 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
165 SNDRV_PCM_RATE_48000) 165 SNDRV_PCM_RATE_48000)
166 166
167static struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
168 .hw_params = pxa2xx_ac97_hw_params,
169};
170
171static struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
172 .hw_params = pxa2xx_ac97_hw_aux_params,
173};
174
175static struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
176 .hw_params = pxa2xx_ac97_hw_mic_params,
177};
178
167/* 179/*
168 * There is only 1 physical AC97 interface for pxa2xx, but it 180 * There is only 1 physical AC97 interface for pxa2xx, but it
169 * has extra fifo's that can be used for aux DACs and ADCs. 181 * has extra fifo's that can be used for aux DACs and ADCs.
@@ -189,8 +201,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
189 .channels_max = 2, 201 .channels_max = 2,
190 .rates = PXA2XX_AC97_RATES, 202 .rates = PXA2XX_AC97_RATES,
191 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 203 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
192 .ops = { 204 .ops = &pxa_ac97_hifi_dai_ops,
193 .hw_params = pxa2xx_ac97_hw_params,},
194}, 205},
195{ 206{
196 .name = "pxa2xx-ac97-aux", 207 .name = "pxa2xx-ac97-aux",
@@ -208,8 +219,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
208 .channels_max = 1, 219 .channels_max = 1,
209 .rates = PXA2XX_AC97_RATES, 220 .rates = PXA2XX_AC97_RATES,
210 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 221 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
211 .ops = { 222 .ops = &pxa_ac97_aux_dai_ops,
212 .hw_params = pxa2xx_ac97_hw_aux_params,},
213}, 223},
214{ 224{
215 .name = "pxa2xx-ac97-mic", 225 .name = "pxa2xx-ac97-mic",
@@ -221,23 +231,52 @@ struct snd_soc_dai pxa_ac97_dai[] = {
221 .channels_max = 1, 231 .channels_max = 1,
222 .rates = PXA2XX_AC97_RATES, 232 .rates = PXA2XX_AC97_RATES,
223 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 233 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
224 .ops = { 234 .ops = &pxa_ac97_mic_dai_ops,
225 .hw_params = pxa2xx_ac97_hw_mic_params,},
226}, 235},
227}; 236};
228 237
229EXPORT_SYMBOL_GPL(pxa_ac97_dai); 238EXPORT_SYMBOL_GPL(pxa_ac97_dai);
230EXPORT_SYMBOL_GPL(soc_ac97_ops); 239EXPORT_SYMBOL_GPL(soc_ac97_ops);
231 240
232static int __init pxa_ac97_init(void) 241static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev)
233{ 242{
243 int i;
244
245 for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++)
246 pxa_ac97_dai[i].dev = &pdev->dev;
247
248 /* Punt most of the init to the SoC probe; we may need the machine
249 * driver to do interesting things with the clocking to get us up
250 * and running.
251 */
234 return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); 252 return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
235} 253}
254
255static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
256{
257 snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
258
259 return 0;
260}
261
262static struct platform_driver pxa2xx_ac97_driver = {
263 .probe = pxa2xx_ac97_dev_probe,
264 .remove = __devexit_p(pxa2xx_ac97_dev_remove),
265 .driver = {
266 .name = "pxa2xx-ac97",
267 .owner = THIS_MODULE,
268 },
269};
270
271static int __init pxa_ac97_init(void)
272{
273 return platform_driver_register(&pxa2xx_ac97_driver);
274}
236module_init(pxa_ac97_init); 275module_init(pxa_ac97_init);
237 276
238static void __exit pxa_ac97_exit(void) 277static void __exit pxa_ac97_exit(void)
239{ 278{
240 snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); 279 platform_driver_unregister(&pxa2xx_ac97_driver);
241} 280}
242module_exit(pxa_ac97_exit); 281module_exit(pxa_ac97_exit);
243 282
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 517991fb1099..e6c24408c5f9 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -25,20 +25,11 @@
25 25
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <mach/pxa-regs.h> 27#include <mach/pxa-regs.h>
28#include <mach/pxa2xx-gpio.h>
29#include <mach/audio.h> 28#include <mach/audio.h>
30 29
31#include "pxa2xx-pcm.h" 30#include "pxa2xx-pcm.h"
32#include "pxa2xx-i2s.h" 31#include "pxa2xx-i2s.h"
33 32
34struct pxa2xx_gpio {
35 u32 sys;
36 u32 rx;
37 u32 tx;
38 u32 clk;
39 u32 frm;
40};
41
42/* 33/*
43 * I2S Controller Register and Bit Definitions 34 * I2S Controller Register and Bit Definitions
44 */ 35 */
@@ -106,21 +97,6 @@ static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = {
106 DCMD_BURST32 | DCMD_WIDTH4, 97 DCMD_BURST32 | DCMD_WIDTH4,
107}; 98};
108 99
109static struct pxa2xx_gpio gpio_bus[] = {
110 { /* I2S SoC Slave */
111 .rx = GPIO29_SDATA_IN_I2S_MD,
112 .tx = GPIO30_SDATA_OUT_I2S_MD,
113 .clk = GPIO28_BITCLK_IN_I2S_MD,
114 .frm = GPIO31_SYNC_I2S_MD,
115 },
116 { /* I2S SoC Master */
117 .rx = GPIO29_SDATA_IN_I2S_MD,
118 .tx = GPIO30_SDATA_OUT_I2S_MD,
119 .clk = GPIO28_BITCLK_OUT_I2S_MD,
120 .frm = GPIO31_SYNC_I2S_MD,
121 },
122};
123
124static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream, 100static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
125 struct snd_soc_dai *dai) 101 struct snd_soc_dai *dai)
126{ 102{
@@ -181,9 +157,6 @@ static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
181 if (clk_id != PXA2XX_I2S_SYSCLK) 157 if (clk_id != PXA2XX_I2S_SYSCLK)
182 return -ENODEV; 158 return -ENODEV;
183 159
184 if (pxa_i2s.master && dir == SND_SOC_CLOCK_OUT)
185 pxa_gpio_mode(gpio_bus[pxa_i2s.master].sys);
186
187 return 0; 160 return 0;
188} 161}
189 162
@@ -194,10 +167,6 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
194 struct snd_soc_pcm_runtime *rtd = substream->private_data; 167 struct snd_soc_pcm_runtime *rtd = substream->private_data;
195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 168 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
196 169
197 pxa_gpio_mode(gpio_bus[pxa_i2s.master].rx);
198 pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx);
199 pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm);
200 pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk);
201 BUG_ON(IS_ERR(clk_i2s)); 170 BUG_ON(IS_ERR(clk_i2s));
202 clk_enable(clk_i2s); 171 clk_enable(clk_i2s);
203 pxa_i2s_wait(); 172 pxa_i2s_wait();
@@ -335,6 +304,15 @@ static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
335 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ 304 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
336 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) 305 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
337 306
307static struct snd_soc_dai_ops pxa_i2s_dai_ops = {
308 .startup = pxa2xx_i2s_startup,
309 .shutdown = pxa2xx_i2s_shutdown,
310 .trigger = pxa2xx_i2s_trigger,
311 .hw_params = pxa2xx_i2s_hw_params,
312 .set_fmt = pxa2xx_i2s_set_dai_fmt,
313 .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
314};
315
338struct snd_soc_dai pxa_i2s_dai = { 316struct snd_soc_dai pxa_i2s_dai = {
339 .name = "pxa2xx-i2s", 317 .name = "pxa2xx-i2s",
340 .id = 0, 318 .id = 0,
@@ -350,14 +328,7 @@ struct snd_soc_dai pxa_i2s_dai = {
350 .channels_max = 2, 328 .channels_max = 2,
351 .rates = PXA2XX_I2S_RATES, 329 .rates = PXA2XX_I2S_RATES,
352 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 330 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
353 .ops = { 331 .ops = &pxa_i2s_dai_ops,
354 .startup = pxa2xx_i2s_startup,
355 .shutdown = pxa2xx_i2s_shutdown,
356 .trigger = pxa2xx_i2s_trigger,
357 .hw_params = pxa2xx_i2s_hw_params,
358 .set_fmt = pxa2xx_i2s_set_dai_fmt,
359 .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
360 },
361}; 332};
362 333
363EXPORT_SYMBOL_GPL(pxa_i2s_dai); 334EXPORT_SYMBOL_GPL(pxa_i2s_dai);
@@ -398,11 +369,6 @@ static struct platform_driver pxa2xx_i2s_driver = {
398 369
399static int __init pxa2xx_i2s_init(void) 370static int __init pxa2xx_i2s_init(void)
400{ 371{
401 if (cpu_is_pxa27x())
402 gpio_bus[1].sys = GPIO113_I2S_SYSCLK_MD;
403 else
404 gpio_bus[1].sys = GPIO32_SYSCLK_I2S_MD;
405
406 clk_i2s = ERR_PTR(-ENOENT); 372 clk_i2s = ERR_PTR(-ENOENT);
407 return platform_driver_register(&pxa2xx_i2s_driver); 373 return platform_driver_register(&pxa2xx_i2s_driver);
408} 374}
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index a3b9e6bdf979..6ca9f53080c6 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -109,7 +109,7 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
109static int spitz_startup(struct snd_pcm_substream *substream) 109static int spitz_startup(struct snd_pcm_substream *substream)
110{ 110{
111 struct snd_soc_pcm_runtime *rtd = substream->private_data; 111 struct snd_soc_pcm_runtime *rtd = substream->private_data;
112 struct snd_soc_codec *codec = rtd->socdev->codec; 112 struct snd_soc_codec *codec = rtd->socdev->card->codec;
113 113
114 /* check the jack status at stream startup */ 114 /* check the jack status at stream startup */
115 spitz_ext_control(codec); 115 spitz_ext_control(codec);
@@ -278,7 +278,7 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
278 */ 278 */
279static int spitz_wm8750_init(struct snd_soc_codec *codec) 279static int spitz_wm8750_init(struct snd_soc_codec *codec)
280{ 280{
281 int i, err; 281 int err;
282 282
283 /* NC codec pins */ 283 /* NC codec pins */
284 snd_soc_dapm_nc_pin(codec, "RINPUT1"); 284 snd_soc_dapm_nc_pin(codec, "RINPUT1");
@@ -290,12 +290,10 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
290 snd_soc_dapm_nc_pin(codec, "MONO1"); 290 snd_soc_dapm_nc_pin(codec, "MONO1");
291 291
292 /* Add spitz specific controls */ 292 /* Add spitz specific controls */
293 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { 293 err = snd_soc_add_controls(codec, wm8750_spitz_controls,
294 err = snd_ctl_add(codec->card, 294 ARRAY_SIZE(wm8750_spitz_controls));
295 snd_soc_cnew(&wm8750_spitz_controls[i], codec, NULL)); 295 if (err < 0)
296 if (err < 0) 296 return err;
297 return err;
298 }
299 297
300 /* Add spitz specific widgets */ 298 /* Add spitz specific widgets */
301 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, 299 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index c77194f74c9b..fc781374b1bf 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -82,7 +82,7 @@ static void tosa_ext_control(struct snd_soc_codec *codec)
82static int tosa_startup(struct snd_pcm_substream *substream) 82static int tosa_startup(struct snd_pcm_substream *substream)
83{ 83{
84 struct snd_soc_pcm_runtime *rtd = substream->private_data; 84 struct snd_soc_pcm_runtime *rtd = substream->private_data;
85 struct snd_soc_codec *codec = rtd->socdev->codec; 85 struct snd_soc_codec *codec = rtd->socdev->card->codec;
86 86
87 /* check the jack status at stream startup */ 87 /* check the jack status at stream startup */
88 tosa_ext_control(codec); 88 tosa_ext_control(codec);
@@ -188,18 +188,16 @@ static const struct snd_kcontrol_new tosa_controls[] = {
188 188
189static int tosa_ac97_init(struct snd_soc_codec *codec) 189static int tosa_ac97_init(struct snd_soc_codec *codec)
190{ 190{
191 int i, err; 191 int err;
192 192
193 snd_soc_dapm_nc_pin(codec, "OUT3"); 193 snd_soc_dapm_nc_pin(codec, "OUT3");
194 snd_soc_dapm_nc_pin(codec, "MONOOUT"); 194 snd_soc_dapm_nc_pin(codec, "MONOOUT");
195 195
196 /* add tosa specific controls */ 196 /* add tosa specific controls */
197 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { 197 err = snd_soc_add_controls(codec, tosa_controls,
198 err = snd_ctl_add(codec->card, 198 ARRAY_SIZE(tosa_controls));
199 snd_soc_cnew(&tosa_controls[i],codec, NULL)); 199 if (err < 0)
200 if (err < 0) 200 return err;
201 return err;
202 }
203 201
204 /* add tosa specific widgets */ 202 /* add tosa specific widgets */
205 snd_soc_dapm_new_controls(codec, tosa_dapm_widgets, 203 snd_soc_dapm_new_controls(codec, tosa_dapm_widgets,
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index f8e9ecd589d3..9a386b4c4ed1 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/clk.h>
17#include <linux/i2c.h> 18#include <linux/i2c.h>
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
@@ -26,6 +27,17 @@
26#include "pxa2xx-ac97.h" 27#include "pxa2xx-ac97.h"
27#include "pxa-ssp.h" 28#include "pxa-ssp.h"
28 29
30/*
31 * There is a physical switch SW15 on the board which changes the MCLK
32 * for the WM9713 between the standard AC97 master clock and the
33 * output of the CLK_POUT signal from the PXA.
34 */
35static int clk_pout;
36module_param(clk_pout, int, 0);
37MODULE_PARM_DESC(clk_pout, "Use CLK_POUT as WM9713 MCLK (SW15 on board).");
38
39static struct clk *pout;
40
29static struct snd_soc_card zylonite; 41static struct snd_soc_card zylonite;
30 42
31static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = { 43static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = {
@@ -61,10 +73,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
61 73
62static int zylonite_wm9713_init(struct snd_soc_codec *codec) 74static int zylonite_wm9713_init(struct snd_soc_codec *codec)
63{ 75{
64 /* Currently we only support use of the AC97 clock here. If 76 if (clk_pout)
65 * CLK_POUT is selected by SW15 then the clock API will need 77 snd_soc_dai_set_pll(&codec->dai[0], 0, clk_get_rate(pout), 0);
66 * to be used to request and enable it here.
67 */
68 78
69 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, 79 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
70 ARRAY_SIZE(zylonite_dapm_widgets)); 80 ARRAY_SIZE(zylonite_dapm_widgets));
@@ -86,40 +96,35 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
86 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 96 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
87 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 97 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
88 unsigned int pll_out = 0; 98 unsigned int pll_out = 0;
89 unsigned int acds = 0;
90 unsigned int wm9713_div = 0; 99 unsigned int wm9713_div = 0;
91 int ret = 0; 100 int ret = 0;
101 int rate = params_rate(params);
102 int width = snd_pcm_format_physical_width(params_format(params));
92 103
93 switch (params_rate(params)) { 104 /* Only support ratios that we can generate neatly from the AC97
105 * based master clock - in particular, this excludes 44.1kHz.
106 * In most applications the voice DAC will be used for telephony
107 * data so multiples of 8kHz will be the common case.
108 */
109 switch (rate) {
94 case 8000: 110 case 8000:
95 wm9713_div = 12; 111 wm9713_div = 12;
96 pll_out = 2048000;
97 break; 112 break;
98 case 16000: 113 case 16000:
99 wm9713_div = 6; 114 wm9713_div = 6;
100 pll_out = 4096000;
101 break; 115 break;
102 case 48000: 116 case 48000:
103 default:
104 wm9713_div = 2; 117 wm9713_div = 2;
105 pll_out = 12288000;
106 acds = 1;
107 break; 118 break;
119 default:
120 /* Don't support OSS emulation */
121 return -EINVAL;
108 } 122 }
109 123
110 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 124 /* Add 1 to the width for the leading clock cycle */
111 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 125 pll_out = rate * (width + 1) * 8;
112 if (ret < 0)
113 return ret;
114
115 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
116 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
117 if (ret < 0)
118 return ret;
119 126
120 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 127 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
121 params_channels(params),
122 params_channels(params));
123 if (ret < 0) 128 if (ret < 0)
124 return ret; 129 return ret;
125 130
@@ -127,19 +132,22 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
127 if (ret < 0) 132 if (ret < 0)
128 return ret; 133 return ret;
129 134
130 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, acds); 135 if (clk_pout)
136 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV,
137 WM9713_PCMDIV(wm9713_div));
138 else
139 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
140 WM9713_PCMDIV(wm9713_div));
131 if (ret < 0) 141 if (ret < 0)
132 return ret; 142 return ret;
133 143
134 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1); 144 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
145 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
135 if (ret < 0) 146 if (ret < 0)
136 return ret; 147 return ret;
137 148
138 /* Note that if the PLL is in use the WM9713_PCMCLK_PLL_DIV needs 149 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
139 * to be set instead. 150 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
140 */
141 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
142 WM9713_PCMDIV(wm9713_div));
143 if (ret < 0) 151 if (ret < 0)
144 return ret; 152 return ret;
145 153
@@ -173,8 +181,72 @@ static struct snd_soc_dai_link zylonite_dai[] = {
173}, 181},
174}; 182};
175 183
184static int zylonite_probe(struct platform_device *pdev)
185{
186 int ret;
187
188 if (clk_pout) {
189 pout = clk_get(NULL, "CLK_POUT");
190 if (IS_ERR(pout)) {
191 dev_err(&pdev->dev, "Unable to obtain CLK_POUT: %ld\n",
192 PTR_ERR(pout));
193 return PTR_ERR(pout);
194 }
195
196 ret = clk_enable(pout);
197 if (ret != 0) {
198 dev_err(&pdev->dev, "Unable to enable CLK_POUT: %d\n",
199 ret);
200 clk_put(pout);
201 return ret;
202 }
203
204 dev_dbg(&pdev->dev, "MCLK enabled at %luHz\n",
205 clk_get_rate(pout));
206 }
207
208 return 0;
209}
210
211static int zylonite_remove(struct platform_device *pdev)
212{
213 if (clk_pout) {
214 clk_disable(pout);
215 clk_put(pout);
216 }
217
218 return 0;
219}
220
221static int zylonite_suspend_post(struct platform_device *pdev,
222 pm_message_t state)
223{
224 if (clk_pout)
225 clk_disable(pout);
226
227 return 0;
228}
229
230static int zylonite_resume_pre(struct platform_device *pdev)
231{
232 int ret = 0;
233
234 if (clk_pout) {
235 ret = clk_enable(pout);
236 if (ret != 0)
237 dev_err(&pdev->dev, "Unable to enable CLK_POUT: %d\n",
238 ret);
239 }
240
241 return ret;
242}
243
176static struct snd_soc_card zylonite = { 244static struct snd_soc_card zylonite = {
177 .name = "Zylonite", 245 .name = "Zylonite",
246 .probe = &zylonite_probe,
247 .remove = &zylonite_remove,
248 .suspend_post = &zylonite_suspend_post,
249 .resume_pre = &zylonite_resume_pre,
178 .platform = &pxa2xx_soc_platform, 250 .platform = &pxa2xx_soc_platform,
179 .dai_link = zylonite_dai, 251 .dai_link = zylonite_dai,
180 .num_links = ARRAY_SIZE(zylonite_dai), 252 .num_links = ARRAY_SIZE(zylonite_dai),
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index fcd03acf10f6..2f3a21eee051 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -1,19 +1,31 @@
1config SND_S3C24XX_SOC 1config SND_S3C24XX_SOC
2 tristate "SoC Audio for the Samsung S3C24XX chips" 2 tristate "SoC Audio for the Samsung S3CXXXX chips"
3 depends on ARCH_S3C2410 3 depends on ARCH_S3C2410 || ARCH_S3C64XX
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
6 the S3C24XX AC97, I2S or SSP interface. You will also need 6 the S3C24XX and S3C64XX AC97, I2S or SSP interface. You will
7 to select the audio interfaces to support below. 7 also need to select the audio interfaces to support below.
8 8
9config SND_S3C24XX_SOC_I2S 9config SND_S3C24XX_SOC_I2S
10 tristate 10 tristate
11 select S3C2410_DMA
12
13config SND_S3C_I2SV2_SOC
14 tristate
11 15
12config SND_S3C2412_SOC_I2S 16config SND_S3C2412_SOC_I2S
13 tristate 17 tristate
18 select SND_S3C_I2SV2_SOC
19 select S3C2410_DMA
20
21config SND_S3C64XX_SOC_I2S
22 tristate
23 select SND_S3C_I2SV2_SOC
24 select S3C64XX_DMA
14 25
15config SND_S3C2443_SOC_AC97 26config SND_S3C2443_SOC_AC97
16 tristate 27 tristate
28 select S3C2410_DMA
17 select AC97_BUS 29 select AC97_BUS
18 select SND_SOC_AC97_BUS 30 select SND_SOC_AC97_BUS
19 31
@@ -26,6 +38,14 @@ config SND_S3C24XX_SOC_NEO1973_WM8753
26 Say Y if you want to add support for SoC audio on smdk2440 38 Say Y if you want to add support for SoC audio on smdk2440
27 with the WM8753. 39 with the WM8753.
28 40
41config SND_S3C24XX_SOC_JIVE_WM8750
42 tristate "SoC I2S Audio support for Jive"
43 depends on SND_S3C24XX_SOC && MACH_JIVE
44 select SND_SOC_WM8750
45 select SND_S3C2412_SOC_I2S
46 help
47 Sat Y if you want to add support for SoC audio on the Jive.
48
29config SND_S3C24XX_SOC_SMDK2443_WM9710 49config SND_S3C24XX_SOC_SMDK2443_WM9710
30 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 50 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
31 depends on SND_S3C24XX_SOC && MACH_SMDK2443 51 depends on SND_S3C24XX_SOC && MACH_SMDK2443
@@ -48,4 +68,5 @@ config SND_S3C24XX_SOC_S3C24XX_UDA134X
48 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" 68 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
49 depends on SND_S3C24XX_SOC 69 depends on SND_S3C24XX_SOC
50 select SND_S3C24XX_SOC_I2S 70 select SND_S3C24XX_SOC_I2S
71 select SND_SOC_L3
51 select SND_SOC_UDA134X 72 select SND_SOC_UDA134X
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 96b3f3f617d4..07a93a2ebe5f 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -2,19 +2,25 @@
2snd-soc-s3c24xx-objs := s3c24xx-pcm.o 2snd-soc-s3c24xx-objs := s3c24xx-pcm.o
3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o 3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o 4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
5snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o 6snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o
7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
6 8
7obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o 9obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
8obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o 10obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
9obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o 11obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o
10obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o 12obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
13obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
14obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
11 15
12# S3C24XX Machine Support 16# S3C24XX Machine Support
17snd-soc-jive-wm8750-objs := jive_wm8750.o
13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 18snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 19snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 20snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
16snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o 21snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
17 22
23obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
18obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 24obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
19obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 25obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
20obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 26obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c
new file mode 100644
index 000000000000..32063790d95b
--- /dev/null
+++ b/sound/soc/s3c24xx/jive_wm8750.c
@@ -0,0 +1,201 @@
1/* sound/soc/s3c24xx/jive_wm8750.c
2 *
3 * Copyright 2007,2008 Simtec Electronics
4 *
5 * Based on sound/soc/pxa/spitz.c
6 * Copyright 2005 Wolfson Microelectronics PLC.
7 * Copyright 2005 Openedhand Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/timer.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/clk.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25
26#include <asm/mach-types.h>
27
28#include "s3c24xx-pcm.h"
29#include "s3c2412-i2s.h"
30
31#include "../codecs/wm8750.h"
32
33static const struct snd_soc_dapm_route audio_map[] = {
34 { "Headphone Jack", NULL, "LOUT1" },
35 { "Headphone Jack", NULL, "ROUT1" },
36 { "Internal Speaker", NULL, "LOUT2" },
37 { "Internal Speaker", NULL, "ROUT2" },
38 { "LINPUT1", NULL, "Line Input" },
39 { "RINPUT1", NULL, "Line Input" },
40};
41
42static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
43 SND_SOC_DAPM_HP("Headphone Jack", NULL),
44 SND_SOC_DAPM_SPK("Internal Speaker", NULL),
45 SND_SOC_DAPM_LINE("Line In", NULL),
46};
47
48static int jive_hw_params(struct snd_pcm_substream *substream,
49 struct snd_pcm_hw_params *params)
50{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
54 struct s3c_i2sv2_rate_calc div;
55 unsigned int clk = 0;
56 int ret = 0;
57
58 switch (params_rate(params)) {
59 case 8000:
60 case 16000:
61 case 48000:
62 case 96000:
63 clk = 12288000;
64 break;
65 case 11025:
66 case 22050:
67 case 44100:
68 clk = 11289600;
69 break;
70 }
71
72 s3c_i2sv2_calc_rate(&div, NULL, params_rate(params),
73 s3c2412_get_iisclk());
74
75 /* set codec DAI configuration */
76 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
77 SND_SOC_DAIFMT_NB_NF |
78 SND_SOC_DAIFMT_CBS_CFS);
79 if (ret < 0)
80 return ret;
81
82 /* set cpu DAI configuration */
83 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
84 SND_SOC_DAIFMT_NB_NF |
85 SND_SOC_DAIFMT_CBS_CFS);
86 if (ret < 0)
87 return ret;
88
89 /* set the codec system clock for DAC and ADC */
90 ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
91 SND_SOC_CLOCK_IN);
92 if (ret < 0)
93 return ret;
94
95 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div);
96 if (ret < 0)
97 return ret;
98
99 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER,
100 div.clk_div - 1);
101 if (ret < 0)
102 return ret;
103
104 return 0;
105}
106
107static struct snd_soc_ops jive_ops = {
108 .hw_params = jive_hw_params,
109};
110
111static int jive_wm8750_init(struct snd_soc_codec *codec)
112{
113 int err;
114
115 /* These endpoints are not being used. */
116 snd_soc_dapm_nc_pin(codec, "LINPUT2");
117 snd_soc_dapm_nc_pin(codec, "RINPUT2");
118 snd_soc_dapm_nc_pin(codec, "LINPUT3");
119 snd_soc_dapm_nc_pin(codec, "RINPUT3");
120 snd_soc_dapm_nc_pin(codec, "OUT3");
121 snd_soc_dapm_nc_pin(codec, "MONO");
122
123 /* Add jive specific widgets */
124 err = snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
125 ARRAY_SIZE(wm8750_dapm_widgets));
126 if (err) {
127 printk(KERN_ERR "%s: failed to add widgets (%d)\n",
128 __func__, err);
129 return err;
130 }
131
132 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
133 snd_soc_dapm_sync(codec);
134
135 return 0;
136}
137
138static struct snd_soc_dai_link jive_dai = {
139 .name = "wm8750",
140 .stream_name = "WM8750",
141 .cpu_dai = &s3c2412_i2s_dai,
142 .codec_dai = &wm8750_dai,
143 .init = jive_wm8750_init,
144 .ops = &jive_ops,
145};
146
147/* jive audio machine driver */
148static struct snd_soc_machine snd_soc_machine_jive = {
149 .name = "Jive",
150 .dai_link = &jive_dai,
151 .num_links = 1,
152};
153
154/* jive audio private data */
155static struct wm8750_setup_data jive_wm8750_setup = {
156};
157
158/* jive audio subsystem */
159static struct snd_soc_device jive_snd_devdata = {
160 .machine = &snd_soc_machine_jive,
161 .platform = &s3c24xx_soc_platform,
162 .codec_dev = &soc_codec_dev_wm8750_spi,
163 .codec_data = &jive_wm8750_setup,
164};
165
166static struct platform_device *jive_snd_device;
167
168static int __init jive_init(void)
169{
170 int ret;
171
172 if (!machine_is_jive())
173 return 0;
174
175 printk("JIVE WM8750 Audio support\n");
176
177 jive_snd_device = platform_device_alloc("soc-audio", -1);
178 if (!jive_snd_device)
179 return -ENOMEM;
180
181 platform_set_drvdata(jive_snd_device, &jive_snd_devdata);
182 jive_snd_devdata.dev = &jive_snd_device->dev;
183 ret = platform_device_add(jive_snd_device);
184
185 if (ret)
186 platform_device_put(jive_snd_device);
187
188 return ret;
189}
190
191static void __exit jive_exit(void)
192{
193 platform_device_unregister(jive_snd_device);
194}
195
196module_init(jive_init);
197module_exit(jive_exit);
198
199MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
200MODULE_DESCRIPTION("ALSA SoC Jive Audio support");
201MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 45bb12e8ea44..289fadf60b10 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -29,25 +29,17 @@
29#include <mach/regs-clock.h> 29#include <mach/regs-clock.h>
30#include <mach/regs-gpio.h> 30#include <mach/regs-gpio.h>
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <mach/audio.h> 32#include <plat/audio.h>
33#include <linux/io.h> 33#include <linux/io.h>
34#include <mach/spi-gpio.h> 34#include <mach/spi-gpio.h>
35 35
36#include <asm/plat-s3c24xx/regs-iis.h> 36#include <plat/regs-iis.h>
37 37
38#include "../codecs/wm8753.h" 38#include "../codecs/wm8753.h"
39#include "lm4857.h" 39#include "lm4857.h"
40#include "s3c24xx-pcm.h" 40#include "s3c24xx-pcm.h"
41#include "s3c24xx-i2s.h" 41#include "s3c24xx-i2s.h"
42 42
43/* Debugging stuff */
44#define S3C24XX_SOC_NEO1973_WM8753_DEBUG 0
45#if S3C24XX_SOC_NEO1973_WM8753_DEBUG
46#define DBG(x...) printk(KERN_DEBUG "s3c24xx-soc-neo1973-wm8753: " x)
47#else
48#define DBG(x...)
49#endif
50
51/* define the scenarios */ 43/* define the scenarios */
52#define NEO_AUDIO_OFF 0 44#define NEO_AUDIO_OFF 0
53#define NEO_GSM_CALL_AUDIO_HANDSET 1 45#define NEO_GSM_CALL_AUDIO_HANDSET 1
@@ -72,7 +64,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
72 int ret = 0; 64 int ret = 0;
73 unsigned long iis_clkrate; 65 unsigned long iis_clkrate;
74 66
75 DBG("Entered %s\n", __func__); 67 pr_debug("Entered %s\n", __func__);
76 68
77 iis_clkrate = s3c24xx_i2s_get_clockrate(); 69 iis_clkrate = s3c24xx_i2s_get_clockrate();
78 70
@@ -158,7 +150,7 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
158 struct snd_soc_pcm_runtime *rtd = substream->private_data; 150 struct snd_soc_pcm_runtime *rtd = substream->private_data;
159 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 151 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
160 152
161 DBG("Entered %s\n", __func__); 153 pr_debug("Entered %s\n", __func__);
162 154
163 /* disable the PLL */ 155 /* disable the PLL */
164 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); 156 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0);
@@ -181,7 +173,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
181 int ret = 0; 173 int ret = 0;
182 unsigned long iis_clkrate; 174 unsigned long iis_clkrate;
183 175
184 DBG("Entered %s\n", __func__); 176 pr_debug("Entered %s\n", __func__);
185 177
186 iis_clkrate = s3c24xx_i2s_get_clockrate(); 178 iis_clkrate = s3c24xx_i2s_get_clockrate();
187 179
@@ -224,7 +216,7 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
224 struct snd_soc_pcm_runtime *rtd = substream->private_data; 216 struct snd_soc_pcm_runtime *rtd = substream->private_data;
225 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 217 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
226 218
227 DBG("Entered %s\n", __func__); 219 pr_debug("Entered %s\n", __func__);
228 220
229 /* disable the PLL */ 221 /* disable the PLL */
230 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); 222 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0);
@@ -246,7 +238,7 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
246 238
247static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) 239static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
248{ 240{
249 DBG("Entered %s\n", __func__); 241 pr_debug("Entered %s\n", __func__);
250 242
251 switch (neo1973_scenario) { 243 switch (neo1973_scenario) {
252 case NEO_AUDIO_OFF: 244 case NEO_AUDIO_OFF:
@@ -330,7 +322,7 @@ static int neo1973_set_scenario(struct snd_kcontrol *kcontrol,
330{ 322{
331 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 323 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
332 324
333 DBG("Entered %s\n", __func__); 325 pr_debug("Entered %s\n", __func__);
334 326
335 if (neo1973_scenario == ucontrol->value.integer.value[0]) 327 if (neo1973_scenario == ucontrol->value.integer.value[0])
336 return 0; 328 return 0;
@@ -344,7 +336,7 @@ static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0};
344 336
345static void lm4857_write_regs(void) 337static void lm4857_write_regs(void)
346{ 338{
347 DBG("Entered %s\n", __func__); 339 pr_debug("Entered %s\n", __func__);
348 340
349 if (i2c_master_send(i2c, lm4857_regs, 4) != 4) 341 if (i2c_master_send(i2c, lm4857_regs, 4) != 4)
350 printk(KERN_ERR "lm4857: i2c write failed\n"); 342 printk(KERN_ERR "lm4857: i2c write failed\n");
@@ -357,7 +349,7 @@ static int lm4857_get_reg(struct snd_kcontrol *kcontrol,
357 int shift = (kcontrol->private_value >> 8) & 0x0F; 349 int shift = (kcontrol->private_value >> 8) & 0x0F;
358 int mask = (kcontrol->private_value >> 16) & 0xFF; 350 int mask = (kcontrol->private_value >> 16) & 0xFF;
359 351
360 DBG("Entered %s\n", __func__); 352 pr_debug("Entered %s\n", __func__);
361 353
362 ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; 354 ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask;
363 return 0; 355 return 0;
@@ -385,7 +377,7 @@ static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
385{ 377{
386 u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; 378 u8 value = lm4857_regs[LM4857_CTRL] & 0x0F;
387 379
388 DBG("Entered %s\n", __func__); 380 pr_debug("Entered %s\n", __func__);
389 381
390 if (value) 382 if (value)
391 value -= 5; 383 value -= 5;
@@ -399,7 +391,7 @@ static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
399{ 391{
400 u8 value = ucontrol->value.integer.value[0]; 392 u8 value = ucontrol->value.integer.value[0];
401 393
402 DBG("Entered %s\n", __func__); 394 pr_debug("Entered %s\n", __func__);
403 395
404 if (value) 396 if (value)
405 value += 5; 397 value += 5;
@@ -506,9 +498,9 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
506 */ 498 */
507static int neo1973_wm8753_init(struct snd_soc_codec *codec) 499static int neo1973_wm8753_init(struct snd_soc_codec *codec)
508{ 500{
509 int i, err; 501 int err;
510 502
511 DBG("Entered %s\n", __func__); 503 pr_debug("Entered %s\n", __func__);
512 504
513 /* set up NC codec pins */ 505 /* set up NC codec pins */
514 snd_soc_dapm_nc_pin(codec, "LOUT2"); 506 snd_soc_dapm_nc_pin(codec, "LOUT2");
@@ -526,13 +518,10 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
526 set_scenario_endpoints(codec, NEO_AUDIO_OFF); 518 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
527 519
528 /* add neo1973 specific controls */ 520 /* add neo1973 specific controls */
529 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { 521 err = snd_soc_add_controls(codec, wm8753_neo1973_controls,
530 err = snd_ctl_add(codec->card, 522 ARRAY_SIZE(8753_neo1973_controls));
531 snd_soc_cnew(&wm8753_neo1973_controls[i], 523 if (err < 0)
532 codec, NULL)); 524 return err;
533 if (err < 0)
534 return err;
535 }
536 525
537 /* set up neo1973 specific audio routes */ 526 /* set up neo1973 specific audio routes */
538 err = snd_soc_dapm_add_routes(codec, dapm_routes, 527 err = snd_soc_dapm_add_routes(codec, dapm_routes,
@@ -585,21 +574,15 @@ static struct snd_soc_card neo1973 = {
585 .num_links = ARRAY_SIZE(neo1973_dai), 574 .num_links = ARRAY_SIZE(neo1973_dai),
586}; 575};
587 576
588static struct wm8753_setup_data neo1973_wm8753_setup = {
589 .i2c_bus = 0,
590 .i2c_address = 0x1a,
591};
592
593static struct snd_soc_device neo1973_snd_devdata = { 577static struct snd_soc_device neo1973_snd_devdata = {
594 .card = &neo1973, 578 .card = &neo1973,
595 .codec_dev = &soc_codec_dev_wm8753, 579 .codec_dev = &soc_codec_dev_wm8753,
596 .codec_data = &neo1973_wm8753_setup,
597}; 580};
598 581
599static int lm4857_i2c_probe(struct i2c_client *client, 582static int lm4857_i2c_probe(struct i2c_client *client,
600 const struct i2c_device_id *id) 583 const struct i2c_device_id *id)
601{ 584{
602 DBG("Entered %s\n", __func__); 585 pr_debug("Entered %s\n", __func__);
603 586
604 i2c = client; 587 i2c = client;
605 588
@@ -609,7 +592,7 @@ static int lm4857_i2c_probe(struct i2c_client *client,
609 592
610static int lm4857_i2c_remove(struct i2c_client *client) 593static int lm4857_i2c_remove(struct i2c_client *client)
611{ 594{
612 DBG("Entered %s\n", __func__); 595 pr_debug("Entered %s\n", __func__);
613 596
614 i2c = NULL; 597 i2c = NULL;
615 598
@@ -620,7 +603,7 @@ static u8 lm4857_state;
620 603
621static int lm4857_suspend(struct i2c_client *dev, pm_message_t state) 604static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
622{ 605{
623 DBG("Entered %s\n", __func__); 606 pr_debug("Entered %s\n", __func__);
624 607
625 dev_dbg(&dev->dev, "lm4857_suspend\n"); 608 dev_dbg(&dev->dev, "lm4857_suspend\n");
626 lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf; 609 lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf;
@@ -633,7 +616,7 @@ static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
633 616
634static int lm4857_resume(struct i2c_client *dev) 617static int lm4857_resume(struct i2c_client *dev)
635{ 618{
636 DBG("Entered %s\n", __func__); 619 pr_debug("Entered %s\n", __func__);
637 620
638 if (lm4857_state) { 621 if (lm4857_state) {
639 lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f); 622 lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f);
@@ -644,7 +627,7 @@ static int lm4857_resume(struct i2c_client *dev)
644 627
645static void lm4857_shutdown(struct i2c_client *dev) 628static void lm4857_shutdown(struct i2c_client *dev)
646{ 629{
647 DBG("Entered %s\n", __func__); 630 pr_debug("Entered %s\n", __func__);
648 631
649 dev_dbg(&dev->dev, "lm4857_shutdown\n"); 632 dev_dbg(&dev->dev, "lm4857_shutdown\n");
650 lm4857_regs[LM4857_CTRL] &= 0xf0; 633 lm4857_regs[LM4857_CTRL] &= 0xf0;
@@ -675,7 +658,7 @@ static int __init neo1973_init(void)
675{ 658{
676 int ret; 659 int ret;
677 660
678 DBG("Entered %s\n", __func__); 661 pr_debug("Entered %s\n", __func__);
679 662
680 if (!machine_is_neo1973_gta01()) { 663 if (!machine_is_neo1973_gta01()) {
681 printk(KERN_INFO 664 printk(KERN_INFO
@@ -706,7 +689,7 @@ static int __init neo1973_init(void)
706 689
707static void __exit neo1973_exit(void) 690static void __exit neo1973_exit(void)
708{ 691{
709 DBG("Entered %s\n", __func__); 692 pr_debug("Entered %s\n", __func__);
710 693
711 i2c_del_driver(&lm4857_i2c_driver); 694 i2c_del_driver(&lm4857_i2c_driver);
712 platform_device_unregister(neo1973_snd_device); 695 platform_device_unregister(neo1973_snd_device);
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
new file mode 100644
index 000000000000..295a4c910262
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -0,0 +1,638 @@
1/* sound/soc/s3c24xx/s3c-i2c-v2.c
2 *
3 * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs.
4 *
5 * Copyright (c) 2006 Wolfson Microelectronics PLC.
6 * Graeme Gregory graeme.gregory@wolfsonmicro.com
7 * linux@wolfsonmicro.com
8 *
9 * Copyright (c) 2008, 2007, 2004-2005 Simtec Electronics
10 * http://armlinux.simtec.co.uk/
11 * Ben Dooks <ben@simtec.co.uk>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/delay.h>
23#include <linux/clk.h>
24#include <linux/kernel.h>
25#include <linux/io.h>
26
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/initval.h>
31#include <sound/soc.h>
32
33#include <plat/regs-s3c2412-iis.h>
34
35#include <plat/audio.h>
36#include <mach/dma.h>
37
38#include "s3c-i2s-v2.h"
39
40#define S3C2412_I2S_DEBUG_CON 0
41
42static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
43{
44 return cpu_dai->private_data;
45}
46
47#define bit_set(v, b) (((v) & (b)) ? 1 : 0)
48
49#if S3C2412_I2S_DEBUG_CON
50static void dbg_showcon(const char *fn, u32 con)
51{
52 printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn,
53 bit_set(con, S3C2412_IISCON_LRINDEX),
54 bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY),
55 bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY),
56 bit_set(con, S3C2412_IISCON_TXFIFO_FULL),
57 bit_set(con, S3C2412_IISCON_RXFIFO_FULL));
58
59 printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n",
60 fn,
61 bit_set(con, S3C2412_IISCON_TXDMA_PAUSE),
62 bit_set(con, S3C2412_IISCON_RXDMA_PAUSE),
63 bit_set(con, S3C2412_IISCON_TXCH_PAUSE),
64 bit_set(con, S3C2412_IISCON_RXCH_PAUSE));
65 printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn,
66 bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE),
67 bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE),
68 bit_set(con, S3C2412_IISCON_IIS_ACTIVE));
69}
70#else
71static inline void dbg_showcon(const char *fn, u32 con)
72{
73}
74#endif
75
76
77/* Turn on or off the transmission path. */
78void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
79{
80 void __iomem *regs = i2s->regs;
81 u32 fic, con, mod;
82
83 pr_debug("%s(%d)\n", __func__, on);
84
85 fic = readl(regs + S3C2412_IISFIC);
86 con = readl(regs + S3C2412_IISCON);
87 mod = readl(regs + S3C2412_IISMOD);
88
89 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
90
91 if (on) {
92 con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
93 con &= ~S3C2412_IISCON_TXDMA_PAUSE;
94 con &= ~S3C2412_IISCON_TXCH_PAUSE;
95
96 switch (mod & S3C2412_IISMOD_MODE_MASK) {
97 case S3C2412_IISMOD_MODE_TXONLY:
98 case S3C2412_IISMOD_MODE_TXRX:
99 /* do nothing, we are in the right mode */
100 break;
101
102 case S3C2412_IISMOD_MODE_RXONLY:
103 mod &= ~S3C2412_IISMOD_MODE_MASK;
104 mod |= S3C2412_IISMOD_MODE_TXRX;
105 break;
106
107 default:
108 dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n");
109 }
110
111 writel(con, regs + S3C2412_IISCON);
112 writel(mod, regs + S3C2412_IISMOD);
113 } else {
114 /* Note, we do not have any indication that the FIFO problems
115 * tha the S3C2410/2440 had apply here, so we should be able
116 * to disable the DMA and TX without resetting the FIFOS.
117 */
118
119 con |= S3C2412_IISCON_TXDMA_PAUSE;
120 con |= S3C2412_IISCON_TXCH_PAUSE;
121 con &= ~S3C2412_IISCON_TXDMA_ACTIVE;
122
123 switch (mod & S3C2412_IISMOD_MODE_MASK) {
124 case S3C2412_IISMOD_MODE_TXRX:
125 mod &= ~S3C2412_IISMOD_MODE_MASK;
126 mod |= S3C2412_IISMOD_MODE_RXONLY;
127 break;
128
129 case S3C2412_IISMOD_MODE_TXONLY:
130 mod &= ~S3C2412_IISMOD_MODE_MASK;
131 con &= ~S3C2412_IISCON_IIS_ACTIVE;
132 break;
133
134 default:
135 dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n");
136 }
137
138 writel(mod, regs + S3C2412_IISMOD);
139 writel(con, regs + S3C2412_IISCON);
140 }
141
142 fic = readl(regs + S3C2412_IISFIC);
143 dbg_showcon(__func__, con);
144 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
145}
146EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl);
147
148void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
149{
150 void __iomem *regs = i2s->regs;
151 u32 fic, con, mod;
152
153 pr_debug("%s(%d)\n", __func__, on);
154
155 fic = readl(regs + S3C2412_IISFIC);
156 con = readl(regs + S3C2412_IISCON);
157 mod = readl(regs + S3C2412_IISMOD);
158
159 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
160
161 if (on) {
162 con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
163 con &= ~S3C2412_IISCON_RXDMA_PAUSE;
164 con &= ~S3C2412_IISCON_RXCH_PAUSE;
165
166 switch (mod & S3C2412_IISMOD_MODE_MASK) {
167 case S3C2412_IISMOD_MODE_TXRX:
168 case S3C2412_IISMOD_MODE_RXONLY:
169 /* do nothing, we are in the right mode */
170 break;
171
172 case S3C2412_IISMOD_MODE_TXONLY:
173 mod &= ~S3C2412_IISMOD_MODE_MASK;
174 mod |= S3C2412_IISMOD_MODE_TXRX;
175 break;
176
177 default:
178 dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n");
179 }
180
181 writel(mod, regs + S3C2412_IISMOD);
182 writel(con, regs + S3C2412_IISCON);
183 } else {
184 /* See txctrl notes on FIFOs. */
185
186 con &= ~S3C2412_IISCON_RXDMA_ACTIVE;
187 con |= S3C2412_IISCON_RXDMA_PAUSE;
188 con |= S3C2412_IISCON_RXCH_PAUSE;
189
190 switch (mod & S3C2412_IISMOD_MODE_MASK) {
191 case S3C2412_IISMOD_MODE_RXONLY:
192 con &= ~S3C2412_IISCON_IIS_ACTIVE;
193 mod &= ~S3C2412_IISMOD_MODE_MASK;
194 break;
195
196 case S3C2412_IISMOD_MODE_TXRX:
197 mod &= ~S3C2412_IISMOD_MODE_MASK;
198 mod |= S3C2412_IISMOD_MODE_TXONLY;
199 break;
200
201 default:
202 dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n");
203 }
204
205 writel(con, regs + S3C2412_IISCON);
206 writel(mod, regs + S3C2412_IISMOD);
207 }
208
209 fic = readl(regs + S3C2412_IISFIC);
210 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
211}
212EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl);
213
214/*
215 * Wait for the LR signal to allow synchronisation to the L/R clock
216 * from the codec. May only be needed for slave mode.
217 */
218static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s)
219{
220 u32 iiscon;
221 unsigned long timeout = jiffies + msecs_to_jiffies(5);
222
223 pr_debug("Entered %s\n", __func__);
224
225 while (1) {
226 iiscon = readl(i2s->regs + S3C2412_IISCON);
227 if (iiscon & S3C2412_IISCON_LRINDEX)
228 break;
229
230 if (timeout < jiffies) {
231 printk(KERN_ERR "%s: timeout\n", __func__);
232 return -ETIMEDOUT;
233 }
234 }
235
236 return 0;
237}
238
239/*
240 * Set S3C2412 I2S DAI format
241 */
242static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
243 unsigned int fmt)
244{
245 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
246 u32 iismod;
247
248 pr_debug("Entered %s\n", __func__);
249
250 iismod = readl(i2s->regs + S3C2412_IISMOD);
251 pr_debug("hw_params r: IISMOD: %x \n", iismod);
252
253#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
254#define IISMOD_MASTER_MASK S3C2412_IISMOD_MASTER_MASK
255#define IISMOD_SLAVE S3C2412_IISMOD_SLAVE
256#define IISMOD_MASTER S3C2412_IISMOD_MASTER_INTERNAL
257#endif
258
259#if defined(CONFIG_PLAT_S3C64XX)
260/* From Rev1.1 datasheet, we have two master and two slave modes:
261 * IMS[11:10]:
262 * 00 = master mode, fed from PCLK
263 * 01 = master mode, fed from CLKAUDIO
264 * 10 = slave mode, using PCLK
265 * 11 = slave mode, using I2SCLK
266 */
267#define IISMOD_MASTER_MASK (1 << 11)
268#define IISMOD_SLAVE (1 << 11)
269#define IISMOD_MASTER (0x0)
270#endif
271
272 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
273 case SND_SOC_DAIFMT_CBM_CFM:
274 i2s->master = 0;
275 iismod &= ~IISMOD_MASTER_MASK;
276 iismod |= IISMOD_SLAVE;
277 break;
278 case SND_SOC_DAIFMT_CBS_CFS:
279 i2s->master = 1;
280 iismod &= ~IISMOD_MASTER_MASK;
281 iismod |= IISMOD_MASTER;
282 break;
283 default:
284 pr_debug("unknwon master/slave format\n");
285 return -EINVAL;
286 }
287
288 iismod &= ~S3C2412_IISMOD_SDF_MASK;
289
290 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
291 case SND_SOC_DAIFMT_RIGHT_J:
292 iismod |= S3C2412_IISMOD_SDF_MSB;
293 break;
294 case SND_SOC_DAIFMT_LEFT_J:
295 iismod |= S3C2412_IISMOD_SDF_LSB;
296 break;
297 case SND_SOC_DAIFMT_I2S:
298 iismod |= S3C2412_IISMOD_SDF_IIS;
299 break;
300 default:
301 pr_debug("Unknown data format\n");
302 return -EINVAL;
303 }
304
305 writel(iismod, i2s->regs + S3C2412_IISMOD);
306 pr_debug("hw_params w: IISMOD: %x \n", iismod);
307 return 0;
308}
309
310static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
311 struct snd_pcm_hw_params *params,
312 struct snd_soc_dai *socdai)
313{
314 struct snd_soc_pcm_runtime *rtd = substream->private_data;
315 struct snd_soc_dai_link *dai = rtd->dai;
316 struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
317 u32 iismod;
318
319 pr_debug("Entered %s\n", __func__);
320
321 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
322 dai->cpu_dai->dma_data = i2s->dma_playback;
323 else
324 dai->cpu_dai->dma_data = i2s->dma_capture;
325
326 /* Working copies of register */
327 iismod = readl(i2s->regs + S3C2412_IISMOD);
328 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
329
330 switch (params_format(params)) {
331 case SNDRV_PCM_FORMAT_S8:
332 iismod |= S3C2412_IISMOD_8BIT;
333 break;
334 case SNDRV_PCM_FORMAT_S16_LE:
335 iismod &= ~S3C2412_IISMOD_8BIT;
336 break;
337 }
338
339 writel(iismod, i2s->regs + S3C2412_IISMOD);
340 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
341 return 0;
342}
343
344static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
345 struct snd_soc_dai *dai)
346{
347 struct snd_soc_pcm_runtime *rtd = substream->private_data;
348 struct s3c_i2sv2_info *i2s = to_info(rtd->dai->cpu_dai);
349 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
350 unsigned long irqs;
351 int ret = 0;
352
353 pr_debug("Entered %s\n", __func__);
354
355 switch (cmd) {
356 case SNDRV_PCM_TRIGGER_START:
357 /* On start, ensure that the FIFOs are cleared and reset. */
358
359 writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH,
360 i2s->regs + S3C2412_IISFIC);
361
362 /* clear again, just in case */
363 writel(0x0, i2s->regs + S3C2412_IISFIC);
364
365 case SNDRV_PCM_TRIGGER_RESUME:
366 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
367 if (!i2s->master) {
368 ret = s3c2412_snd_lrsync(i2s);
369 if (ret)
370 goto exit_err;
371 }
372
373 local_irq_save(irqs);
374
375 if (capture)
376 s3c2412_snd_rxctrl(i2s, 1);
377 else
378 s3c2412_snd_txctrl(i2s, 1);
379
380 local_irq_restore(irqs);
381 break;
382
383 case SNDRV_PCM_TRIGGER_STOP:
384 case SNDRV_PCM_TRIGGER_SUSPEND:
385 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
386 local_irq_save(irqs);
387
388 if (capture)
389 s3c2412_snd_rxctrl(i2s, 0);
390 else
391 s3c2412_snd_txctrl(i2s, 0);
392
393 local_irq_restore(irqs);
394 break;
395 default:
396 ret = -EINVAL;
397 break;
398 }
399
400exit_err:
401 return ret;
402}
403
404/*
405 * Set S3C2412 Clock dividers
406 */
407static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
408 int div_id, int div)
409{
410 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
411 u32 reg;
412
413 pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div);
414
415 switch (div_id) {
416 case S3C_I2SV2_DIV_BCLK:
417 reg = readl(i2s->regs + S3C2412_IISMOD);
418 reg &= ~S3C2412_IISMOD_BCLK_MASK;
419 writel(reg | div, i2s->regs + S3C2412_IISMOD);
420
421 pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
422 break;
423
424 case S3C_I2SV2_DIV_RCLK:
425 if (div > 3) {
426 /* convert value to bit field */
427
428 switch (div) {
429 case 256:
430 div = S3C2412_IISMOD_RCLK_256FS;
431 break;
432
433 case 384:
434 div = S3C2412_IISMOD_RCLK_384FS;
435 break;
436
437 case 512:
438 div = S3C2412_IISMOD_RCLK_512FS;
439 break;
440
441 case 768:
442 div = S3C2412_IISMOD_RCLK_768FS;
443 break;
444
445 default:
446 return -EINVAL;
447 }
448 }
449
450 reg = readl(i2s->regs + S3C2412_IISMOD);
451 reg &= ~S3C2412_IISMOD_RCLK_MASK;
452 writel(reg | div, i2s->regs + S3C2412_IISMOD);
453 pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
454 break;
455
456 case S3C_I2SV2_DIV_PRESCALER:
457 if (div >= 0) {
458 writel((div << 8) | S3C2412_IISPSR_PSREN,
459 i2s->regs + S3C2412_IISPSR);
460 } else {
461 writel(0x0, i2s->regs + S3C2412_IISPSR);
462 }
463 pr_debug("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR));
464 break;
465
466 default:
467 return -EINVAL;
468 }
469
470 return 0;
471}
472
473/* default table of all avaialable root fs divisors */
474static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 };
475
476int s3c2412_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
477 unsigned int *fstab,
478 unsigned int rate, struct clk *clk)
479{
480 unsigned long clkrate = clk_get_rate(clk);
481 unsigned int div;
482 unsigned int fsclk;
483 unsigned int actual;
484 unsigned int fs;
485 unsigned int fsdiv;
486 signed int deviation = 0;
487 unsigned int best_fs = 0;
488 unsigned int best_div = 0;
489 unsigned int best_rate = 0;
490 unsigned int best_deviation = INT_MAX;
491
492 if (fstab == NULL)
493 fstab = iis_fs_tab;
494
495 for (fs = 0; fs < ARRAY_SIZE(iis_fs_tab); fs++) {
496 fsdiv = iis_fs_tab[fs];
497
498 fsclk = clkrate / fsdiv;
499 div = fsclk / rate;
500
501 if ((fsclk % rate) > (rate / 2))
502 div++;
503
504 if (div <= 1)
505 continue;
506
507 actual = clkrate / (fsdiv * div);
508 deviation = actual - rate;
509
510 printk(KERN_DEBUG "%dfs: div %d => result %d, deviation %d\n",
511 fsdiv, div, actual, deviation);
512
513 deviation = abs(deviation);
514
515 if (deviation < best_deviation) {
516 best_fs = fsdiv;
517 best_div = div;
518 best_rate = actual;
519 best_deviation = deviation;
520 }
521
522 if (deviation == 0)
523 break;
524 }
525
526 printk(KERN_DEBUG "best: fs=%d, div=%d, rate=%d\n",
527 best_fs, best_div, best_rate);
528
529 info->fs_div = best_fs;
530 info->clk_div = best_div;
531
532 return 0;
533}
534EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate);
535
536int s3c_i2sv2_probe(struct platform_device *pdev,
537 struct snd_soc_dai *dai,
538 struct s3c_i2sv2_info *i2s,
539 unsigned long base)
540{
541 struct device *dev = &pdev->dev;
542
543 i2s->dev = dev;
544
545 /* record our i2s structure for later use in the callbacks */
546 dai->private_data = i2s;
547
548 i2s->regs = ioremap(base, 0x100);
549 if (i2s->regs == NULL) {
550 dev_err(dev, "cannot ioremap registers\n");
551 return -ENXIO;
552 }
553
554 i2s->iis_pclk = clk_get(dev, "iis");
555 if (i2s->iis_pclk == NULL) {
556 dev_err(dev, "failed to get iis_clock\n");
557 iounmap(i2s->regs);
558 return -ENOENT;
559 }
560
561 clk_enable(i2s->iis_pclk);
562
563 s3c2412_snd_txctrl(i2s, 0);
564 s3c2412_snd_rxctrl(i2s, 0);
565
566 return 0;
567}
568
569EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);
570
571#ifdef CONFIG_PM
572static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
573{
574 struct s3c_i2sv2_info *i2s = to_info(dai);
575 u32 iismod;
576
577 if (dai->active) {
578 i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
579 i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
580 i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
581
582 /* some basic suspend checks */
583
584 iismod = readl(i2s->regs + S3C2412_IISMOD);
585
586 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
587 pr_warning("%s: RXDMA active?\n", __func__);
588
589 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
590 pr_warning("%s: TXDMA active?\n", __func__);
591
592 if (iismod & S3C2412_IISCON_IIS_ACTIVE)
593 pr_warning("%s: IIS active\n", __func__);
594 }
595
596 return 0;
597}
598
599static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
600{
601 struct s3c_i2sv2_info *i2s = to_info(dai);
602
603 pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
604 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
605
606 if (dai->active) {
607 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
608 writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
609 writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
610
611 writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
612 i2s->regs + S3C2412_IISFIC);
613
614 ndelay(250);
615 writel(0x0, i2s->regs + S3C2412_IISFIC);
616 }
617
618 return 0;
619}
620#else
621#define s3c2412_i2s_suspend NULL
622#define s3c2412_i2s_resume NULL
623#endif
624
625int s3c_i2sv2_register_dai(struct snd_soc_dai *dai)
626{
627 dai->ops.trigger = s3c2412_i2s_trigger;
628 dai->ops.hw_params = s3c2412_i2s_hw_params;
629 dai->ops.set_fmt = s3c2412_i2s_set_fmt;
630 dai->ops.set_clkdiv = s3c2412_i2s_set_clkdiv;
631
632 dai->suspend = s3c2412_i2s_suspend;
633 dai->resume = s3c2412_i2s_resume;
634
635 return snd_soc_register_dai(dai);
636}
637
638EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai);
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/s3c24xx/s3c-i2s-v2.h
new file mode 100644
index 000000000000..f66854a77fb2
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.h
@@ -0,0 +1,90 @@
1/* sound/soc/s3c24xx/s3c-i2s-v2.h
2 *
3 * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver
4 *
5 * Copyright (c) 2007 Simtec Electronics
6 * http://armlinux.simtec.co.uk/
7 * Ben Dooks <ben@simtec.co.uk>
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/* This code is the core support for the I2S block found in a number of
16 * Samsung SoC devices which is unofficially named I2S-V2. Currently the
17 * S3C2412 and the S3C64XX series use this block to provide 1 or 2 I2S
18 * channels via configurable GPIO.
19 */
20
21#ifndef __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H
22#define __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H __FILE__
23
24#define S3C_I2SV2_DIV_BCLK (1)
25#define S3C_I2SV2_DIV_RCLK (2)
26#define S3C_I2SV2_DIV_PRESCALER (3)
27
28/**
29 * struct s3c_i2sv2_info - S3C I2S-V2 information
30 * @dev: The parent device passed to use from the probe.
31 * @regs: The pointer to the device registe block.
32 * @master: True if the I2S core is the I2S bit clock master.
33 * @dma_playback: DMA information for playback channel.
34 * @dma_capture: DMA information for capture channel.
35 * @suspend_iismod: PM save for the IISMOD register.
36 * @suspend_iiscon: PM save for the IISCON register.
37 * @suspend_iispsr: PM save for the IISPSR register.
38 *
39 * This is the private codec state for the hardware associated with an
40 * I2S channel such as the register mappings and clock sources.
41 */
42struct s3c_i2sv2_info {
43 struct device *dev;
44 void __iomem *regs;
45
46 struct clk *iis_pclk;
47 struct clk *iis_cclk;
48 struct clk *iis_clk;
49
50 unsigned char master;
51
52 struct s3c24xx_pcm_dma_params *dma_playback;
53 struct s3c24xx_pcm_dma_params *dma_capture;
54
55 u32 suspend_iismod;
56 u32 suspend_iiscon;
57 u32 suspend_iispsr;
58};
59
60struct s3c_i2sv2_rate_calc {
61 unsigned int clk_div; /* for prescaler */
62 unsigned int fs_div; /* for root frame clock */
63};
64
65extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
66 unsigned int *fstab,
67 unsigned int rate, struct clk *clk);
68
69/**
70 * s3c_i2sv2_probe - probe for i2s device helper
71 * @pdev: The platform device supplied to the original probe.
72 * @dai: The ASoC DAI structure supplied to the original probe.
73 * @i2s: Our local i2s structure to fill in.
74 * @base: The base address for the registers.
75 */
76extern int s3c_i2sv2_probe(struct platform_device *pdev,
77 struct snd_soc_dai *dai,
78 struct s3c_i2sv2_info *i2s,
79 unsigned long base);
80
81/**
82 * s3c_i2sv2_register_dai - register dai with soc core
83 * @dai: The snd_soc_dai structure to register
84 *
85 * Fill in any missing fields and then register the given dai with the
86 * soc core.
87 */
88extern int s3c_i2sv2_register_dai(struct snd_soc_dai *dai);
89
90#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index f3fc0aba0aaf..1ca3cdaa8213 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -22,6 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/io.h>
25 26
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
@@ -30,26 +31,16 @@
30#include <sound/soc.h> 31#include <sound/soc.h>
31#include <mach/hardware.h> 32#include <mach/hardware.h>
32 33
33#include <linux/io.h> 34#include <plat/regs-s3c2412-iis.h>
34#include <asm/dma.h>
35
36#include <asm/plat-s3c24xx/regs-s3c2412-iis.h>
37 35
38#include <mach/regs-gpio.h> 36#include <plat/regs-gpio.h>
39#include <mach/audio.h> 37#include <plat/audio.h>
40#include <mach/dma.h> 38#include <mach/dma.h>
41 39
42#include "s3c24xx-pcm.h" 40#include "s3c24xx-pcm.h"
43#include "s3c2412-i2s.h" 41#include "s3c2412-i2s.h"
44 42
45#define S3C2412_I2S_DEBUG 0 43#define S3C2412_I2S_DEBUG 0
46#define S3C2412_I2S_DEBUG_CON 0
47
48#if S3C2412_I2S_DEBUG
49#define DBG(x...) printk(KERN_INFO x)
50#else
51#define DBG(x...) do { } while (0)
52#endif
53 44
54static struct s3c2410_dma_client s3c2412_dma_client_out = { 45static struct s3c2410_dma_client s3c2412_dma_client_out = {
55 .name = "I2S PCM Stereo out" 46 .name = "I2S PCM Stereo out"
@@ -73,431 +64,7 @@ static struct s3c24xx_pcm_dma_params s3c2412_i2s_pcm_stereo_in = {
73 .dma_size = 4, 64 .dma_size = 4,
74}; 65};
75 66
76struct s3c2412_i2s_info { 67static struct s3c_i2sv2_info s3c2412_i2s;
77 struct device *dev;
78 void __iomem *regs;
79 struct clk *iis_clk;
80 struct clk *iis_pclk;
81 struct clk *iis_cclk;
82
83 u32 suspend_iismod;
84 u32 suspend_iiscon;
85 u32 suspend_iispsr;
86};
87
88static struct s3c2412_i2s_info s3c2412_i2s;
89
90#define bit_set(v, b) (((v) & (b)) ? 1 : 0)
91
92#if S3C2412_I2S_DEBUG_CON
93static void dbg_showcon(const char *fn, u32 con)
94{
95 printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn,
96 bit_set(con, S3C2412_IISCON_LRINDEX),
97 bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY),
98 bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY),
99 bit_set(con, S3C2412_IISCON_TXFIFO_FULL),
100 bit_set(con, S3C2412_IISCON_RXFIFO_FULL));
101
102 printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n",
103 fn,
104 bit_set(con, S3C2412_IISCON_TXDMA_PAUSE),
105 bit_set(con, S3C2412_IISCON_RXDMA_PAUSE),
106 bit_set(con, S3C2412_IISCON_TXCH_PAUSE),
107 bit_set(con, S3C2412_IISCON_RXCH_PAUSE));
108 printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn,
109 bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE),
110 bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE),
111 bit_set(con, S3C2412_IISCON_IIS_ACTIVE));
112}
113#else
114static inline void dbg_showcon(const char *fn, u32 con)
115{
116}
117#endif
118
119/* Turn on or off the transmission path. */
120static void s3c2412_snd_txctrl(int on)
121{
122 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
123 void __iomem *regs = i2s->regs;
124 u32 fic, con, mod;
125
126 DBG("%s(%d)\n", __func__, on);
127
128 fic = readl(regs + S3C2412_IISFIC);
129 con = readl(regs + S3C2412_IISCON);
130 mod = readl(regs + S3C2412_IISMOD);
131
132 DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
133
134 if (on) {
135 con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
136 con &= ~S3C2412_IISCON_TXDMA_PAUSE;
137 con &= ~S3C2412_IISCON_TXCH_PAUSE;
138
139 switch (mod & S3C2412_IISMOD_MODE_MASK) {
140 case S3C2412_IISMOD_MODE_TXONLY:
141 case S3C2412_IISMOD_MODE_TXRX:
142 /* do nothing, we are in the right mode */
143 break;
144
145 case S3C2412_IISMOD_MODE_RXONLY:
146 mod &= ~S3C2412_IISMOD_MODE_MASK;
147 mod |= S3C2412_IISMOD_MODE_TXRX;
148 break;
149
150 default:
151 dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n");
152 }
153
154 writel(con, regs + S3C2412_IISCON);
155 writel(mod, regs + S3C2412_IISMOD);
156 } else {
157 /* Note, we do not have any indication that the FIFO problems
158 * tha the S3C2410/2440 had apply here, so we should be able
159 * to disable the DMA and TX without resetting the FIFOS.
160 */
161
162 con |= S3C2412_IISCON_TXDMA_PAUSE;
163 con |= S3C2412_IISCON_TXCH_PAUSE;
164 con &= ~S3C2412_IISCON_TXDMA_ACTIVE;
165
166 switch (mod & S3C2412_IISMOD_MODE_MASK) {
167 case S3C2412_IISMOD_MODE_TXRX:
168 mod &= ~S3C2412_IISMOD_MODE_MASK;
169 mod |= S3C2412_IISMOD_MODE_RXONLY;
170 break;
171
172 case S3C2412_IISMOD_MODE_TXONLY:
173 mod &= ~S3C2412_IISMOD_MODE_MASK;
174 con &= ~S3C2412_IISCON_IIS_ACTIVE;
175 break;
176
177 default:
178 dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n");
179 }
180
181 writel(mod, regs + S3C2412_IISMOD);
182 writel(con, regs + S3C2412_IISCON);
183 }
184
185 fic = readl(regs + S3C2412_IISFIC);
186 dbg_showcon(__func__, con);
187 DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
188}
189
190static void s3c2412_snd_rxctrl(int on)
191{
192 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
193 void __iomem *regs = i2s->regs;
194 u32 fic, con, mod;
195
196 DBG("%s(%d)\n", __func__, on);
197
198 fic = readl(regs + S3C2412_IISFIC);
199 con = readl(regs + S3C2412_IISCON);
200 mod = readl(regs + S3C2412_IISMOD);
201
202 DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
203
204 if (on) {
205 con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
206 con &= ~S3C2412_IISCON_RXDMA_PAUSE;
207 con &= ~S3C2412_IISCON_RXCH_PAUSE;
208
209 switch (mod & S3C2412_IISMOD_MODE_MASK) {
210 case S3C2412_IISMOD_MODE_TXRX:
211 case S3C2412_IISMOD_MODE_RXONLY:
212 /* do nothing, we are in the right mode */
213 break;
214
215 case S3C2412_IISMOD_MODE_TXONLY:
216 mod &= ~S3C2412_IISMOD_MODE_MASK;
217 mod |= S3C2412_IISMOD_MODE_TXRX;
218 break;
219
220 default:
221 dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n");
222 }
223
224 writel(mod, regs + S3C2412_IISMOD);
225 writel(con, regs + S3C2412_IISCON);
226 } else {
227 /* See txctrl notes on FIFOs. */
228
229 con &= ~S3C2412_IISCON_RXDMA_ACTIVE;
230 con |= S3C2412_IISCON_RXDMA_PAUSE;
231 con |= S3C2412_IISCON_RXCH_PAUSE;
232
233 switch (mod & S3C2412_IISMOD_MODE_MASK) {
234 case S3C2412_IISMOD_MODE_RXONLY:
235 con &= ~S3C2412_IISCON_IIS_ACTIVE;
236 mod &= ~S3C2412_IISMOD_MODE_MASK;
237 break;
238
239 case S3C2412_IISMOD_MODE_TXRX:
240 mod &= ~S3C2412_IISMOD_MODE_MASK;
241 mod |= S3C2412_IISMOD_MODE_TXONLY;
242 break;
243
244 default:
245 dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n");
246 }
247
248 writel(con, regs + S3C2412_IISCON);
249 writel(mod, regs + S3C2412_IISMOD);
250 }
251
252 fic = readl(regs + S3C2412_IISFIC);
253 DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
254}
255
256
257/*
258 * Wait for the LR signal to allow synchronisation to the L/R clock
259 * from the codec. May only be needed for slave mode.
260 */
261static int s3c2412_snd_lrsync(void)
262{
263 u32 iiscon;
264 unsigned long timeout = jiffies + msecs_to_jiffies(5);
265
266 DBG("Entered %s\n", __func__);
267
268 while (1) {
269 iiscon = readl(s3c2412_i2s.regs + S3C2412_IISCON);
270 if (iiscon & S3C2412_IISCON_LRINDEX)
271 break;
272
273 if (timeout < jiffies) {
274 printk(KERN_ERR "%s: timeout\n", __func__);
275 return -ETIMEDOUT;
276 }
277 }
278
279 return 0;
280}
281
282/*
283 * Check whether CPU is the master or slave
284 */
285static inline int s3c2412_snd_is_clkmaster(void)
286{
287 u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD);
288
289 DBG("Entered %s\n", __func__);
290
291 iismod &= S3C2412_IISMOD_MASTER_MASK;
292 return !(iismod == S3C2412_IISMOD_SLAVE);
293}
294
295/*
296 * Set S3C2412 I2S DAI format
297 */
298static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
299 unsigned int fmt)
300{
301 u32 iismod;
302
303
304 DBG("Entered %s\n", __func__);
305
306 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD);
307 DBG("hw_params r: IISMOD: %x \n", iismod);
308
309 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
310 case SND_SOC_DAIFMT_CBM_CFM:
311 iismod &= ~S3C2412_IISMOD_MASTER_MASK;
312 iismod |= S3C2412_IISMOD_SLAVE;
313 break;
314 case SND_SOC_DAIFMT_CBS_CFS:
315 iismod &= ~S3C2412_IISMOD_MASTER_MASK;
316 iismod |= S3C2412_IISMOD_MASTER_INTERNAL;
317 break;
318 default:
319 DBG("unknwon master/slave format\n");
320 return -EINVAL;
321 }
322
323 iismod &= ~S3C2412_IISMOD_SDF_MASK;
324
325 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
326 case SND_SOC_DAIFMT_RIGHT_J:
327 iismod |= S3C2412_IISMOD_SDF_MSB;
328 break;
329 case SND_SOC_DAIFMT_LEFT_J:
330 iismod |= S3C2412_IISMOD_SDF_LSB;
331 break;
332 case SND_SOC_DAIFMT_I2S:
333 iismod |= S3C2412_IISMOD_SDF_IIS;
334 break;
335 default:
336 DBG("Unknown data format\n");
337 return -EINVAL;
338 }
339
340 writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD);
341 DBG("hw_params w: IISMOD: %x \n", iismod);
342 return 0;
343}
344
345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
346 struct snd_pcm_hw_params *params,
347 struct snd_soc_dai *dai)
348{
349 struct snd_soc_pcm_runtime *rtd = substream->private_data;
350 u32 iismod;
351
352 DBG("Entered %s\n", __func__);
353
354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
355 rtd->dai->cpu_dai->dma_data = &s3c2412_i2s_pcm_stereo_out;
356 else
357 rtd->dai->cpu_dai->dma_data = &s3c2412_i2s_pcm_stereo_in;
358
359 /* Working copies of register */
360 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD);
361 DBG("%s: r: IISMOD: %x\n", __func__, iismod);
362
363 switch (params_format(params)) {
364 case SNDRV_PCM_FORMAT_S8:
365 iismod |= S3C2412_IISMOD_8BIT;
366 break;
367 case SNDRV_PCM_FORMAT_S16_LE:
368 iismod &= ~S3C2412_IISMOD_8BIT;
369 break;
370 }
371
372 writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD);
373 DBG("%s: w: IISMOD: %x\n", __func__, iismod);
374 return 0;
375}
376
377static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
378 struct snd_soc_dai *dai)
379{
380 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
381 unsigned long irqs;
382 int ret = 0;
383
384 DBG("Entered %s\n", __func__);
385
386 switch (cmd) {
387 case SNDRV_PCM_TRIGGER_START:
388 /* On start, ensure that the FIFOs are cleared and reset. */
389
390 writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH,
391 s3c2412_i2s.regs + S3C2412_IISFIC);
392
393 /* clear again, just in case */
394 writel(0x0, s3c2412_i2s.regs + S3C2412_IISFIC);
395
396 case SNDRV_PCM_TRIGGER_RESUME:
397 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
398 if (!s3c2412_snd_is_clkmaster()) {
399 ret = s3c2412_snd_lrsync();
400 if (ret)
401 goto exit_err;
402 }
403
404 local_irq_save(irqs);
405
406 if (capture)
407 s3c2412_snd_rxctrl(1);
408 else
409 s3c2412_snd_txctrl(1);
410
411 local_irq_restore(irqs);
412 break;
413
414 case SNDRV_PCM_TRIGGER_STOP:
415 case SNDRV_PCM_TRIGGER_SUSPEND:
416 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
417 local_irq_save(irqs);
418
419 if (capture)
420 s3c2412_snd_rxctrl(0);
421 else
422 s3c2412_snd_txctrl(0);
423
424 local_irq_restore(irqs);
425 break;
426 default:
427 ret = -EINVAL;
428 break;
429 }
430
431exit_err:
432 return ret;
433}
434
435/* default table of all avaialable root fs divisors */
436static unsigned int s3c2412_iis_fs[] = { 256, 512, 384, 768, 0 };
437
438int s3c2412_iis_calc_rate(struct s3c2412_rate_calc *info,
439 unsigned int *fstab,
440 unsigned int rate, struct clk *clk)
441{
442 unsigned long clkrate = clk_get_rate(clk);
443 unsigned int div;
444 unsigned int fsclk;
445 unsigned int actual;
446 unsigned int fs;
447 unsigned int fsdiv;
448 signed int deviation = 0;
449 unsigned int best_fs = 0;
450 unsigned int best_div = 0;
451 unsigned int best_rate = 0;
452 unsigned int best_deviation = INT_MAX;
453
454
455 if (fstab == NULL)
456 fstab = s3c2412_iis_fs;
457
458 for (fs = 0;; fs++) {
459 fsdiv = s3c2412_iis_fs[fs];
460
461 if (fsdiv == 0)
462 break;
463
464 fsclk = clkrate / fsdiv;
465 div = fsclk / rate;
466
467 if ((fsclk % rate) > (rate / 2))
468 div++;
469
470 if (div <= 1)
471 continue;
472
473 actual = clkrate / (fsdiv * div);
474 deviation = actual - rate;
475
476 printk(KERN_DEBUG "%dfs: div %d => result %d, deviation %d\n",
477 fsdiv, div, actual, deviation);
478
479 deviation = abs(deviation);
480
481 if (deviation < best_deviation) {
482 best_fs = fsdiv;
483 best_div = div;
484 best_rate = actual;
485 best_deviation = deviation;
486 }
487
488 if (deviation == 0)
489 break;
490 }
491
492 printk(KERN_DEBUG "best: fs=%d, div=%d, rate=%d\n",
493 best_fs, best_div, best_rate);
494
495 info->fs_div = best_fs;
496 info->clk_div = best_div;
497
498 return 0;
499}
500EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate);
501 68
502/* 69/*
503 * Set S3C2412 Clock source 70 * Set S3C2412 Clock source
@@ -507,15 +74,17 @@ static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
507{ 74{
508 u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); 75 u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD);
509 76
510 DBG("%s(%p, %d, %u, %d)\n", __func__, cpu_dai, clk_id, 77 pr_debug("%s(%p, %d, %u, %d)\n", __func__, cpu_dai, clk_id,
511 freq, dir); 78 freq, dir);
512 79
513 switch (clk_id) { 80 switch (clk_id) {
514 case S3C2412_CLKSRC_PCLK: 81 case S3C2412_CLKSRC_PCLK:
82 s3c2412_i2s.master = 1;
515 iismod &= ~S3C2412_IISMOD_MASTER_MASK; 83 iismod &= ~S3C2412_IISMOD_MASTER_MASK;
516 iismod |= S3C2412_IISMOD_MASTER_INTERNAL; 84 iismod |= S3C2412_IISMOD_MASTER_INTERNAL;
517 break; 85 break;
518 case S3C2412_CLKSRC_I2SCLK: 86 case S3C2412_CLKSRC_I2SCLK:
87 s3c2412_i2s.master = 0;
519 iismod &= ~S3C2412_IISMOD_MASTER_MASK; 88 iismod &= ~S3C2412_IISMOD_MASTER_MASK;
520 iismod |= S3C2412_IISMOD_MASTER_EXTERNAL; 89 iismod |= S3C2412_IISMOD_MASTER_EXTERNAL;
521 break; 90 break;
@@ -527,74 +96,6 @@ static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
527 return 0; 96 return 0;
528} 97}
529 98
530/*
531 * Set S3C2412 Clock dividers
532 */
533static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
534 int div_id, int div)
535{
536 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
537 u32 reg;
538
539 DBG("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div);
540
541 switch (div_id) {
542 case S3C2412_DIV_BCLK:
543 reg = readl(i2s->regs + S3C2412_IISMOD);
544 reg &= ~S3C2412_IISMOD_BCLK_MASK;
545 writel(reg | div, i2s->regs + S3C2412_IISMOD);
546
547 DBG("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
548 break;
549
550 case S3C2412_DIV_RCLK:
551 if (div > 3) {
552 /* convert value to bit field */
553
554 switch (div) {
555 case 256:
556 div = S3C2412_IISMOD_RCLK_256FS;
557 break;
558
559 case 384:
560 div = S3C2412_IISMOD_RCLK_384FS;
561 break;
562
563 case 512:
564 div = S3C2412_IISMOD_RCLK_512FS;
565 break;
566
567 case 768:
568 div = S3C2412_IISMOD_RCLK_768FS;
569 break;
570
571 default:
572 return -EINVAL;
573 }
574 }
575
576 reg = readl(s3c2412_i2s.regs + S3C2412_IISMOD);
577 reg &= ~S3C2412_IISMOD_RCLK_MASK;
578 writel(reg | div, i2s->regs + S3C2412_IISMOD);
579 DBG("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
580 break;
581
582 case S3C2412_DIV_PRESCALER:
583 if (div >= 0) {
584 writel((div << 8) | S3C2412_IISPSR_PSREN,
585 i2s->regs + S3C2412_IISPSR);
586 } else {
587 writel(0x0, i2s->regs + S3C2412_IISPSR);
588 }
589 DBG("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR));
590 break;
591
592 default:
593 return -EINVAL;
594 }
595
596 return 0;
597}
598 99
599struct clk *s3c2412_get_iisclk(void) 100struct clk *s3c2412_get_iisclk(void)
600{ 101{
@@ -606,34 +107,30 @@ EXPORT_SYMBOL_GPL(s3c2412_get_iisclk);
606static int s3c2412_i2s_probe(struct platform_device *pdev, 107static int s3c2412_i2s_probe(struct platform_device *pdev,
607 struct snd_soc_dai *dai) 108 struct snd_soc_dai *dai)
608{ 109{
609 DBG("Entered %s\n", __func__); 110 int ret;
610 111
611 s3c2412_i2s.dev = &pdev->dev; 112 pr_debug("Entered %s\n", __func__);
612 113
613 s3c2412_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); 114 ret = s3c_i2sv2_probe(pdev, dai, &s3c2412_i2s, S3C2410_PA_IIS);
614 if (s3c2412_i2s.regs == NULL) 115 if (ret)
615 return -ENXIO; 116 return ret;
616 117
617 s3c2412_i2s.iis_pclk = clk_get(&pdev->dev, "iis"); 118 s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
618 if (s3c2412_i2s.iis_pclk == NULL) { 119 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
619 DBG("failed to get iis_clock\n");
620 iounmap(s3c2412_i2s.regs);
621 return -ENODEV;
622 }
623 120
624 s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk"); 121 s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk");
625 if (s3c2412_i2s.iis_cclk == NULL) { 122 if (s3c2412_i2s.iis_cclk == NULL) {
626 DBG("failed to get i2sclk clock\n"); 123 pr_debug("failed to get i2sclk clock\n");
627 iounmap(s3c2412_i2s.regs); 124 iounmap(s3c2412_i2s.regs);
628 return -ENODEV; 125 return -ENODEV;
629 } 126 }
630 127
631 clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); 128 /* Set MPLL as the source for IIS CLK */
632 129
633 clk_enable(s3c2412_i2s.iis_pclk); 130 clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll"));
634 clk_enable(s3c2412_i2s.iis_cclk); 131 clk_enable(s3c2412_i2s.iis_cclk);
635 132
636 s3c2412_i2s.iis_clk = s3c2412_i2s.iis_pclk; 133 s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk;
637 134
638 /* Configure the I2S pins in correct mode */ 135 /* Configure the I2S pins in correct mode */
639 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); 136 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK);
@@ -642,78 +139,22 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
642 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); 139 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
643 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); 140 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
644 141
645 s3c2412_snd_txctrl(0);
646 s3c2412_snd_rxctrl(0);
647
648 return 0; 142 return 0;
649} 143}
650 144
651#ifdef CONFIG_PM
652static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
653{
654 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
655 u32 iismod;
656
657 if (dai->active) {
658 i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
659 i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
660 i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
661
662 /* some basic suspend checks */
663
664 iismod = readl(i2s->regs + S3C2412_IISMOD);
665
666 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
667 pr_warning("%s: RXDMA active?\n", __func__);
668
669 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
670 pr_warning("%s: TXDMA active?\n", __func__);
671
672 if (iismod & S3C2412_IISCON_IIS_ACTIVE)
673 pr_warning("%s: IIS active\n", __func__);
674 }
675
676 return 0;
677}
678
679static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
680{
681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
682
683 pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
685
686 if (dai->active) {
687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
688 writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
689 writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
690
691 writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
692 i2s->regs + S3C2412_IISFIC);
693
694 ndelay(250);
695 writel(0x0, i2s->regs + S3C2412_IISFIC);
696
697 }
698
699 return 0;
700}
701#else
702#define s3c2412_i2s_suspend NULL
703#define s3c2412_i2s_resume NULL
704#endif /* CONFIG_PM */
705
706#define S3C2412_I2S_RATES \ 145#define S3C2412_I2S_RATES \
707 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ 146 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
708 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 147 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
709 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 148 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
710 149
150static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
151 .set_sysclk = s3c2412_i2s_set_sysclk,
152};
153
711struct snd_soc_dai s3c2412_i2s_dai = { 154struct snd_soc_dai s3c2412_i2s_dai = {
712 .name = "s3c2412-i2s", 155 .name = "s3c2412-i2s",
713 .id = 0, 156 .id = 0,
714 .probe = s3c2412_i2s_probe, 157 .probe = s3c2412_i2s_probe,
715 .suspend = s3c2412_i2s_suspend,
716 .resume = s3c2412_i2s_resume,
717 .playback = { 158 .playback = {
718 .channels_min = 2, 159 .channels_min = 2,
719 .channels_max = 2, 160 .channels_max = 2,
@@ -726,19 +167,13 @@ struct snd_soc_dai s3c2412_i2s_dai = {
726 .rates = S3C2412_I2S_RATES, 167 .rates = S3C2412_I2S_RATES,
727 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, 168 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,
728 }, 169 },
729 .ops = { 170 .ops = &s3c2412_i2s_dai_ops,
730 .trigger = s3c2412_i2s_trigger,
731 .hw_params = s3c2412_i2s_hw_params,
732 .set_fmt = s3c2412_i2s_set_fmt,
733 .set_clkdiv = s3c2412_i2s_set_clkdiv,
734 .set_sysclk = s3c2412_i2s_set_sysclk,
735 },
736}; 171};
737EXPORT_SYMBOL_GPL(s3c2412_i2s_dai); 172EXPORT_SYMBOL_GPL(s3c2412_i2s_dai);
738 173
739static int __init s3c2412_i2s_init(void) 174static int __init s3c2412_i2s_init(void)
740{ 175{
741 return snd_soc_register_dai(&s3c2412_i2s_dai); 176 return s3c_i2sv2_register_dai(&s3c2412_i2s_dai);
742} 177}
743module_init(s3c2412_i2s_init); 178module_init(s3c2412_i2s_init);
744 179
@@ -748,7 +183,6 @@ static void __exit s3c2412_i2s_exit(void)
748} 183}
749module_exit(s3c2412_i2s_exit); 184module_exit(s3c2412_i2s_exit);
750 185
751
752/* Module information */ 186/* Module information */
753MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 187MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
754MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); 188MODULE_DESCRIPTION("S3C2412 I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/s3c24xx/s3c2412-i2s.h
index aac08a25e541..92848e54be16 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.h
+++ b/sound/soc/s3c24xx/s3c2412-i2s.h
@@ -15,9 +15,11 @@
15#ifndef __SND_SOC_S3C24XX_S3C2412_I2S_H 15#ifndef __SND_SOC_S3C24XX_S3C2412_I2S_H
16#define __SND_SOC_S3C24XX_S3C2412_I2S_H __FILE__ 16#define __SND_SOC_S3C24XX_S3C2412_I2S_H __FILE__
17 17
18#define S3C2412_DIV_BCLK (1) 18#include "s3c-i2s-v2.h"
19#define S3C2412_DIV_RCLK (2) 19
20#define S3C2412_DIV_PRESCALER (3) 20#define S3C2412_DIV_BCLK S3C_I2SV2_DIV_BCLK
21#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK
22#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
21 23
22#define S3C2412_CLKSRC_PCLK (0) 24#define S3C2412_CLKSRC_PCLK (0)
23#define S3C2412_CLKSRC_I2SCLK (1) 25#define S3C2412_CLKSRC_I2SCLK (1)
@@ -26,13 +28,4 @@ extern struct clk *s3c2412_get_iisclk(void);
26 28
27extern struct snd_soc_dai s3c2412_i2s_dai; 29extern struct snd_soc_dai s3c2412_i2s_dai;
28 30
29struct s3c2412_rate_calc {
30 unsigned int clk_div; /* for prescaler */
31 unsigned int fs_div; /* for root frame clock */
32};
33
34extern int s3c2412_iis_calc_rate(struct s3c2412_rate_calc *info,
35 unsigned int *fstab,
36 unsigned int rate, struct clk *clk);
37
38#endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */ 31#endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index 5822d2dd49ba..3698f707c44d 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -31,7 +31,7 @@
31#include <plat/regs-ac97.h> 31#include <plat/regs-ac97.h>
32#include <mach/regs-gpio.h> 32#include <mach/regs-gpio.h>
33#include <mach/regs-clock.h> 33#include <mach/regs-clock.h>
34#include <mach/audio.h> 34#include <plat/audio.h>
35#include <asm/dma.h> 35#include <asm/dma.h>
36#include <mach/dma.h> 36#include <mach/dma.h>
37 37
@@ -355,6 +355,16 @@ static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
355 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ 355 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
356 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 356 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
357 357
358static struct snd_soc_dai_ops s3c2443_ac97_dai_ops = {
359 .hw_params = s3c2443_ac97_hw_params,
360 .trigger = s3c2443_ac97_trigger,
361};
362
363static struct snd_soc_dai_ops s3c2443_ac97_mic_dai_ops = {
364 .hw_params = s3c2443_ac97_hw_mic_params,
365 .trigger = s3c2443_ac97_mic_trigger,
366};
367
358struct snd_soc_dai s3c2443_ac97_dai[] = { 368struct snd_soc_dai s3c2443_ac97_dai[] = {
359{ 369{
360 .name = "s3c2443-ac97", 370 .name = "s3c2443-ac97",
@@ -374,9 +384,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
374 .channels_max = 2, 384 .channels_max = 2,
375 .rates = s3c2443_AC97_RATES, 385 .rates = s3c2443_AC97_RATES,
376 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 386 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
377 .ops = { 387 .ops = &s3c2443_ac97_dai_ops,
378 .hw_params = s3c2443_ac97_hw_params,
379 .trigger = s3c2443_ac97_trigger},
380}, 388},
381{ 389{
382 .name = "pxa2xx-ac97-mic", 390 .name = "pxa2xx-ac97-mic",
@@ -388,9 +396,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
388 .channels_max = 1, 396 .channels_max = 1,
389 .rates = s3c2443_AC97_RATES, 397 .rates = s3c2443_AC97_RATES,
390 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 398 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
391 .ops = { 399 .ops = &s3c2443_ac97_mic_dai_ops,
392 .hw_params = s3c2443_ac97_hw_mic_params,
393 .trigger = s3c2443_ac97_mic_trigger,},
394}, 400},
395}; 401};
396EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); 402EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 6f4d439b57aa..cc066964dad6 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -4,7 +4,7 @@
4 * (c) 2006 Wolfson Microelectronics PLC. 4 * (c) 2006 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
6 * 6 *
7 * (c) 2004-2005 Simtec Electronics 7 * Copyright 2004-2005 Simtec Electronics
8 * http://armlinux.simtec.co.uk/ 8 * http://armlinux.simtec.co.uk/
9 * Ben Dooks <ben@simtec.co.uk> 9 * Ben Dooks <ben@simtec.co.uk>
10 * 10 *
@@ -30,22 +30,15 @@
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/regs-gpio.h> 31#include <mach/regs-gpio.h>
32#include <mach/regs-clock.h> 32#include <mach/regs-clock.h>
33#include <mach/audio.h> 33#include <plat/audio.h>
34#include <asm/dma.h> 34#include <asm/dma.h>
35#include <mach/dma.h> 35#include <mach/dma.h>
36 36
37#include <asm/plat-s3c24xx/regs-iis.h> 37#include <plat/regs-iis.h>
38 38
39#include "s3c24xx-pcm.h" 39#include "s3c24xx-pcm.h"
40#include "s3c24xx-i2s.h" 40#include "s3c24xx-i2s.h"
41 41
42#define S3C24XX_I2S_DEBUG 0
43#if S3C24XX_I2S_DEBUG
44#define DBG(x...) printk(KERN_DEBUG "s3c24xx-i2s: " x)
45#else
46#define DBG(x...)
47#endif
48
49static struct s3c2410_dma_client s3c24xx_dma_client_out = { 42static struct s3c2410_dma_client s3c24xx_dma_client_out = {
50 .name = "I2S PCM Stereo out" 43 .name = "I2S PCM Stereo out"
51}; 44};
@@ -84,13 +77,13 @@ static void s3c24xx_snd_txctrl(int on)
84 u32 iiscon; 77 u32 iiscon;
85 u32 iismod; 78 u32 iismod;
86 79
87 DBG("Entered %s\n", __func__); 80 pr_debug("Entered %s\n", __func__);
88 81
89 iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); 82 iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
90 iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); 83 iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
91 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 84 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
92 85
93 DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); 86 pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
94 87
95 if (on) { 88 if (on) {
96 iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE; 89 iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE;
@@ -120,7 +113,7 @@ static void s3c24xx_snd_txctrl(int on)
120 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); 113 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
121 } 114 }
122 115
123 DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); 116 pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
124} 117}
125 118
126static void s3c24xx_snd_rxctrl(int on) 119static void s3c24xx_snd_rxctrl(int on)
@@ -129,13 +122,13 @@ static void s3c24xx_snd_rxctrl(int on)
129 u32 iiscon; 122 u32 iiscon;
130 u32 iismod; 123 u32 iismod;
131 124
132 DBG("Entered %s\n", __func__); 125 pr_debug("Entered %s\n", __func__);
133 126
134 iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); 127 iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
135 iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); 128 iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
136 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 129 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
137 130
138 DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); 131 pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
139 132
140 if (on) { 133 if (on) {
141 iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; 134 iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE;
@@ -165,7 +158,7 @@ static void s3c24xx_snd_rxctrl(int on)
165 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); 158 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
166 } 159 }
167 160
168 DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); 161 pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
169} 162}
170 163
171/* 164/*
@@ -177,7 +170,7 @@ static int s3c24xx_snd_lrsync(void)
177 u32 iiscon; 170 u32 iiscon;
178 int timeout = 50; /* 5ms */ 171 int timeout = 50; /* 5ms */
179 172
180 DBG("Entered %s\n", __func__); 173 pr_debug("Entered %s\n", __func__);
181 174
182 while (1) { 175 while (1) {
183 iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); 176 iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
@@ -197,7 +190,7 @@ static int s3c24xx_snd_lrsync(void)
197 */ 190 */
198static inline int s3c24xx_snd_is_clkmaster(void) 191static inline int s3c24xx_snd_is_clkmaster(void)
199{ 192{
200 DBG("Entered %s\n", __func__); 193 pr_debug("Entered %s\n", __func__);
201 194
202 return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1; 195 return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1;
203} 196}
@@ -210,10 +203,10 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
210{ 203{
211 u32 iismod; 204 u32 iismod;
212 205
213 DBG("Entered %s\n", __func__); 206 pr_debug("Entered %s\n", __func__);
214 207
215 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 208 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
216 DBG("hw_params r: IISMOD: %lx \n", iismod); 209 pr_debug("hw_params r: IISMOD: %x \n", iismod);
217 210
218 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 211 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
219 case SND_SOC_DAIFMT_CBM_CFM: 212 case SND_SOC_DAIFMT_CBM_CFM:
@@ -238,7 +231,7 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
238 } 231 }
239 232
240 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); 233 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
241 DBG("hw_params w: IISMOD: %lx \n", iismod); 234 pr_debug("hw_params w: IISMOD: %x \n", iismod);
242 return 0; 235 return 0;
243} 236}
244 237
@@ -249,7 +242,7 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
249 struct snd_soc_pcm_runtime *rtd = substream->private_data; 242 struct snd_soc_pcm_runtime *rtd = substream->private_data;
250 u32 iismod; 243 u32 iismod;
251 244
252 DBG("Entered %s\n", __func__); 245 pr_debug("Entered %s\n", __func__);
253 246
254 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 247 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
255 rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; 248 rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
@@ -258,7 +251,7 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
258 251
259 /* Working copies of register */ 252 /* Working copies of register */
260 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 253 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
261 DBG("hw_params r: IISMOD: %lx\n", iismod); 254 pr_debug("hw_params r: IISMOD: %x\n", iismod);
262 255
263 switch (params_format(params)) { 256 switch (params_format(params)) {
264 case SNDRV_PCM_FORMAT_S8: 257 case SNDRV_PCM_FORMAT_S8:
@@ -276,7 +269,7 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
276 } 269 }
277 270
278 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); 271 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
279 DBG("hw_params w: IISMOD: %lx\n", iismod); 272 pr_debug("hw_params w: IISMOD: %x\n", iismod);
280 return 0; 273 return 0;
281} 274}
282 275
@@ -285,7 +278,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
285{ 278{
286 int ret = 0; 279 int ret = 0;
287 280
288 DBG("Entered %s\n", __func__); 281 pr_debug("Entered %s\n", __func__);
289 282
290 switch (cmd) { 283 switch (cmd) {
291 case SNDRV_PCM_TRIGGER_START: 284 case SNDRV_PCM_TRIGGER_START:
@@ -327,7 +320,7 @@ static int s3c24xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
327{ 320{
328 u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 321 u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
329 322
330 DBG("Entered %s\n", __func__); 323 pr_debug("Entered %s\n", __func__);
331 324
332 iismod &= ~S3C2440_IISMOD_MPLL; 325 iismod &= ~S3C2440_IISMOD_MPLL;
333 326
@@ -353,7 +346,7 @@ static int s3c24xx_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
353{ 346{
354 u32 reg; 347 u32 reg;
355 348
356 DBG("Entered %s\n", __func__); 349 pr_debug("Entered %s\n", __func__);
357 350
358 switch (div_id) { 351 switch (div_id) {
359 case S3C24XX_DIV_BCLK: 352 case S3C24XX_DIV_BCLK:
@@ -389,7 +382,7 @@ EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate);
389static int s3c24xx_i2s_probe(struct platform_device *pdev, 382static int s3c24xx_i2s_probe(struct platform_device *pdev,
390 struct snd_soc_dai *dai) 383 struct snd_soc_dai *dai)
391{ 384{
392 DBG("Entered %s\n", __func__); 385 pr_debug("Entered %s\n", __func__);
393 386
394 s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); 387 s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);
395 if (s3c24xx_i2s.regs == NULL) 388 if (s3c24xx_i2s.regs == NULL)
@@ -397,7 +390,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev,
397 390
398 s3c24xx_i2s.iis_clk = clk_get(&pdev->dev, "iis"); 391 s3c24xx_i2s.iis_clk = clk_get(&pdev->dev, "iis");
399 if (s3c24xx_i2s.iis_clk == NULL) { 392 if (s3c24xx_i2s.iis_clk == NULL) {
400 DBG("failed to get iis_clock\n"); 393 pr_err("failed to get iis_clock\n");
401 iounmap(s3c24xx_i2s.regs); 394 iounmap(s3c24xx_i2s.regs);
402 return -ENODEV; 395 return -ENODEV;
403 } 396 }
@@ -421,7 +414,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev,
421#ifdef CONFIG_PM 414#ifdef CONFIG_PM
422static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai) 415static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
423{ 416{
424 DBG("Entered %s\n", __func__); 417 pr_debug("Entered %s\n", __func__);
425 418
426 s3c24xx_i2s.iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); 419 s3c24xx_i2s.iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
427 s3c24xx_i2s.iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 420 s3c24xx_i2s.iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -435,7 +428,7 @@ static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
435 428
436static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) 429static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
437{ 430{
438 DBG("Entered %s\n", __func__); 431 pr_debug("Entered %s\n", __func__);
439 clk_enable(s3c24xx_i2s.iis_clk); 432 clk_enable(s3c24xx_i2s.iis_clk);
440 433
441 writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); 434 writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
@@ -456,6 +449,14 @@ static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
456 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 449 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
457 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 450 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
458 451
452static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = {
453 .trigger = s3c24xx_i2s_trigger,
454 .hw_params = s3c24xx_i2s_hw_params,
455 .set_fmt = s3c24xx_i2s_set_fmt,
456 .set_clkdiv = s3c24xx_i2s_set_clkdiv,
457 .set_sysclk = s3c24xx_i2s_set_sysclk,
458};
459
459struct snd_soc_dai s3c24xx_i2s_dai = { 460struct snd_soc_dai s3c24xx_i2s_dai = {
460 .name = "s3c24xx-i2s", 461 .name = "s3c24xx-i2s",
461 .id = 0, 462 .id = 0,
@@ -472,13 +473,7 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
472 .channels_max = 2, 473 .channels_max = 2,
473 .rates = S3C24XX_I2S_RATES, 474 .rates = S3C24XX_I2S_RATES,
474 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, 475 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
475 .ops = { 476 .ops = &s3c24xx_i2s_dai_ops,
476 .trigger = s3c24xx_i2s_trigger,
477 .hw_params = s3c24xx_i2s_hw_params,
478 .set_fmt = s3c24xx_i2s_set_fmt,
479 .set_clkdiv = s3c24xx_i2s_set_clkdiv,
480 .set_sysclk = s3c24xx_i2s_set_sysclk,
481 },
482}; 477};
483EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); 478EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai);
484 479
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index 7c64d31d067e..a9d68fa2b34a 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -4,7 +4,7 @@
4 * (c) 2006 Wolfson Microelectronics PLC. 4 * (c) 2006 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
6 * 6 *
7 * (c) 2004-2005 Simtec Electronics 7 * Copyright 2004-2005 Simtec Electronics
8 * http://armlinux.simtec.co.uk/ 8 * http://armlinux.simtec.co.uk/
9 * Ben Dooks <ben@simtec.co.uk> 9 * Ben Dooks <ben@simtec.co.uk>
10 * 10 *
@@ -29,17 +29,10 @@
29#include <asm/dma.h> 29#include <asm/dma.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/dma.h> 31#include <mach/dma.h>
32#include <mach/audio.h> 32#include <plat/audio.h>
33 33
34#include "s3c24xx-pcm.h" 34#include "s3c24xx-pcm.h"
35 35
36#define S3C24XX_PCM_DEBUG 0
37#if S3C24XX_PCM_DEBUG
38#define DBG(x...) printk(KERN_DEBUG "s3c24xx-pcm: " x)
39#else
40#define DBG(x...)
41#endif
42
43static const struct snd_pcm_hardware s3c24xx_pcm_hardware = { 36static const struct snd_pcm_hardware s3c24xx_pcm_hardware = {
44 .info = SNDRV_PCM_INFO_INTERLEAVED | 37 .info = SNDRV_PCM_INFO_INTERLEAVED |
45 SNDRV_PCM_INFO_BLOCK_TRANSFER | 38 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -84,16 +77,16 @@ static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream)
84 dma_addr_t pos = prtd->dma_pos; 77 dma_addr_t pos = prtd->dma_pos;
85 int ret; 78 int ret;
86 79
87 DBG("Entered %s\n", __func__); 80 pr_debug("Entered %s\n", __func__);
88 81
89 while (prtd->dma_loaded < prtd->dma_limit) { 82 while (prtd->dma_loaded < prtd->dma_limit) {
90 unsigned long len = prtd->dma_period; 83 unsigned long len = prtd->dma_period;
91 84
92 DBG("dma_loaded: %d\n", prtd->dma_loaded); 85 pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
93 86
94 if ((pos + len) > prtd->dma_end) { 87 if ((pos + len) > prtd->dma_end) {
95 len = prtd->dma_end - pos; 88 len = prtd->dma_end - pos;
96 DBG(KERN_DEBUG "%s: corrected dma len %ld\n", 89 pr_debug(KERN_DEBUG "%s: corrected dma len %ld\n",
97 __func__, len); 90 __func__, len);
98 } 91 }
99 92
@@ -119,7 +112,7 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
119 struct snd_pcm_substream *substream = dev_id; 112 struct snd_pcm_substream *substream = dev_id;
120 struct s3c24xx_runtime_data *prtd; 113 struct s3c24xx_runtime_data *prtd;
121 114
122 DBG("Entered %s\n", __func__); 115 pr_debug("Entered %s\n", __func__);
123 116
124 if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) 117 if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR)
125 return; 118 return;
@@ -148,7 +141,7 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
148 unsigned long totbytes = params_buffer_bytes(params); 141 unsigned long totbytes = params_buffer_bytes(params);
149 int ret = 0; 142 int ret = 0;
150 143
151 DBG("Entered %s\n", __func__); 144 pr_debug("Entered %s\n", __func__);
152 145
153 /* return if this is a bufferless transfer e.g. 146 /* return if this is a bufferless transfer e.g.
154 * codec <--> BT codec or GSM modem -- lg FIXME */ 147 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -161,14 +154,14 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
161 /* prepare DMA */ 154 /* prepare DMA */
162 prtd->params = dma; 155 prtd->params = dma;
163 156
164 DBG("params %p, client %p, channel %d\n", prtd->params, 157 pr_debug("params %p, client %p, channel %d\n", prtd->params,
165 prtd->params->client, prtd->params->channel); 158 prtd->params->client, prtd->params->channel);
166 159
167 ret = s3c2410_dma_request(prtd->params->channel, 160 ret = s3c2410_dma_request(prtd->params->channel,
168 prtd->params->client, NULL); 161 prtd->params->client, NULL);
169 162
170 if (ret < 0) { 163 if (ret < 0) {
171 DBG(KERN_ERR "failed to get dma channel\n"); 164 printk(KERN_ERR "failed to get dma channel\n");
172 return ret; 165 return ret;
173 } 166 }
174 } 167 }
@@ -196,7 +189,7 @@ static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream)
196{ 189{
197 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 190 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
198 191
199 DBG("Entered %s\n", __func__); 192 pr_debug("Entered %s\n", __func__);
200 193
201 /* TODO - do we need to ensure DMA flushed */ 194 /* TODO - do we need to ensure DMA flushed */
202 snd_pcm_set_runtime_buffer(substream, NULL); 195 snd_pcm_set_runtime_buffer(substream, NULL);
@@ -214,7 +207,7 @@ static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream)
214 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 207 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
215 int ret = 0; 208 int ret = 0;
216 209
217 DBG("Entered %s\n", __func__); 210 pr_debug("Entered %s\n", __func__);
218 211
219 /* return if this is a bufferless transfer e.g. 212 /* return if this is a bufferless transfer e.g.
220 * codec <--> BT codec or GSM modem -- lg FIXME */ 213 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -259,7 +252,7 @@ static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
259 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 252 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
260 int ret = 0; 253 int ret = 0;
261 254
262 DBG("Entered %s\n", __func__); 255 pr_debug("Entered %s\n", __func__);
263 256
264 spin_lock(&prtd->lock); 257 spin_lock(&prtd->lock);
265 258
@@ -297,7 +290,7 @@ s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
297 unsigned long res; 290 unsigned long res;
298 dma_addr_t src, dst; 291 dma_addr_t src, dst;
299 292
300 DBG("Entered %s\n", __func__); 293 pr_debug("Entered %s\n", __func__);
301 294
302 spin_lock(&prtd->lock); 295 spin_lock(&prtd->lock);
303 s3c2410_dma_getposition(prtd->params->channel, &src, &dst); 296 s3c2410_dma_getposition(prtd->params->channel, &src, &dst);
@@ -309,7 +302,7 @@ s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
309 302
310 spin_unlock(&prtd->lock); 303 spin_unlock(&prtd->lock);
311 304
312 DBG("Pointer %x %x\n", src, dst); 305 pr_debug("Pointer %x %x\n", src, dst);
313 306
314 /* we seem to be getting the odd error from the pcm library due 307 /* we seem to be getting the odd error from the pcm library due
315 * to out-of-bounds pointers. this is maybe due to the dma engine 308 * to out-of-bounds pointers. this is maybe due to the dma engine
@@ -330,7 +323,7 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
330 struct snd_pcm_runtime *runtime = substream->runtime; 323 struct snd_pcm_runtime *runtime = substream->runtime;
331 struct s3c24xx_runtime_data *prtd; 324 struct s3c24xx_runtime_data *prtd;
332 325
333 DBG("Entered %s\n", __func__); 326 pr_debug("Entered %s\n", __func__);
334 327
335 snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); 328 snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware);
336 329
@@ -349,10 +342,10 @@ static int s3c24xx_pcm_close(struct snd_pcm_substream *substream)
349 struct snd_pcm_runtime *runtime = substream->runtime; 342 struct snd_pcm_runtime *runtime = substream->runtime;
350 struct s3c24xx_runtime_data *prtd = runtime->private_data; 343 struct s3c24xx_runtime_data *prtd = runtime->private_data;
351 344
352 DBG("Entered %s\n", __func__); 345 pr_debug("Entered %s\n", __func__);
353 346
354 if (!prtd) 347 if (!prtd)
355 DBG("s3c24xx_pcm_close called with prtd == NULL\n"); 348 pr_debug("s3c24xx_pcm_close called with prtd == NULL\n");
356 349
357 kfree(prtd); 350 kfree(prtd);
358 351
@@ -364,7 +357,7 @@ static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream,
364{ 357{
365 struct snd_pcm_runtime *runtime = substream->runtime; 358 struct snd_pcm_runtime *runtime = substream->runtime;
366 359
367 DBG("Entered %s\n", __func__); 360 pr_debug("Entered %s\n", __func__);
368 361
369 return dma_mmap_writecombine(substream->pcm->card->dev, vma, 362 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
370 runtime->dma_area, 363 runtime->dma_area,
@@ -390,7 +383,7 @@ static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
390 struct snd_dma_buffer *buf = &substream->dma_buffer; 383 struct snd_dma_buffer *buf = &substream->dma_buffer;
391 size_t size = s3c24xx_pcm_hardware.buffer_bytes_max; 384 size_t size = s3c24xx_pcm_hardware.buffer_bytes_max;
392 385
393 DBG("Entered %s\n", __func__); 386 pr_debug("Entered %s\n", __func__);
394 387
395 buf->dev.type = SNDRV_DMA_TYPE_DEV; 388 buf->dev.type = SNDRV_DMA_TYPE_DEV;
396 buf->dev.dev = pcm->card->dev; 389 buf->dev.dev = pcm->card->dev;
@@ -409,7 +402,7 @@ static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
409 struct snd_dma_buffer *buf; 402 struct snd_dma_buffer *buf;
410 int stream; 403 int stream;
411 404
412 DBG("Entered %s\n", __func__); 405 pr_debug("Entered %s\n", __func__);
413 406
414 for (stream = 0; stream < 2; stream++) { 407 for (stream = 0; stream < 2; stream++) {
415 substream = pcm->streams[stream].substream; 408 substream = pcm->streams[stream].substream;
@@ -433,7 +426,7 @@ static int s3c24xx_pcm_new(struct snd_card *card,
433{ 426{
434 int ret = 0; 427 int ret = 0;
435 428
436 DBG("Entered %s\n", __func__); 429 pr_debug("Entered %s\n", __func__);
437 430
438 if (!card->dev->dma_mask) 431 if (!card->dev->dma_mask)
439 card->dev->dma_mask = &s3c24xx_pcm_dmamask; 432 card->dev->dma_mask = &s3c24xx_pcm_dmamask;
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
index a0a4d1832a14..8e79a416db57 100644
--- a/sound/soc/s3c24xx/s3c24xx_uda134x.c
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -22,7 +22,7 @@
22#include <sound/s3c24xx_uda134x.h> 22#include <sound/s3c24xx_uda134x.h>
23#include <sound/uda134x.h> 23#include <sound/uda134x.h>
24 24
25#include <asm/plat-s3c24xx/regs-iis.h> 25#include <plat/regs-iis.h>
26 26
27#include "s3c24xx-pcm.h" 27#include "s3c24xx-pcm.h"
28#include "s3c24xx-i2s.h" 28#include "s3c24xx-i2s.h"
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
new file mode 100644
index 000000000000..33c5de7e255f
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -0,0 +1,222 @@
1/* sound/soc/s3c24xx/s3c64xx-i2s.c
2 *
3 * ALSA SoC Audio Layer - S3C64XX I2S driver
4 *
5 * Copyright 2008 Openmoko, Inc.
6 * Copyright 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
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/init.h>
16#include <linux/module.h>
17#include <linux/device.h>
18#include <linux/delay.h>
19#include <linux/clk.h>
20#include <linux/kernel.h>
21#include <linux/gpio.h>
22#include <linux/io.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/initval.h>
28#include <sound/soc.h>
29
30#include <plat/regs-s3c2412-iis.h>
31#include <plat/gpio-bank-d.h>
32#include <plat/gpio-bank-e.h>
33#include <plat/gpio-cfg.h>
34#include <plat/audio.h>
35
36#include <mach/map.h>
37#include <mach/dma.h>
38
39#include "s3c24xx-pcm.h"
40#include "s3c64xx-i2s.h"
41
42static struct s3c2410_dma_client s3c64xx_dma_client_out = {
43 .name = "I2S PCM Stereo out"
44};
45
46static struct s3c2410_dma_client s3c64xx_dma_client_in = {
47 .name = "I2S PCM Stereo in"
48};
49
50static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_out[2] = {
51 [0] = {
52 .channel = DMACH_I2S0_OUT,
53 .client = &s3c64xx_dma_client_out,
54 .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD,
55 .dma_size = 4,
56 },
57 [1] = {
58 .channel = DMACH_I2S1_OUT,
59 .client = &s3c64xx_dma_client_out,
60 .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD,
61 .dma_size = 4,
62 },
63};
64
65static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_in[2] = {
66 [0] = {
67 .channel = DMACH_I2S0_IN,
68 .client = &s3c64xx_dma_client_in,
69 .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD,
70 .dma_size = 4,
71 },
72 [1] = {
73 .channel = DMACH_I2S1_IN,
74 .client = &s3c64xx_dma_client_in,
75 .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD,
76 .dma_size = 4,
77 },
78};
79
80static struct s3c_i2sv2_info s3c64xx_i2s[2];
81
82static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
83{
84 return cpu_dai->private_data;
85}
86
87static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
88 int clk_id, unsigned int freq, int dir)
89{
90 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
91 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
92
93 switch (clk_id) {
94 case S3C64XX_CLKSRC_PCLK:
95 iismod &= ~S3C64XX_IISMOD_IMS_SYSMUX;
96 break;
97
98 case S3C64XX_CLKSRC_MUX:
99 iismod |= S3C64XX_IISMOD_IMS_SYSMUX;
100 break;
101
102 default:
103 return -EINVAL;
104 }
105
106 writel(iismod, i2s->regs + S3C2412_IISMOD);
107
108 return 0;
109}
110
111
112unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai)
113{
114 struct s3c_i2sv2_info *i2s = to_info(dai);
115
116 return clk_get_rate(i2s->iis_cclk);
117}
118EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate);
119
120static int s3c64xx_i2s_probe(struct platform_device *pdev,
121 struct snd_soc_dai *dai)
122{
123 struct device *dev = &pdev->dev;
124 struct s3c_i2sv2_info *i2s;
125 int ret;
126
127 dev_dbg(dev, "%s: probing dai %d\n", __func__, pdev->id);
128
129 if (pdev->id < 0 || pdev->id > ARRAY_SIZE(s3c64xx_i2s)) {
130 dev_err(dev, "id %d out of range\n", pdev->id);
131 return -EINVAL;
132 }
133
134 i2s = &s3c64xx_i2s[pdev->id];
135
136 ret = s3c_i2sv2_probe(pdev, dai, i2s,
137 pdev->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0);
138 if (ret)
139 return ret;
140
141 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
142 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
143
144 i2s->iis_cclk = clk_get(dev, "audio-bus");
145 if (IS_ERR(i2s->iis_cclk)) {
146 dev_err(dev, "failed to get audio-bus");
147 iounmap(i2s->regs);
148 return -ENODEV;
149 }
150
151 /* configure GPIO for i2s port */
152 switch (pdev->id) {
153 case 0:
154 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
155 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
156 s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK);
157 s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI);
158 s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0);
159 break;
160 case 1:
161 s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK);
162 s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK);
163 s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK);
164 s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI);
165 s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0);
166 }
167
168 return 0;
169}
170
171
172#define S3C64XX_I2S_RATES \
173 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
174 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
175 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
176
177#define S3C64XX_I2S_FMTS \
178 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE)
179
180static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
181 .set_sysclk = s3c64xx_i2s_set_sysclk,
182};
183
184struct snd_soc_dai s3c64xx_i2s_dai = {
185 .name = "s3c64xx-i2s",
186 .id = 0,
187 .probe = s3c64xx_i2s_probe,
188 .playback = {
189 .channels_min = 2,
190 .channels_max = 2,
191 .rates = S3C64XX_I2S_RATES,
192 .formats = S3C64XX_I2S_FMTS,
193 },
194 .capture = {
195 .channels_min = 2,
196 .channels_max = 2,
197 .rates = S3C64XX_I2S_RATES,
198 .formats = S3C64XX_I2S_FMTS,
199 },
200 .ops = &s3c64xx_i2s_dai_ops,
201};
202EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
203
204static int __init s3c64xx_i2s_init(void)
205{
206 return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai);
207}
208module_init(s3c64xx_i2s_init);
209
210static void __exit s3c64xx_i2s_exit(void)
211{
212 snd_soc_unregister_dai(&s3c64xx_i2s_dai);
213}
214module_exit(s3c64xx_i2s_exit);
215
216/* Module information */
217MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
218MODULE_DESCRIPTION("S3C64XX I2S SoC Interface");
219MODULE_LICENSE("GPL");
220
221
222
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
new file mode 100644
index 000000000000..b7ffe3c38b66
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -0,0 +1,31 @@
1/* sound/soc/s3c24xx/s3c64xx-i2s.h
2 *
3 * ALSA SoC Audio Layer - S3C64XX I2S driver
4 *
5 * Copyright 2008 Openmoko, Inc.
6 * Copyright 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
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 __SND_SOC_S3C24XX_S3C64XX_I2S_H
16#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
17
18#include "s3c-i2s-v2.h"
19
20#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
21#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK
22#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
23
24#define S3C64XX_CLKSRC_PCLK (0)
25#define S3C64XX_CLKSRC_MUX (1)
26
27extern struct snd_soc_dai s3c64xx_i2s_dai;
28
29extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai);
30
31#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index eab31838badf..41db75af3c69 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -267,6 +267,10 @@ static int hac_hw_params(struct snd_pcm_substream *substream,
267#define AC97_FMTS \ 267#define AC97_FMTS \
268 SNDRV_PCM_FMTBIT_S16_LE 268 SNDRV_PCM_FMTBIT_S16_LE
269 269
270static struct snd_soc_dai_ops hac_dai_ops = {
271 .hw_params = hac_hw_params,
272};
273
270struct snd_soc_dai sh4_hac_dai[] = { 274struct snd_soc_dai sh4_hac_dai[] = {
271{ 275{
272 .name = "HAC0", 276 .name = "HAC0",
@@ -284,9 +288,7 @@ struct snd_soc_dai sh4_hac_dai[] = {
284 .channels_min = 2, 288 .channels_min = 2,
285 .channels_max = 2, 289 .channels_max = 2,
286 }, 290 },
287 .ops = { 291 .ops = &hac_dai_ops,
288 .hw_params = hac_hw_params,
289 },
290}, 292},
291#ifdef CONFIG_CPU_SUBTYPE_SH7760 293#ifdef CONFIG_CPU_SUBTYPE_SH7760
292{ 294{
@@ -305,9 +307,7 @@ struct snd_soc_dai sh4_hac_dai[] = {
305 .channels_min = 2, 307 .channels_min = 2,
306 .channels_max = 2, 308 .channels_max = 2,
307 }, 309 },
308 .ops = { 310 .ops = &hac_dai_ops,
309 .hw_params = hac_hw_params,
310 },
311 311
312}, 312},
313#endif 313#endif
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index d1e5390fddeb..56fa0872abbb 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -336,6 +336,16 @@ static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
336 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ 336 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
337 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) 337 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
338 338
339static struct snd_soc_dai_ops ssi_dai_ops = {
340 .startup = ssi_startup,
341 .shutdown = ssi_shutdown,
342 .trigger = ssi_trigger,
343 .hw_params = ssi_hw_params,
344 .set_sysclk = ssi_set_sysclk,
345 .set_clkdiv = ssi_set_clkdiv,
346 .set_fmt = ssi_set_fmt,
347};
348
339struct snd_soc_dai sh4_ssi_dai[] = { 349struct snd_soc_dai sh4_ssi_dai[] = {
340{ 350{
341 .name = "SSI0", 351 .name = "SSI0",
@@ -352,15 +362,7 @@ struct snd_soc_dai sh4_ssi_dai[] = {
352 .channels_min = 2, 362 .channels_min = 2,
353 .channels_max = 8, 363 .channels_max = 8,
354 }, 364 },
355 .ops = { 365 .ops = &ssi_dai_ops,
356 .startup = ssi_startup,
357 .shutdown = ssi_shutdown,
358 .trigger = ssi_trigger,
359 .hw_params = ssi_hw_params,
360 .set_sysclk = ssi_set_sysclk,
361 .set_clkdiv = ssi_set_clkdiv,
362 .set_fmt = ssi_set_fmt,
363 },
364}, 366},
365#ifdef CONFIG_CPU_SUBTYPE_SH7760 367#ifdef CONFIG_CPU_SUBTYPE_SH7760
366{ 368{
@@ -378,15 +380,7 @@ struct snd_soc_dai sh4_ssi_dai[] = {
378 .channels_min = 2, 380 .channels_min = 2,
379 .channels_max = 8, 381 .channels_max = 8,
380 }, 382 },
381 .ops = { 383 .ops = &ssi_dai_ops,
382 .startup = ssi_startup,
383 .shutdown = ssi_shutdown,
384 .trigger = ssi_trigger,
385 .hw_params = ssi_hw_params,
386 .set_sysclk = ssi_set_sysclk,
387 .set_clkdiv = ssi_set_clkdiv,
388 .set_fmt = ssi_set_fmt,
389 },
390}, 384},
391#endif 385#endif
392}; 386};
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 637f0d1ea98e..6e710f705a74 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -133,8 +133,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
133 mutex_lock(&pcm_mutex); 133 mutex_lock(&pcm_mutex);
134 134
135 /* startup the audio subsystem */ 135 /* startup the audio subsystem */
136 if (cpu_dai->ops.startup) { 136 if (cpu_dai->ops->startup) {
137 ret = cpu_dai->ops.startup(substream, cpu_dai); 137 ret = cpu_dai->ops->startup(substream, cpu_dai);
138 if (ret < 0) { 138 if (ret < 0) {
139 printk(KERN_ERR "asoc: can't open interface %s\n", 139 printk(KERN_ERR "asoc: can't open interface %s\n",
140 cpu_dai->name); 140 cpu_dai->name);
@@ -150,8 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
150 } 150 }
151 } 151 }
152 152
153 if (codec_dai->ops.startup) { 153 if (codec_dai->ops->startup) {
154 ret = codec_dai->ops.startup(substream, codec_dai); 154 ret = codec_dai->ops->startup(substream, codec_dai);
155 if (ret < 0) { 155 if (ret < 0) {
156 printk(KERN_ERR "asoc: can't open codec %s\n", 156 printk(KERN_ERR "asoc: can't open codec %s\n",
157 codec_dai->name); 157 codec_dai->name);
@@ -234,7 +234,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
234 cpu_dai->capture.active = codec_dai->capture.active = 1; 234 cpu_dai->capture.active = codec_dai->capture.active = 1;
235 cpu_dai->active = codec_dai->active = 1; 235 cpu_dai->active = codec_dai->active = 1;
236 cpu_dai->runtime = runtime; 236 cpu_dai->runtime = runtime;
237 socdev->codec->active++; 237 card->codec->active++;
238 mutex_unlock(&pcm_mutex); 238 mutex_unlock(&pcm_mutex);
239 return 0; 239 return 0;
240 240
@@ -247,8 +247,8 @@ codec_dai_err:
247 platform->pcm_ops->close(substream); 247 platform->pcm_ops->close(substream);
248 248
249platform_err: 249platform_err:
250 if (cpu_dai->ops.shutdown) 250 if (cpu_dai->ops->shutdown)
251 cpu_dai->ops.shutdown(substream, cpu_dai); 251 cpu_dai->ops->shutdown(substream, cpu_dai);
252out: 252out:
253 mutex_unlock(&pcm_mutex); 253 mutex_unlock(&pcm_mutex);
254 return ret; 254 return ret;
@@ -264,7 +264,7 @@ static void close_delayed_work(struct work_struct *work)
264 struct snd_soc_card *card = container_of(work, struct snd_soc_card, 264 struct snd_soc_card *card = container_of(work, struct snd_soc_card,
265 delayed_work.work); 265 delayed_work.work);
266 struct snd_soc_device *socdev = card->socdev; 266 struct snd_soc_device *socdev = card->socdev;
267 struct snd_soc_codec *codec = socdev->codec; 267 struct snd_soc_codec *codec = card->codec;
268 struct snd_soc_dai *codec_dai; 268 struct snd_soc_dai *codec_dai;
269 int i; 269 int i;
270 270
@@ -319,7 +319,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
319 struct snd_soc_platform *platform = card->platform; 319 struct snd_soc_platform *platform = card->platform;
320 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 320 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
321 struct snd_soc_dai *codec_dai = machine->codec_dai; 321 struct snd_soc_dai *codec_dai = machine->codec_dai;
322 struct snd_soc_codec *codec = socdev->codec; 322 struct snd_soc_codec *codec = card->codec;
323 323
324 mutex_lock(&pcm_mutex); 324 mutex_lock(&pcm_mutex);
325 325
@@ -340,11 +340,11 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
340 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 340 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
341 snd_soc_dai_digital_mute(codec_dai, 1); 341 snd_soc_dai_digital_mute(codec_dai, 1);
342 342
343 if (cpu_dai->ops.shutdown) 343 if (cpu_dai->ops->shutdown)
344 cpu_dai->ops.shutdown(substream, cpu_dai); 344 cpu_dai->ops->shutdown(substream, cpu_dai);
345 345
346 if (codec_dai->ops.shutdown) 346 if (codec_dai->ops->shutdown)
347 codec_dai->ops.shutdown(substream, codec_dai); 347 codec_dai->ops->shutdown(substream, codec_dai);
348 348
349 if (machine->ops && machine->ops->shutdown) 349 if (machine->ops && machine->ops->shutdown)
350 machine->ops->shutdown(substream); 350 machine->ops->shutdown(substream);
@@ -387,7 +387,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
387 struct snd_soc_platform *platform = card->platform; 387 struct snd_soc_platform *platform = card->platform;
388 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 388 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
389 struct snd_soc_dai *codec_dai = machine->codec_dai; 389 struct snd_soc_dai *codec_dai = machine->codec_dai;
390 struct snd_soc_codec *codec = socdev->codec; 390 struct snd_soc_codec *codec = card->codec;
391 int ret = 0; 391 int ret = 0;
392 392
393 mutex_lock(&pcm_mutex); 393 mutex_lock(&pcm_mutex);
@@ -408,16 +408,16 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
408 } 408 }
409 } 409 }
410 410
411 if (codec_dai->ops.prepare) { 411 if (codec_dai->ops->prepare) {
412 ret = codec_dai->ops.prepare(substream, codec_dai); 412 ret = codec_dai->ops->prepare(substream, codec_dai);
413 if (ret < 0) { 413 if (ret < 0) {
414 printk(KERN_ERR "asoc: codec DAI prepare error\n"); 414 printk(KERN_ERR "asoc: codec DAI prepare error\n");
415 goto out; 415 goto out;
416 } 416 }
417 } 417 }
418 418
419 if (cpu_dai->ops.prepare) { 419 if (cpu_dai->ops->prepare) {
420 ret = cpu_dai->ops.prepare(substream, cpu_dai); 420 ret = cpu_dai->ops->prepare(substream, cpu_dai);
421 if (ret < 0) { 421 if (ret < 0) {
422 printk(KERN_ERR "asoc: cpu DAI prepare error\n"); 422 printk(KERN_ERR "asoc: cpu DAI prepare error\n");
423 goto out; 423 goto out;
@@ -494,8 +494,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
494 } 494 }
495 } 495 }
496 496
497 if (codec_dai->ops.hw_params) { 497 if (codec_dai->ops->hw_params) {
498 ret = codec_dai->ops.hw_params(substream, params, codec_dai); 498 ret = codec_dai->ops->hw_params(substream, params, codec_dai);
499 if (ret < 0) { 499 if (ret < 0) {
500 printk(KERN_ERR "asoc: can't set codec %s hw params\n", 500 printk(KERN_ERR "asoc: can't set codec %s hw params\n",
501 codec_dai->name); 501 codec_dai->name);
@@ -503,8 +503,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
503 } 503 }
504 } 504 }
505 505
506 if (cpu_dai->ops.hw_params) { 506 if (cpu_dai->ops->hw_params) {
507 ret = cpu_dai->ops.hw_params(substream, params, cpu_dai); 507 ret = cpu_dai->ops->hw_params(substream, params, cpu_dai);
508 if (ret < 0) { 508 if (ret < 0) {
509 printk(KERN_ERR "asoc: interface %s hw params failed\n", 509 printk(KERN_ERR "asoc: interface %s hw params failed\n",
510 cpu_dai->name); 510 cpu_dai->name);
@@ -526,12 +526,12 @@ out:
526 return ret; 526 return ret;
527 527
528platform_err: 528platform_err:
529 if (cpu_dai->ops.hw_free) 529 if (cpu_dai->ops->hw_free)
530 cpu_dai->ops.hw_free(substream, cpu_dai); 530 cpu_dai->ops->hw_free(substream, cpu_dai);
531 531
532interface_err: 532interface_err:
533 if (codec_dai->ops.hw_free) 533 if (codec_dai->ops->hw_free)
534 codec_dai->ops.hw_free(substream, codec_dai); 534 codec_dai->ops->hw_free(substream, codec_dai);
535 535
536codec_err: 536codec_err:
537 if (machine->ops && machine->ops->hw_free) 537 if (machine->ops && machine->ops->hw_free)
@@ -553,7 +553,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
553 struct snd_soc_platform *platform = card->platform; 553 struct snd_soc_platform *platform = card->platform;
554 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 554 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
555 struct snd_soc_dai *codec_dai = machine->codec_dai; 555 struct snd_soc_dai *codec_dai = machine->codec_dai;
556 struct snd_soc_codec *codec = socdev->codec; 556 struct snd_soc_codec *codec = card->codec;
557 557
558 mutex_lock(&pcm_mutex); 558 mutex_lock(&pcm_mutex);
559 559
@@ -570,11 +570,11 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
570 platform->pcm_ops->hw_free(substream); 570 platform->pcm_ops->hw_free(substream);
571 571
572 /* now free hw params for the DAI's */ 572 /* now free hw params for the DAI's */
573 if (codec_dai->ops.hw_free) 573 if (codec_dai->ops->hw_free)
574 codec_dai->ops.hw_free(substream, codec_dai); 574 codec_dai->ops->hw_free(substream, codec_dai);
575 575
576 if (cpu_dai->ops.hw_free) 576 if (cpu_dai->ops->hw_free)
577 cpu_dai->ops.hw_free(substream, cpu_dai); 577 cpu_dai->ops->hw_free(substream, cpu_dai);
578 578
579 mutex_unlock(&pcm_mutex); 579 mutex_unlock(&pcm_mutex);
580 return 0; 580 return 0;
@@ -591,8 +591,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
591 struct snd_soc_dai *codec_dai = machine->codec_dai; 591 struct snd_soc_dai *codec_dai = machine->codec_dai;
592 int ret; 592 int ret;
593 593
594 if (codec_dai->ops.trigger) { 594 if (codec_dai->ops->trigger) {
595 ret = codec_dai->ops.trigger(substream, cmd, codec_dai); 595 ret = codec_dai->ops->trigger(substream, cmd, codec_dai);
596 if (ret < 0) 596 if (ret < 0)
597 return ret; 597 return ret;
598 } 598 }
@@ -603,8 +603,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
603 return ret; 603 return ret;
604 } 604 }
605 605
606 if (cpu_dai->ops.trigger) { 606 if (cpu_dai->ops->trigger) {
607 ret = cpu_dai->ops.trigger(substream, cmd, cpu_dai); 607 ret = cpu_dai->ops->trigger(substream, cmd, cpu_dai);
608 if (ret < 0) 608 if (ret < 0)
609 return ret; 609 return ret;
610 } 610 }
@@ -629,7 +629,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
629 struct snd_soc_card *card = socdev->card; 629 struct snd_soc_card *card = socdev->card;
630 struct snd_soc_platform *platform = card->platform; 630 struct snd_soc_platform *platform = card->platform;
631 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 631 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
632 struct snd_soc_codec *codec = socdev->codec; 632 struct snd_soc_codec *codec = card->codec;
633 int i; 633 int i;
634 634
635 /* Due to the resume being scheduled into a workqueue we could 635 /* Due to the resume being scheduled into a workqueue we could
@@ -645,8 +645,8 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
645 /* mute any active DAC's */ 645 /* mute any active DAC's */
646 for (i = 0; i < card->num_links; i++) { 646 for (i = 0; i < card->num_links; i++) {
647 struct snd_soc_dai *dai = card->dai_link[i].codec_dai; 647 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
648 if (dai->ops.digital_mute && dai->playback.active) 648 if (dai->ops->digital_mute && dai->playback.active)
649 dai->ops.digital_mute(dai, 1); 649 dai->ops->digital_mute(dai, 1);
650 } 650 }
651 651
652 /* suspend all pcms */ 652 /* suspend all pcms */
@@ -705,7 +705,7 @@ static void soc_resume_deferred(struct work_struct *work)
705 struct snd_soc_device *socdev = card->socdev; 705 struct snd_soc_device *socdev = card->socdev;
706 struct snd_soc_platform *platform = card->platform; 706 struct snd_soc_platform *platform = card->platform;
707 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 707 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
708 struct snd_soc_codec *codec = socdev->codec; 708 struct snd_soc_codec *codec = card->codec;
709 struct platform_device *pdev = to_platform_device(socdev->dev); 709 struct platform_device *pdev = to_platform_device(socdev->dev);
710 int i; 710 int i;
711 711
@@ -741,8 +741,8 @@ static void soc_resume_deferred(struct work_struct *work)
741 /* unmute any active DACs */ 741 /* unmute any active DACs */
742 for (i = 0; i < card->num_links; i++) { 742 for (i = 0; i < card->num_links; i++) {
743 struct snd_soc_dai *dai = card->dai_link[i].codec_dai; 743 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
744 if (dai->ops.digital_mute && dai->playback.active) 744 if (dai->ops->digital_mute && dai->playback.active)
745 dai->ops.digital_mute(dai, 0); 745 dai->ops->digital_mute(dai, 0);
746 } 746 }
747 747
748 for (i = 0; i < card->num_links; i++) { 748 for (i = 0; i < card->num_links; i++) {
@@ -982,8 +982,8 @@ static struct platform_driver soc_driver = {
982static int soc_new_pcm(struct snd_soc_device *socdev, 982static int soc_new_pcm(struct snd_soc_device *socdev,
983 struct snd_soc_dai_link *dai_link, int num) 983 struct snd_soc_dai_link *dai_link, int num)
984{ 984{
985 struct snd_soc_codec *codec = socdev->codec;
986 struct snd_soc_card *card = socdev->card; 985 struct snd_soc_card *card = socdev->card;
986 struct snd_soc_codec *codec = card->codec;
987 struct snd_soc_platform *platform = card->platform; 987 struct snd_soc_platform *platform = card->platform;
988 struct snd_soc_dai *codec_dai = dai_link->codec_dai; 988 struct snd_soc_dai *codec_dai = dai_link->codec_dai;
989 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai; 989 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai;
@@ -998,7 +998,7 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
998 998
999 rtd->dai = dai_link; 999 rtd->dai = dai_link;
1000 rtd->socdev = socdev; 1000 rtd->socdev = socdev;
1001 codec_dai->codec = socdev->codec; 1001 codec_dai->codec = card->codec;
1002 1002
1003 /* check client and interface hw capabilities */ 1003 /* check client and interface hw capabilities */
1004 sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name, 1004 sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name,
@@ -1048,9 +1048,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1048} 1048}
1049 1049
1050/* codec register dump */ 1050/* codec register dump */
1051static ssize_t soc_codec_reg_show(struct snd_soc_device *devdata, char *buf) 1051static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
1052{ 1052{
1053 struct snd_soc_codec *codec = devdata->codec;
1054 int i, step = 1, count = 0; 1053 int i, step = 1, count = 0;
1055 1054
1056 if (!codec->reg_cache_size) 1055 if (!codec->reg_cache_size)
@@ -1090,7 +1089,7 @@ static ssize_t codec_reg_show(struct device *dev,
1090 struct device_attribute *attr, char *buf) 1089 struct device_attribute *attr, char *buf)
1091{ 1090{
1092 struct snd_soc_device *devdata = dev_get_drvdata(dev); 1091 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1093 return soc_codec_reg_show(devdata, buf); 1092 return soc_codec_reg_show(devdata->card->codec, buf);
1094} 1093}
1095 1094
1096static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 1095static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
@@ -1107,12 +1106,10 @@ static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
1107{ 1106{
1108 ssize_t ret; 1107 ssize_t ret;
1109 struct snd_soc_codec *codec = file->private_data; 1108 struct snd_soc_codec *codec = file->private_data;
1110 struct device *card_dev = codec->card->dev;
1111 struct snd_soc_device *devdata = card_dev->driver_data;
1112 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1109 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1113 if (!buf) 1110 if (!buf)
1114 return -ENOMEM; 1111 return -ENOMEM;
1115 ret = soc_codec_reg_show(devdata, buf); 1112 ret = soc_codec_reg_show(codec, buf);
1116 if (ret >= 0) 1113 if (ret >= 0)
1117 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 1114 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1118 kfree(buf); 1115 kfree(buf);
@@ -1309,8 +1306,8 @@ EXPORT_SYMBOL_GPL(snd_soc_test_bits);
1309 */ 1306 */
1310int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) 1307int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1311{ 1308{
1312 struct snd_soc_codec *codec = socdev->codec;
1313 struct snd_soc_card *card = socdev->card; 1309 struct snd_soc_card *card = socdev->card;
1310 struct snd_soc_codec *codec = card->codec;
1314 int ret, i; 1311 int ret, i;
1315 1312
1316 mutex_lock(&codec->mutex); 1313 mutex_lock(&codec->mutex);
@@ -1355,8 +1352,8 @@ EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1355 */ 1352 */
1356int snd_soc_init_card(struct snd_soc_device *socdev) 1353int snd_soc_init_card(struct snd_soc_device *socdev)
1357{ 1354{
1358 struct snd_soc_codec *codec = socdev->codec;
1359 struct snd_soc_card *card = socdev->card; 1355 struct snd_soc_card *card = socdev->card;
1356 struct snd_soc_codec *codec = card->codec;
1360 int ret = 0, i, ac97 = 0, err = 0; 1357 int ret = 0, i, ac97 = 0, err = 0;
1361 1358
1362 for (i = 0; i < card->num_links; i++) { 1359 for (i = 0; i < card->num_links; i++) {
@@ -1407,7 +1404,7 @@ int snd_soc_init_card(struct snd_soc_device *socdev)
1407 if (err < 0) 1404 if (err < 0)
1408 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); 1405 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1409 1406
1410 soc_init_codec_debugfs(socdev->codec); 1407 soc_init_codec_debugfs(codec);
1411 mutex_unlock(&codec->mutex); 1408 mutex_unlock(&codec->mutex);
1412 1409
1413out: 1410out:
@@ -1424,18 +1421,19 @@ EXPORT_SYMBOL_GPL(snd_soc_init_card);
1424 */ 1421 */
1425void snd_soc_free_pcms(struct snd_soc_device *socdev) 1422void snd_soc_free_pcms(struct snd_soc_device *socdev)
1426{ 1423{
1427 struct snd_soc_codec *codec = socdev->codec; 1424 struct snd_soc_codec *codec = socdev->card->codec;
1428#ifdef CONFIG_SND_SOC_AC97_BUS 1425#ifdef CONFIG_SND_SOC_AC97_BUS
1429 struct snd_soc_dai *codec_dai; 1426 struct snd_soc_dai *codec_dai;
1430 int i; 1427 int i;
1431#endif 1428#endif
1432 1429
1433 mutex_lock(&codec->mutex); 1430 mutex_lock(&codec->mutex);
1434 soc_cleanup_codec_debugfs(socdev->codec); 1431 soc_cleanup_codec_debugfs(codec);
1435#ifdef CONFIG_SND_SOC_AC97_BUS 1432#ifdef CONFIG_SND_SOC_AC97_BUS
1436 for (i = 0; i < codec->num_dai; i++) { 1433 for (i = 0; i < codec->num_dai; i++) {
1437 codec_dai = &codec->dai[i]; 1434 codec_dai = &codec->dai[i];
1438 if (codec_dai->ac97_control && codec->ac97) { 1435 if (codec_dai->ac97_control && codec->ac97 &&
1436 strcmp(codec->name, "AC97") != 0) {
1439 soc_ac97_dev_unregister(codec); 1437 soc_ac97_dev_unregister(codec);
1440 goto free_card; 1438 goto free_card;
1441 } 1439 }
@@ -1498,6 +1496,37 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
1498EXPORT_SYMBOL_GPL(snd_soc_cnew); 1496EXPORT_SYMBOL_GPL(snd_soc_cnew);
1499 1497
1500/** 1498/**
1499 * snd_soc_add_controls - add an array of controls to a codec.
1500 * Convienience function to add a list of controls. Many codecs were
1501 * duplicating this code.
1502 *
1503 * @codec: codec to add controls to
1504 * @controls: array of controls to add
1505 * @num_controls: number of elements in the array
1506 *
1507 * Return 0 for success, else error.
1508 */
1509int snd_soc_add_controls(struct snd_soc_codec *codec,
1510 const struct snd_kcontrol_new *controls, int num_controls)
1511{
1512 struct snd_card *card = codec->card;
1513 int err, i;
1514
1515 for (i = 0; i < num_controls; i++) {
1516 const struct snd_kcontrol_new *control = &controls[i];
1517 err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL));
1518 if (err < 0) {
1519 dev_err(codec->dev, "%s: Failed to add %s\n",
1520 codec->name, control->name);
1521 return err;
1522 }
1523 }
1524
1525 return 0;
1526}
1527EXPORT_SYMBOL_GPL(snd_soc_add_controls);
1528
1529/**
1501 * snd_soc_info_enum_double - enumerated double mixer info callback 1530 * snd_soc_info_enum_double - enumerated double mixer info callback
1502 * @kcontrol: mixer control 1531 * @kcontrol: mixer control
1503 * @uinfo: control element information 1532 * @uinfo: control element information
@@ -2023,8 +2052,8 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2023int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 2052int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2024 unsigned int freq, int dir) 2053 unsigned int freq, int dir)
2025{ 2054{
2026 if (dai->ops.set_sysclk) 2055 if (dai->ops->set_sysclk)
2027 return dai->ops.set_sysclk(dai, clk_id, freq, dir); 2056 return dai->ops->set_sysclk(dai, clk_id, freq, dir);
2028 else 2057 else
2029 return -EINVAL; 2058 return -EINVAL;
2030} 2059}
@@ -2043,8 +2072,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2043int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, 2072int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
2044 int div_id, int div) 2073 int div_id, int div)
2045{ 2074{
2046 if (dai->ops.set_clkdiv) 2075 if (dai->ops->set_clkdiv)
2047 return dai->ops.set_clkdiv(dai, div_id, div); 2076 return dai->ops->set_clkdiv(dai, div_id, div);
2048 else 2077 else
2049 return -EINVAL; 2078 return -EINVAL;
2050} 2079}
@@ -2062,8 +2091,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
2062int snd_soc_dai_set_pll(struct snd_soc_dai *dai, 2091int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
2063 int pll_id, unsigned int freq_in, unsigned int freq_out) 2092 int pll_id, unsigned int freq_in, unsigned int freq_out)
2064{ 2093{
2065 if (dai->ops.set_pll) 2094 if (dai->ops->set_pll)
2066 return dai->ops.set_pll(dai, pll_id, freq_in, freq_out); 2095 return dai->ops->set_pll(dai, pll_id, freq_in, freq_out);
2067 else 2096 else
2068 return -EINVAL; 2097 return -EINVAL;
2069} 2098}
@@ -2078,8 +2107,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
2078 */ 2107 */
2079int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2108int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2080{ 2109{
2081 if (dai->ops.set_fmt) 2110 if (dai->ops->set_fmt)
2082 return dai->ops.set_fmt(dai, fmt); 2111 return dai->ops->set_fmt(dai, fmt);
2083 else 2112 else
2084 return -EINVAL; 2113 return -EINVAL;
2085} 2114}
@@ -2097,8 +2126,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
2097int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 2126int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2098 unsigned int mask, int slots) 2127 unsigned int mask, int slots)
2099{ 2128{
2100 if (dai->ops.set_sysclk) 2129 if (dai->ops->set_sysclk)
2101 return dai->ops.set_tdm_slot(dai, mask, slots); 2130 return dai->ops->set_tdm_slot(dai, mask, slots);
2102 else 2131 else
2103 return -EINVAL; 2132 return -EINVAL;
2104} 2133}
@@ -2113,8 +2142,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
2113 */ 2142 */
2114int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) 2143int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
2115{ 2144{
2116 if (dai->ops.set_sysclk) 2145 if (dai->ops->set_sysclk)
2117 return dai->ops.set_tristate(dai, tristate); 2146 return dai->ops->set_tristate(dai, tristate);
2118 else 2147 else
2119 return -EINVAL; 2148 return -EINVAL;
2120} 2149}
@@ -2129,8 +2158,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
2129 */ 2158 */
2130int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) 2159int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
2131{ 2160{
2132 if (dai->ops.digital_mute) 2161 if (dai->ops->digital_mute)
2133 return dai->ops.digital_mute(dai, mute); 2162 return dai->ops->digital_mute(dai, mute);
2134 else 2163 else
2135 return -EINVAL; 2164 return -EINVAL;
2136} 2165}
@@ -2183,6 +2212,9 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
2183 return 0; 2212 return 0;
2184} 2213}
2185 2214
2215static struct snd_soc_dai_ops null_dai_ops = {
2216};
2217
2186/** 2218/**
2187 * snd_soc_register_dai - Register a DAI with the ASoC core 2219 * snd_soc_register_dai - Register a DAI with the ASoC core
2188 * 2220 *
@@ -2197,6 +2229,9 @@ int snd_soc_register_dai(struct snd_soc_dai *dai)
2197 if (!dai->dev) 2229 if (!dai->dev)
2198 printk(KERN_WARNING "No device for DAI %s\n", dai->name); 2230 printk(KERN_WARNING "No device for DAI %s\n", dai->name);
2199 2231
2232 if (!dai->ops)
2233 dai->ops = &null_dai_ops;
2234
2200 INIT_LIST_HEAD(&dai->list); 2235 INIT_LIST_HEAD(&dai->list);
2201 2236
2202 mutex_lock(&client_mutex); 2237 mutex_lock(&client_mutex);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index a2f1da8b4646..735903a74675 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -54,14 +54,15 @@
54static int dapm_up_seq[] = { 54static int dapm_up_seq[] = {
55 snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, 55 snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic,
56 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac, 56 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac,
57 snd_soc_dapm_mixer, snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, 57 snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga,
58 snd_soc_dapm_spk, snd_soc_dapm_post 58 snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post
59}; 59};
60
60static int dapm_down_seq[] = { 61static int dapm_down_seq[] = {
61 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, 62 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
62 snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic, 63 snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer,
63 snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_value_mux, 64 snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias,
64 snd_soc_dapm_post 65 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post
65}; 66};
66 67
67static int dapm_status = 1; 68static int dapm_status = 1;
@@ -101,7 +102,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
101{ 102{
102 switch (w->id) { 103 switch (w->id) {
103 case snd_soc_dapm_switch: 104 case snd_soc_dapm_switch:
104 case snd_soc_dapm_mixer: { 105 case snd_soc_dapm_mixer:
106 case snd_soc_dapm_mixer_named_ctl: {
105 int val; 107 int val;
106 struct soc_mixer_control *mc = (struct soc_mixer_control *) 108 struct soc_mixer_control *mc = (struct soc_mixer_control *)
107 w->kcontrols[i].private_value; 109 w->kcontrols[i].private_value;
@@ -323,15 +325,32 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
323 if (path->name != (char*)w->kcontrols[i].name) 325 if (path->name != (char*)w->kcontrols[i].name)
324 continue; 326 continue;
325 327
326 /* add dapm control with long name */ 328 /* add dapm control with long name.
327 name_len = 2 + strlen(w->name) 329 * for dapm_mixer this is the concatenation of the
328 + strlen(w->kcontrols[i].name); 330 * mixer and kcontrol name.
331 * for dapm_mixer_named_ctl this is simply the
332 * kcontrol name.
333 */
334 name_len = strlen(w->kcontrols[i].name) + 1;
335 if (w->id != snd_soc_dapm_mixer_named_ctl)
336 name_len += 1 + strlen(w->name);
337
329 path->long_name = kmalloc(name_len, GFP_KERNEL); 338 path->long_name = kmalloc(name_len, GFP_KERNEL);
339
330 if (path->long_name == NULL) 340 if (path->long_name == NULL)
331 return -ENOMEM; 341 return -ENOMEM;
332 342
333 snprintf(path->long_name, name_len, "%s %s", 343 switch (w->id) {
334 w->name, w->kcontrols[i].name); 344 default:
345 snprintf(path->long_name, name_len, "%s %s",
346 w->name, w->kcontrols[i].name);
347 break;
348 case snd_soc_dapm_mixer_named_ctl:
349 snprintf(path->long_name, name_len, "%s",
350 w->kcontrols[i].name);
351 break;
352 }
353
335 path->long_name[name_len - 1] = '\0'; 354 path->long_name[name_len - 1] = '\0';
336 355
337 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 356 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
@@ -503,6 +522,137 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
503EXPORT_SYMBOL_GPL(dapm_reg_event); 522EXPORT_SYMBOL_GPL(dapm_reg_event);
504 523
505/* 524/*
525 * Scan a single DAPM widget for a complete audio path and update the
526 * power status appropriately.
527 */
528static int dapm_power_widget(struct snd_soc_codec *codec, int event,
529 struct snd_soc_dapm_widget *w)
530{
531 int in, out, power_change, power, ret;
532
533 /* vmid - no action */
534 if (w->id == snd_soc_dapm_vmid)
535 return 0;
536
537 /* active ADC */
538 if (w->id == snd_soc_dapm_adc && w->active) {
539 in = is_connected_input_ep(w);
540 dapm_clear_walk(w->codec);
541 w->power = (in != 0) ? 1 : 0;
542 dapm_update_bits(w);
543 return 0;
544 }
545
546 /* active DAC */
547 if (w->id == snd_soc_dapm_dac && w->active) {
548 out = is_connected_output_ep(w);
549 dapm_clear_walk(w->codec);
550 w->power = (out != 0) ? 1 : 0;
551 dapm_update_bits(w);
552 return 0;
553 }
554
555 /* pre and post event widgets */
556 if (w->id == snd_soc_dapm_pre) {
557 if (!w->event)
558 return 0;
559
560 if (event == SND_SOC_DAPM_STREAM_START) {
561 ret = w->event(w,
562 NULL, SND_SOC_DAPM_PRE_PMU);
563 if (ret < 0)
564 return ret;
565 } else if (event == SND_SOC_DAPM_STREAM_STOP) {
566 ret = w->event(w,
567 NULL, SND_SOC_DAPM_PRE_PMD);
568 if (ret < 0)
569 return ret;
570 }
571 return 0;
572 }
573 if (w->id == snd_soc_dapm_post) {
574 if (!w->event)
575 return 0;
576
577 if (event == SND_SOC_DAPM_STREAM_START) {
578 ret = w->event(w,
579 NULL, SND_SOC_DAPM_POST_PMU);
580 if (ret < 0)
581 return ret;
582 } else if (event == SND_SOC_DAPM_STREAM_STOP) {
583 ret = w->event(w,
584 NULL, SND_SOC_DAPM_POST_PMD);
585 if (ret < 0)
586 return ret;
587 }
588 return 0;
589 }
590
591 /* all other widgets */
592 in = is_connected_input_ep(w);
593 dapm_clear_walk(w->codec);
594 out = is_connected_output_ep(w);
595 dapm_clear_walk(w->codec);
596 power = (out != 0 && in != 0) ? 1 : 0;
597 power_change = (w->power == power) ? 0 : 1;
598 w->power = power;
599
600 if (!power_change)
601 return 0;
602
603 /* call any power change event handlers */
604 if (w->event)
605 pr_debug("power %s event for %s flags %x\n",
606 w->power ? "on" : "off",
607 w->name, w->event_flags);
608
609 /* power up pre event */
610 if (power && w->event &&
611 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
612 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
613 if (ret < 0)
614 return ret;
615 }
616
617 /* power down pre event */
618 if (!power && w->event &&
619 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
620 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
621 if (ret < 0)
622 return ret;
623 }
624
625 /* Lower PGA volume to reduce pops */
626 if (w->id == snd_soc_dapm_pga && !power)
627 dapm_set_pga(w, power);
628
629 dapm_update_bits(w);
630
631 /* Raise PGA volume to reduce pops */
632 if (w->id == snd_soc_dapm_pga && power)
633 dapm_set_pga(w, power);
634
635 /* power up post event */
636 if (power && w->event &&
637 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
638 ret = w->event(w,
639 NULL, SND_SOC_DAPM_POST_PMU);
640 if (ret < 0)
641 return ret;
642 }
643
644 /* power down post event */
645 if (!power && w->event &&
646 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
647 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
648 if (ret < 0)
649 return ret;
650 }
651
652 return 0;
653}
654
655/*
506 * Scan each dapm widget for complete audio path. 656 * Scan each dapm widget for complete audio path.
507 * A complete path is a route that has valid endpoints i.e.:- 657 * A complete path is a route that has valid endpoints i.e.:-
508 * 658 *
@@ -514,7 +664,7 @@ EXPORT_SYMBOL_GPL(dapm_reg_event);
514static int dapm_power_widgets(struct snd_soc_codec *codec, int event) 664static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
515{ 665{
516 struct snd_soc_dapm_widget *w; 666 struct snd_soc_dapm_widget *w;
517 int in, out, i, c = 1, *seq = NULL, ret = 0, power_change, power; 667 int i, c = 1, *seq = NULL, ret = 0;
518 668
519 /* do we have a sequenced stream event */ 669 /* do we have a sequenced stream event */
520 if (event == SND_SOC_DAPM_STREAM_START) { 670 if (event == SND_SOC_DAPM_STREAM_START) {
@@ -525,135 +675,20 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
525 seq = dapm_down_seq; 675 seq = dapm_down_seq;
526 } 676 }
527 677
528 for(i = 0; i < c; i++) { 678 for (i = 0; i < c; i++) {
529 list_for_each_entry(w, &codec->dapm_widgets, list) { 679 list_for_each_entry(w, &codec->dapm_widgets, list) {
530 680
531 /* is widget in stream order */ 681 /* is widget in stream order */
532 if (seq && seq[i] && w->id != seq[i]) 682 if (seq && seq[i] && w->id != seq[i])
533 continue; 683 continue;
534 684
535 /* vmid - no action */ 685 ret = dapm_power_widget(codec, event, w);
536 if (w->id == snd_soc_dapm_vmid) 686 if (ret != 0)
537 continue; 687 return ret;
538
539 /* active ADC */
540 if (w->id == snd_soc_dapm_adc && w->active) {
541 in = is_connected_input_ep(w);
542 dapm_clear_walk(w->codec);
543 w->power = (in != 0) ? 1 : 0;
544 dapm_update_bits(w);
545 continue;
546 }
547
548 /* active DAC */
549 if (w->id == snd_soc_dapm_dac && w->active) {
550 out = is_connected_output_ep(w);
551 dapm_clear_walk(w->codec);
552 w->power = (out != 0) ? 1 : 0;
553 dapm_update_bits(w);
554 continue;
555 }
556
557 /* pre and post event widgets */
558 if (w->id == snd_soc_dapm_pre) {
559 if (!w->event)
560 continue;
561
562 if (event == SND_SOC_DAPM_STREAM_START) {
563 ret = w->event(w,
564 NULL, SND_SOC_DAPM_PRE_PMU);
565 if (ret < 0)
566 return ret;
567 } else if (event == SND_SOC_DAPM_STREAM_STOP) {
568 ret = w->event(w,
569 NULL, SND_SOC_DAPM_PRE_PMD);
570 if (ret < 0)
571 return ret;
572 }
573 continue;
574 }
575 if (w->id == snd_soc_dapm_post) {
576 if (!w->event)
577 continue;
578
579 if (event == SND_SOC_DAPM_STREAM_START) {
580 ret = w->event(w,
581 NULL, SND_SOC_DAPM_POST_PMU);
582 if (ret < 0)
583 return ret;
584 } else if (event == SND_SOC_DAPM_STREAM_STOP) {
585 ret = w->event(w,
586 NULL, SND_SOC_DAPM_POST_PMD);
587 if (ret < 0)
588 return ret;
589 }
590 continue;
591 }
592
593 /* all other widgets */
594 in = is_connected_input_ep(w);
595 dapm_clear_walk(w->codec);
596 out = is_connected_output_ep(w);
597 dapm_clear_walk(w->codec);
598 power = (out != 0 && in != 0) ? 1 : 0;
599 power_change = (w->power == power) ? 0: 1;
600 w->power = power;
601
602 if (!power_change)
603 continue;
604
605 /* call any power change event handlers */
606 if (w->event)
607 pr_debug("power %s event for %s flags %x\n",
608 w->power ? "on" : "off",
609 w->name, w->event_flags);
610
611 /* power up pre event */
612 if (power && w->event &&
613 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
614 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
615 if (ret < 0)
616 return ret;
617 }
618
619 /* power down pre event */
620 if (!power && w->event &&
621 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
622 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
623 if (ret < 0)
624 return ret;
625 }
626
627 /* Lower PGA volume to reduce pops */
628 if (w->id == snd_soc_dapm_pga && !power)
629 dapm_set_pga(w, power);
630
631 dapm_update_bits(w);
632
633 /* Raise PGA volume to reduce pops */
634 if (w->id == snd_soc_dapm_pga && power)
635 dapm_set_pga(w, power);
636
637 /* power up post event */
638 if (power && w->event &&
639 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
640 ret = w->event(w,
641 NULL, SND_SOC_DAPM_POST_PMU);
642 if (ret < 0)
643 return ret;
644 }
645
646 /* power down post event */
647 if (!power && w->event &&
648 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
649 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
650 if (ret < 0)
651 return ret;
652 }
653 } 688 }
654 } 689 }
655 690
656 return ret; 691 return 0;
657} 692}
658 693
659#ifdef DEBUG 694#ifdef DEBUG
@@ -687,6 +722,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
687 case snd_soc_dapm_adc: 722 case snd_soc_dapm_adc:
688 case snd_soc_dapm_pga: 723 case snd_soc_dapm_pga:
689 case snd_soc_dapm_mixer: 724 case snd_soc_dapm_mixer:
725 case snd_soc_dapm_mixer_named_ctl:
690 if (w->name) { 726 if (w->name) {
691 in = is_connected_input_ep(w); 727 in = is_connected_input_ep(w);
692 dapm_clear_walk(w->codec); 728 dapm_clear_walk(w->codec);
@@ -760,6 +796,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
760 int found = 0; 796 int found = 0;
761 797
762 if (widget->id != snd_soc_dapm_mixer && 798 if (widget->id != snd_soc_dapm_mixer &&
799 widget->id != snd_soc_dapm_mixer_named_ctl &&
763 widget->id != snd_soc_dapm_switch) 800 widget->id != snd_soc_dapm_switch)
764 return -ENODEV; 801 return -ENODEV;
765 802
@@ -795,7 +832,7 @@ static ssize_t dapm_widget_show(struct device *dev,
795 struct device_attribute *attr, char *buf) 832 struct device_attribute *attr, char *buf)
796{ 833{
797 struct snd_soc_device *devdata = dev_get_drvdata(dev); 834 struct snd_soc_device *devdata = dev_get_drvdata(dev);
798 struct snd_soc_codec *codec = devdata->codec; 835 struct snd_soc_codec *codec = devdata->card->codec;
799 struct snd_soc_dapm_widget *w; 836 struct snd_soc_dapm_widget *w;
800 int count = 0; 837 int count = 0;
801 char *state = "not set"; 838 char *state = "not set";
@@ -813,6 +850,7 @@ static ssize_t dapm_widget_show(struct device *dev,
813 case snd_soc_dapm_adc: 850 case snd_soc_dapm_adc:
814 case snd_soc_dapm_pga: 851 case snd_soc_dapm_pga:
815 case snd_soc_dapm_mixer: 852 case snd_soc_dapm_mixer:
853 case snd_soc_dapm_mixer_named_ctl:
816 if (w->name) 854 if (w->name)
817 count += sprintf(buf + count, "%s: %s\n", 855 count += sprintf(buf + count, "%s: %s\n",
818 w->name, w->power ? "On":"Off"); 856 w->name, w->power ? "On":"Off");
@@ -876,7 +914,7 @@ static void dapm_free_widgets(struct snd_soc_codec *codec)
876} 914}
877 915
878static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, 916static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
879 char *pin, int status) 917 const char *pin, int status)
880{ 918{
881 struct snd_soc_dapm_widget *w; 919 struct snd_soc_dapm_widget *w;
882 920
@@ -991,6 +1029,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
991 break; 1029 break;
992 case snd_soc_dapm_switch: 1030 case snd_soc_dapm_switch:
993 case snd_soc_dapm_mixer: 1031 case snd_soc_dapm_mixer:
1032 case snd_soc_dapm_mixer_named_ctl:
994 ret = dapm_connect_mixer(codec, wsource, wsink, path, control); 1033 ret = dapm_connect_mixer(codec, wsource, wsink, path, control);
995 if (ret != 0) 1034 if (ret != 0)
996 goto err; 1035 goto err;
@@ -1068,6 +1107,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1068 switch(w->id) { 1107 switch(w->id) {
1069 case snd_soc_dapm_switch: 1108 case snd_soc_dapm_switch:
1070 case snd_soc_dapm_mixer: 1109 case snd_soc_dapm_mixer:
1110 case snd_soc_dapm_mixer_named_ctl:
1071 dapm_new_mixer(codec, w); 1111 dapm_new_mixer(codec, w);
1072 break; 1112 break;
1073 case snd_soc_dapm_mux: 1113 case snd_soc_dapm_mux:
@@ -1396,6 +1436,76 @@ out:
1396EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 1436EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
1397 1437
1398/** 1438/**
1439 * snd_soc_dapm_info_pin_switch - Info for a pin switch
1440 *
1441 * @kcontrol: mixer control
1442 * @uinfo: control element information
1443 *
1444 * Callback to provide information about a pin switch control.
1445 */
1446int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
1447 struct snd_ctl_elem_info *uinfo)
1448{
1449 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1450 uinfo->count = 1;
1451 uinfo->value.integer.min = 0;
1452 uinfo->value.integer.max = 1;
1453
1454 return 0;
1455}
1456EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
1457
1458/**
1459 * snd_soc_dapm_get_pin_switch - Get information for a pin switch
1460 *
1461 * @kcontrol: mixer control
1462 * @ucontrol: Value
1463 */
1464int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
1465 struct snd_ctl_elem_value *ucontrol)
1466{
1467 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1468 const char *pin = (const char *)kcontrol->private_value;
1469
1470 mutex_lock(&codec->mutex);
1471
1472 ucontrol->value.integer.value[0] =
1473 snd_soc_dapm_get_pin_status(codec, pin);
1474
1475 mutex_unlock(&codec->mutex);
1476
1477 return 0;
1478}
1479EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
1480
1481/**
1482 * snd_soc_dapm_put_pin_switch - Set information for a pin switch
1483 *
1484 * @kcontrol: mixer control
1485 * @ucontrol: Value
1486 */
1487int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
1488 struct snd_ctl_elem_value *ucontrol)
1489{
1490 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1491 const char *pin = (const char *)kcontrol->private_value;
1492
1493 mutex_lock(&codec->mutex);
1494
1495 if (ucontrol->value.integer.value[0])
1496 snd_soc_dapm_enable_pin(codec, pin);
1497 else
1498 snd_soc_dapm_disable_pin(codec, pin);
1499
1500 snd_soc_dapm_sync(codec);
1501
1502 mutex_unlock(&codec->mutex);
1503
1504 return 0;
1505}
1506EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
1507
1508/**
1399 * snd_soc_dapm_new_control - create new dapm control 1509 * snd_soc_dapm_new_control - create new dapm control
1400 * @codec: audio codec 1510 * @codec: audio codec
1401 * @widget: widget template 1511 * @widget: widget template
@@ -1527,8 +1637,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
1527int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, 1637int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1528 enum snd_soc_bias_level level) 1638 enum snd_soc_bias_level level)
1529{ 1639{
1530 struct snd_soc_codec *codec = socdev->codec;
1531 struct snd_soc_card *card = socdev->card; 1640 struct snd_soc_card *card = socdev->card;
1641 struct snd_soc_codec *codec = socdev->card->codec;
1532 int ret = 0; 1642 int ret = 0;
1533 1643
1534 if (card->set_bias_level) 1644 if (card->set_bias_level)
@@ -1549,7 +1659,7 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1549 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 1659 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1550 * do any widget power switching. 1660 * do any widget power switching.
1551 */ 1661 */
1552int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin) 1662int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin)
1553{ 1663{
1554 return snd_soc_dapm_set_pin(codec, pin, 1); 1664 return snd_soc_dapm_set_pin(codec, pin, 1);
1555} 1665}
@@ -1564,7 +1674,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
1564 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 1674 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1565 * do any widget power switching. 1675 * do any widget power switching.
1566 */ 1676 */
1567int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin) 1677int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin)
1568{ 1678{
1569 return snd_soc_dapm_set_pin(codec, pin, 0); 1679 return snd_soc_dapm_set_pin(codec, pin, 0);
1570} 1680}
@@ -1584,7 +1694,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
1584 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 1694 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1585 * do any widget power switching. 1695 * do any widget power switching.
1586 */ 1696 */
1587int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin) 1697int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin)
1588{ 1698{
1589 return snd_soc_dapm_set_pin(codec, pin, 0); 1699 return snd_soc_dapm_set_pin(codec, pin, 0);
1590} 1700}
@@ -1599,7 +1709,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
1599 * 1709 *
1600 * Returns 1 for connected otherwise 0. 1710 * Returns 1 for connected otherwise 0.
1601 */ 1711 */
1602int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin) 1712int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin)
1603{ 1713{
1604 struct snd_soc_dapm_widget *w; 1714 struct snd_soc_dapm_widget *w;
1605 1715
@@ -1620,7 +1730,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
1620 */ 1730 */
1621void snd_soc_dapm_free(struct snd_soc_device *socdev) 1731void snd_soc_dapm_free(struct snd_soc_device *socdev)
1622{ 1732{
1623 struct snd_soc_codec *codec = socdev->codec; 1733 struct snd_soc_codec *codec = socdev->card->codec;
1624 1734
1625 snd_soc_dapm_sys_remove(socdev->dev); 1735 snd_soc_dapm_sys_remove(socdev->dev);
1626 dapm_free_widgets(codec); 1736 dapm_free_widgets(codec);
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
new file mode 100644
index 000000000000..28346fb2e70c
--- /dev/null
+++ b/sound/soc/soc-jack.c
@@ -0,0 +1,267 @@
1/*
2 * soc-jack.c -- ALSA SoC jack handling
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <sound/jack.h>
15#include <sound/soc.h>
16#include <sound/soc-dapm.h>
17#include <linux/gpio.h>
18#include <linux/interrupt.h>
19#include <linux/workqueue.h>
20#include <linux/delay.h>
21
22/**
23 * snd_soc_jack_new - Create a new jack
24 * @card: ASoC card
25 * @id: an identifying string for this jack
26 * @type: a bitmask of enum snd_jack_type values that can be detected by
27 * this jack
28 * @jack: structure to use for the jack
29 *
30 * Creates a new jack object.
31 *
32 * Returns zero if successful, or a negative error code on failure.
33 * On success jack will be initialised.
34 */
35int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
36 struct snd_soc_jack *jack)
37{
38 jack->card = card;
39 INIT_LIST_HEAD(&jack->pins);
40
41 return snd_jack_new(card->codec->card, id, type, &jack->jack);
42}
43EXPORT_SYMBOL_GPL(snd_soc_jack_new);
44
45/**
46 * snd_soc_jack_report - Report the current status for a jack
47 *
48 * @jack: the jack
49 * @status: a bitmask of enum snd_jack_type values that are currently detected.
50 * @mask: a bitmask of enum snd_jack_type values that being reported.
51 *
52 * If configured using snd_soc_jack_add_pins() then the associated
53 * DAPM pins will be enabled or disabled as appropriate and DAPM
54 * synchronised.
55 *
56 * Note: This function uses mutexes and should be called from a
57 * context which can sleep (such as a workqueue).
58 */
59void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
60{
61 struct snd_soc_codec *codec = jack->card->codec;
62 struct snd_soc_jack_pin *pin;
63 int enable;
64 int oldstatus;
65
66 if (!jack) {
67 WARN_ON_ONCE(!jack);
68 return;
69 }
70
71 mutex_lock(&codec->mutex);
72
73 oldstatus = jack->status;
74
75 jack->status &= ~mask;
76 jack->status |= status;
77
78 /* The DAPM sync is expensive enough to be worth skipping */
79 if (jack->status == oldstatus)
80 goto out;
81
82 list_for_each_entry(pin, &jack->pins, list) {
83 enable = pin->mask & status;
84
85 if (pin->invert)
86 enable = !enable;
87
88 if (enable)
89 snd_soc_dapm_enable_pin(codec, pin->pin);
90 else
91 snd_soc_dapm_disable_pin(codec, pin->pin);
92 }
93
94 snd_soc_dapm_sync(codec);
95
96 snd_jack_report(jack->jack, status);
97
98out:
99 mutex_unlock(&codec->mutex);
100}
101EXPORT_SYMBOL_GPL(snd_soc_jack_report);
102
103/**
104 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack
105 *
106 * @jack: ASoC jack
107 * @count: Number of pins
108 * @pins: Array of pins
109 *
110 * After this function has been called the DAPM pins specified in the
111 * pins array will have their status updated to reflect the current
112 * state of the jack whenever the jack status is updated.
113 */
114int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
115 struct snd_soc_jack_pin *pins)
116{
117 int i;
118
119 for (i = 0; i < count; i++) {
120 if (!pins[i].pin) {
121 printk(KERN_ERR "No name for pin %d\n", i);
122 return -EINVAL;
123 }
124 if (!pins[i].mask) {
125 printk(KERN_ERR "No mask for pin %d (%s)\n", i,
126 pins[i].pin);
127 return -EINVAL;
128 }
129
130 INIT_LIST_HEAD(&pins[i].list);
131 list_add(&(pins[i].list), &jack->pins);
132 }
133
134 /* Update to reflect the last reported status; canned jack
135 * implementations are likely to set their state before the
136 * card has an opportunity to associate pins.
137 */
138 snd_soc_jack_report(jack, 0, 0);
139
140 return 0;
141}
142EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins);
143
144#ifdef CONFIG_GPIOLIB
145/* gpio detect */
146static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
147{
148 struct snd_soc_jack *jack = gpio->jack;
149 int enable;
150 int report;
151
152 if (gpio->debounce_time > 0)
153 mdelay(gpio->debounce_time);
154
155 enable = gpio_get_value(gpio->gpio);
156 if (gpio->invert)
157 enable = !enable;
158
159 if (enable)
160 report = gpio->report;
161 else
162 report = 0;
163
164 snd_soc_jack_report(jack, report, gpio->report);
165}
166
167/* irq handler for gpio pin */
168static irqreturn_t gpio_handler(int irq, void *data)
169{
170 struct snd_soc_jack_gpio *gpio = data;
171
172 schedule_work(&gpio->work);
173
174 return IRQ_HANDLED;
175}
176
177/* gpio work */
178static void gpio_work(struct work_struct *work)
179{
180 struct snd_soc_jack_gpio *gpio;
181
182 gpio = container_of(work, struct snd_soc_jack_gpio, work);
183 snd_soc_jack_gpio_detect(gpio);
184}
185
186/**
187 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack
188 *
189 * @jack: ASoC jack
190 * @count: number of pins
191 * @gpios: array of gpio pins
192 *
193 * This function will request gpio, set data direction and request irq
194 * for each gpio in the array.
195 */
196int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
197 struct snd_soc_jack_gpio *gpios)
198{
199 int i, ret;
200
201 for (i = 0; i < count; i++) {
202 if (!gpio_is_valid(gpios[i].gpio)) {
203 printk(KERN_ERR "Invalid gpio %d\n",
204 gpios[i].gpio);
205 ret = -EINVAL;
206 goto undo;
207 }
208 if (!gpios[i].name) {
209 printk(KERN_ERR "No name for gpio %d\n",
210 gpios[i].gpio);
211 ret = -EINVAL;
212 goto undo;
213 }
214
215 ret = gpio_request(gpios[i].gpio, gpios[i].name);
216 if (ret)
217 goto undo;
218
219 ret = gpio_direction_input(gpios[i].gpio);
220 if (ret)
221 goto err;
222
223 ret = request_irq(gpio_to_irq(gpios[i].gpio),
224 gpio_handler,
225 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
226 jack->card->dev->driver->name,
227 &gpios[i]);
228 if (ret)
229 goto err;
230
231 INIT_WORK(&gpios[i].work, gpio_work);
232 gpios[i].jack = jack;
233 }
234
235 return 0;
236
237err:
238 gpio_free(gpios[i].gpio);
239undo:
240 snd_soc_jack_free_gpios(jack, i, gpios);
241
242 return ret;
243}
244EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios);
245
246/**
247 * snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack
248 *
249 * @jack: ASoC jack
250 * @count: number of pins
251 * @gpios: array of gpio pins
252 *
253 * Release gpio and irq resources for gpio pins associated with an ASoC jack.
254 */
255void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
256 struct snd_soc_jack_gpio *gpios)
257{
258 int i;
259
260 for (i = 0; i < count; i++) {
261 free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]);
262 gpio_free(gpios[i].gpio);
263 gpios[i].jack = NULL;
264 }
265}
266EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios);
267#endif /* CONFIG_GPIOLIB */