aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c2
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/au1x/dbdma2.c117
-rw-r--r--sound/soc/au1x/psc-ac97.c243
-rw-r--r--sound/soc/au1x/psc-i2s.c189
-rw-r--r--sound/soc/au1x/psc.h7
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c7
-rw-r--r--sound/soc/blackfin/bf5xx-ad1938.c9
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c15
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c9
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c45
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.h11
-rw-r--r--sound/soc/codecs/Kconfig21
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ac97.c3
-rw-r--r--sound/soc/codecs/ad1836.c6
-rw-r--r--sound/soc/codecs/ad1938.c6
-rw-r--r--sound/soc/codecs/ad1980.c5
-rw-r--r--sound/soc/codecs/ad73311.c8
-rw-r--r--sound/soc/codecs/ak4104.c8
-rw-r--r--sound/soc/codecs/ak4535.c8
-rw-r--r--sound/soc/codecs/ak4642.c9
-rw-r--r--sound/soc/codecs/ak4671.c816
-rw-r--r--sound/soc/codecs/ak4671.h156
-rw-r--r--sound/soc/codecs/cs4270.c28
-rw-r--r--sound/soc/codecs/cx20442.c6
-rw-r--r--sound/soc/codecs/pcm3008.c9
-rw-r--r--sound/soc/codecs/ssm2602.c8
-rw-r--r--sound/soc/codecs/stac9766.c3
-rw-r--r--sound/soc/codecs/tlv320aic23.c8
-rw-r--r--sound/soc/codecs/tlv320aic26.c11
-rw-r--r--sound/soc/codecs/tlv320aic3x.c10
-rw-r--r--sound/soc/codecs/tlv320dac33.c1229
-rw-r--r--sound/soc/codecs/tlv320dac33.h267
-rw-r--r--sound/soc/codecs/tpa6130a2.c463
-rw-r--r--sound/soc/codecs/tpa6130a2.h61
-rw-r--r--sound/soc/codecs/twl4030.c407
-rw-r--r--sound/soc/codecs/twl4030.h242
-rw-r--r--sound/soc/codecs/uda134x.c9
-rw-r--r--sound/soc/codecs/uda1380.c8
-rw-r--r--sound/soc/codecs/wm8350.c30
-rw-r--r--sound/soc/codecs/wm8400.c26
-rw-r--r--sound/soc/codecs/wm8510.c13
-rw-r--r--sound/soc/codecs/wm8523.c25
-rw-r--r--sound/soc/codecs/wm8580.c29
-rw-r--r--sound/soc/codecs/wm8711.c634
-rw-r--r--sound/soc/codecs/wm8711.h42
-rw-r--r--sound/soc/codecs/wm8727.c135
-rw-r--r--sound/soc/codecs/wm8727.h21
-rw-r--r--sound/soc/codecs/wm8728.c8
-rw-r--r--sound/soc/codecs/wm8731.c93
-rw-r--r--sound/soc/codecs/wm8750.c8
-rw-r--r--sound/soc/codecs/wm8753.c48
-rw-r--r--sound/soc/codecs/wm8776.c43
-rw-r--r--sound/soc/codecs/wm8900.c27
-rw-r--r--sound/soc/codecs/wm8903.c26
-rw-r--r--sound/soc/codecs/wm8940.c27
-rw-r--r--sound/soc/codecs/wm8960.c29
-rw-r--r--sound/soc/codecs/wm8961.c26
-rw-r--r--sound/soc/codecs/wm8971.c9
-rw-r--r--sound/soc/codecs/wm8974.c35
-rw-r--r--sound/soc/codecs/wm8988.c43
-rw-r--r--sound/soc/codecs/wm8990.c13
-rw-r--r--sound/soc/codecs/wm8993.c47
-rw-r--r--sound/soc/codecs/wm9081.c26
-rw-r--r--sound/soc/codecs/wm9705.c8
-rw-r--r--sound/soc/codecs/wm9712.c8
-rw-r--r--sound/soc/codecs/wm9713.c11
-rw-r--r--sound/soc/codecs/wm_hubs.c35
-rw-r--r--sound/soc/codecs/wm_hubs.h5
-rw-r--r--sound/soc/davinci/Kconfig4
-rw-r--r--sound/soc/davinci/davinci-evm.c7
-rw-r--r--sound/soc/davinci/davinci-i2s.c2
-rw-r--r--sound/soc/davinci/davinci-mcasp.c17
-rw-r--r--sound/soc/davinci/davinci-pcm.c21
-rw-r--r--sound/soc/davinci/davinci-pcm.h1
-rw-r--r--sound/soc/imx/mx27vis_wm8974.c2
-rw-r--r--sound/soc/omap/Kconfig9
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/am3517evm.c202
-rw-r--r--sound/soc/omap/ams-delta.c4
-rw-r--r--sound/soc/omap/omap3evm.c7
-rw-r--r--sound/soc/pxa/Kconfig3
-rw-r--r--sound/soc/pxa/magician.c2
-rw-r--r--sound/soc/pxa/pxa-ssp.c20
-rw-r--r--sound/soc/pxa/zylonite.c5
-rw-r--r--sound/soc/s3c24xx/Kconfig9
-rw-r--r--sound/soc/s3c24xx/Makefile2
-rw-r--r--sound/soc/s3c24xx/neo1973_gta02_wm8753.c8
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c9
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c31
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c1
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c1
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c2
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c1
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c20
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h1
-rw-r--r--sound/soc/s3c24xx/smdk64xx_wm8580.c268
-rw-r--r--sound/soc/sh/Kconfig1
-rw-r--r--sound/soc/sh/fsi.c234
-rw-r--r--sound/soc/soc-cache.c46
-rw-r--r--sound/soc/soc-core.c571
-rw-r--r--sound/soc/soc-dapm.c135
-rw-r--r--sound/soc/soc-jack.c3
104 files changed, 5802 insertions, 1860 deletions
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 9eb610c2ba91..9df4c68ef000 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -268,7 +268,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
268#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ 268#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
269 269
270 270
271 ret = snd_soc_dai_set_pll(codec_dai, 0, 271 ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
272 clk_get_rate(CODEC_CLK), pll_out); 272 clk_get_rate(CODEC_CLK), pll_out);
273 if (ret < 0) { 273 if (ret < 0) {
274 pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", 274 pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n",
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 885ba012557e..e028744c32ce 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -207,7 +207,7 @@ static int __init at91sam9g20ek_init(void)
207 struct clk *pllb; 207 struct clk *pllb;
208 int ret; 208 int ret;
209 209
210 if (!machine_is_at91sam9g20ek()) 210 if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
211 return -ENODEV; 211 return -ENODEV;
212 212
213 /* 213 /*
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 594c6c5b7838..fe9f4657c959 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -333,6 +333,30 @@ static int au1xpsc_pcm_new(struct snd_card *card,
333 333
334static int au1xpsc_pcm_probe(struct platform_device *pdev) 334static int au1xpsc_pcm_probe(struct platform_device *pdev)
335{ 335{
336 if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
337 return -ENODEV;
338
339 return 0;
340}
341
342static int au1xpsc_pcm_remove(struct platform_device *pdev)
343{
344 return 0;
345}
346
347/* au1xpsc audio platform */
348struct snd_soc_platform au1xpsc_soc_platform = {
349 .name = "au1xpsc-pcm-dbdma",
350 .probe = au1xpsc_pcm_probe,
351 .remove = au1xpsc_pcm_remove,
352 .pcm_ops = &au1xpsc_pcm_ops,
353 .pcm_new = au1xpsc_pcm_new,
354 .pcm_free = au1xpsc_pcm_free_dma_buffers,
355};
356EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
357
358static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
359{
336 struct resource *r; 360 struct resource *r;
337 int ret; 361 int ret;
338 362
@@ -365,7 +389,9 @@ static int au1xpsc_pcm_probe(struct platform_device *pdev)
365 } 389 }
366 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; 390 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start;
367 391
368 return 0; 392 ret = snd_soc_register_platform(&au1xpsc_soc_platform);
393 if (!ret)
394 return ret;
369 395
370out2: 396out2:
371 kfree(au1xpsc_audio_pcmdma[PCM_RX]); 397 kfree(au1xpsc_audio_pcmdma[PCM_RX]);
@@ -376,10 +402,12 @@ out1:
376 return ret; 402 return ret;
377} 403}
378 404
379static int au1xpsc_pcm_remove(struct platform_device *pdev) 405static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
380{ 406{
381 int i; 407 int i;
382 408
409 snd_soc_unregister_platform(&au1xpsc_soc_platform);
410
383 for (i = 0; i < 2; i++) { 411 for (i = 0; i < 2; i++) {
384 if (au1xpsc_audio_pcmdma[i]) { 412 if (au1xpsc_audio_pcmdma[i]) {
385 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]); 413 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]);
@@ -391,32 +419,83 @@ static int au1xpsc_pcm_remove(struct platform_device *pdev)
391 return 0; 419 return 0;
392} 420}
393 421
394/* au1xpsc audio platform */ 422static struct platform_driver au1xpsc_pcm_driver = {
395struct snd_soc_platform au1xpsc_soc_platform = { 423 .driver = {
396 .name = "au1xpsc-pcm-dbdma", 424 .name = "au1xpsc-pcm",
397 .probe = au1xpsc_pcm_probe, 425 .owner = THIS_MODULE,
398 .remove = au1xpsc_pcm_remove, 426 },
399 .pcm_ops = &au1xpsc_pcm_ops, 427 .probe = au1xpsc_pcm_drvprobe,
400 .pcm_new = au1xpsc_pcm_new, 428 .remove = __devexit_p(au1xpsc_pcm_drvremove),
401 .pcm_free = au1xpsc_pcm_free_dma_buffers,
402}; 429};
403EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
404 430
405static int __init au1xpsc_audio_dbdma_init(void) 431static int __init au1xpsc_audio_dbdma_load(void)
406{ 432{
407 au1xpsc_audio_pcmdma[PCM_TX] = NULL; 433 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
408 au1xpsc_audio_pcmdma[PCM_RX] = NULL; 434 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
409 return snd_soc_register_platform(&au1xpsc_soc_platform); 435 return platform_driver_register(&au1xpsc_pcm_driver);
410} 436}
411 437
412static void __exit au1xpsc_audio_dbdma_exit(void) 438static void __exit au1xpsc_audio_dbdma_unload(void)
413{ 439{
414 snd_soc_unregister_platform(&au1xpsc_soc_platform); 440 platform_driver_unregister(&au1xpsc_pcm_driver);
441}
442
443module_init(au1xpsc_audio_dbdma_load);
444module_exit(au1xpsc_audio_dbdma_unload);
445
446
447struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
448{
449 struct resource *res, *r;
450 struct platform_device *pd;
451 int id[2];
452 int ret;
453
454 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
455 if (!r)
456 return NULL;
457 id[0] = r->start;
458
459 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
460 if (!r)
461 return NULL;
462 id[1] = r->start;
463
464 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
465 if (!res)
466 return NULL;
467
468 res[0].start = res[0].end = id[0];
469 res[1].start = res[1].end = id[1];
470 res[0].flags = res[1].flags = IORESOURCE_DMA;
471
472 pd = platform_device_alloc("au1xpsc-pcm", -1);
473 if (!pd)
474 goto out;
475
476 pd->resource = res;
477 pd->num_resources = 2;
478
479 ret = platform_device_add(pd);
480 if (!ret)
481 return pd;
482
483out:
484 kfree(res);
485 return NULL;
415} 486}
487EXPORT_SYMBOL_GPL(au1xpsc_pcm_add);
416 488
417module_init(au1xpsc_audio_dbdma_init); 489void au1xpsc_pcm_destroy(struct platform_device *dmapd)
418module_exit(au1xpsc_audio_dbdma_exit); 490{
491 if (dmapd) {
492 kfree(dmapd->resource);
493 dmapd->resource = NULL;
494 platform_device_unregister(dmapd);
495 }
496}
497EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy);
419 498
420MODULE_LICENSE("GPL"); 499MODULE_LICENSE("GPL");
421MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); 500MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
422MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 501MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index a521aa90ddee..340311d7fed5 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -61,7 +61,8 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
61{ 61{
62 /* FIXME */ 62 /* FIXME */
63 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 63 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
64 unsigned short data, retry, tmo; 64 unsigned short retry, tmo;
65 unsigned long data;
65 66
66 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 67 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
67 au_sync(); 68 au_sync();
@@ -74,20 +75,26 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
74 AC97_CDC(pscdata)); 75 AC97_CDC(pscdata));
75 au_sync(); 76 au_sync();
76 77
77 tmo = 2000; 78 tmo = 20;
78 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) 79 do {
79 && --tmo) 80 udelay(21);
80 udelay(2); 81 if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
82 break;
83 } while (--tmo);
81 84
82 data = au_readl(AC97_CDC(pscdata)) & 0xffff; 85 data = au_readl(AC97_CDC(pscdata));
83 86
84 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 87 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
85 au_sync(); 88 au_sync();
86 89
87 mutex_unlock(&pscdata->lock); 90 mutex_unlock(&pscdata->lock);
91
92 if (reg != ((data >> 16) & 0x7f))
93 tmo = 1; /* wrong register, try again */
94
88 } while (--retry && !tmo); 95 } while (--retry && !tmo);
89 96
90 return retry ? data : 0xffff; 97 return retry ? data & 0xffff : 0xffff;
91} 98}
92 99
93/* AC97 controller writes to codec register */ 100/* AC97 controller writes to codec register */
@@ -109,10 +116,12 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
109 AC97_CDC(pscdata)); 116 AC97_CDC(pscdata));
110 au_sync(); 117 au_sync();
111 118
112 tmo = 2000; 119 tmo = 20;
113 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) 120 do {
114 && --tmo) 121 udelay(21);
115 udelay(2); 122 if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
123 break;
124 } while (--tmo);
116 125
117 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 126 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
118 au_sync(); 127 au_sync();
@@ -195,7 +204,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
195 /* FIXME */ 204 /* FIXME */
196 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 205 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
197 unsigned long r, ro, stat; 206 unsigned long r, ro, stat;
198 int chans, stype = SUBSTREAM_TYPE(substream); 207 int chans, t, stype = SUBSTREAM_TYPE(substream);
199 208
200 chans = params_channels(params); 209 chans = params_channels(params);
201 210
@@ -237,8 +246,12 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
237 au_sync(); 246 au_sync();
238 247
239 /* ...wait for it... */ 248 /* ...wait for it... */
240 while (au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) 249 t = 100;
241 asm volatile ("nop"); 250 while ((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t)
251 msleep(1);
252
253 if (!t)
254 printk(KERN_ERR "PSC-AC97: can't disable!\n");
242 255
243 /* ...write config... */ 256 /* ...write config... */
244 au_writel(r, AC97_CFG(pscdata)); 257 au_writel(r, AC97_CFG(pscdata));
@@ -249,8 +262,12 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
249 au_sync(); 262 au_sync();
250 263
251 /* ...and wait for ready bit */ 264 /* ...and wait for ready bit */
252 while (!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) 265 t = 100;
253 asm volatile ("nop"); 266 while ((!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t)
267 msleep(1);
268
269 if (!t)
270 printk(KERN_ERR "PSC-AC97: can't enable!\n");
254 271
255 mutex_unlock(&pscdata->lock); 272 mutex_unlock(&pscdata->lock);
256 273
@@ -300,19 +317,55 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
300static int au1xpsc_ac97_probe(struct platform_device *pdev, 317static int au1xpsc_ac97_probe(struct platform_device *pdev,
301 struct snd_soc_dai *dai) 318 struct snd_soc_dai *dai)
302{ 319{
320 return au1xpsc_ac97_workdata ? 0 : -ENODEV;
321}
322
323static void au1xpsc_ac97_remove(struct platform_device *pdev,
324 struct snd_soc_dai *dai)
325{
326}
327
328static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
329 .trigger = au1xpsc_ac97_trigger,
330 .hw_params = au1xpsc_ac97_hw_params,
331};
332
333struct snd_soc_dai au1xpsc_ac97_dai = {
334 .name = "au1xpsc_ac97",
335 .ac97_control = 1,
336 .probe = au1xpsc_ac97_probe,
337 .remove = au1xpsc_ac97_remove,
338 .playback = {
339 .rates = AC97_RATES,
340 .formats = AC97_FMTS,
341 .channels_min = 2,
342 .channels_max = 2,
343 },
344 .capture = {
345 .rates = AC97_RATES,
346 .formats = AC97_FMTS,
347 .channels_min = 2,
348 .channels_max = 2,
349 },
350 .ops = &au1xpsc_ac97_dai_ops,
351};
352EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
353
354static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
355{
303 int ret; 356 int ret;
304 struct resource *r; 357 struct resource *r;
305 unsigned long sel; 358 unsigned long sel;
359 struct au1xpsc_audio_data *wd;
306 360
307 if (au1xpsc_ac97_workdata) 361 if (au1xpsc_ac97_workdata)
308 return -EBUSY; 362 return -EBUSY;
309 363
310 au1xpsc_ac97_workdata = 364 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
311 kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 365 if (!wd)
312 if (!au1xpsc_ac97_workdata)
313 return -ENOMEM; 366 return -ENOMEM;
314 367
315 mutex_init(&au1xpsc_ac97_workdata->lock); 368 mutex_init(&wd->lock);
316 369
317 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 370 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
318 if (!r) { 371 if (!r) {
@@ -321,81 +374,95 @@ static int au1xpsc_ac97_probe(struct platform_device *pdev,
321 } 374 }
322 375
323 ret = -EBUSY; 376 ret = -EBUSY;
324 au1xpsc_ac97_workdata->ioarea = 377 wd->ioarea = request_mem_region(r->start, r->end - r->start + 1,
325 request_mem_region(r->start, r->end - r->start + 1,
326 "au1xpsc_ac97"); 378 "au1xpsc_ac97");
327 if (!au1xpsc_ac97_workdata->ioarea) 379 if (!wd->ioarea)
328 goto out0; 380 goto out0;
329 381
330 au1xpsc_ac97_workdata->mmio = ioremap(r->start, 0xffff); 382 wd->mmio = ioremap(r->start, 0xffff);
331 if (!au1xpsc_ac97_workdata->mmio) 383 if (!wd->mmio)
332 goto out1; 384 goto out1;
333 385
334 /* configuration: max dma trigger threshold, enable ac97 */ 386 /* configuration: max dma trigger threshold, enable ac97 */
335 au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 | 387 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
336 PSC_AC97CFG_TT_FIFO8 | 388 PSC_AC97CFG_DE_ENABLE;
337 PSC_AC97CFG_DE_ENABLE;
338 389
339 /* preserve PSC clock source set up by platform (dev.platform_data 390 /* preserve PSC clock source set up by platform */
340 * is already occupied by soc layer) 391 sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
341 */ 392 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
342 sel = au_readl(PSC_SEL(au1xpsc_ac97_workdata)) & PSC_SEL_CLK_MASK;
343 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata));
344 au_sync(); 393 au_sync();
345 au_writel(0, PSC_SEL(au1xpsc_ac97_workdata)); 394 au_writel(0, PSC_SEL(wd));
346 au_sync(); 395 au_sync();
347 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(au1xpsc_ac97_workdata)); 396 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
348 au_sync(); 397 au_sync();
349 /* next up: cold reset. Dont check for PSC-ready now since
350 * there may not be any codec clock yet.
351 */
352 398
353 return 0; 399 ret = snd_soc_register_dai(&au1xpsc_ac97_dai);
400 if (ret)
401 goto out1;
354 402
403 wd->dmapd = au1xpsc_pcm_add(pdev);
404 if (wd->dmapd) {
405 platform_set_drvdata(pdev, wd);
406 au1xpsc_ac97_workdata = wd; /* MDEV */
407 return 0;
408 }
409
410 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
355out1: 411out1:
356 release_resource(au1xpsc_ac97_workdata->ioarea); 412 release_resource(wd->ioarea);
357 kfree(au1xpsc_ac97_workdata->ioarea); 413 kfree(wd->ioarea);
358out0: 414out0:
359 kfree(au1xpsc_ac97_workdata); 415 kfree(wd);
360 au1xpsc_ac97_workdata = NULL;
361 return ret; 416 return ret;
362} 417}
363 418
364static void au1xpsc_ac97_remove(struct platform_device *pdev, 419static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
365 struct snd_soc_dai *dai)
366{ 420{
421 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
422
423 if (wd->dmapd)
424 au1xpsc_pcm_destroy(wd->dmapd);
425
426 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
427
367 /* disable PSC completely */ 428 /* disable PSC completely */
368 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); 429 au_writel(0, AC97_CFG(wd));
369 au_sync(); 430 au_sync();
370 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); 431 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
371 au_sync(); 432 au_sync();
372 433
373 iounmap(au1xpsc_ac97_workdata->mmio); 434 iounmap(wd->mmio);
374 release_resource(au1xpsc_ac97_workdata->ioarea); 435 release_resource(wd->ioarea);
375 kfree(au1xpsc_ac97_workdata->ioarea); 436 kfree(wd->ioarea);
376 kfree(au1xpsc_ac97_workdata); 437 kfree(wd);
377 au1xpsc_ac97_workdata = NULL; 438
439 au1xpsc_ac97_workdata = NULL; /* MDEV */
440
441 return 0;
378} 442}
379 443
380static int au1xpsc_ac97_suspend(struct snd_soc_dai *dai) 444#ifdef CONFIG_PM
445static int au1xpsc_ac97_drvsuspend(struct device *dev)
381{ 446{
447 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
448
382 /* save interesting registers and disable PSC */ 449 /* save interesting registers and disable PSC */
383 au1xpsc_ac97_workdata->pm[0] = 450 wd->pm[0] = au_readl(PSC_SEL(wd));
384 au_readl(PSC_SEL(au1xpsc_ac97_workdata));
385 451
386 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); 452 au_writel(0, AC97_CFG(wd));
387 au_sync(); 453 au_sync();
388 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); 454 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
389 au_sync(); 455 au_sync();
390 456
391 return 0; 457 return 0;
392} 458}
393 459
394static int au1xpsc_ac97_resume(struct snd_soc_dai *dai) 460static int au1xpsc_ac97_drvresume(struct device *dev)
395{ 461{
462 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
463
396 /* restore PSC clock config */ 464 /* restore PSC clock config */
397 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE, 465 au_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd));
398 PSC_SEL(au1xpsc_ac97_workdata));
399 au_sync(); 466 au_sync();
400 467
401 /* after this point the ac97 core will cold-reset the codec. 468 /* after this point the ac97 core will cold-reset the codec.
@@ -405,48 +472,44 @@ static int au1xpsc_ac97_resume(struct snd_soc_dai *dai)
405 return 0; 472 return 0;
406} 473}
407 474
408static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { 475static struct dev_pm_ops au1xpscac97_pmops = {
409 .trigger = au1xpsc_ac97_trigger, 476 .suspend = au1xpsc_ac97_drvsuspend,
410 .hw_params = au1xpsc_ac97_hw_params, 477 .resume = au1xpsc_ac97_drvresume,
411}; 478};
412 479
413struct snd_soc_dai au1xpsc_ac97_dai = { 480#define AU1XPSCAC97_PMOPS &au1xpscac97_pmops
414 .name = "au1xpsc_ac97", 481
415 .ac97_control = 1, 482#else
416 .probe = au1xpsc_ac97_probe, 483
417 .remove = au1xpsc_ac97_remove, 484#define AU1XPSCAC97_PMOPS NULL
418 .suspend = au1xpsc_ac97_suspend, 485
419 .resume = au1xpsc_ac97_resume, 486#endif
420 .playback = { 487
421 .rates = AC97_RATES, 488static struct platform_driver au1xpsc_ac97_driver = {
422 .formats = AC97_FMTS, 489 .driver = {
423 .channels_min = 2, 490 .name = "au1xpsc_ac97",
424 .channels_max = 2, 491 .owner = THIS_MODULE,
425 }, 492 .pm = AU1XPSCAC97_PMOPS,
426 .capture = {
427 .rates = AC97_RATES,
428 .formats = AC97_FMTS,
429 .channels_min = 2,
430 .channels_max = 2,
431 }, 493 },
432 .ops = &au1xpsc_ac97_dai_ops, 494 .probe = au1xpsc_ac97_drvprobe,
495 .remove = __devexit_p(au1xpsc_ac97_drvremove),
433}; 496};
434EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
435 497
436static int __init au1xpsc_ac97_init(void) 498static int __init au1xpsc_ac97_load(void)
437{ 499{
438 au1xpsc_ac97_workdata = NULL; 500 au1xpsc_ac97_workdata = NULL;
439 return snd_soc_register_dai(&au1xpsc_ac97_dai); 501 return platform_driver_register(&au1xpsc_ac97_driver);
440} 502}
441 503
442static void __exit au1xpsc_ac97_exit(void) 504static void __exit au1xpsc_ac97_unload(void)
443{ 505{
444 snd_soc_unregister_dai(&au1xpsc_ac97_dai); 506 platform_driver_unregister(&au1xpsc_ac97_driver);
445} 507}
446 508
447module_init(au1xpsc_ac97_init); 509module_init(au1xpsc_ac97_load);
448module_exit(au1xpsc_ac97_exit); 510module_exit(au1xpsc_ac97_unload);
449 511
450MODULE_LICENSE("GPL"); 512MODULE_LICENSE("GPL");
451MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); 513MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
452MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>"); 514MODULE_AUTHOR("Manuel Lauss");
515
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index bb589327ee32..0cf2ca61c776 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -265,16 +265,52 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
265static int au1xpsc_i2s_probe(struct platform_device *pdev, 265static int au1xpsc_i2s_probe(struct platform_device *pdev,
266 struct snd_soc_dai *dai) 266 struct snd_soc_dai *dai)
267{ 267{
268 return au1xpsc_i2s_workdata ? 0 : -ENODEV;
269}
270
271static void au1xpsc_i2s_remove(struct platform_device *pdev,
272 struct snd_soc_dai *dai)
273{
274}
275
276static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
277 .trigger = au1xpsc_i2s_trigger,
278 .hw_params = au1xpsc_i2s_hw_params,
279 .set_fmt = au1xpsc_i2s_set_fmt,
280};
281
282struct snd_soc_dai au1xpsc_i2s_dai = {
283 .name = "au1xpsc_i2s",
284 .probe = au1xpsc_i2s_probe,
285 .remove = au1xpsc_i2s_remove,
286 .playback = {
287 .rates = AU1XPSC_I2S_RATES,
288 .formats = AU1XPSC_I2S_FMTS,
289 .channels_min = 2,
290 .channels_max = 8, /* 2 without external help */
291 },
292 .capture = {
293 .rates = AU1XPSC_I2S_RATES,
294 .formats = AU1XPSC_I2S_FMTS,
295 .channels_min = 2,
296 .channels_max = 8, /* 2 without external help */
297 },
298 .ops = &au1xpsc_i2s_dai_ops,
299};
300EXPORT_SYMBOL(au1xpsc_i2s_dai);
301
302static int __init au1xpsc_i2s_drvprobe(struct platform_device *pdev)
303{
268 struct resource *r; 304 struct resource *r;
269 unsigned long sel; 305 unsigned long sel;
270 int ret; 306 int ret;
307 struct au1xpsc_audio_data *wd;
271 308
272 if (au1xpsc_i2s_workdata) 309 if (au1xpsc_i2s_workdata)
273 return -EBUSY; 310 return -EBUSY;
274 311
275 au1xpsc_i2s_workdata = 312 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
276 kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 313 if (!wd)
277 if (!au1xpsc_i2s_workdata)
278 return -ENOMEM; 314 return -ENOMEM;
279 315
280 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 316 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -284,131 +320,146 @@ static int au1xpsc_i2s_probe(struct platform_device *pdev,
284 } 320 }
285 321
286 ret = -EBUSY; 322 ret = -EBUSY;
287 au1xpsc_i2s_workdata->ioarea = 323 wd->ioarea = request_mem_region(r->start, r->end - r->start + 1,
288 request_mem_region(r->start, r->end - r->start + 1,
289 "au1xpsc_i2s"); 324 "au1xpsc_i2s");
290 if (!au1xpsc_i2s_workdata->ioarea) 325 if (!wd->ioarea)
291 goto out0; 326 goto out0;
292 327
293 au1xpsc_i2s_workdata->mmio = ioremap(r->start, 0xffff); 328 wd->mmio = ioremap(r->start, 0xffff);
294 if (!au1xpsc_i2s_workdata->mmio) 329 if (!wd->mmio)
295 goto out1; 330 goto out1;
296 331
297 /* preserve PSC clock source set up by platform (dev.platform_data 332 /* preserve PSC clock source set up by platform (dev.platform_data
298 * is already occupied by soc layer) 333 * is already occupied by soc layer)
299 */ 334 */
300 sel = au_readl(PSC_SEL(au1xpsc_i2s_workdata)) & PSC_SEL_CLK_MASK; 335 sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
301 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 336 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
302 au_sync(); 337 au_sync();
303 au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(au1xpsc_i2s_workdata)); 338 au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd));
304 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 339 au_writel(0, I2S_CFG(wd));
305 au_sync(); 340 au_sync();
306 341
307 /* preconfigure: set max rx/tx fifo depths */ 342 /* preconfigure: set max rx/tx fifo depths */
308 au1xpsc_i2s_workdata->cfg |= 343 wd->cfg |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;
309 PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;
310 344
311 /* don't wait for I2S core to become ready now; clocks may not 345 /* don't wait for I2S core to become ready now; clocks may not
312 * be running yet; depending on clock input for PSC a wait might 346 * be running yet; depending on clock input for PSC a wait might
313 * time out. 347 * time out.
314 */ 348 */
315 349
316 return 0; 350 ret = snd_soc_register_dai(&au1xpsc_i2s_dai);
351 if (ret)
352 goto out1;
317 353
354 /* finally add the DMA device for this PSC */
355 wd->dmapd = au1xpsc_pcm_add(pdev);
356 if (wd->dmapd) {
357 platform_set_drvdata(pdev, wd);
358 au1xpsc_i2s_workdata = wd;
359 return 0;
360 }
361
362 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
318out1: 363out1:
319 release_resource(au1xpsc_i2s_workdata->ioarea); 364 release_resource(wd->ioarea);
320 kfree(au1xpsc_i2s_workdata->ioarea); 365 kfree(wd->ioarea);
321out0: 366out0:
322 kfree(au1xpsc_i2s_workdata); 367 kfree(wd);
323 au1xpsc_i2s_workdata = NULL;
324 return ret; 368 return ret;
325} 369}
326 370
327static void au1xpsc_i2s_remove(struct platform_device *pdev, 371static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
328 struct snd_soc_dai *dai)
329{ 372{
330 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 373 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
374
375 if (wd->dmapd)
376 au1xpsc_pcm_destroy(wd->dmapd);
377
378 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
379
380 au_writel(0, I2S_CFG(wd));
331 au_sync(); 381 au_sync();
332 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 382 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
333 au_sync(); 383 au_sync();
334 384
335 iounmap(au1xpsc_i2s_workdata->mmio); 385 iounmap(wd->mmio);
336 release_resource(au1xpsc_i2s_workdata->ioarea); 386 release_resource(wd->ioarea);
337 kfree(au1xpsc_i2s_workdata->ioarea); 387 kfree(wd->ioarea);
338 kfree(au1xpsc_i2s_workdata); 388 kfree(wd);
339 au1xpsc_i2s_workdata = NULL; 389
390 au1xpsc_i2s_workdata = NULL; /* MDEV */
391
392 return 0;
340} 393}
341 394
342static int au1xpsc_i2s_suspend(struct snd_soc_dai *cpu_dai) 395#ifdef CONFIG_PM
396static int au1xpsc_i2s_drvsuspend(struct device *dev)
343{ 397{
398 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
399
344 /* save interesting register and disable PSC */ 400 /* save interesting register and disable PSC */
345 au1xpsc_i2s_workdata->pm[0] = 401 wd->pm[0] = au_readl(PSC_SEL(wd));
346 au_readl(PSC_SEL(au1xpsc_i2s_workdata));
347 402
348 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 403 au_writel(0, I2S_CFG(wd));
349 au_sync(); 404 au_sync();
350 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 405 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
351 au_sync(); 406 au_sync();
352 407
353 return 0; 408 return 0;
354} 409}
355 410
356static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai) 411static int au1xpsc_i2s_drvresume(struct device *dev)
357{ 412{
413 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
414
358 /* select I2S mode and PSC clock */ 415 /* select I2S mode and PSC clock */
359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 416 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
360 au_sync(); 417 au_sync();
361 au_writel(0, PSC_SEL(au1xpsc_i2s_workdata)); 418 au_writel(0, PSC_SEL(wd));
362 au_sync(); 419 au_sync();
363 au_writel(au1xpsc_i2s_workdata->pm[0], 420 au_writel(wd->pm[0], PSC_SEL(wd));
364 PSC_SEL(au1xpsc_i2s_workdata));
365 au_sync(); 421 au_sync();
366 422
367 return 0; 423 return 0;
368} 424}
369 425
370static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 426static struct dev_pm_ops au1xpsci2s_pmops = {
371 .trigger = au1xpsc_i2s_trigger, 427 .suspend = au1xpsc_i2s_drvsuspend,
372 .hw_params = au1xpsc_i2s_hw_params, 428 .resume = au1xpsc_i2s_drvresume,
373 .set_fmt = au1xpsc_i2s_set_fmt,
374}; 429};
375 430
376struct snd_soc_dai au1xpsc_i2s_dai = { 431#define AU1XPSCI2S_PMOPS &au1xpsci2s_pmops
377 .name = "au1xpsc_i2s", 432
378 .probe = au1xpsc_i2s_probe, 433#else
379 .remove = au1xpsc_i2s_remove, 434
380 .suspend = au1xpsc_i2s_suspend, 435#define AU1XPSCI2S_PMOPS NULL
381 .resume = au1xpsc_i2s_resume, 436
382 .playback = { 437#endif
383 .rates = AU1XPSC_I2S_RATES, 438
384 .formats = AU1XPSC_I2S_FMTS, 439static struct platform_driver au1xpsc_i2s_driver = {
385 .channels_min = 2, 440 .driver = {
386 .channels_max = 8, /* 2 without external help */ 441 .name = "au1xpsc_i2s",
387 }, 442 .owner = THIS_MODULE,
388 .capture = { 443 .pm = AU1XPSCI2S_PMOPS,
389 .rates = AU1XPSC_I2S_RATES,
390 .formats = AU1XPSC_I2S_FMTS,
391 .channels_min = 2,
392 .channels_max = 8, /* 2 without external help */
393 }, 444 },
394 .ops = &au1xpsc_i2s_dai_ops, 445 .probe = au1xpsc_i2s_drvprobe,
446 .remove = __devexit_p(au1xpsc_i2s_drvremove),
395}; 447};
396EXPORT_SYMBOL(au1xpsc_i2s_dai);
397 448
398static int __init au1xpsc_i2s_init(void) 449static int __init au1xpsc_i2s_load(void)
399{ 450{
400 au1xpsc_i2s_workdata = NULL; 451 au1xpsc_i2s_workdata = NULL;
401 return snd_soc_register_dai(&au1xpsc_i2s_dai); 452 return platform_driver_register(&au1xpsc_i2s_driver);
402} 453}
403 454
404static void __exit au1xpsc_i2s_exit(void) 455static void __exit au1xpsc_i2s_unload(void)
405{ 456{
406 snd_soc_unregister_dai(&au1xpsc_i2s_dai); 457 platform_driver_unregister(&au1xpsc_i2s_driver);
407} 458}
408 459
409module_init(au1xpsc_i2s_init); 460module_init(au1xpsc_i2s_load);
410module_exit(au1xpsc_i2s_exit); 461module_exit(au1xpsc_i2s_unload);
411 462
412MODULE_LICENSE("GPL"); 463MODULE_LICENSE("GPL");
413MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver"); 464MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver");
414MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 465MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index 3f474e8ed4f6..32d3807d3f5a 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -21,6 +21,10 @@ extern struct snd_soc_dai au1xpsc_i2s_dai;
21extern struct snd_soc_platform au1xpsc_soc_platform; 21extern struct snd_soc_platform au1xpsc_soc_platform;
22extern struct snd_ac97_bus_ops soc_ac97_ops; 22extern struct snd_ac97_bus_ops soc_ac97_ops;
23 23
24/* DBDMA helpers */
25extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
26extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
27
24struct au1xpsc_audio_data { 28struct au1xpsc_audio_data {
25 void __iomem *mmio; 29 void __iomem *mmio;
26 30
@@ -30,6 +34,7 @@ struct au1xpsc_audio_data {
30 unsigned long pm[2]; 34 unsigned long pm[2];
31 struct resource *ioarea; 35 struct resource *ioarea;
32 struct mutex lock; 36 struct mutex lock;
37 struct platform_device *dmapd;
33}; 38};
34 39
35#define PCM_TX 0 40#define PCM_TX 0
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index cd361e304b0f..0f45a3f56be8 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -52,6 +52,7 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
52 struct snd_soc_pcm_runtime *rtd = substream->private_data; 52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
55 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
55 int ret = 0; 56 int ret = 0;
56 /* set cpu DAI configuration */ 57 /* set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 58 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
@@ -65,6 +66,12 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
65 if (ret < 0) 66 if (ret < 0)
66 return ret; 67 return ret;
67 68
69 /* set cpu DAI channel mapping */
70 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
71 channel_map, ARRAY_SIZE(channel_map), channel_map);
72 if (ret < 0)
73 return ret;
74
68 return 0; 75 return 0;
69} 76}
70 77
diff --git a/sound/soc/blackfin/bf5xx-ad1938.c b/sound/soc/blackfin/bf5xx-ad1938.c
index 08269e91810c..2ef1e5013b8c 100644
--- a/sound/soc/blackfin/bf5xx-ad1938.c
+++ b/sound/soc/blackfin/bf5xx-ad1938.c
@@ -61,6 +61,7 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
61 struct snd_soc_pcm_runtime *rtd = substream->private_data; 61 struct snd_soc_pcm_runtime *rtd = substream->private_data;
62 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 62 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
64 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
64 int ret = 0; 65 int ret = 0;
65 /* set cpu DAI configuration */ 66 /* set cpu DAI configuration */
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 67 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
@@ -75,7 +76,13 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
75 return ret; 76 return ret;
76 77
77 /* set codec DAI slots, 8 channels, all channels are enabled */ 78 /* set codec DAI slots, 8 channels, all channels are enabled */
78 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 8); 79 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
80 if (ret < 0)
81 return ret;
82
83 /* set cpu DAI channel mapping */
84 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
85 channel_map, ARRAY_SIZE(channel_map), channel_map);
79 if (ret < 0) 86 if (ret < 0)
80 return ret; 87 return ret;
81 88
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 084b68884ada..3e6ada0dd1c4 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -49,7 +49,6 @@ struct bf5xx_i2s_port {
49 u16 rcr1; 49 u16 rcr1;
50 u16 tcr2; 50 u16 tcr2;
51 u16 rcr2; 51 u16 rcr2;
52 int counter;
53 int configured; 52 int configured;
54}; 53};
55 54
@@ -133,16 +132,6 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
133 return ret; 132 return ret;
134} 133}
135 134
136static int bf5xx_i2s_startup(struct snd_pcm_substream *substream,
137 struct snd_soc_dai *dai)
138{
139 pr_debug("%s enter\n", __func__);
140
141 /*this counter is used for counting how many pcm streams are opened*/
142 bf5xx_i2s.counter++;
143 return 0;
144}
145
146static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, 135static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
147 struct snd_pcm_hw_params *params, 136 struct snd_pcm_hw_params *params,
148 struct snd_soc_dai *dai) 137 struct snd_soc_dai *dai)
@@ -201,9 +190,8 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
201 struct snd_soc_dai *dai) 190 struct snd_soc_dai *dai)
202{ 191{
203 pr_debug("%s enter\n", __func__); 192 pr_debug("%s enter\n", __func__);
204 bf5xx_i2s.counter--;
205 /* No active stream, SPORT is allowed to be configured again. */ 193 /* No active stream, SPORT is allowed to be configured again. */
206 if (!bf5xx_i2s.counter) 194 if (!dai->active)
207 bf5xx_i2s.configured = 0; 195 bf5xx_i2s.configured = 0;
208} 196}
209 197
@@ -284,7 +272,6 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
284 SNDRV_PCM_FMTBIT_S32_LE) 272 SNDRV_PCM_FMTBIT_S32_LE)
285 273
286static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { 274static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
287 .startup = bf5xx_i2s_startup,
288 .shutdown = bf5xx_i2s_shutdown, 275 .shutdown = bf5xx_i2s_shutdown,
289 .hw_params = bf5xx_i2s_hw_params, 276 .hw_params = bf5xx_i2s_hw_params,
290 .set_fmt = bf5xx_i2s_set_dai_fmt, 277 .set_fmt = bf5xx_i2s_set_dai_fmt,
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index ccb5e823bd18..a8c73cbbd685 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -43,7 +43,7 @@
43#include "bf5xx-tdm.h" 43#include "bf5xx-tdm.h"
44#include "bf5xx-sport.h" 44#include "bf5xx-sport.h"
45 45
46#define PCM_BUFFER_MAX 0x10000 46#define PCM_BUFFER_MAX 0x8000
47#define FRAGMENT_SIZE_MIN (4*1024) 47#define FRAGMENT_SIZE_MIN (4*1024)
48#define FRAGMENTS_MIN 2 48#define FRAGMENTS_MIN 2
49#define FRAGMENTS_MAX 32 49#define FRAGMENTS_MAX 32
@@ -177,6 +177,9 @@ out:
177static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, 177static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
178 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count) 178 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
179{ 179{
180 struct snd_pcm_runtime *runtime = substream->runtime;
181 struct sport_device *sport = runtime->private_data;
182 struct bf5xx_tdm_port *tdm_port = sport->private_data;
180 unsigned int *src; 183 unsigned int *src;
181 unsigned int *dst; 184 unsigned int *dst;
182 int i; 185 int i;
@@ -188,7 +191,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
188 dst += pos * 8; 191 dst += pos * 8;
189 while (count--) { 192 while (count--) {
190 for (i = 0; i < substream->runtime->channels; i++) 193 for (i = 0; i < substream->runtime->channels; i++)
191 *(dst + i) = *src++; 194 *(dst + tdm_port->tx_map[i]) = *src++;
192 dst += 8; 195 dst += 8;
193 } 196 }
194 } else { 197 } else {
@@ -198,7 +201,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
198 src += pos * 8; 201 src += pos * 8;
199 while (count--) { 202 while (count--) {
200 for (i = 0; i < substream->runtime->channels; i++) 203 for (i = 0; i < substream->runtime->channels; i++)
201 *dst++ = *(src+i); 204 *dst++ = *(src + tdm_port->rx_map[i]);
202 src += 8; 205 src += 8;
203 } 206 }
204 } 207 }
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index ff546e91a22e..4b360124083e 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -46,14 +46,6 @@
46#include "bf5xx-sport.h" 46#include "bf5xx-sport.h"
47#include "bf5xx-tdm.h" 47#include "bf5xx-tdm.h"
48 48
49struct bf5xx_tdm_port {
50 u16 tcr1;
51 u16 rcr1;
52 u16 tcr2;
53 u16 rcr2;
54 int configured;
55};
56
57static struct bf5xx_tdm_port bf5xx_tdm; 49static struct bf5xx_tdm_port bf5xx_tdm;
58static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; 50static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
59 51
@@ -181,6 +173,40 @@ static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
181 bf5xx_tdm.configured = 0; 173 bf5xx_tdm.configured = 0;
182} 174}
183 175
176static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
177 unsigned int tx_num, unsigned int *tx_slot,
178 unsigned int rx_num, unsigned int *rx_slot)
179{
180 int i;
181 unsigned int slot;
182 unsigned int tx_mapped = 0, rx_mapped = 0;
183
184 if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) ||
185 (rx_num > BFIN_TDM_DAI_MAX_SLOTS))
186 return -EINVAL;
187
188 for (i = 0; i < tx_num; i++) {
189 slot = tx_slot[i];
190 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
191 (!(tx_mapped & (1 << slot)))) {
192 bf5xx_tdm.tx_map[i] = slot;
193 tx_mapped |= 1 << slot;
194 } else
195 return -EINVAL;
196 }
197 for (i = 0; i < rx_num; i++) {
198 slot = rx_slot[i];
199 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
200 (!(rx_mapped & (1 << slot)))) {
201 bf5xx_tdm.rx_map[i] = slot;
202 rx_mapped |= 1 << slot;
203 } else
204 return -EINVAL;
205 }
206
207 return 0;
208}
209
184#ifdef CONFIG_PM 210#ifdef CONFIG_PM
185static int bf5xx_tdm_suspend(struct snd_soc_dai *dai) 211static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
186{ 212{
@@ -235,6 +261,7 @@ static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
235 .hw_params = bf5xx_tdm_hw_params, 261 .hw_params = bf5xx_tdm_hw_params,
236 .set_fmt = bf5xx_tdm_set_dai_fmt, 262 .set_fmt = bf5xx_tdm_set_dai_fmt,
237 .shutdown = bf5xx_tdm_shutdown, 263 .shutdown = bf5xx_tdm_shutdown,
264 .set_channel_map = bf5xx_tdm_set_channel_map,
238}; 265};
239 266
240struct snd_soc_dai bf5xx_tdm_dai = { 267struct snd_soc_dai bf5xx_tdm_dai = {
@@ -300,6 +327,8 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
300 pr_err("Failed to register DAI: %d\n", ret); 327 pr_err("Failed to register DAI: %d\n", ret);
301 goto sport_config_err; 328 goto sport_config_err;
302 } 329 }
330
331 sport_handle->private_data = &bf5xx_tdm;
303 return 0; 332 return 0;
304 333
305sport_config_err: 334sport_config_err:
diff --git a/sound/soc/blackfin/bf5xx-tdm.h b/sound/soc/blackfin/bf5xx-tdm.h
index 618ec3d90cd4..04189a18c1ba 100644
--- a/sound/soc/blackfin/bf5xx-tdm.h
+++ b/sound/soc/blackfin/bf5xx-tdm.h
@@ -9,6 +9,17 @@
9#ifndef _BF5XX_TDM_H 9#ifndef _BF5XX_TDM_H
10#define _BF5XX_TDM_H 10#define _BF5XX_TDM_H
11 11
12#define BFIN_TDM_DAI_MAX_SLOTS 8
13struct bf5xx_tdm_port {
14 u16 tcr1;
15 u16 rcr1;
16 u16 tcr2;
17 u16 rcr2;
18 unsigned int tx_map[BFIN_TDM_DAI_MAX_SLOTS];
19 unsigned int rx_map[BFIN_TDM_DAI_MAX_SLOTS];
20 int configured;
21};
22
12extern struct snd_soc_dai bf5xx_tdm_dai; 23extern struct snd_soc_dai bf5xx_tdm_dai;
13 24
14#endif 25#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0edca93af3b0..4a3e8dcf24d9 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -19,6 +19,7 @@ config SND_SOC_ALL_CODECS
19 select SND_SOC_AK4104 if SPI_MASTER 19 select SND_SOC_AK4104 if SPI_MASTER
20 select SND_SOC_AK4535 if I2C 20 select SND_SOC_AK4535 if I2C
21 select SND_SOC_AK4642 if I2C 21 select SND_SOC_AK4642 if I2C
22 select SND_SOC_AK4671 if I2C
22 select SND_SOC_CS4270 if I2C 23 select SND_SOC_CS4270 if I2C
23 select SND_SOC_MAX9877 if I2C 24 select SND_SOC_MAX9877 if I2C
24 select SND_SOC_PCM3008 25 select SND_SOC_PCM3008
@@ -28,6 +29,8 @@ config SND_SOC_ALL_CODECS
28 select SND_SOC_TLV320AIC23 if I2C 29 select SND_SOC_TLV320AIC23 if I2C
29 select SND_SOC_TLV320AIC26 if SPI_MASTER 30 select SND_SOC_TLV320AIC26 if SPI_MASTER
30 select SND_SOC_TLV320AIC3X if I2C 31 select SND_SOC_TLV320AIC3X if I2C
32 select SND_SOC_TPA6130A2 if I2C
33 select SND_SOC_TLV320DAC33 if I2C
31 select SND_SOC_TWL4030 if TWL4030_CORE 34 select SND_SOC_TWL4030 if TWL4030_CORE
32 select SND_SOC_UDA134X 35 select SND_SOC_UDA134X
33 select SND_SOC_UDA1380 if I2C 36 select SND_SOC_UDA1380 if I2C
@@ -36,6 +39,8 @@ config SND_SOC_ALL_CODECS
36 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 39 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
37 select SND_SOC_WM8523 if I2C 40 select SND_SOC_WM8523 if I2C
38 select SND_SOC_WM8580 if I2C 41 select SND_SOC_WM8580 if I2C
42 select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI
43 select SND_SOC_WM8727
39 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 44 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
40 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 45 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
41 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 46 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
@@ -96,6 +101,9 @@ config SND_SOC_AK4535
96config SND_SOC_AK4642 101config SND_SOC_AK4642
97 tristate 102 tristate
98 103
104config SND_SOC_AK4671
105 tristate
106
99# Cirrus Logic CS4270 Codec 107# Cirrus Logic CS4270 Codec
100config SND_SOC_CS4270 108config SND_SOC_CS4270
101 tristate 109 tristate
@@ -136,7 +144,11 @@ config SND_SOC_TLV320AIC26
136config SND_SOC_TLV320AIC3X 144config SND_SOC_TLV320AIC3X
137 tristate 145 tristate
138 146
147config SND_SOC_TLV320DAC33
148 tristate
149
139config SND_SOC_TWL4030 150config SND_SOC_TWL4030
151 select TWL4030_CODEC
140 tristate 152 tristate
141 153
142config SND_SOC_UDA134X 154config SND_SOC_UDA134X
@@ -160,6 +172,12 @@ config SND_SOC_WM8523
160config SND_SOC_WM8580 172config SND_SOC_WM8580
161 tristate 173 tristate
162 174
175config SND_SOC_WM8711
176 tristate
177
178config SND_SOC_WM8727
179 tristate
180
163config SND_SOC_WM8728 181config SND_SOC_WM8728
164 tristate 182 tristate
165 183
@@ -220,3 +238,6 @@ config SND_SOC_WM9713
220# Amp 238# Amp
221config SND_SOC_MAX9877 239config SND_SOC_MAX9877
222 tristate 240 tristate
241
242config SND_SOC_TPA6130A2
243 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fb4af28486ba..cacfc7692d7f 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -6,6 +6,7 @@ snd-soc-ad73311-objs := ad73311.o
6snd-soc-ak4104-objs := ak4104.o 6snd-soc-ak4104-objs := ak4104.o
7snd-soc-ak4535-objs := ak4535.o 7snd-soc-ak4535-objs := ak4535.o
8snd-soc-ak4642-objs := ak4642.o 8snd-soc-ak4642-objs := ak4642.o
9snd-soc-ak4671-objs := ak4671.o
9snd-soc-cs4270-objs := cs4270.o 10snd-soc-cs4270-objs := cs4270.o
10snd-soc-cx20442-objs := cx20442.o 11snd-soc-cx20442-objs := cx20442.o
11snd-soc-l3-objs := l3.o 12snd-soc-l3-objs := l3.o
@@ -16,6 +17,7 @@ snd-soc-stac9766-objs := stac9766.o
16snd-soc-tlv320aic23-objs := tlv320aic23.o 17snd-soc-tlv320aic23-objs := tlv320aic23.o
17snd-soc-tlv320aic26-objs := tlv320aic26.o 18snd-soc-tlv320aic26-objs := tlv320aic26.o
18snd-soc-tlv320aic3x-objs := tlv320aic3x.o 19snd-soc-tlv320aic3x-objs := tlv320aic3x.o
20snd-soc-tlv320dac33-objs := tlv320dac33.o
19snd-soc-twl4030-objs := twl4030.o 21snd-soc-twl4030-objs := twl4030.o
20snd-soc-uda134x-objs := uda134x.o 22snd-soc-uda134x-objs := uda134x.o
21snd-soc-uda1380-objs := uda1380.o 23snd-soc-uda1380-objs := uda1380.o
@@ -24,6 +26,8 @@ snd-soc-wm8400-objs := wm8400.o
24snd-soc-wm8510-objs := wm8510.o 26snd-soc-wm8510-objs := wm8510.o
25snd-soc-wm8523-objs := wm8523.o 27snd-soc-wm8523-objs := wm8523.o
26snd-soc-wm8580-objs := wm8580.o 28snd-soc-wm8580-objs := wm8580.o
29snd-soc-wm8711-objs := wm8711.o
30snd-soc-wm8727-objs := wm8727.o
27snd-soc-wm8728-objs := wm8728.o 31snd-soc-wm8728-objs := wm8728.o
28snd-soc-wm8731-objs := wm8731.o 32snd-soc-wm8731-objs := wm8731.o
29snd-soc-wm8750-objs := wm8750.o 33snd-soc-wm8750-objs := wm8750.o
@@ -47,6 +51,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
47 51
48# Amp 52# Amp
49snd-soc-max9877-objs := max9877.o 53snd-soc-max9877-objs := max9877.o
54snd-soc-tpa6130a2-objs := tpa6130a2.o
50 55
51obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 56obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
52obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 57obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
@@ -56,6 +61,7 @@ obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
56obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 61obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
57obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 62obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
58obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 63obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
64obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
59obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 65obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
60obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 66obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
61obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 67obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
@@ -66,6 +72,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
66obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 72obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
67obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 73obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
68obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 74obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
75obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
69obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 76obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
70obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 77obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
71obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 78obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
@@ -74,6 +81,8 @@ obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
74obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 81obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
75obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o 82obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
76obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 83obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
84obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
85obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
77obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 86obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
78obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 87obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
79obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 88obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
@@ -97,3 +106,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
97 106
98# Amp 107# Amp
99obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 108obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
109obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 932299bb5d1e..69bd0acc81c8 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -117,9 +117,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
117 if (ret < 0) 117 if (ret < 0)
118 goto bus_err; 118 goto bus_err;
119 119
120 ret = snd_soc_init_card(socdev);
121 if (ret < 0)
122 goto bus_err;
123 return 0; 120 return 0;
124 121
125bus_err: 122bus_err:
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c48485f2c55d..2e360c243075 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -387,12 +387,6 @@ static int ad1836_probe(struct platform_device *pdev)
387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
388 snd_soc_dapm_new_widgets(codec); 388 snd_soc_dapm_new_widgets(codec);
389 389
390 ret = snd_soc_init_card(socdev);
391 if (ret < 0) {
392 dev_err(codec->dev, "failed to register card: %d\n", ret);
393 goto card_err;
394 }
395
396 return ret; 390 return ret;
397 391
398card_err: 392card_err:
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index 34b30efc3cb0..09c008ad1476 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -596,12 +596,6 @@ static int ad1938_probe(struct platform_device *pdev)
596 596
597 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 597 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
598 598
599 ret = snd_soc_init_card(socdev);
600 if (ret < 0) {
601 dev_err(codec->dev, "failed to register card: %d\n", ret);
602 goto card_err;
603 }
604
605 return ret; 599 return ret;
606 600
607card_err: 601card_err:
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index d7440a982d22..39c0f7584e65 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -257,11 +257,6 @@ static int ad1980_soc_probe(struct platform_device *pdev)
257 257
258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls, 258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls,
259 ARRAY_SIZE(ad1980_snd_ac97_controls)); 259 ARRAY_SIZE(ad1980_snd_ac97_controls));
260 ret = snd_soc_init_card(socdev);
261 if (ret < 0) {
262 printk(KERN_ERR "ad1980: failed to register card\n");
263 goto reset_err;
264 }
265 260
266 return 0; 261 return 0;
267 262
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index e61dac5e7b8f..d2fcc601722c 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -64,16 +64,8 @@ static int ad73311_soc_probe(struct platform_device *pdev)
64 goto pcm_err; 64 goto pcm_err;
65 } 65 }
66 66
67 ret = snd_soc_init_card(socdev);
68 if (ret < 0) {
69 printk(KERN_ERR "ad73311: failed to register card\n");
70 goto register_err;
71 }
72
73 return ret; 67 return ret;
74 68
75register_err:
76 snd_soc_free_pcms(socdev);
77pcm_err: 69pcm_err:
78 kfree(socdev->card->codec); 70 kfree(socdev->card->codec);
79 socdev->card->codec = NULL; 71 socdev->card->codec = NULL;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 4d47bc4f7428..3a14c6fc4f5e 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -313,14 +313,6 @@ static int ak4104_probe(struct platform_device *pdev)
313 return ret; 313 return ret;
314 } 314 }
315 315
316 /* Register the socdev */
317 ret = snd_soc_init_card(socdev);
318 if (ret < 0) {
319 dev_err(codec->dev, "failed to register card\n");
320 snd_soc_free_pcms(socdev);
321 return ret;
322 }
323
324 return 0; 316 return 0;
325} 317}
326 318
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 0abec0d29a96..57a6846a9a1f 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -485,17 +485,9 @@ static int ak4535_init(struct snd_soc_device *socdev)
485 snd_soc_add_controls(codec, ak4535_snd_controls, 485 snd_soc_add_controls(codec, ak4535_snd_controls,
486 ARRAY_SIZE(ak4535_snd_controls)); 486 ARRAY_SIZE(ak4535_snd_controls));
487 ak4535_add_widgets(codec); 487 ak4535_add_widgets(codec);
488 ret = snd_soc_init_card(socdev);
489 if (ret < 0) {
490 printk(KERN_ERR "ak4535: failed to register card\n");
491 goto card_err;
492 }
493 488
494 return ret; 489 return ret;
495 490
496card_err:
497 snd_soc_free_pcms(socdev);
498 snd_soc_dapm_free(socdev);
499pcm_err: 491pcm_err:
500 kfree(codec->reg_cache); 492 kfree(codec->reg_cache);
501 493
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index e057c7b578df..b69861d52161 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -442,18 +442,9 @@ static int ak4642_probe(struct platform_device *pdev)
442 goto pcm_err; 442 goto pcm_err;
443 } 443 }
444 444
445 ret = snd_soc_init_card(socdev);
446 if (ret < 0) {
447 printk(KERN_ERR "ak4642: failed to register card\n");
448 goto card_err;
449 }
450
451 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 445 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
452 return ret; 446 return ret;
453 447
454card_err:
455 snd_soc_free_pcms(socdev);
456 snd_soc_dapm_free(socdev);
457pcm_err: 448pcm_err:
458 return ret; 449 return ret;
459 450
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
new file mode 100644
index 000000000000..364832ccd748
--- /dev/null
+++ b/sound/soc/codecs/ak4671.c
@@ -0,0 +1,816 @@
1/*
2 * ak4671.c -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/delay.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20#include <sound/initval.h>
21#include <sound/tlv.h>
22
23#include "ak4671.h"
24
25static struct snd_soc_codec *ak4671_codec;
26
27/* codec private data */
28struct ak4671_priv {
29 struct snd_soc_codec codec;
30 u8 reg_cache[AK4671_CACHEREGNUM];
31};
32
33/* ak4671 register cache & default register settings */
34static const u8 ak4671_reg[AK4671_CACHEREGNUM] = {
35 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
36 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */
37 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */
38 0x02, /* AK4671_FORMAT_SELECT (0x03) */
39 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
40 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */
41 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
42 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
43 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
44 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
45 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
46 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
47 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
48 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
49 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
50 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
51 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
52 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
53 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
54 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
55 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
56 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
57 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */
58 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */
59 0x02, /* AK4671_MODE_CONTROL1 (0x18) */
60 0x01, /* AK4671_MODE_CONTROL2 (0x19) */
61 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
62 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
63 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
64 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
65 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
66 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
67 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
68 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
69 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */
70 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */
71 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */
72 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */
73 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */
74 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */
75 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
76 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
77 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
78 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
79 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
80 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
81 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
82 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
83 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
84 0x00, /* this register not used */
85 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */
86 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */
87 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */
88 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */
89 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */
90 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */
91 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */
92 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */
93 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */
94 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */
95 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */
96 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */
97 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */
98 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */
99 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */
100 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */
101 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */
102 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */
103 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */
104 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */
105 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */
106 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */
107 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */
108 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */
109 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */
110 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */
111 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */
112 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */
113 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */
114 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */
115 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
116 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
117 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
118 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */
119 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */
120 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */
121 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
122 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
123 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
124 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
125 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */
126};
127
128/*
129 * LOUT1/ROUT1 output volume control:
130 * from -24 to 6 dB in 6 dB steps (mute instead of -30 dB)
131 */
132static DECLARE_TLV_DB_SCALE(out1_tlv, -3000, 600, 1);
133
134/*
135 * LOUT2/ROUT2 output volume control:
136 * from -33 to 6 dB in 3 dB steps (mute instead of -33 dB)
137 */
138static DECLARE_TLV_DB_SCALE(out2_tlv, -3300, 300, 1);
139
140/*
141 * LOUT3/ROUT3 output volume control:
142 * from -6 to 3 dB in 3 dB steps
143 */
144static DECLARE_TLV_DB_SCALE(out3_tlv, -600, 300, 0);
145
146/*
147 * Mic amp gain control:
148 * from -15 to 30 dB in 3 dB steps
149 * REVISIT: The actual min value(0x01) is -12 dB and the reg value 0x00 is not
150 * available
151 */
152static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -1500, 300, 0);
153
154static const struct snd_kcontrol_new ak4671_snd_controls[] = {
155 /* Common playback gain controls */
156 SOC_SINGLE_TLV("Line Output1 Playback Volume",
157 AK4671_OUTPUT_VOLUME_CONTROL, 0, 0x6, 0, out1_tlv),
158 SOC_SINGLE_TLV("Headphone Output2 Playback Volume",
159 AK4671_OUTPUT_VOLUME_CONTROL, 4, 0xd, 0, out2_tlv),
160 SOC_SINGLE_TLV("Line Output3 Playback Volume",
161 AK4671_LOUT3_POWER_MANAGERMENT, 6, 0x3, 0, out3_tlv),
162
163 /* Common capture gain controls */
164 SOC_DOUBLE_TLV("Mic Amp Capture Volume",
165 AK4671_MIC_AMP_GAIN, 0, 4, 0xf, 0, mic_amp_tlv),
166};
167
168/* event handlers */
169static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
170 struct snd_kcontrol *kcontrol, int event)
171{
172 struct snd_soc_codec *codec = w->codec;
173 u8 reg;
174
175 switch (event) {
176 case SND_SOC_DAPM_POST_PMU:
177 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
178 reg |= AK4671_MUTEN;
179 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
180 break;
181 case SND_SOC_DAPM_PRE_PMD:
182 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
183 reg &= ~AK4671_MUTEN;
184 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
185 break;
186 }
187
188 return 0;
189}
190
191/* Output Mixers */
192static const struct snd_kcontrol_new ak4671_lout1_mixer_controls[] = {
193 SOC_DAPM_SINGLE("DACL", AK4671_LOUT1_SIGNAL_SELECT, 0, 1, 0),
194 SOC_DAPM_SINGLE("LINL1", AK4671_LOUT1_SIGNAL_SELECT, 1, 1, 0),
195 SOC_DAPM_SINGLE("LINL2", AK4671_LOUT1_SIGNAL_SELECT, 2, 1, 0),
196 SOC_DAPM_SINGLE("LINL3", AK4671_LOUT1_SIGNAL_SELECT, 3, 1, 0),
197 SOC_DAPM_SINGLE("LINL4", AK4671_LOUT1_SIGNAL_SELECT, 4, 1, 0),
198 SOC_DAPM_SINGLE("LOOPL", AK4671_LOUT1_SIGNAL_SELECT, 5, 1, 0),
199};
200
201static const struct snd_kcontrol_new ak4671_rout1_mixer_controls[] = {
202 SOC_DAPM_SINGLE("DACR", AK4671_ROUT1_SIGNAL_SELECT, 0, 1, 0),
203 SOC_DAPM_SINGLE("RINR1", AK4671_ROUT1_SIGNAL_SELECT, 1, 1, 0),
204 SOC_DAPM_SINGLE("RINR2", AK4671_ROUT1_SIGNAL_SELECT, 2, 1, 0),
205 SOC_DAPM_SINGLE("RINR3", AK4671_ROUT1_SIGNAL_SELECT, 3, 1, 0),
206 SOC_DAPM_SINGLE("RINR4", AK4671_ROUT1_SIGNAL_SELECT, 4, 1, 0),
207 SOC_DAPM_SINGLE("LOOPR", AK4671_ROUT1_SIGNAL_SELECT, 5, 1, 0),
208};
209
210static const struct snd_kcontrol_new ak4671_lout2_mixer_controls[] = {
211 SOC_DAPM_SINGLE("DACHL", AK4671_LOUT2_SIGNAL_SELECT, 0, 1, 0),
212 SOC_DAPM_SINGLE("LINH1", AK4671_LOUT2_SIGNAL_SELECT, 1, 1, 0),
213 SOC_DAPM_SINGLE("LINH2", AK4671_LOUT2_SIGNAL_SELECT, 2, 1, 0),
214 SOC_DAPM_SINGLE("LINH3", AK4671_LOUT2_SIGNAL_SELECT, 3, 1, 0),
215 SOC_DAPM_SINGLE("LINH4", AK4671_LOUT2_SIGNAL_SELECT, 4, 1, 0),
216 SOC_DAPM_SINGLE("LOOPHL", AK4671_LOUT2_SIGNAL_SELECT, 5, 1, 0),
217};
218
219static const struct snd_kcontrol_new ak4671_rout2_mixer_controls[] = {
220 SOC_DAPM_SINGLE("DACHR", AK4671_ROUT2_SIGNAL_SELECT, 0, 1, 0),
221 SOC_DAPM_SINGLE("RINH1", AK4671_ROUT2_SIGNAL_SELECT, 1, 1, 0),
222 SOC_DAPM_SINGLE("RINH2", AK4671_ROUT2_SIGNAL_SELECT, 2, 1, 0),
223 SOC_DAPM_SINGLE("RINH3", AK4671_ROUT2_SIGNAL_SELECT, 3, 1, 0),
224 SOC_DAPM_SINGLE("RINH4", AK4671_ROUT2_SIGNAL_SELECT, 4, 1, 0),
225 SOC_DAPM_SINGLE("LOOPHR", AK4671_ROUT2_SIGNAL_SELECT, 5, 1, 0),
226};
227
228static const struct snd_kcontrol_new ak4671_lout3_mixer_controls[] = {
229 SOC_DAPM_SINGLE("DACSL", AK4671_LOUT3_SIGNAL_SELECT, 0, 1, 0),
230 SOC_DAPM_SINGLE("LINS1", AK4671_LOUT3_SIGNAL_SELECT, 1, 1, 0),
231 SOC_DAPM_SINGLE("LINS2", AK4671_LOUT3_SIGNAL_SELECT, 2, 1, 0),
232 SOC_DAPM_SINGLE("LINS3", AK4671_LOUT3_SIGNAL_SELECT, 3, 1, 0),
233 SOC_DAPM_SINGLE("LINS4", AK4671_LOUT3_SIGNAL_SELECT, 4, 1, 0),
234 SOC_DAPM_SINGLE("LOOPSL", AK4671_LOUT3_SIGNAL_SELECT, 5, 1, 0),
235};
236
237static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
238 SOC_DAPM_SINGLE("DACSR", AK4671_ROUT3_SIGNAL_SELECT, 0, 1, 0),
239 SOC_DAPM_SINGLE("RINS1", AK4671_ROUT3_SIGNAL_SELECT, 1, 1, 0),
240 SOC_DAPM_SINGLE("RINS2", AK4671_ROUT3_SIGNAL_SELECT, 2, 1, 0),
241 SOC_DAPM_SINGLE("RINS3", AK4671_ROUT3_SIGNAL_SELECT, 3, 1, 0),
242 SOC_DAPM_SINGLE("RINS4", AK4671_ROUT3_SIGNAL_SELECT, 4, 1, 0),
243 SOC_DAPM_SINGLE("LOOPSR", AK4671_ROUT3_SIGNAL_SELECT, 5, 1, 0),
244};
245
246/* Input MUXs */
247static const char *ak4671_lin_mux_texts[] =
248 {"LIN1", "LIN2", "LIN3", "LIN4"};
249static const struct soc_enum ak4671_lin_mux_enum =
250 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0,
251 ARRAY_SIZE(ak4671_lin_mux_texts),
252 ak4671_lin_mux_texts);
253static const struct snd_kcontrol_new ak4671_lin_mux_control =
254 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
255
256static const char *ak4671_rin_mux_texts[] =
257 {"RIN1", "RIN2", "RIN3", "RIN4"};
258static const struct soc_enum ak4671_rin_mux_enum =
259 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2,
260 ARRAY_SIZE(ak4671_rin_mux_texts),
261 ak4671_rin_mux_texts);
262static const struct snd_kcontrol_new ak4671_rin_mux_control =
263 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
264
265static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
266 /* Inputs */
267 SND_SOC_DAPM_INPUT("LIN1"),
268 SND_SOC_DAPM_INPUT("RIN1"),
269 SND_SOC_DAPM_INPUT("LIN2"),
270 SND_SOC_DAPM_INPUT("RIN2"),
271 SND_SOC_DAPM_INPUT("LIN3"),
272 SND_SOC_DAPM_INPUT("RIN3"),
273 SND_SOC_DAPM_INPUT("LIN4"),
274 SND_SOC_DAPM_INPUT("RIN4"),
275
276 /* Outputs */
277 SND_SOC_DAPM_OUTPUT("LOUT1"),
278 SND_SOC_DAPM_OUTPUT("ROUT1"),
279 SND_SOC_DAPM_OUTPUT("LOUT2"),
280 SND_SOC_DAPM_OUTPUT("ROUT2"),
281 SND_SOC_DAPM_OUTPUT("LOUT3"),
282 SND_SOC_DAPM_OUTPUT("ROUT3"),
283
284 /* DAC */
285 SND_SOC_DAPM_DAC("DAC Left", "Left HiFi Playback",
286 AK4671_AD_DA_POWER_MANAGEMENT, 6, 0),
287 SND_SOC_DAPM_DAC("DAC Right", "Right HiFi Playback",
288 AK4671_AD_DA_POWER_MANAGEMENT, 7, 0),
289
290 /* ADC */
291 SND_SOC_DAPM_ADC("ADC Left", "Left HiFi Capture",
292 AK4671_AD_DA_POWER_MANAGEMENT, 4, 0),
293 SND_SOC_DAPM_ADC("ADC Right", "Right HiFi Capture",
294 AK4671_AD_DA_POWER_MANAGEMENT, 5, 0),
295
296 /* PGA */
297 SND_SOC_DAPM_PGA("LOUT2 Mix Amp",
298 AK4671_LOUT2_POWER_MANAGERMENT, 5, 0, NULL, 0),
299 SND_SOC_DAPM_PGA("ROUT2 Mix Amp",
300 AK4671_LOUT2_POWER_MANAGERMENT, 6, 0, NULL, 0),
301
302 SND_SOC_DAPM_PGA("LIN1 Mixing Circuit",
303 AK4671_MIXING_POWER_MANAGEMENT1, 0, 0, NULL, 0),
304 SND_SOC_DAPM_PGA("RIN1 Mixing Circuit",
305 AK4671_MIXING_POWER_MANAGEMENT1, 1, 0, NULL, 0),
306 SND_SOC_DAPM_PGA("LIN2 Mixing Circuit",
307 AK4671_MIXING_POWER_MANAGEMENT1, 2, 0, NULL, 0),
308 SND_SOC_DAPM_PGA("RIN2 Mixing Circuit",
309 AK4671_MIXING_POWER_MANAGEMENT1, 3, 0, NULL, 0),
310 SND_SOC_DAPM_PGA("LIN3 Mixing Circuit",
311 AK4671_MIXING_POWER_MANAGEMENT1, 4, 0, NULL, 0),
312 SND_SOC_DAPM_PGA("RIN3 Mixing Circuit",
313 AK4671_MIXING_POWER_MANAGEMENT1, 5, 0, NULL, 0),
314 SND_SOC_DAPM_PGA("LIN4 Mixing Circuit",
315 AK4671_MIXING_POWER_MANAGEMENT1, 6, 0, NULL, 0),
316 SND_SOC_DAPM_PGA("RIN4 Mixing Circuit",
317 AK4671_MIXING_POWER_MANAGEMENT1, 7, 0, NULL, 0),
318
319 /* Output Mixers */
320 SND_SOC_DAPM_MIXER("LOUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 0, 0,
321 &ak4671_lout1_mixer_controls[0],
322 ARRAY_SIZE(ak4671_lout1_mixer_controls)),
323 SND_SOC_DAPM_MIXER("ROUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 1, 0,
324 &ak4671_rout1_mixer_controls[0],
325 ARRAY_SIZE(ak4671_rout1_mixer_controls)),
326 SND_SOC_DAPM_MIXER_E("LOUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
327 0, 0, &ak4671_lout2_mixer_controls[0],
328 ARRAY_SIZE(ak4671_lout2_mixer_controls),
329 ak4671_out2_event,
330 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
331 SND_SOC_DAPM_MIXER_E("ROUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
332 1, 0, &ak4671_rout2_mixer_controls[0],
333 ARRAY_SIZE(ak4671_rout2_mixer_controls),
334 ak4671_out2_event,
335 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
336 SND_SOC_DAPM_MIXER("LOUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 0, 0,
337 &ak4671_lout3_mixer_controls[0],
338 ARRAY_SIZE(ak4671_lout3_mixer_controls)),
339 SND_SOC_DAPM_MIXER("ROUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 1, 0,
340 &ak4671_rout3_mixer_controls[0],
341 ARRAY_SIZE(ak4671_rout3_mixer_controls)),
342
343 /* Input MUXs */
344 SND_SOC_DAPM_MUX("LIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 2, 0,
345 &ak4671_lin_mux_control),
346 SND_SOC_DAPM_MUX("RIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 3, 0,
347 &ak4671_rin_mux_control),
348
349 /* Mic Power */
350 SND_SOC_DAPM_MICBIAS("Mic Bias", AK4671_AD_DA_POWER_MANAGEMENT, 1, 0),
351
352 /* Supply */
353 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
354};
355
356static const struct snd_soc_dapm_route intercon[] = {
357 {"DAC Left", "NULL", "PMPLL"},
358 {"DAC Right", "NULL", "PMPLL"},
359 {"ADC Left", "NULL", "PMPLL"},
360 {"ADC Right", "NULL", "PMPLL"},
361
362 /* Outputs */
363 {"LOUT1", "NULL", "LOUT1 Mixer"},
364 {"ROUT1", "NULL", "ROUT1 Mixer"},
365 {"LOUT2", "NULL", "LOUT2 Mix Amp"},
366 {"ROUT2", "NULL", "ROUT2 Mix Amp"},
367 {"LOUT3", "NULL", "LOUT3 Mixer"},
368 {"ROUT3", "NULL", "ROUT3 Mixer"},
369
370 {"LOUT1 Mixer", "DACL", "DAC Left"},
371 {"ROUT1 Mixer", "DACR", "DAC Right"},
372 {"LOUT2 Mixer", "DACHL", "DAC Left"},
373 {"ROUT2 Mixer", "DACHR", "DAC Right"},
374 {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"},
375 {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"},
376 {"LOUT3 Mixer", "DACSL", "DAC Left"},
377 {"ROUT3 Mixer", "DACSR", "DAC Right"},
378
379 /* Inputs */
380 {"LIN MUX", "LIN1", "LIN1"},
381 {"LIN MUX", "LIN2", "LIN2"},
382 {"LIN MUX", "LIN3", "LIN3"},
383 {"LIN MUX", "LIN4", "LIN4"},
384
385 {"RIN MUX", "RIN1", "RIN1"},
386 {"RIN MUX", "RIN2", "RIN2"},
387 {"RIN MUX", "RIN3", "RIN3"},
388 {"RIN MUX", "RIN4", "RIN4"},
389
390 {"LIN1", NULL, "Mic Bias"},
391 {"RIN1", NULL, "Mic Bias"},
392 {"LIN2", NULL, "Mic Bias"},
393 {"RIN2", NULL, "Mic Bias"},
394
395 {"ADC Left", "NULL", "LIN MUX"},
396 {"ADC Right", "NULL", "RIN MUX"},
397
398 /* Analog Loops */
399 {"LIN1 Mixing Circuit", "NULL", "LIN1"},
400 {"RIN1 Mixing Circuit", "NULL", "RIN1"},
401 {"LIN2 Mixing Circuit", "NULL", "LIN2"},
402 {"RIN2 Mixing Circuit", "NULL", "RIN2"},
403 {"LIN3 Mixing Circuit", "NULL", "LIN3"},
404 {"RIN3 Mixing Circuit", "NULL", "RIN3"},
405 {"LIN4 Mixing Circuit", "NULL", "LIN4"},
406 {"RIN4 Mixing Circuit", "NULL", "RIN4"},
407
408 {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
409 {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
410 {"LOUT2 Mixer", "LINH1", "LIN1 Mixing Circuit"},
411 {"ROUT2 Mixer", "RINH1", "RIN1 Mixing Circuit"},
412 {"LOUT3 Mixer", "LINS1", "LIN1 Mixing Circuit"},
413 {"ROUT3 Mixer", "RINS1", "RIN1 Mixing Circuit"},
414
415 {"LOUT1 Mixer", "LINL2", "LIN2 Mixing Circuit"},
416 {"ROUT1 Mixer", "RINR2", "RIN2 Mixing Circuit"},
417 {"LOUT2 Mixer", "LINH2", "LIN2 Mixing Circuit"},
418 {"ROUT2 Mixer", "RINH2", "RIN2 Mixing Circuit"},
419 {"LOUT3 Mixer", "LINS2", "LIN2 Mixing Circuit"},
420 {"ROUT3 Mixer", "RINS2", "RIN2 Mixing Circuit"},
421
422 {"LOUT1 Mixer", "LINL3", "LIN3 Mixing Circuit"},
423 {"ROUT1 Mixer", "RINR3", "RIN3 Mixing Circuit"},
424 {"LOUT2 Mixer", "LINH3", "LIN3 Mixing Circuit"},
425 {"ROUT2 Mixer", "RINH3", "RIN3 Mixing Circuit"},
426 {"LOUT3 Mixer", "LINS3", "LIN3 Mixing Circuit"},
427 {"ROUT3 Mixer", "RINS3", "RIN3 Mixing Circuit"},
428
429 {"LOUT1 Mixer", "LINL4", "LIN4 Mixing Circuit"},
430 {"ROUT1 Mixer", "RINR4", "RIN4 Mixing Circuit"},
431 {"LOUT2 Mixer", "LINH4", "LIN4 Mixing Circuit"},
432 {"ROUT2 Mixer", "RINH4", "RIN4 Mixing Circuit"},
433 {"LOUT3 Mixer", "LINS4", "LIN4 Mixing Circuit"},
434 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
435};
436
437static int ak4671_add_widgets(struct snd_soc_codec *codec)
438{
439 snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
440 ARRAY_SIZE(ak4671_dapm_widgets));
441
442 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
443
444 snd_soc_dapm_new_widgets(codec);
445 return 0;
446}
447
448static int ak4671_hw_params(struct snd_pcm_substream *substream,
449 struct snd_pcm_hw_params *params,
450 struct snd_soc_dai *dai)
451{
452 struct snd_soc_codec *codec = dai->codec;
453 u8 fs;
454
455 fs = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
456 fs &= ~AK4671_FS;
457
458 switch (params_rate(params)) {
459 case 8000:
460 fs |= AK4671_FS_8KHZ;
461 break;
462 case 12000:
463 fs |= AK4671_FS_12KHZ;
464 break;
465 case 16000:
466 fs |= AK4671_FS_16KHZ;
467 break;
468 case 24000:
469 fs |= AK4671_FS_24KHZ;
470 break;
471 case 11025:
472 fs |= AK4671_FS_11_025KHZ;
473 break;
474 case 22050:
475 fs |= AK4671_FS_22_05KHZ;
476 break;
477 case 32000:
478 fs |= AK4671_FS_32KHZ;
479 break;
480 case 44100:
481 fs |= AK4671_FS_44_1KHZ;
482 break;
483 case 48000:
484 fs |= AK4671_FS_48KHZ;
485 break;
486 default:
487 return -EINVAL;
488 }
489
490 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, fs);
491
492 return 0;
493}
494
495static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
496 unsigned int freq, int dir)
497{
498 struct snd_soc_codec *codec = dai->codec;
499 u8 pll;
500
501 pll = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
502 pll &= ~AK4671_PLL;
503
504 switch (freq) {
505 case 11289600:
506 pll |= AK4671_PLL_11_2896MHZ;
507 break;
508 case 12000000:
509 pll |= AK4671_PLL_12MHZ;
510 break;
511 case 12288000:
512 pll |= AK4671_PLL_12_288MHZ;
513 break;
514 case 13000000:
515 pll |= AK4671_PLL_13MHZ;
516 break;
517 case 13500000:
518 pll |= AK4671_PLL_13_5MHZ;
519 break;
520 case 19200000:
521 pll |= AK4671_PLL_19_2MHZ;
522 break;
523 case 24000000:
524 pll |= AK4671_PLL_24MHZ;
525 break;
526 case 26000000:
527 pll |= AK4671_PLL_26MHZ;
528 break;
529 case 27000000:
530 pll |= AK4671_PLL_27MHZ;
531 break;
532 default:
533 return -EINVAL;
534 }
535
536 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, pll);
537
538 return 0;
539}
540
541static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
542{
543 struct snd_soc_codec *codec = dai->codec;
544 u8 mode;
545 u8 format;
546
547 /* set master/slave audio interface */
548 mode = snd_soc_read(codec, AK4671_PLL_MODE_SELECT1);
549
550 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
551 case SND_SOC_DAIFMT_CBM_CFM:
552 mode |= AK4671_M_S;
553 break;
554 case SND_SOC_DAIFMT_CBM_CFS:
555 mode &= ~(AK4671_M_S);
556 break;
557 default:
558 return -EINVAL;
559 }
560
561 /* interface format */
562 format = snd_soc_read(codec, AK4671_FORMAT_SELECT);
563 format &= ~AK4671_DIF;
564
565 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
566 case SND_SOC_DAIFMT_I2S:
567 format |= AK4671_DIF_I2S_MODE;
568 break;
569 case SND_SOC_DAIFMT_LEFT_J:
570 format |= AK4671_DIF_MSB_MODE;
571 break;
572 case SND_SOC_DAIFMT_DSP_A:
573 format |= AK4671_DIF_DSP_MODE;
574 format |= AK4671_BCKP;
575 format |= AK4671_MSBS;
576 break;
577 default:
578 return -EINVAL;
579 }
580
581 /* set mode and format */
582 snd_soc_write(codec, AK4671_PLL_MODE_SELECT1, mode);
583 snd_soc_write(codec, AK4671_FORMAT_SELECT, format);
584
585 return 0;
586}
587
588static int ak4671_set_bias_level(struct snd_soc_codec *codec,
589 enum snd_soc_bias_level level)
590{
591 u8 reg;
592
593 switch (level) {
594 case SND_SOC_BIAS_ON:
595 case SND_SOC_BIAS_PREPARE:
596 case SND_SOC_BIAS_STANDBY:
597 reg = snd_soc_read(codec, AK4671_AD_DA_POWER_MANAGEMENT);
598 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT,
599 reg | AK4671_PMVCM);
600 break;
601 case SND_SOC_BIAS_OFF:
602 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
603 break;
604 }
605 codec->bias_level = level;
606 return 0;
607}
608
609#define AK4671_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
610 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
611 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
612 SNDRV_PCM_RATE_48000)
613
614#define AK4671_FORMATS SNDRV_PCM_FMTBIT_S16_LE
615
616static struct snd_soc_dai_ops ak4671_dai_ops = {
617 .hw_params = ak4671_hw_params,
618 .set_sysclk = ak4671_set_dai_sysclk,
619 .set_fmt = ak4671_set_dai_fmt,
620};
621
622struct snd_soc_dai ak4671_dai = {
623 .name = "AK4671",
624 .playback = {
625 .stream_name = "Playback",
626 .channels_min = 1,
627 .channels_max = 2,
628 .rates = AK4671_RATES,
629 .formats = AK4671_FORMATS,},
630 .capture = {
631 .stream_name = "Capture",
632 .channels_min = 1,
633 .channels_max = 2,
634 .rates = AK4671_RATES,
635 .formats = AK4671_FORMATS,},
636 .ops = &ak4671_dai_ops,
637};
638EXPORT_SYMBOL_GPL(ak4671_dai);
639
640static int ak4671_probe(struct platform_device *pdev)
641{
642 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
643 struct snd_soc_codec *codec;
644 int ret = 0;
645
646 if (ak4671_codec == NULL) {
647 dev_err(&pdev->dev, "Codec device not registered\n");
648 return -ENODEV;
649 }
650
651 socdev->card->codec = ak4671_codec;
652 codec = ak4671_codec;
653
654 /* register pcms */
655 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
656 if (ret < 0) {
657 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
658 goto pcm_err;
659 }
660
661 snd_soc_add_controls(codec, ak4671_snd_controls,
662 ARRAY_SIZE(ak4671_snd_controls));
663 ak4671_add_widgets(codec);
664
665 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
666
667 return ret;
668
669pcm_err:
670 return ret;
671}
672
673static int ak4671_remove(struct platform_device *pdev)
674{
675 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
676
677 snd_soc_free_pcms(socdev);
678 snd_soc_dapm_free(socdev);
679
680 return 0;
681}
682
683struct snd_soc_codec_device soc_codec_dev_ak4671 = {
684 .probe = ak4671_probe,
685 .remove = ak4671_remove,
686};
687EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
688
689static int ak4671_register(struct ak4671_priv *ak4671,
690 enum snd_soc_control_type control)
691{
692 int ret;
693 struct snd_soc_codec *codec = &ak4671->codec;
694
695 if (ak4671_codec) {
696 dev_err(codec->dev, "Another AK4671 is registered\n");
697 ret = -EINVAL;
698 goto err;
699 }
700
701 mutex_init(&codec->mutex);
702 INIT_LIST_HEAD(&codec->dapm_widgets);
703 INIT_LIST_HEAD(&codec->dapm_paths);
704
705 codec->private_data = ak4671;
706 codec->name = "AK4671";
707 codec->owner = THIS_MODULE;
708 codec->bias_level = SND_SOC_BIAS_OFF;
709 codec->set_bias_level = ak4671_set_bias_level;
710 codec->dai = &ak4671_dai;
711 codec->num_dai = 1;
712 codec->reg_cache_size = AK4671_CACHEREGNUM;
713 codec->reg_cache = &ak4671->reg_cache;
714
715 memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
716
717 ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
718 if (ret < 0) {
719 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
720 goto err;
721 }
722
723 ak4671_dai.dev = codec->dev;
724 ak4671_codec = codec;
725
726 ret = snd_soc_register_codec(codec);
727 if (ret != 0) {
728 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
729 goto err;
730 }
731
732 ret = snd_soc_register_dai(&ak4671_dai);
733 if (ret != 0) {
734 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
735 goto err_codec;
736 }
737
738 return 0;
739
740err_codec:
741 snd_soc_unregister_codec(codec);
742err:
743 kfree(ak4671);
744 return ret;
745}
746
747static void ak4671_unregister(struct ak4671_priv *ak4671)
748{
749 ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
750 snd_soc_unregister_dai(&ak4671_dai);
751 snd_soc_unregister_codec(&ak4671->codec);
752 kfree(ak4671);
753 ak4671_codec = NULL;
754}
755
756static int __devinit ak4671_i2c_probe(struct i2c_client *client,
757 const struct i2c_device_id *id)
758{
759 struct ak4671_priv *ak4671;
760 struct snd_soc_codec *codec;
761
762 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
763 if (ak4671 == NULL)
764 return -ENOMEM;
765
766 codec = &ak4671->codec;
767 codec->hw_write = (hw_write_t)i2c_master_send;
768
769 i2c_set_clientdata(client, ak4671);
770 codec->control_data = client;
771
772 codec->dev = &client->dev;
773
774 return ak4671_register(ak4671, SND_SOC_I2C);
775}
776
777static __devexit int ak4671_i2c_remove(struct i2c_client *client)
778{
779 struct ak4671_priv *ak4671 = i2c_get_clientdata(client);
780
781 ak4671_unregister(ak4671);
782
783 return 0;
784}
785
786static const struct i2c_device_id ak4671_i2c_id[] = {
787 { "ak4671", 0 },
788 { }
789};
790MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
791
792static struct i2c_driver ak4671_i2c_driver = {
793 .driver = {
794 .name = "ak4671",
795 .owner = THIS_MODULE,
796 },
797 .probe = ak4671_i2c_probe,
798 .remove = __devexit_p(ak4671_i2c_remove),
799 .id_table = ak4671_i2c_id,
800};
801
802static int __init ak4671_modinit(void)
803{
804 return i2c_add_driver(&ak4671_i2c_driver);
805}
806module_init(ak4671_modinit);
807
808static void __exit ak4671_exit(void)
809{
810 i2c_del_driver(&ak4671_i2c_driver);
811}
812module_exit(ak4671_exit);
813
814MODULE_DESCRIPTION("ASoC AK4671 codec driver");
815MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
816MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
new file mode 100644
index 000000000000..e2fad964e88b
--- /dev/null
+++ b/sound/soc/codecs/ak4671.h
@@ -0,0 +1,156 @@
1/*
2 * ak4671.h -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef _AK4671_H
15#define _AK4671_H
16
17#define AK4671_AD_DA_POWER_MANAGEMENT 0x00
18#define AK4671_PLL_MODE_SELECT0 0x01
19#define AK4671_PLL_MODE_SELECT1 0x02
20#define AK4671_FORMAT_SELECT 0x03
21#define AK4671_MIC_SIGNAL_SELECT 0x04
22#define AK4671_MIC_AMP_GAIN 0x05
23#define AK4671_MIXING_POWER_MANAGEMENT0 0x06
24#define AK4671_MIXING_POWER_MANAGEMENT1 0x07
25#define AK4671_OUTPUT_VOLUME_CONTROL 0x08
26#define AK4671_LOUT1_SIGNAL_SELECT 0x09
27#define AK4671_ROUT1_SIGNAL_SELECT 0x0a
28#define AK4671_LOUT2_SIGNAL_SELECT 0x0b
29#define AK4671_ROUT2_SIGNAL_SELECT 0x0c
30#define AK4671_LOUT3_SIGNAL_SELECT 0x0d
31#define AK4671_ROUT3_SIGNAL_SELECT 0x0e
32#define AK4671_LOUT1_POWER_MANAGERMENT 0x0f
33#define AK4671_LOUT2_POWER_MANAGERMENT 0x10
34#define AK4671_LOUT3_POWER_MANAGERMENT 0x11
35#define AK4671_LCH_INPUT_VOLUME_CONTROL 0x12
36#define AK4671_RCH_INPUT_VOLUME_CONTROL 0x13
37#define AK4671_ALC_REFERENCE_SELECT 0x14
38#define AK4671_DIGITAL_MIXING_CONTROL 0x15
39#define AK4671_ALC_TIMER_SELECT 0x16
40#define AK4671_ALC_MODE_CONTROL 0x17
41#define AK4671_MODE_CONTROL1 0x18
42#define AK4671_MODE_CONTROL2 0x19
43#define AK4671_LCH_OUTPUT_VOLUME_CONTROL 0x1a
44#define AK4671_RCH_OUTPUT_VOLUME_CONTROL 0x1b
45#define AK4671_SIDETONE_A_CONTROL 0x1c
46#define AK4671_DIGITAL_FILTER_SELECT 0x1d
47#define AK4671_FIL3_COEFFICIENT0 0x1e
48#define AK4671_FIL3_COEFFICIENT1 0x1f
49#define AK4671_FIL3_COEFFICIENT2 0x20
50#define AK4671_FIL3_COEFFICIENT3 0x21
51#define AK4671_EQ_COEFFICIENT0 0x22
52#define AK4671_EQ_COEFFICIENT1 0x23
53#define AK4671_EQ_COEFFICIENT2 0x24
54#define AK4671_EQ_COEFFICIENT3 0x25
55#define AK4671_EQ_COEFFICIENT4 0x26
56#define AK4671_EQ_COEFFICIENT5 0x27
57#define AK4671_FIL1_COEFFICIENT0 0x28
58#define AK4671_FIL1_COEFFICIENT1 0x29
59#define AK4671_FIL1_COEFFICIENT2 0x2a
60#define AK4671_FIL1_COEFFICIENT3 0x2b
61#define AK4671_FIL2_COEFFICIENT0 0x2c
62#define AK4671_FIL2_COEFFICIENT1 0x2d
63#define AK4671_FIL2_COEFFICIENT2 0x2e
64#define AK4671_FIL2_COEFFICIENT3 0x2f
65#define AK4671_DIGITAL_FILTER_SELECT2 0x30
66#define AK4671_E1_COEFFICIENT0 0x32
67#define AK4671_E1_COEFFICIENT1 0x33
68#define AK4671_E1_COEFFICIENT2 0x34
69#define AK4671_E1_COEFFICIENT3 0x35
70#define AK4671_E1_COEFFICIENT4 0x36
71#define AK4671_E1_COEFFICIENT5 0x37
72#define AK4671_E2_COEFFICIENT0 0x38
73#define AK4671_E2_COEFFICIENT1 0x39
74#define AK4671_E2_COEFFICIENT2 0x3a
75#define AK4671_E2_COEFFICIENT3 0x3b
76#define AK4671_E2_COEFFICIENT4 0x3c
77#define AK4671_E2_COEFFICIENT5 0x3d
78#define AK4671_E3_COEFFICIENT0 0x3e
79#define AK4671_E3_COEFFICIENT1 0x3f
80#define AK4671_E3_COEFFICIENT2 0x40
81#define AK4671_E3_COEFFICIENT3 0x41
82#define AK4671_E3_COEFFICIENT4 0x42
83#define AK4671_E3_COEFFICIENT5 0x43
84#define AK4671_E4_COEFFICIENT0 0x44
85#define AK4671_E4_COEFFICIENT1 0x45
86#define AK4671_E4_COEFFICIENT2 0x46
87#define AK4671_E4_COEFFICIENT3 0x47
88#define AK4671_E4_COEFFICIENT4 0x48
89#define AK4671_E4_COEFFICIENT5 0x49
90#define AK4671_E5_COEFFICIENT0 0x4a
91#define AK4671_E5_COEFFICIENT1 0x4b
92#define AK4671_E5_COEFFICIENT2 0x4c
93#define AK4671_E5_COEFFICIENT3 0x4d
94#define AK4671_E5_COEFFICIENT4 0x4e
95#define AK4671_E5_COEFFICIENT5 0x4f
96#define AK4671_EQ_CONTROL_250HZ_100HZ 0x50
97#define AK4671_EQ_CONTROL_3500HZ_1KHZ 0x51
98#define AK4671_EQ_CONTRO_10KHZ 0x52
99#define AK4671_PCM_IF_CONTROL0 0x53
100#define AK4671_PCM_IF_CONTROL1 0x54
101#define AK4671_PCM_IF_CONTROL2 0x55
102#define AK4671_DIGITAL_VOLUME_B_CONTROL 0x56
103#define AK4671_DIGITAL_VOLUME_C_CONTROL 0x57
104#define AK4671_SIDETONE_VOLUME_CONTROL 0x58
105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
106#define AK4671_SAR_ADC_CONTROL 0x5a
107
108#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
109
110/* Bitfield Definitions */
111
112/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
113#define AK4671_PMVCM 0x01
114
115/* AK4671_PLL_MODE_SELECT0 (0x01) Fields */
116#define AK4671_PLL 0x0f
117#define AK4671_PLL_11_2896MHZ (4 << 0)
118#define AK4671_PLL_12_288MHZ (5 << 0)
119#define AK4671_PLL_12MHZ (6 << 0)
120#define AK4671_PLL_24MHZ (7 << 0)
121#define AK4671_PLL_19_2MHZ (8 << 0)
122#define AK4671_PLL_13_5MHZ (12 << 0)
123#define AK4671_PLL_27MHZ (13 << 0)
124#define AK4671_PLL_13MHZ (14 << 0)
125#define AK4671_PLL_26MHZ (15 << 0)
126#define AK4671_FS 0xf0
127#define AK4671_FS_8KHZ (0 << 4)
128#define AK4671_FS_12KHZ (1 << 4)
129#define AK4671_FS_16KHZ (2 << 4)
130#define AK4671_FS_24KHZ (3 << 4)
131#define AK4671_FS_11_025KHZ (5 << 4)
132#define AK4671_FS_22_05KHZ (7 << 4)
133#define AK4671_FS_32KHZ (10 << 4)
134#define AK4671_FS_48KHZ (11 << 4)
135#define AK4671_FS_44_1KHZ (15 << 4)
136
137/* AK4671_PLL_MODE_SELECT1 (0x02) Fields */
138#define AK4671_PMPLL 0x01
139#define AK4671_M_S 0x02
140
141/* AK4671_FORMAT_SELECT (0x03) Fields */
142#define AK4671_DIF 0x03
143#define AK4671_DIF_DSP_MODE (0 << 0)
144#define AK4671_DIF_MSB_MODE (2 << 0)
145#define AK4671_DIF_I2S_MODE (3 << 0)
146#define AK4671_BCKP 0x04
147#define AK4671_MSBS 0x08
148#define AK4671_SDOD 0x10
149
150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
151#define AK4671_MUTEN 0x04
152
153extern struct snd_soc_dai ak4671_dai;
154extern struct snd_soc_codec_device soc_codec_dev_ak4671;
155
156#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ca1e24a8f12a..ffe122d1cd76 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -520,6 +520,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0), 520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0), 521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), 522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
523 SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
523 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), 524 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
524 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), 525 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
525 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1), 526 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
@@ -598,13 +599,6 @@ static int cs4270_probe(struct platform_device *pdev)
598 goto error_free_pcms; 599 goto error_free_pcms;
599 } 600 }
600 601
601 /* And finally, register the socdev */
602 ret = snd_soc_init_card(socdev);
603 if (ret < 0) {
604 dev_err(codec->dev, "failed to register card\n");
605 goto error_free_pcms;
606 }
607
608 return 0; 602 return 0;
609 603
610error_free_pcms: 604error_free_pcms:
@@ -802,22 +796,6 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
802 * and all registers are written back to the hardware when resuming. 796 * and all registers are written back to the hardware when resuming.
803 */ 797 */
804 798
805static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
806{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
808 struct snd_soc_codec *codec = &cs4270->codec;
809
810 return snd_soc_suspend_device(codec->dev);
811}
812
813static int cs4270_i2c_resume(struct i2c_client *client)
814{
815 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
816 struct snd_soc_codec *codec = &cs4270->codec;
817
818 return snd_soc_resume_device(codec->dev);
819}
820
821static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 799static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
822{ 800{
823 struct snd_soc_codec *codec = cs4270_codec; 801 struct snd_soc_codec *codec = cs4270_codec;
@@ -853,8 +831,6 @@ static int cs4270_soc_resume(struct platform_device *pdev)
853 return snd_soc_write(codec, CS4270_PWRCTL, reg); 831 return snd_soc_write(codec, CS4270_PWRCTL, reg);
854} 832}
855#else 833#else
856#define cs4270_i2c_suspend NULL
857#define cs4270_i2c_resume NULL
858#define cs4270_soc_suspend NULL 834#define cs4270_soc_suspend NULL
859#define cs4270_soc_resume NULL 835#define cs4270_soc_resume NULL
860#endif /* CONFIG_PM */ 836#endif /* CONFIG_PM */
@@ -873,8 +849,6 @@ static struct i2c_driver cs4270_i2c_driver = {
873 .id_table = cs4270_id, 849 .id_table = cs4270_id,
874 .probe = cs4270_i2c_probe, 850 .probe = cs4270_i2c_probe,
875 .remove = cs4270_i2c_remove, 851 .remove = cs4270_i2c_remove,
876 .suspend = cs4270_i2c_suspend,
877 .resume = cs4270_i2c_resume,
878}; 852};
879 853
880/* 854/*
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 38eac9c866e1..d7f9bf18b72e 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -355,12 +355,6 @@ static int cx20442_codec_probe(struct platform_device *pdev)
355 355
356 cx20442_add_widgets(codec); 356 cx20442_add_widgets(codec);
357 357
358 ret = snd_soc_init_card(socdev);
359 if (ret < 0) {
360 dev_err(&pdev->dev, "failed to register card\n");
361 goto card_err;
362 }
363
364 return ret; 358 return ret;
365 359
366card_err: 360card_err:
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 5cda9e6b5a74..2afcd0a8669d 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -90,13 +90,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
90 goto pcm_err; 90 goto pcm_err;
91 } 91 }
92 92
93 /* Register Card. */
94 ret = snd_soc_init_card(socdev);
95 if (ret < 0) {
96 printk(KERN_ERR "pcm3008: failed to register card\n");
97 goto card_err;
98 }
99
100 /* DEM1 DEM0 DE-EMPHASIS_MODE 93 /* DEM1 DEM0 DE-EMPHASIS_MODE
101 * Low Low De-emphasis 44.1 kHz ON 94 * Low Low De-emphasis 44.1 kHz ON
102 * Low High De-emphasis OFF 95 * Low High De-emphasis OFF
@@ -136,8 +129,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
136 129
137gpio_err: 130gpio_err:
138 pcm3008_gpio_free(setup); 131 pcm3008_gpio_free(setup);
139card_err:
140 snd_soc_free_pcms(socdev);
141pcm_err: 132pcm_err:
142 kfree(socdev->card->codec); 133 kfree(socdev->card->codec);
143 134
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index c550750c79c0..b3130339d29a 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -613,17 +613,9 @@ static int ssm2602_init(struct snd_soc_device *socdev)
613 snd_soc_add_controls(codec, ssm2602_snd_controls, 613 snd_soc_add_controls(codec, ssm2602_snd_controls,
614 ARRAY_SIZE(ssm2602_snd_controls)); 614 ARRAY_SIZE(ssm2602_snd_controls));
615 ssm2602_add_widgets(codec); 615 ssm2602_add_widgets(codec);
616 ret = snd_soc_init_card(socdev);
617 if (ret < 0) {
618 pr_err("ssm2602: failed to register card\n");
619 goto card_err;
620 }
621 616
622 return ret; 617 return ret;
623 618
624card_err:
625 snd_soc_free_pcms(socdev);
626 snd_soc_dapm_free(socdev);
627pcm_err: 619pcm_err:
628 kfree(codec->reg_cache); 620 kfree(codec->reg_cache);
629 return ret; 621 return ret;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index befc6488c39a..bbc72c2ddfca 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -418,9 +418,6 @@ static int stac9766_codec_probe(struct platform_device *pdev)
418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls, 418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls,
419 ARRAY_SIZE(stac9766_snd_ac97_controls)); 419 ARRAY_SIZE(stac9766_snd_ac97_controls));
420 420
421 ret = snd_soc_init_card(socdev);
422 if (ret < 0)
423 goto reset_err;
424 return 0; 421 return 0;
425 422
426reset_err: 423reset_err:
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 0b8dcb5cd729..ee8cb2c08b87 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -707,17 +707,9 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
707 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 707 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
708 ARRAY_SIZE(tlv320aic23_snd_controls)); 708 ARRAY_SIZE(tlv320aic23_snd_controls));
709 tlv320aic23_add_widgets(codec); 709 tlv320aic23_add_widgets(codec);
710 ret = snd_soc_init_card(socdev);
711 if (ret < 0) {
712 printk(KERN_ERR "tlv320aic23: failed to register card\n");
713 goto card_err;
714 }
715 710
716 return ret; 711 return ret;
717 712
718card_err:
719 snd_soc_free_pcms(socdev);
720 snd_soc_dapm_free(socdev);
721pcm_err: 713pcm_err:
722 kfree(codec->reg_cache); 714 kfree(codec->reg_cache);
723 return ret; 715 return ret;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 3387d9e736ea..357b609196e3 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -356,18 +356,7 @@ static int aic26_probe(struct platform_device *pdev)
356 ARRAY_SIZE(aic26_snd_controls)); 356 ARRAY_SIZE(aic26_snd_controls));
357 WARN_ON(err < 0); 357 WARN_ON(err < 0);
358 358
359 /* CODEC is setup, we can register the card now */
360 dev_dbg(&pdev->dev, "Registering card\n");
361 ret = snd_soc_init_card(socdev);
362 if (ret < 0) {
363 dev_err(&pdev->dev, "aic26: failed to register card\n");
364 goto card_err;
365 }
366 return 0; 359 return 0;
367
368 card_err:
369 snd_soc_free_pcms(socdev);
370 return ret;
371} 360}
372 361
373static int aic26_remove(struct platform_device *pdev) 362static int aic26_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 3395cf945d56..03cad250f58d 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1405,18 +1405,8 @@ static int aic3x_probe(struct platform_device *pdev)
1405 1405
1406 aic3x_add_widgets(codec); 1406 aic3x_add_widgets(codec);
1407 1407
1408 ret = snd_soc_init_card(socdev);
1409 if (ret < 0) {
1410 printk(KERN_ERR "aic3x: failed to register card\n");
1411 goto card_err;
1412 }
1413
1414 return ret; 1408 return ret;
1415 1409
1416card_err:
1417 snd_soc_free_pcms(socdev);
1418 snd_soc_dapm_free(socdev);
1419
1420pcm_err: 1410pcm_err:
1421 kfree(codec->reg_cache); 1411 kfree(codec->reg_cache);
1422 return ret; 1412 return ret;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
new file mode 100644
index 000000000000..bff476d65d05
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -0,0 +1,1229 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/pm.h>
29#include <linux/i2c.h>
30#include <linux/platform_device.h>
31#include <linux/interrupt.h>
32#include <linux/gpio.h>
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37#include <sound/soc-dapm.h>
38#include <sound/initval.h>
39#include <sound/tlv.h>
40
41#include <sound/tlv320dac33-plat.h>
42#include "tlv320dac33.h"
43
44#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words,
45 * 6144 stereo */
46#define DAC33_BUFFER_SIZE_SAMPLES 6144
47
48#define NSAMPLE_MAX 5700
49
50#define LATENCY_TIME_MS 20
51
52static struct snd_soc_codec *tlv320dac33_codec;
53
54enum dac33_state {
55 DAC33_IDLE = 0,
56 DAC33_PREFILL,
57 DAC33_PLAYBACK,
58 DAC33_FLUSH,
59};
60
61struct tlv320dac33_priv {
62 struct mutex mutex;
63 struct workqueue_struct *dac33_wq;
64 struct work_struct work;
65 struct snd_soc_codec codec;
66 int power_gpio;
67 int chip_power;
68 int irq;
69 unsigned int refclk;
70
71 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
72 unsigned int nsample_min; /* nsample should not be lower than
73 * this */
74 unsigned int nsample_max; /* nsample should not be higher than
75 * this */
76 unsigned int nsample_switch; /* Use FIFO or bypass FIFO switch */
77 unsigned int nsample; /* burst read amount from host */
78
79 enum dac33_state state;
80};
81
82static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
830x00, 0x00, 0x00, 0x00, /* 0x00 - 0x03 */
840x00, 0x00, 0x00, 0x00, /* 0x04 - 0x07 */
850x00, 0x00, 0x00, 0x00, /* 0x08 - 0x0b */
860x00, 0x00, 0x00, 0x00, /* 0x0c - 0x0f */
870x00, 0x00, 0x00, 0x00, /* 0x10 - 0x13 */
880x00, 0x00, 0x00, 0x00, /* 0x14 - 0x17 */
890x00, 0x00, 0x00, 0x00, /* 0x18 - 0x1b */
900x00, 0x00, 0x00, 0x00, /* 0x1c - 0x1f */
910x00, 0x00, 0x00, 0x00, /* 0x20 - 0x23 */
920x00, 0x00, 0x00, 0x00, /* 0x24 - 0x27 */
930x00, 0x00, 0x00, 0x00, /* 0x28 - 0x2b */
940x00, 0x00, 0x00, 0x80, /* 0x2c - 0x2f */
950x80, 0x00, 0x00, 0x00, /* 0x30 - 0x33 */
960x00, 0x00, 0x00, 0x00, /* 0x34 - 0x37 */
970x00, 0x00, /* 0x38 - 0x39 */
98/* Registers 0x3a - 0x3f are reserved */
99 0x00, 0x00, /* 0x3a - 0x3b */
1000x00, 0x00, 0x00, 0x00, /* 0x3c - 0x3f */
101
1020x00, 0x00, 0x00, 0x00, /* 0x40 - 0x43 */
1030x00, 0x80, /* 0x44 - 0x45 */
104/* Registers 0x46 - 0x47 are reserved */
105 0x80, 0x80, /* 0x46 - 0x47 */
106
1070x80, 0x00, 0x00, /* 0x48 - 0x4a */
108/* Registers 0x4b - 0x7c are reserved */
109 0x00, /* 0x4b */
1100x00, 0x00, 0x00, 0x00, /* 0x4c - 0x4f */
1110x00, 0x00, 0x00, 0x00, /* 0x50 - 0x53 */
1120x00, 0x00, 0x00, 0x00, /* 0x54 - 0x57 */
1130x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5b */
1140x00, 0x00, 0x00, 0x00, /* 0x5c - 0x5f */
1150x00, 0x00, 0x00, 0x00, /* 0x60 - 0x63 */
1160x00, 0x00, 0x00, 0x00, /* 0x64 - 0x67 */
1170x00, 0x00, 0x00, 0x00, /* 0x68 - 0x6b */
1180x00, 0x00, 0x00, 0x00, /* 0x6c - 0x6f */
1190x00, 0x00, 0x00, 0x00, /* 0x70 - 0x73 */
1200x00, 0x00, 0x00, 0x00, /* 0x74 - 0x77 */
1210x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7b */
1220x00, /* 0x7c */
123
124 0xda, 0x33, 0x03, /* 0x7d - 0x7f */
125};
126
127/* Register read and write */
128static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
129 unsigned reg)
130{
131 u8 *cache = codec->reg_cache;
132 if (reg >= DAC33_CACHEREGNUM)
133 return 0;
134
135 return cache[reg];
136}
137
138static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
139 u8 reg, u8 value)
140{
141 u8 *cache = codec->reg_cache;
142 if (reg >= DAC33_CACHEREGNUM)
143 return;
144
145 cache[reg] = value;
146}
147
148static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
149 u8 *value)
150{
151 struct tlv320dac33_priv *dac33 = codec->private_data;
152 int val;
153
154 *value = reg & 0xff;
155
156 /* If powered off, return the cached value */
157 if (dac33->chip_power) {
158 val = i2c_smbus_read_byte_data(codec->control_data, value[0]);
159 if (val < 0) {
160 dev_err(codec->dev, "Read failed (%d)\n", val);
161 value[0] = dac33_read_reg_cache(codec, reg);
162 } else {
163 value[0] = val;
164 dac33_write_reg_cache(codec, reg, val);
165 }
166 } else {
167 value[0] = dac33_read_reg_cache(codec, reg);
168 }
169
170 return 0;
171}
172
173static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
174 unsigned int value)
175{
176 struct tlv320dac33_priv *dac33 = codec->private_data;
177 u8 data[2];
178 int ret = 0;
179
180 /*
181 * data is
182 * D15..D8 dac33 register offset
183 * D7...D0 register data
184 */
185 data[0] = reg & 0xff;
186 data[1] = value & 0xff;
187
188 dac33_write_reg_cache(codec, data[0], data[1]);
189 if (dac33->chip_power) {
190 ret = codec->hw_write(codec->control_data, data, 2);
191 if (ret != 2)
192 dev_err(codec->dev, "Write failed (%d)\n", ret);
193 else
194 ret = 0;
195 }
196
197 return ret;
198}
199
200static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
201 unsigned int value)
202{
203 struct tlv320dac33_priv *dac33 = codec->private_data;
204 int ret;
205
206 mutex_lock(&dac33->mutex);
207 ret = dac33_write(codec, reg, value);
208 mutex_unlock(&dac33->mutex);
209
210 return ret;
211}
212
213#define DAC33_I2C_ADDR_AUTOINC 0x80
214static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
215 unsigned int value)
216{
217 struct tlv320dac33_priv *dac33 = codec->private_data;
218 u8 data[3];
219 int ret = 0;
220
221 /*
222 * data is
223 * D23..D16 dac33 register offset
224 * D15..D8 register data MSB
225 * D7...D0 register data LSB
226 */
227 data[0] = reg & 0xff;
228 data[1] = (value >> 8) & 0xff;
229 data[2] = value & 0xff;
230
231 dac33_write_reg_cache(codec, data[0], data[1]);
232 dac33_write_reg_cache(codec, data[0] + 1, data[2]);
233
234 if (dac33->chip_power) {
235 /* We need to set autoincrement mode for 16 bit writes */
236 data[0] |= DAC33_I2C_ADDR_AUTOINC;
237 ret = codec->hw_write(codec->control_data, data, 3);
238 if (ret != 3)
239 dev_err(codec->dev, "Write failed (%d)\n", ret);
240 else
241 ret = 0;
242 }
243
244 return ret;
245}
246
247static void dac33_restore_regs(struct snd_soc_codec *codec)
248{
249 struct tlv320dac33_priv *dac33 = codec->private_data;
250 u8 *cache = codec->reg_cache;
251 u8 data[2];
252 int i, ret;
253
254 if (!dac33->chip_power)
255 return;
256
257 for (i = DAC33_PWR_CTRL; i <= DAC33_INTP_CTRL_B; i++) {
258 data[0] = i;
259 data[1] = cache[i];
260 /* Skip the read only registers */
261 if ((i >= DAC33_INT_OSC_STATUS &&
262 i <= DAC33_INT_OSC_FREQ_RAT_READ_B) ||
263 (i >= DAC33_FIFO_WPTR_MSB && i <= DAC33_FIFO_IRQ_FLAG) ||
264 i == DAC33_DAC_STATUS_FLAGS ||
265 i == DAC33_SRC_EST_REF_CLK_RATIO_A ||
266 i == DAC33_SRC_EST_REF_CLK_RATIO_B)
267 continue;
268 ret = codec->hw_write(codec->control_data, data, 2);
269 if (ret != 2)
270 dev_err(codec->dev, "Write failed (%d)\n", ret);
271 }
272 for (i = DAC33_LDAC_PWR_CTRL; i <= DAC33_LINEL_TO_LLO_VOL; i++) {
273 data[0] = i;
274 data[1] = cache[i];
275 ret = codec->hw_write(codec->control_data, data, 2);
276 if (ret != 2)
277 dev_err(codec->dev, "Write failed (%d)\n", ret);
278 }
279 for (i = DAC33_LINER_TO_RLO_VOL; i <= DAC33_OSC_TRIM; i++) {
280 data[0] = i;
281 data[1] = cache[i];
282 ret = codec->hw_write(codec->control_data, data, 2);
283 if (ret != 2)
284 dev_err(codec->dev, "Write failed (%d)\n", ret);
285 }
286}
287
288static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
289{
290 u8 reg;
291
292 reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
293 if (power)
294 reg |= DAC33_PDNALLB;
295 else
296 reg &= ~DAC33_PDNALLB;
297 dac33_write(codec, DAC33_PWR_CTRL, reg);
298}
299
300static void dac33_hard_power(struct snd_soc_codec *codec, int power)
301{
302 struct tlv320dac33_priv *dac33 = codec->private_data;
303
304 mutex_lock(&dac33->mutex);
305 if (power) {
306 if (dac33->power_gpio >= 0) {
307 gpio_set_value(dac33->power_gpio, 1);
308 dac33->chip_power = 1;
309 /* Restore registers */
310 dac33_restore_regs(codec);
311 }
312 dac33_soft_power(codec, 1);
313 } else {
314 dac33_soft_power(codec, 0);
315 if (dac33->power_gpio >= 0) {
316 gpio_set_value(dac33->power_gpio, 0);
317 dac33->chip_power = 0;
318 }
319 }
320 mutex_unlock(&dac33->mutex);
321
322}
323
324static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
325 struct snd_ctl_elem_value *ucontrol)
326{
327 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
328 struct tlv320dac33_priv *dac33 = codec->private_data;
329
330 ucontrol->value.integer.value[0] = dac33->nsample;
331
332 return 0;
333}
334
335static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_value *ucontrol)
337{
338 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
339 struct tlv320dac33_priv *dac33 = codec->private_data;
340 int ret = 0;
341
342 if (dac33->nsample == ucontrol->value.integer.value[0])
343 return 0;
344
345 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
346 ucontrol->value.integer.value[0] > dac33->nsample_max)
347 ret = -EINVAL;
348 else
349 dac33->nsample = ucontrol->value.integer.value[0];
350
351 return ret;
352}
353
354static int dac33_get_nsample_switch(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct tlv320dac33_priv *dac33 = codec->private_data;
359
360 ucontrol->value.integer.value[0] = dac33->nsample_switch;
361
362 return 0;
363}
364
365static int dac33_set_nsample_switch(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
367{
368 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct tlv320dac33_priv *dac33 = codec->private_data;
370 int ret = 0;
371
372 if (dac33->nsample_switch == ucontrol->value.integer.value[0])
373 return 0;
374 /* Do not allow changes while stream is running*/
375 if (codec->active)
376 return -EPERM;
377
378 if (ucontrol->value.integer.value[0] < 0 ||
379 ucontrol->value.integer.value[0] > 1)
380 ret = -EINVAL;
381 else
382 dac33->nsample_switch = ucontrol->value.integer.value[0];
383
384 return ret;
385}
386
387/*
388 * DACL/R digital volume control:
389 * from 0 dB to -63.5 in 0.5 dB steps
390 * Need to be inverted later on:
391 * 0x00 == 0 dB
392 * 0x7f == -63.5 dB
393 */
394static DECLARE_TLV_DB_SCALE(dac_digivol_tlv, -6350, 50, 0);
395
396static const struct snd_kcontrol_new dac33_snd_controls[] = {
397 SOC_DOUBLE_R_TLV("DAC Digital Playback Volume",
398 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL,
399 0, 0x7f, 1, dac_digivol_tlv),
400 SOC_DOUBLE_R("DAC Digital Playback Switch",
401 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1),
402 SOC_DOUBLE_R("Line to Line Out Volume",
403 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
404};
405
406static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
407 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
408 dac33_get_nsample, dac33_set_nsample),
409 SOC_SINGLE_EXT("nSample Switch", 0, 0, 1, 0,
410 dac33_get_nsample_switch, dac33_set_nsample_switch),
411};
412
413/* Analog bypass */
414static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
415 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
416
417static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
418 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
419
420static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
421 SND_SOC_DAPM_OUTPUT("LEFT_LO"),
422 SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
423
424 SND_SOC_DAPM_INPUT("LINEL"),
425 SND_SOC_DAPM_INPUT("LINER"),
426
427 SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0),
428 SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0),
429
430 /* Analog bypass */
431 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
432 &dac33_dapm_abypassl_control),
433 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
434 &dac33_dapm_abypassr_control),
435
436 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power",
437 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
438 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
439 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
440};
441
442static const struct snd_soc_dapm_route audio_map[] = {
443 /* Analog bypass */
444 {"Analog Left Bypass", "Switch", "LINEL"},
445 {"Analog Right Bypass", "Switch", "LINER"},
446
447 {"Output Left Amp Power", NULL, "DACL"},
448 {"Output Right Amp Power", NULL, "DACR"},
449
450 {"Output Left Amp Power", NULL, "Analog Left Bypass"},
451 {"Output Right Amp Power", NULL, "Analog Right Bypass"},
452
453 /* output */
454 {"LEFT_LO", NULL, "Output Left Amp Power"},
455 {"RIGHT_LO", NULL, "Output Right Amp Power"},
456};
457
458static int dac33_add_widgets(struct snd_soc_codec *codec)
459{
460 snd_soc_dapm_new_controls(codec, dac33_dapm_widgets,
461 ARRAY_SIZE(dac33_dapm_widgets));
462
463 /* set up audio path interconnects */
464 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
465 snd_soc_dapm_new_widgets(codec);
466
467 return 0;
468}
469
470static int dac33_set_bias_level(struct snd_soc_codec *codec,
471 enum snd_soc_bias_level level)
472{
473 switch (level) {
474 case SND_SOC_BIAS_ON:
475 dac33_soft_power(codec, 1);
476 break;
477 case SND_SOC_BIAS_PREPARE:
478 break;
479 case SND_SOC_BIAS_STANDBY:
480 if (codec->bias_level == SND_SOC_BIAS_OFF)
481 dac33_hard_power(codec, 1);
482 dac33_soft_power(codec, 0);
483 break;
484 case SND_SOC_BIAS_OFF:
485 dac33_hard_power(codec, 0);
486 break;
487 }
488 codec->bias_level = level;
489
490 return 0;
491}
492
493static void dac33_work(struct work_struct *work)
494{
495 struct snd_soc_codec *codec;
496 struct tlv320dac33_priv *dac33;
497 u8 reg;
498
499 dac33 = container_of(work, struct tlv320dac33_priv, work);
500 codec = &dac33->codec;
501
502 mutex_lock(&dac33->mutex);
503 switch (dac33->state) {
504 case DAC33_PREFILL:
505 dac33->state = DAC33_PLAYBACK;
506 dac33_write16(codec, DAC33_NSAMPLE_MSB,
507 DAC33_THRREG(dac33->nsample));
508 dac33_write16(codec, DAC33_PREFILL_MSB,
509 DAC33_THRREG(dac33->alarm_threshold));
510 break;
511 case DAC33_PLAYBACK:
512 dac33_write16(codec, DAC33_NSAMPLE_MSB,
513 DAC33_THRREG(dac33->nsample));
514 break;
515 case DAC33_IDLE:
516 break;
517 case DAC33_FLUSH:
518 dac33->state = DAC33_IDLE;
519 /* Mask all interrupts from dac33 */
520 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
521
522 /* flush fifo */
523 reg = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
524 reg |= DAC33_FIFOFLUSH;
525 dac33_write(codec, DAC33_FIFO_CTRL_A, reg);
526 break;
527 }
528 mutex_unlock(&dac33->mutex);
529}
530
531static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
532{
533 struct snd_soc_codec *codec = dev;
534 struct tlv320dac33_priv *dac33 = codec->private_data;
535
536 queue_work(dac33->dac33_wq, &dac33->work);
537
538 return IRQ_HANDLED;
539}
540
541static void dac33_shutdown(struct snd_pcm_substream *substream,
542 struct snd_soc_dai *dai)
543{
544 struct snd_soc_pcm_runtime *rtd = substream->private_data;
545 struct snd_soc_device *socdev = rtd->socdev;
546 struct snd_soc_codec *codec = socdev->card->codec;
547 struct tlv320dac33_priv *dac33 = codec->private_data;
548 unsigned int pwr_ctrl;
549
550 /* Stop pending workqueue */
551 if (dac33->nsample_switch)
552 cancel_work_sync(&dac33->work);
553
554 mutex_lock(&dac33->mutex);
555 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
556 pwr_ctrl &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
557 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
558 mutex_unlock(&dac33->mutex);
559}
560
561static void dac33_oscwait(struct snd_soc_codec *codec)
562{
563 int timeout = 20;
564 u8 reg;
565
566 do {
567 msleep(1);
568 dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
569 } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
570 if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
571 dev_err(codec->dev,
572 "internal oscillator calibration failed\n");
573}
574
575static int dac33_hw_params(struct snd_pcm_substream *substream,
576 struct snd_pcm_hw_params *params,
577 struct snd_soc_dai *dai)
578{
579 struct snd_soc_pcm_runtime *rtd = substream->private_data;
580 struct snd_soc_device *socdev = rtd->socdev;
581 struct snd_soc_codec *codec = socdev->card->codec;
582
583 /* Check parameters for validity */
584 switch (params_rate(params)) {
585 case 44100:
586 case 48000:
587 break;
588 default:
589 dev_err(codec->dev, "unsupported rate %d\n",
590 params_rate(params));
591 return -EINVAL;
592 }
593
594 switch (params_format(params)) {
595 case SNDRV_PCM_FORMAT_S16_LE:
596 break;
597 default:
598 dev_err(codec->dev, "unsupported format %d\n",
599 params_format(params));
600 return -EINVAL;
601 }
602
603 return 0;
604}
605
606#define CALC_OSCSET(rate, refclk) ( \
607 ((((rate * 10000) / refclk) * 4096) + 5000) / 10000)
608#define CALC_RATIOSET(rate, refclk) ( \
609 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
610
611/*
612 * tlv320dac33 is strict on the sequence of the register writes, if the register
613 * writes happens in different order, than dac33 might end up in unknown state.
614 * Use the known, working sequence of register writes to initialize the dac33.
615 */
616static int dac33_prepare_chip(struct snd_pcm_substream *substream)
617{
618 struct snd_soc_pcm_runtime *rtd = substream->private_data;
619 struct snd_soc_device *socdev = rtd->socdev;
620 struct snd_soc_codec *codec = socdev->card->codec;
621 struct tlv320dac33_priv *dac33 = codec->private_data;
622 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
623 u8 aictrl_a, fifoctrl_a;
624
625 switch (substream->runtime->rate) {
626 case 44100:
627 case 48000:
628 oscset = CALC_OSCSET(substream->runtime->rate, dac33->refclk);
629 ratioset = CALC_RATIOSET(substream->runtime->rate,
630 dac33->refclk);
631 break;
632 default:
633 dev_err(codec->dev, "unsupported rate %d\n",
634 substream->runtime->rate);
635 return -EINVAL;
636 }
637
638
639 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
640 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
641 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
642 fifoctrl_a &= ~DAC33_WIDTH;
643 switch (substream->runtime->format) {
644 case SNDRV_PCM_FORMAT_S16_LE:
645 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
646 fifoctrl_a |= DAC33_WIDTH;
647 break;
648 default:
649 dev_err(codec->dev, "unsupported format %d\n",
650 substream->runtime->format);
651 return -EINVAL;
652 }
653
654 mutex_lock(&dac33->mutex);
655 dac33_soft_power(codec, 1);
656
657 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
658 dac33_write(codec, DAC33_INT_OSC_CTRL, reg_tmp);
659
660 /* Write registers 0x08 and 0x09 (MSB, LSB) */
661 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
662
663 /* calib time: 128 is a nice number ;) */
664 dac33_write(codec, DAC33_CALIB_TIME, 128);
665
666 /* adjustment treshold & step */
667 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
668 DAC33_ADJSTEP(1));
669
670 /* div=4 / gain=1 / div */
671 dac33_write(codec, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
672
673 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
674 pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
675 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
676
677 dac33_oscwait(codec);
678
679 if (dac33->nsample_switch) {
680 /* 50-51 : ASRC Control registers */
681 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
682 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
683
684 /* Write registers 0x34 and 0x35 (MSB, LSB) */
685 dac33_write16(codec, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
686
687 /* Set interrupts to high active */
688 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
689
690 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
691 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
692 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
693 } else {
694 /* 50-51 : ASRC Control registers */
695 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
696 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
697 }
698
699 if (dac33->nsample_switch)
700 fifoctrl_a &= ~DAC33_FBYPAS;
701 else
702 fifoctrl_a |= DAC33_FBYPAS;
703 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
704
705 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
706 reg_tmp = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
707 if (dac33->nsample_switch)
708 reg_tmp &= ~DAC33_BCLKON;
709 else
710 reg_tmp |= DAC33_BCLKON;
711 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg_tmp);
712
713 if (dac33->nsample_switch) {
714 /* 20: BCLK divide ratio */
715 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 3);
716
717 dac33_write16(codec, DAC33_ATHR_MSB,
718 DAC33_THRREG(dac33->alarm_threshold));
719 } else {
720 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
721 }
722
723 mutex_unlock(&dac33->mutex);
724
725 return 0;
726}
727
728static void dac33_calculate_times(struct snd_pcm_substream *substream)
729{
730 struct snd_soc_pcm_runtime *rtd = substream->private_data;
731 struct snd_soc_device *socdev = rtd->socdev;
732 struct snd_soc_codec *codec = socdev->card->codec;
733 struct tlv320dac33_priv *dac33 = codec->private_data;
734 unsigned int nsample_limit;
735
736 /* Number of samples (16bit, stereo) in one period */
737 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
738
739 /* Number of samples (16bit, stereo) in ALSA buffer */
740 dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
741 /* Subtract one period from the total */
742 dac33->nsample_max -= dac33->nsample_min;
743
744 /* Number of samples for LATENCY_TIME_MS / 2 */
745 dac33->alarm_threshold = substream->runtime->rate /
746 (1000 / (LATENCY_TIME_MS / 2));
747
748 /* Find and fix up the lowest nsmaple limit */
749 nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
750
751 if (dac33->nsample_min < nsample_limit)
752 dac33->nsample_min = nsample_limit;
753
754 if (dac33->nsample < dac33->nsample_min)
755 dac33->nsample = dac33->nsample_min;
756
757 /*
758 * Find and fix up the highest nsmaple limit
759 * In order to not overflow the DAC33 buffer substract the
760 * alarm_threshold value from the size of the DAC33 buffer
761 */
762 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
763
764 if (dac33->nsample_max > nsample_limit)
765 dac33->nsample_max = nsample_limit;
766
767 if (dac33->nsample > dac33->nsample_max)
768 dac33->nsample = dac33->nsample_max;
769}
770
771static int dac33_pcm_prepare(struct snd_pcm_substream *substream,
772 struct snd_soc_dai *dai)
773{
774 dac33_calculate_times(substream);
775 dac33_prepare_chip(substream);
776
777 return 0;
778}
779
780static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
781 struct snd_soc_dai *dai)
782{
783 struct snd_soc_pcm_runtime *rtd = substream->private_data;
784 struct snd_soc_device *socdev = rtd->socdev;
785 struct snd_soc_codec *codec = socdev->card->codec;
786 struct tlv320dac33_priv *dac33 = codec->private_data;
787 int ret = 0;
788
789 switch (cmd) {
790 case SNDRV_PCM_TRIGGER_START:
791 case SNDRV_PCM_TRIGGER_RESUME:
792 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
793 if (dac33->nsample_switch) {
794 dac33->state = DAC33_PREFILL;
795 queue_work(dac33->dac33_wq, &dac33->work);
796 }
797 break;
798 case SNDRV_PCM_TRIGGER_STOP:
799 case SNDRV_PCM_TRIGGER_SUSPEND:
800 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
801 if (dac33->nsample_switch) {
802 dac33->state = DAC33_FLUSH;
803 queue_work(dac33->dac33_wq, &dac33->work);
804 }
805 break;
806 default:
807 ret = -EINVAL;
808 }
809
810 return ret;
811}
812
813static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
814 int clk_id, unsigned int freq, int dir)
815{
816 struct snd_soc_codec *codec = codec_dai->codec;
817 struct tlv320dac33_priv *dac33 = codec->private_data;
818 u8 ioc_reg, asrcb_reg;
819
820 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
821 asrcb_reg = dac33_read_reg_cache(codec, DAC33_ASRC_CTRL_B);
822 switch (clk_id) {
823 case TLV320DAC33_MCLK:
824 ioc_reg |= DAC33_REFSEL;
825 asrcb_reg |= DAC33_SRCREFSEL;
826 break;
827 case TLV320DAC33_SLEEPCLK:
828 ioc_reg &= ~DAC33_REFSEL;
829 asrcb_reg &= ~DAC33_SRCREFSEL;
830 break;
831 default:
832 dev_err(codec->dev, "Invalid clock ID (%d)\n", clk_id);
833 break;
834 }
835 dac33->refclk = freq;
836
837 dac33_write_reg_cache(codec, DAC33_INT_OSC_CTRL, ioc_reg);
838 dac33_write_reg_cache(codec, DAC33_ASRC_CTRL_B, asrcb_reg);
839
840 return 0;
841}
842
843static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
844 unsigned int fmt)
845{
846 struct snd_soc_codec *codec = codec_dai->codec;
847 u8 aictrl_a, aictrl_b;
848
849 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
850 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
851 /* set master/slave audio interface */
852 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
853 case SND_SOC_DAIFMT_CBM_CFM:
854 /* Codec Master */
855 aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK);
856 break;
857 case SND_SOC_DAIFMT_CBS_CFS:
858 /* Codec Slave */
859 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
860 break;
861 default:
862 return -EINVAL;
863 }
864
865 aictrl_a &= ~DAC33_AFMT_MASK;
866 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
867 case SND_SOC_DAIFMT_I2S:
868 aictrl_a |= DAC33_AFMT_I2S;
869 break;
870 case SND_SOC_DAIFMT_DSP_A:
871 aictrl_a |= DAC33_AFMT_DSP;
872 aictrl_b &= ~DAC33_DATA_DELAY_MASK;
873 aictrl_b |= DAC33_DATA_DELAY(1); /* 1 bit delay */
874 break;
875 case SND_SOC_DAIFMT_DSP_B:
876 aictrl_a |= DAC33_AFMT_DSP;
877 aictrl_b &= ~DAC33_DATA_DELAY_MASK; /* No delay */
878 break;
879 case SND_SOC_DAIFMT_RIGHT_J:
880 aictrl_a |= DAC33_AFMT_RIGHT_J;
881 break;
882 case SND_SOC_DAIFMT_LEFT_J:
883 aictrl_a |= DAC33_AFMT_LEFT_J;
884 break;
885 default:
886 dev_err(codec->dev, "Unsupported format (%u)\n",
887 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
888 return -EINVAL;
889 }
890
891 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
892 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
893
894 return 0;
895}
896
897static void dac33_init_chip(struct snd_soc_codec *codec)
898{
899 /* 44-46: DAC Control Registers */
900 /* A : DAC sample rate Fsref/1.5 */
901 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(1));
902 /* B : DAC src=normal, not muted */
903 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
904 DAC33_DACSRCL_LEFT);
905 /* C : (defaults) */
906 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
907
908 /* 64-65 : L&R DAC power control
909 Line In -> OUT 1V/V Gain, DAC -> OUT 4V/V Gain*/
910 dac33_write(codec, DAC33_LDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
911 dac33_write(codec, DAC33_RDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
912
913 /* 73 : volume soft stepping control,
914 clock source = internal osc (?) */
915 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
916
917 /* 66 : LOP/LOM Modes */
918 dac33_write(codec, DAC33_OUT_AMP_CM_CTRL, 0xff);
919
920 /* 68 : LOM inverted from LOP */
921 dac33_write(codec, DAC33_OUT_AMP_CTRL, (3<<2));
922
923 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
924}
925
926static int dac33_soc_probe(struct platform_device *pdev)
927{
928 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
929 struct snd_soc_codec *codec;
930 struct tlv320dac33_priv *dac33;
931 int ret = 0;
932
933 BUG_ON(!tlv320dac33_codec);
934
935 codec = tlv320dac33_codec;
936 socdev->card->codec = codec;
937 dac33 = codec->private_data;
938
939 /* Power up the codec */
940 dac33_hard_power(codec, 1);
941 /* Set default configuration */
942 dac33_init_chip(codec);
943
944 /* register pcms */
945 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
946 if (ret < 0) {
947 dev_err(codec->dev, "failed to create pcms\n");
948 goto pcm_err;
949 }
950
951 snd_soc_add_controls(codec, dac33_snd_controls,
952 ARRAY_SIZE(dac33_snd_controls));
953 /* Only add the nSample controls, if we have valid IRQ number */
954 if (dac33->irq >= 0)
955 snd_soc_add_controls(codec, dac33_nsample_snd_controls,
956 ARRAY_SIZE(dac33_nsample_snd_controls));
957
958 dac33_add_widgets(codec);
959
960 /* power on device */
961 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
962
963 return 0;
964
965pcm_err:
966 dac33_hard_power(codec, 0);
967 return ret;
968}
969
970static int dac33_soc_remove(struct platform_device *pdev)
971{
972 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
973 struct snd_soc_codec *codec = socdev->card->codec;
974
975 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
976
977 snd_soc_free_pcms(socdev);
978 snd_soc_dapm_free(socdev);
979
980 return 0;
981}
982
983static int dac33_soc_suspend(struct platform_device *pdev, pm_message_t state)
984{
985 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
986 struct snd_soc_codec *codec = socdev->card->codec;
987
988 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
989
990 return 0;
991}
992
993static int dac33_soc_resume(struct platform_device *pdev)
994{
995 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
996 struct snd_soc_codec *codec = socdev->card->codec;
997
998 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
999 dac33_set_bias_level(codec, codec->suspend_bias_level);
1000
1001 return 0;
1002}
1003
1004struct snd_soc_codec_device soc_codec_dev_tlv320dac33 = {
1005 .probe = dac33_soc_probe,
1006 .remove = dac33_soc_remove,
1007 .suspend = dac33_soc_suspend,
1008 .resume = dac33_soc_resume,
1009};
1010EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1011
1012#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
1013 SNDRV_PCM_RATE_48000)
1014#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1015
1016static struct snd_soc_dai_ops dac33_dai_ops = {
1017 .shutdown = dac33_shutdown,
1018 .hw_params = dac33_hw_params,
1019 .prepare = dac33_pcm_prepare,
1020 .trigger = dac33_pcm_trigger,
1021 .set_sysclk = dac33_set_dai_sysclk,
1022 .set_fmt = dac33_set_dai_fmt,
1023};
1024
1025struct snd_soc_dai dac33_dai = {
1026 .name = "tlv320dac33",
1027 .playback = {
1028 .stream_name = "Playback",
1029 .channels_min = 2,
1030 .channels_max = 2,
1031 .rates = DAC33_RATES,
1032 .formats = DAC33_FORMATS,},
1033 .ops = &dac33_dai_ops,
1034};
1035EXPORT_SYMBOL_GPL(dac33_dai);
1036
1037static int dac33_i2c_probe(struct i2c_client *client,
1038 const struct i2c_device_id *id)
1039{
1040 struct tlv320dac33_platform_data *pdata;
1041 struct tlv320dac33_priv *dac33;
1042 struct snd_soc_codec *codec;
1043 int ret = 0;
1044
1045 if (client->dev.platform_data == NULL) {
1046 dev_err(&client->dev, "Platform data not set\n");
1047 return -ENODEV;
1048 }
1049 pdata = client->dev.platform_data;
1050
1051 dac33 = kzalloc(sizeof(struct tlv320dac33_priv), GFP_KERNEL);
1052 if (dac33 == NULL)
1053 return -ENOMEM;
1054
1055 codec = &dac33->codec;
1056 codec->private_data = dac33;
1057 codec->control_data = client;
1058
1059 mutex_init(&codec->mutex);
1060 mutex_init(&dac33->mutex);
1061 INIT_LIST_HEAD(&codec->dapm_widgets);
1062 INIT_LIST_HEAD(&codec->dapm_paths);
1063
1064 codec->name = "tlv320dac33";
1065 codec->owner = THIS_MODULE;
1066 codec->read = dac33_read_reg_cache;
1067 codec->write = dac33_write_locked;
1068 codec->hw_write = (hw_write_t) i2c_master_send;
1069 codec->bias_level = SND_SOC_BIAS_OFF;
1070 codec->set_bias_level = dac33_set_bias_level;
1071 codec->dai = &dac33_dai;
1072 codec->num_dai = 1;
1073 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
1074 codec->reg_cache = kmemdup(dac33_reg, ARRAY_SIZE(dac33_reg),
1075 GFP_KERNEL);
1076 if (codec->reg_cache == NULL) {
1077 ret = -ENOMEM;
1078 goto error_reg;
1079 }
1080
1081 i2c_set_clientdata(client, dac33);
1082
1083 dac33->power_gpio = pdata->power_gpio;
1084 dac33->irq = client->irq;
1085 dac33->nsample = NSAMPLE_MAX;
1086 /* Disable FIFO use by default */
1087 dac33->nsample_switch = 0;
1088
1089 tlv320dac33_codec = codec;
1090
1091 codec->dev = &client->dev;
1092 dac33_dai.dev = codec->dev;
1093
1094 /* Check if the reset GPIO number is valid and request it */
1095 if (dac33->power_gpio >= 0) {
1096 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
1097 if (ret < 0) {
1098 dev_err(codec->dev,
1099 "Failed to request reset GPIO (%d)\n",
1100 dac33->power_gpio);
1101 snd_soc_unregister_dai(&dac33_dai);
1102 snd_soc_unregister_codec(codec);
1103 goto error_gpio;
1104 }
1105 gpio_direction_output(dac33->power_gpio, 0);
1106 } else {
1107 dac33->chip_power = 1;
1108 }
1109
1110 /* Check if the IRQ number is valid and request it */
1111 if (dac33->irq >= 0) {
1112 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1113 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1114 codec->name, codec);
1115 if (ret < 0) {
1116 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1117 dac33->irq, ret);
1118 dac33->irq = -1;
1119 }
1120 if (dac33->irq != -1) {
1121 /* Setup work queue */
1122 dac33->dac33_wq = create_rt_workqueue("tlv320dac33");
1123 if (dac33->dac33_wq == NULL) {
1124 free_irq(dac33->irq, &dac33->codec);
1125 ret = -ENOMEM;
1126 goto error_wq;
1127 }
1128
1129 INIT_WORK(&dac33->work, dac33_work);
1130 }
1131 }
1132
1133 ret = snd_soc_register_codec(codec);
1134 if (ret != 0) {
1135 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1136 goto error_codec;
1137 }
1138
1139 ret = snd_soc_register_dai(&dac33_dai);
1140 if (ret != 0) {
1141 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1142 snd_soc_unregister_codec(codec);
1143 goto error_codec;
1144 }
1145
1146 /* Shut down the codec for now */
1147 dac33_hard_power(codec, 0);
1148
1149 return ret;
1150
1151error_codec:
1152 if (dac33->irq >= 0) {
1153 free_irq(dac33->irq, &dac33->codec);
1154 destroy_workqueue(dac33->dac33_wq);
1155 }
1156error_wq:
1157 if (dac33->power_gpio >= 0)
1158 gpio_free(dac33->power_gpio);
1159error_gpio:
1160 kfree(codec->reg_cache);
1161error_reg:
1162 tlv320dac33_codec = NULL;
1163 kfree(dac33);
1164
1165 return ret;
1166}
1167
1168static int dac33_i2c_remove(struct i2c_client *client)
1169{
1170 struct tlv320dac33_priv *dac33;
1171
1172 dac33 = i2c_get_clientdata(client);
1173 dac33_hard_power(&dac33->codec, 0);
1174
1175 if (dac33->power_gpio >= 0)
1176 gpio_free(dac33->power_gpio);
1177 if (dac33->irq >= 0)
1178 free_irq(dac33->irq, &dac33->codec);
1179
1180 destroy_workqueue(dac33->dac33_wq);
1181 snd_soc_unregister_dai(&dac33_dai);
1182 snd_soc_unregister_codec(&dac33->codec);
1183 kfree(dac33->codec.reg_cache);
1184 kfree(dac33);
1185 tlv320dac33_codec = NULL;
1186
1187 return 0;
1188}
1189
1190static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1191 {
1192 .name = "tlv320dac33",
1193 .driver_data = 0,
1194 },
1195 { },
1196};
1197
1198static struct i2c_driver tlv320dac33_i2c_driver = {
1199 .driver = {
1200 .name = "tlv320dac33",
1201 .owner = THIS_MODULE,
1202 },
1203 .probe = dac33_i2c_probe,
1204 .remove = __devexit_p(dac33_i2c_remove),
1205 .id_table = tlv320dac33_i2c_id,
1206};
1207
1208static int __init dac33_module_init(void)
1209{
1210 int r;
1211 r = i2c_add_driver(&tlv320dac33_i2c_driver);
1212 if (r < 0) {
1213 printk(KERN_ERR "DAC33: driver registration failed\n");
1214 return r;
1215 }
1216 return 0;
1217}
1218module_init(dac33_module_init);
1219
1220static void __exit dac33_module_exit(void)
1221{
1222 i2c_del_driver(&tlv320dac33_i2c_driver);
1223}
1224module_exit(dac33_module_exit);
1225
1226
1227MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1228MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
1229MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
new file mode 100644
index 000000000000..eb8ae07f0bd2
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -0,0 +1,267 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TLV320DAC33_H
25#define __TLV320DAC33_H
26
27#define DAC33_PAGE_SELECT 0x00
28#define DAC33_PWR_CTRL 0x01
29#define DAC33_PLL_CTRL_A 0x02
30#define DAC33_PLL_CTRL_B 0x03
31#define DAC33_PLL_CTRL_C 0x04
32#define DAC33_PLL_CTRL_D 0x05
33#define DAC33_PLL_CTRL_E 0x06
34#define DAC33_INT_OSC_CTRL 0x07
35#define DAC33_INT_OSC_FREQ_RAT_A 0x08
36#define DAC33_INT_OSC_FREQ_RAT_B 0x09
37#define DAC33_INT_OSC_DAC_RATIO_SET 0x0A
38#define DAC33_CALIB_TIME 0x0B
39#define DAC33_INT_OSC_CTRL_B 0x0C
40#define DAC33_INT_OSC_CTRL_C 0x0D
41#define DAC33_INT_OSC_STATUS 0x0E
42#define DAC33_INT_OSC_DAC_RATIO_READ 0x0F
43#define DAC33_INT_OSC_FREQ_RAT_READ_A 0x10
44#define DAC33_INT_OSC_FREQ_RAT_READ_B 0x11
45#define DAC33_SER_AUDIOIF_CTRL_A 0x12
46#define DAC33_SER_AUDIOIF_CTRL_B 0x13
47#define DAC33_SER_AUDIOIF_CTRL_C 0x14
48#define DAC33_FIFO_CTRL_A 0x15
49#define DAC33_UTHR_MSB 0x16
50#define DAC33_UTHR_LSB 0x17
51#define DAC33_ATHR_MSB 0x18
52#define DAC33_ATHR_LSB 0x19
53#define DAC33_LTHR_MSB 0x1A
54#define DAC33_LTHR_LSB 0x1B
55#define DAC33_PREFILL_MSB 0x1C
56#define DAC33_PREFILL_LSB 0x1D
57#define DAC33_NSAMPLE_MSB 0x1E
58#define DAC33_NSAMPLE_LSB 0x1F
59#define DAC33_FIFO_WPTR_MSB 0x20
60#define DAC33_FIFO_WPTR_LSB 0x21
61#define DAC33_FIFO_RPTR_MSB 0x22
62#define DAC33_FIFO_RPTR_LSB 0x23
63#define DAC33_FIFO_DEPTH_MSB 0x24
64#define DAC33_FIFO_DEPTH_LSB 0x25
65#define DAC33_SAMPLES_REMAINING_MSB 0x26
66#define DAC33_SAMPLES_REMAINING_LSB 0x27
67#define DAC33_FIFO_IRQ_FLAG 0x28
68#define DAC33_FIFO_IRQ_MASK 0x29
69#define DAC33_FIFO_IRQ_MODE_A 0x2A
70#define DAC33_FIFO_IRQ_MODE_B 0x2B
71#define DAC33_DAC_CTRL_A 0x2C
72#define DAC33_DAC_CTRL_B 0x2D
73#define DAC33_DAC_CTRL_C 0x2E
74#define DAC33_LDAC_DIG_VOL_CTRL 0x2F
75#define DAC33_RDAC_DIG_VOL_CTRL 0x30
76#define DAC33_DAC_STATUS_FLAGS 0x31
77#define DAC33_ASRC_CTRL_A 0x32
78#define DAC33_ASRC_CTRL_B 0x33
79#define DAC33_SRC_REF_CLK_RATIO_A 0x34
80#define DAC33_SRC_REF_CLK_RATIO_B 0x35
81#define DAC33_SRC_EST_REF_CLK_RATIO_A 0x36
82#define DAC33_SRC_EST_REF_CLK_RATIO_B 0x37
83#define DAC33_INTP_CTRL_A 0x38
84#define DAC33_INTP_CTRL_B 0x39
85/* Registers 0x3A - 0x3F Reserved */
86#define DAC33_LDAC_PWR_CTRL 0x40
87#define DAC33_RDAC_PWR_CTRL 0x41
88#define DAC33_OUT_AMP_CM_CTRL 0x42
89#define DAC33_OUT_AMP_PWR_CTRL 0x43
90#define DAC33_OUT_AMP_CTRL 0x44
91#define DAC33_LINEL_TO_LLO_VOL 0x45
92/* Registers 0x45 - 0x47 Reserved */
93#define DAC33_LINER_TO_RLO_VOL 0x48
94#define DAC33_ANA_VOL_SOFT_STEP_CTRL 0x49
95#define DAC33_OSC_TRIM 0x4A
96/* Registers 0x4B - 0x7C Reserved */
97#define DAC33_DEVICE_ID_MSB 0x7D
98#define DAC33_DEVICE_ID_LSB 0x7E
99#define DAC33_DEVICE_REV_ID 0x7F
100
101#define DAC33_CACHEREGNUM 128
102
103/* Bit definitions */
104
105/* DAC33_PWR_CTRL (0x01) */
106#define DAC33_DACRPDNB (0x01 << 0)
107#define DAC33_DACLPDNB (0x01 << 1)
108#define DAC33_OSCPDNB (0x01 << 2)
109#define DAC33_PLLPDNB (0x01 << 3)
110#define DAC33_PDNALLB (0x01 << 4)
111#define DAC33_SOFT_RESET (0x01 << 7)
112
113/* DAC33_INT_OSC_CTRL (0x07) */
114#define DAC33_REFSEL (0x01 << 1)
115
116/* DAC33_INT_OSC_CTRL_B (0x0C) */
117#define DAC33_ADJSTEP(x) (x << 0)
118#define DAC33_ADJTHRSHLD(x) (x << 4)
119
120/* DAC33_INT_OSC_CTRL_C (0x0D) */
121#define DAC33_REFDIV(x) (x << 4)
122
123/* DAC33_INT_OSC_STATUS (0x0E) */
124#define DAC33_OSCSTATUS_IDLE_CALIB (0x00)
125#define DAC33_OSCSTATUS_NORMAL (0x01)
126#define DAC33_OSCSTATUS_ADJUSTMENT (0x03)
127#define DAC33_OSCSTATUS_NOT_USED (0x02)
128
129/* DAC33_SER_AUDIOIF_CTRL_A (0x12) */
130#define DAC33_MSWCLK (0x01 << 0)
131#define DAC33_MSBCLK (0x01 << 1)
132#define DAC33_AFMT_MASK (0x03 << 2)
133#define DAC33_AFMT_I2S (0x00 << 2)
134#define DAC33_AFMT_DSP (0x01 << 2)
135#define DAC33_AFMT_RIGHT_J (0x02 << 2)
136#define DAC33_AFMT_LEFT_J (0x03 << 2)
137#define DAC33_WLEN_MASK (0x03 << 4)
138#define DAC33_WLEN_16 (0x00 << 4)
139#define DAC33_WLEN_20 (0x01 << 4)
140#define DAC33_WLEN_24 (0x02 << 4)
141#define DAC33_WLEN_32 (0x03 << 4)
142#define DAC33_NCYCL_MASK (0x03 << 6)
143#define DAC33_NCYCL_16 (0x00 << 6)
144#define DAC33_NCYCL_20 (0x01 << 6)
145#define DAC33_NCYCL_24 (0x02 << 6)
146#define DAC33_NCYCL_32 (0x03 << 6)
147
148/* DAC33_SER_AUDIOIF_CTRL_B (0x13) */
149#define DAC33_DATA_DELAY_MASK (0x03 << 2)
150#define DAC33_DATA_DELAY(x) (x << 2)
151#define DAC33_BCLKON (0x01 << 5)
152
153/* DAC33_FIFO_CTRL_A (0x15) */
154#define DAC33_WIDTH (0x01 << 0)
155#define DAC33_FBYPAS (0x01 << 1)
156#define DAC33_FAUTO (0x01 << 2)
157#define DAC33_FIFOFLUSH (0x01 << 3)
158
159/*
160 * UTHR, ATHR, LTHR, PREFILL, NSAMPLE (0x16 - 0x1F)
161 * 13-bit values
162*/
163#define DAC33_THRREG(x) (((x) & 0x1FFF) << 3)
164
165/* DAC33_FIFO_IRQ_MASK (0x29) */
166#define DAC33_MNS (0x01 << 0)
167#define DAC33_MPS (0x01 << 1)
168#define DAC33_MAT (0x01 << 2)
169#define DAC33_MLT (0x01 << 3)
170#define DAC33_MUT (0x01 << 4)
171#define DAC33_MUF (0x01 << 5)
172#define DAC33_MOF (0x01 << 6)
173
174#define DAC33_FIFO_IRQ_MODE_MASK (0x03)
175#define DAC33_FIFO_IRQ_MODE_RISING (0x00)
176#define DAC33_FIFO_IRQ_MODE_FALLING (0x01)
177#define DAC33_FIFO_IRQ_MODE_LEVEL (0x02)
178#define DAC33_FIFO_IRQ_MODE_EDGE (0x03)
179
180/* DAC33_FIFO_IRQ_MODE_A (0x2A) */
181#define DAC33_UTM(x) (x << 0)
182#define DAC33_UFM(x) (x << 2)
183#define DAC33_OFM(x) (x << 4)
184
185/* DAC33_FIFO_IRQ_MODE_B (0x2B) */
186#define DAC33_NSM(x) (x << 0)
187#define DAC33_PSM(x) (x << 2)
188#define DAC33_ATM(x) (x << 4)
189#define DAC33_LTM(x) (x << 6)
190
191/* DAC33_DAC_CTRL_A (0x2C) */
192#define DAC33_DACRATE(x) (x << 0)
193#define DAC33_DACDUAL (0x01 << 4)
194#define DAC33_DACLKSEL_MASK (0x03 << 5)
195#define DAC33_DACLKSEL_INTSOC (0x00 << 5)
196#define DAC33_DACLKSEL_PLL (0x01 << 5)
197#define DAC33_DACLKSEL_MCLK (0x02 << 5)
198#define DAC33_DACLKSEL_BCLK (0x03 << 5)
199
200/* DAC33_DAC_CTRL_B (0x2D) */
201#define DAC33_DACSRCR_MASK (0x03 << 0)
202#define DAC33_DACSRCR_MUTE (0x00 << 0)
203#define DAC33_DACSRCR_RIGHT (0x01 << 0)
204#define DAC33_DACSRCR_LEFT (0x02 << 0)
205#define DAC33_DACSRCR_MONOMIX (0x03 << 0)
206#define DAC33_DACSRCL_MASK (0x03 << 2)
207#define DAC33_DACSRCL_MUTE (0x00 << 2)
208#define DAC33_DACSRCL_LEFT (0x01 << 2)
209#define DAC33_DACSRCL_RIGHT (0x02 << 2)
210#define DAC33_DACSRCL_MONOMIX (0x03 << 2)
211#define DAC33_DVOLSTEP_MASK (0x03 << 4)
212#define DAC33_DVOLSTEP_SS_PERFS (0x00 << 4)
213#define DAC33_DVOLSTEP_SS_PER2FS (0x01 << 4)
214#define DAC33_DVOLSTEP_SS_DISABLED (0x02 << 4)
215#define DAC33_DVOLCTRL_MASK (0x03 << 6)
216#define DAC33_DVOLCTRL_LR_INDEPENDENT1 (0x00 << 6)
217#define DAC33_DVOLCTRL_LR_RIGHT_CONTROL (0x01 << 6)
218#define DAC33_DVOLCTRL_LR_LEFT_CONTROL (0x02 << 6)
219#define DAC33_DVOLCTRL_LR_INDEPENDENT2 (0x03 << 6)
220
221/* DAC33_DAC_CTRL_C (0x2E) */
222#define DAC33_DEEMENR (0x01 << 0)
223#define DAC33_EFFENR (0x01 << 1)
224#define DAC33_DEEMENL (0x01 << 2)
225#define DAC33_EFFENL (0x01 << 3)
226#define DAC33_EN3D (0x01 << 4)
227#define DAC33_RESYNMUTE (0x01 << 5)
228#define DAC33_RESYNEN (0x01 << 6)
229
230/* DAC33_ASRC_CTRL_A (0x32) */
231#define DAC33_SRCBYP (0x01 << 0)
232#define DAC33_SRCLKSEL_MASK (0x03 << 1)
233#define DAC33_SRCLKSEL_INTSOC (0x00 << 1)
234#define DAC33_SRCLKSEL_PLL (0x01 << 1)
235#define DAC33_SRCLKSEL_MCLK (0x02 << 1)
236#define DAC33_SRCLKSEL_BCLK (0x03 << 1)
237#define DAC33_SRCLKDIV(x) (x << 3)
238
239/* DAC33_ASRC_CTRL_B (0x33) */
240#define DAC33_SRCSETUP(x) (x << 0)
241#define DAC33_SRCREFSEL (0x01 << 4)
242#define DAC33_SRCREFDIV(x) (x << 5)
243
244/* DAC33_INTP_CTRL_A (0x38) */
245#define DAC33_INTPSEL (0x01 << 0)
246#define DAC33_INTPM_MASK (0x03 << 1)
247#define DAC33_INTPM_ALOW_OPENDRAIN (0x00 << 1)
248#define DAC33_INTPM_ALOW (0x01 << 1)
249#define DAC33_INTPM_AHIGH (0x02 << 1)
250
251/* DAC33_LDAC_PWR_CTRL (0x40) */
252/* DAC33_RDAC_PWR_CTRL (0x41) */
253#define DAC33_DACLRNUM (0x01 << 2)
254#define DAC33_LROUT_GAIN(x) (x << 0)
255
256/* DAC33_ANA_VOL_SOFT_STEP_CTRL (0x49) */
257#define DAC33_VOLCLKSEL (0x01 << 0)
258#define DAC33_VOLCLKEN (0x01 << 1)
259#define DAC33_VOLBYPASS (0x01 << 2)
260
261#define TLV320DAC33_MCLK 0
262#define TLV320DAC33_SLEEPCLK 1
263
264extern struct snd_soc_dai dac33_dai;
265extern struct snd_soc_codec_device soc_codec_dev_tlv320dac33;
266
267#endif /* __TLV320DAC33_H */
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
new file mode 100644
index 000000000000..6b650c1aa3d1
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -0,0 +1,463 @@
1/*
2 * ALSA SoC Texas Instruments TPA6130A2 headset stereo amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/device.h>
26#include <linux/i2c.h>
27#include <linux/gpio.h>
28#include <sound/tpa6130a2-plat.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h>
32
33#include "tpa6130a2.h"
34
35static struct i2c_client *tpa6130a2_client;
36
37/* This struct is used to save the context */
38struct tpa6130a2_data {
39 struct mutex mutex;
40 unsigned char regs[TPA6130A2_CACHEREGNUM];
41 int power_gpio;
42 unsigned char power_state;
43};
44
45static int tpa6130a2_i2c_read(int reg)
46{
47 struct tpa6130a2_data *data;
48 int val;
49
50 BUG_ON(tpa6130a2_client == NULL);
51 data = i2c_get_clientdata(tpa6130a2_client);
52
53 /* If powered off, return the cached value */
54 if (data->power_state) {
55 val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
56 if (val < 0)
57 dev_err(&tpa6130a2_client->dev, "Read failed\n");
58 else
59 data->regs[reg] = val;
60 } else {
61 val = data->regs[reg];
62 }
63
64 return val;
65}
66
67static int tpa6130a2_i2c_write(int reg, u8 value)
68{
69 struct tpa6130a2_data *data;
70 int val = 0;
71
72 BUG_ON(tpa6130a2_client == NULL);
73 data = i2c_get_clientdata(tpa6130a2_client);
74
75 if (data->power_state) {
76 val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
77 if (val < 0)
78 dev_err(&tpa6130a2_client->dev, "Write failed\n");
79 }
80
81 /* Either powered on or off, we save the context */
82 data->regs[reg] = value;
83
84 return val;
85}
86
87static u8 tpa6130a2_read(int reg)
88{
89 struct tpa6130a2_data *data;
90
91 BUG_ON(tpa6130a2_client == NULL);
92 data = i2c_get_clientdata(tpa6130a2_client);
93
94 return data->regs[reg];
95}
96
97static void tpa6130a2_initialize(void)
98{
99 struct tpa6130a2_data *data;
100 int i;
101
102 BUG_ON(tpa6130a2_client == NULL);
103 data = i2c_get_clientdata(tpa6130a2_client);
104
105 for (i = 1; i < TPA6130A2_REG_VERSION; i++)
106 tpa6130a2_i2c_write(i, data->regs[i]);
107}
108
109static void tpa6130a2_power(int power)
110{
111 struct tpa6130a2_data *data;
112 u8 val;
113
114 BUG_ON(tpa6130a2_client == NULL);
115 data = i2c_get_clientdata(tpa6130a2_client);
116
117 mutex_lock(&data->mutex);
118 if (power) {
119 /* Power on */
120 if (data->power_gpio >= 0) {
121 gpio_set_value(data->power_gpio, 1);
122 data->power_state = 1;
123 tpa6130a2_initialize();
124 }
125 /* Clear SWS */
126 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
127 val &= ~TPA6130A2_SWS;
128 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
129 } else {
130 /* set SWS */
131 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
132 val |= TPA6130A2_SWS;
133 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
134 /* Power off */
135 if (data->power_gpio >= 0) {
136 gpio_set_value(data->power_gpio, 0);
137 data->power_state = 0;
138 }
139 }
140 mutex_unlock(&data->mutex);
141}
142
143static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
144 struct snd_ctl_elem_value *ucontrol)
145{
146 struct soc_mixer_control *mc =
147 (struct soc_mixer_control *)kcontrol->private_value;
148 struct tpa6130a2_data *data;
149 unsigned int reg = mc->reg;
150 unsigned int shift = mc->shift;
151 unsigned int mask = mc->max;
152 unsigned int invert = mc->invert;
153
154 BUG_ON(tpa6130a2_client == NULL);
155 data = i2c_get_clientdata(tpa6130a2_client);
156
157 mutex_lock(&data->mutex);
158
159 ucontrol->value.integer.value[0] =
160 (tpa6130a2_read(reg) >> shift) & mask;
161
162 if (invert)
163 ucontrol->value.integer.value[0] =
164 mask - ucontrol->value.integer.value[0];
165
166 mutex_unlock(&data->mutex);
167 return 0;
168}
169
170static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
171 struct snd_ctl_elem_value *ucontrol)
172{
173 struct soc_mixer_control *mc =
174 (struct soc_mixer_control *)kcontrol->private_value;
175 struct tpa6130a2_data *data;
176 unsigned int reg = mc->reg;
177 unsigned int shift = mc->shift;
178 unsigned int mask = mc->max;
179 unsigned int invert = mc->invert;
180 unsigned int val = (ucontrol->value.integer.value[0] & mask);
181 unsigned int val_reg;
182
183 BUG_ON(tpa6130a2_client == NULL);
184 data = i2c_get_clientdata(tpa6130a2_client);
185
186 if (invert)
187 val = mask - val;
188
189 mutex_lock(&data->mutex);
190
191 val_reg = tpa6130a2_read(reg);
192 if (((val_reg >> shift) & mask) == val) {
193 mutex_unlock(&data->mutex);
194 return 0;
195 }
196
197 val_reg &= ~(mask << shift);
198 val_reg |= val << shift;
199 tpa6130a2_i2c_write(reg, val_reg);
200
201 mutex_unlock(&data->mutex);
202
203 return 1;
204}
205
206/*
207 * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
208 * down in gain.
209 */
210static const unsigned int tpa6130_tlv[] = {
211 TLV_DB_RANGE_HEAD(10),
212 0, 1, TLV_DB_SCALE_ITEM(-5950, 600, 0),
213 2, 3, TLV_DB_SCALE_ITEM(-5000, 250, 0),
214 4, 5, TLV_DB_SCALE_ITEM(-4550, 160, 0),
215 6, 7, TLV_DB_SCALE_ITEM(-4140, 190, 0),
216 8, 9, TLV_DB_SCALE_ITEM(-3650, 120, 0),
217 10, 11, TLV_DB_SCALE_ITEM(-3330, 160, 0),
218 12, 13, TLV_DB_SCALE_ITEM(-3040, 180, 0),
219 14, 20, TLV_DB_SCALE_ITEM(-2710, 110, 0),
220 21, 37, TLV_DB_SCALE_ITEM(-1960, 74, 0),
221 38, 63, TLV_DB_SCALE_ITEM(-720, 45, 0),
222};
223
224static const struct snd_kcontrol_new tpa6130a2_controls[] = {
225 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
226 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
227 tpa6130a2_get_reg, tpa6130a2_set_reg,
228 tpa6130_tlv),
229};
230
231/*
232 * Enable or disable channel (left or right)
233 * The bit number for mute and amplifier are the same per channel:
234 * bit 6: Right channel
235 * bit 7: Left channel
236 * in both registers.
237 */
238static void tpa6130a2_channel_enable(u8 channel, int enable)
239{
240 struct tpa6130a2_data *data;
241 u8 val;
242
243 BUG_ON(tpa6130a2_client == NULL);
244 data = i2c_get_clientdata(tpa6130a2_client);
245
246 if (enable) {
247 /* Enable channel */
248 /* Enable amplifier */
249 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
250 val |= channel;
251 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
252
253 /* Unmute channel */
254 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
255 val &= ~channel;
256 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
257 } else {
258 /* Disable channel */
259 /* Mute channel */
260 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
261 val |= channel;
262 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
263
264 /* Disable amplifier */
265 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
266 val &= ~channel;
267 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
268 }
269}
270
271static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w,
272 struct snd_kcontrol *kcontrol, int event)
273{
274 switch (event) {
275 case SND_SOC_DAPM_POST_PMU:
276 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1);
277 break;
278 case SND_SOC_DAPM_POST_PMD:
279 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0);
280 break;
281 }
282 return 0;
283}
284
285static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
286 struct snd_kcontrol *kcontrol, int event)
287{
288 switch (event) {
289 case SND_SOC_DAPM_POST_PMU:
290 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1);
291 break;
292 case SND_SOC_DAPM_POST_PMD:
293 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0);
294 break;
295 }
296 return 0;
297}
298
299static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
300 struct snd_kcontrol *kcontrol, int event)
301{
302 switch (event) {
303 case SND_SOC_DAPM_POST_PMU:
304 tpa6130a2_power(1);
305 break;
306 case SND_SOC_DAPM_POST_PMD:
307 tpa6130a2_power(0);
308 break;
309 }
310 return 0;
311}
312
313static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
314 SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM,
315 0, 0, NULL, 0, tpa6130a2_left_event,
316 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
317 SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM,
318 0, 0, NULL, 0, tpa6130a2_right_event,
319 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
320 SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM,
321 0, 0, tpa6130a2_supply_event,
322 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
323 /* Outputs */
324 SND_SOC_DAPM_HP("TPA6130A2 Headphone Left", NULL),
325 SND_SOC_DAPM_HP("TPA6130A2 Headphone Right", NULL),
326};
327
328static const struct snd_soc_dapm_route audio_map[] = {
329 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"},
330 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"},
331
332 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"},
333 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"},
334};
335
336int tpa6130a2_add_controls(struct snd_soc_codec *codec)
337{
338 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
339 ARRAY_SIZE(tpa6130a2_dapm_widgets));
340
341 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
342
343 return snd_soc_add_controls(codec, tpa6130a2_controls,
344 ARRAY_SIZE(tpa6130a2_controls));
345
346}
347EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
348
349static int tpa6130a2_probe(struct i2c_client *client,
350 const struct i2c_device_id *id)
351{
352 struct device *dev;
353 struct tpa6130a2_data *data;
354 struct tpa6130a2_platform_data *pdata;
355 int ret;
356
357 dev = &client->dev;
358
359 if (client->dev.platform_data == NULL) {
360 dev_err(dev, "Platform data not set\n");
361 dump_stack();
362 return -ENODEV;
363 }
364
365 data = kzalloc(sizeof(*data), GFP_KERNEL);
366 if (data == NULL) {
367 dev_err(dev, "Can not allocate memory\n");
368 return -ENOMEM;
369 }
370
371 tpa6130a2_client = client;
372
373 i2c_set_clientdata(tpa6130a2_client, data);
374
375 pdata = client->dev.platform_data;
376 data->power_gpio = pdata->power_gpio;
377
378 mutex_init(&data->mutex);
379
380 /* Set default register values */
381 data->regs[TPA6130A2_REG_CONTROL] = TPA6130A2_SWS;
382 data->regs[TPA6130A2_REG_VOL_MUTE] = TPA6130A2_MUTE_R |
383 TPA6130A2_MUTE_L;
384
385 if (data->power_gpio >= 0) {
386 ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
387 if (ret < 0) {
388 dev_err(dev, "Failed to request power GPIO (%d)\n",
389 data->power_gpio);
390 goto fail;
391 }
392 gpio_direction_output(data->power_gpio, 0);
393 } else {
394 data->power_state = 1;
395 tpa6130a2_initialize();
396 }
397
398 tpa6130a2_power(1);
399
400 /* Read version */
401 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
402 TPA6130A2_VERSION_MASK;
403 if ((ret != 1) && (ret != 2))
404 dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
405
406 /* Disable the chip */
407 tpa6130a2_power(0);
408
409 return 0;
410fail:
411 kfree(data);
412 i2c_set_clientdata(tpa6130a2_client, NULL);
413 tpa6130a2_client = NULL;
414
415 return ret;
416}
417
418static int tpa6130a2_remove(struct i2c_client *client)
419{
420 struct tpa6130a2_data *data = i2c_get_clientdata(client);
421
422 tpa6130a2_power(0);
423
424 if (data->power_gpio >= 0)
425 gpio_free(data->power_gpio);
426 kfree(data);
427 tpa6130a2_client = NULL;
428
429 return 0;
430}
431
432static const struct i2c_device_id tpa6130a2_id[] = {
433 { "tpa6130a2", 0 },
434 { }
435};
436MODULE_DEVICE_TABLE(i2c, tpa6130a2_id);
437
438static struct i2c_driver tpa6130a2_i2c_driver = {
439 .driver = {
440 .name = "tpa6130a2",
441 .owner = THIS_MODULE,
442 },
443 .probe = tpa6130a2_probe,
444 .remove = __devexit_p(tpa6130a2_remove),
445 .id_table = tpa6130a2_id,
446};
447
448static int __init tpa6130a2_init(void)
449{
450 return i2c_add_driver(&tpa6130a2_i2c_driver);
451}
452
453static void __exit tpa6130a2_exit(void)
454{
455 i2c_del_driver(&tpa6130a2_i2c_driver);
456}
457
458MODULE_AUTHOR("Peter Ujfalusi");
459MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
460MODULE_LICENSE("GPL");
461
462module_init(tpa6130a2_init);
463module_exit(tpa6130a2_exit);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
new file mode 100644
index 000000000000..57e867fd86d1
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -0,0 +1,61 @@
1/*
2 * ALSA SoC TPA6130A2 amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TPA6130A2_H__
25#define __TPA6130A2_H__
26
27/* Register addresses */
28#define TPA6130A2_REG_CONTROL 0x01
29#define TPA6130A2_REG_VOL_MUTE 0x02
30#define TPA6130A2_REG_OUT_IMPEDANCE 0x03
31#define TPA6130A2_REG_VERSION 0x04
32
33#define TPA6130A2_CACHEREGNUM (TPA6130A2_REG_VERSION + 1)
34
35/* Register bits */
36/* TPA6130A2_REG_CONTROL (0x01) */
37#define TPA6130A2_SWS (0x01 << 0)
38#define TPA6130A2_TERMAL (0x01 << 1)
39#define TPA6130A2_MODE(x) (x << 4)
40#define TPA6130A2_MODE_STEREO (0x00)
41#define TPA6130A2_MODE_DUAL_MONO (0x01)
42#define TPA6130A2_MODE_BRIDGE (0x02)
43#define TPA6130A2_MODE_MASK (0x03)
44#define TPA6130A2_HP_EN_R (0x01 << 6)
45#define TPA6130A2_HP_EN_L (0x01 << 7)
46
47/* TPA6130A2_REG_VOL_MUTE (0x02) */
48#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
49#define TPA6130A2_MUTE_R (0x01 << 6)
50#define TPA6130A2_MUTE_L (0x01 << 7)
51
52/* TPA6130A2_REG_OUT_IMPEDANCE (0x03) */
53#define TPA6130A2_HIZ_R (0x01 << 0)
54#define TPA6130A2_HIZ_L (0x01 << 1)
55
56/* TPA6130A2_REG_VERSION (0x04) */
57#define TPA6130A2_VERSION_MASK (0x0f)
58
59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
60
61#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 4df7c6c61c76..928257b25111 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -120,9 +120,10 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
120 120
121/* codec private data */ 121/* codec private data */
122struct twl4030_priv { 122struct twl4030_priv {
123 unsigned int bypass_state; 123 struct snd_soc_codec codec;
124
124 unsigned int codec_powered; 125 unsigned int codec_powered;
125 unsigned int codec_muted; 126 unsigned int apll_enabled;
126 127
127 struct snd_pcm_substream *master_substream; 128 struct snd_pcm_substream *master_substream;
128 struct snd_pcm_substream *slave_substream; 129 struct snd_pcm_substream *slave_substream;
@@ -183,19 +184,20 @@ static int twl4030_write(struct snd_soc_codec *codec,
183static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 184static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
184{ 185{
185 struct twl4030_priv *twl4030 = codec->private_data; 186 struct twl4030_priv *twl4030 = codec->private_data;
186 u8 mode; 187 int mode;
187 188
188 if (enable == twl4030->codec_powered) 189 if (enable == twl4030->codec_powered)
189 return; 190 return;
190 191
191 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
192 if (enable) 192 if (enable)
193 mode |= TWL4030_CODECPDZ; 193 mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
194 else 194 else
195 mode &= ~TWL4030_CODECPDZ; 195 mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
196 196
197 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); 197 if (mode >= 0) {
198 twl4030->codec_powered = enable; 198 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
199 twl4030->codec_powered = enable;
200 }
199 201
200 /* REVISIT: this delay is present in TI sample drivers */ 202 /* REVISIT: this delay is present in TI sample drivers */
201 /* but there seems to be no TRM requirement for it */ 203 /* but there seems to be no TRM requirement for it */
@@ -216,27 +218,25 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
216 218
217} 219}
218 220
219static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) 221static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
220{ 222{
221 struct twl4030_priv *twl4030 = codec->private_data; 223 struct twl4030_priv *twl4030 = codec->private_data;
222 u8 reg_val; 224 int status;
223 225
224 if (mute == twl4030->codec_muted) 226 if (enable == twl4030->apll_enabled)
225 return; 227 return;
226 228
227 if (mute) { 229 if (enable)
228 /* Disable PLL */
229 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
230 reg_val &= ~TWL4030_APLL_EN;
231 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
232 } else {
233 /* Enable PLL */ 230 /* Enable PLL */
234 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 231 status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
235 reg_val |= TWL4030_APLL_EN; 232 else
236 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); 233 /* Disable PLL */
237 } 234 status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
238 235
239 twl4030->codec_muted = mute; 236 if (status >= 0)
237 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
238
239 twl4030->apll_enabled = enable;
240} 240}
241 241
242static void twl4030_power_up(struct snd_soc_codec *codec) 242static void twl4030_power_up(struct snd_soc_codec *codec)
@@ -613,6 +613,27 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
613 return 0; 613 return 0;
614} 614}
615 615
616static int vibramux_event(struct snd_soc_dapm_widget *w,
617 struct snd_kcontrol *kcontrol, int event)
618{
619 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
620 return 0;
621}
622
623static int apll_event(struct snd_soc_dapm_widget *w,
624 struct snd_kcontrol *kcontrol, int event)
625{
626 switch (event) {
627 case SND_SOC_DAPM_PRE_PMU:
628 twl4030_apll_enable(w->codec, 1);
629 break;
630 case SND_SOC_DAPM_POST_PMD:
631 twl4030_apll_enable(w->codec, 0);
632 break;
633 }
634 return 0;
635}
636
616static void headset_ramp(struct snd_soc_codec *codec, int ramp) 637static void headset_ramp(struct snd_soc_codec *codec, int ramp)
617{ 638{
618 struct snd_soc_device *socdev = codec->socdev; 639 struct snd_soc_device *socdev = codec->socdev;
@@ -724,67 +745,6 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
724 return 0; 745 return 0;
725} 746}
726 747
727static int bypass_event(struct snd_soc_dapm_widget *w,
728 struct snd_kcontrol *kcontrol, int event)
729{
730 struct soc_mixer_control *m =
731 (struct soc_mixer_control *)w->kcontrols->private_value;
732 struct twl4030_priv *twl4030 = w->codec->private_data;
733 unsigned char reg, misc;
734
735 reg = twl4030_read_reg_cache(w->codec, m->reg);
736
737 /*
738 * bypass_state[0:3] - analog HiFi bypass
739 * bypass_state[4] - analog voice bypass
740 * bypass_state[5] - digital voice bypass
741 * bypass_state[6:7] - digital HiFi bypass
742 */
743 if (m->reg == TWL4030_REG_VSTPGA) {
744 /* Voice digital bypass */
745 if (reg)
746 twl4030->bypass_state |= (1 << 5);
747 else
748 twl4030->bypass_state &= ~(1 << 5);
749 } else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
750 /* Analog bypass */
751 if (reg & (1 << m->shift))
752 twl4030->bypass_state |=
753 (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
754 else
755 twl4030->bypass_state &=
756 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
757 } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
758 /* Analog voice bypass */
759 if (reg & (1 << m->shift))
760 twl4030->bypass_state |= (1 << 4);
761 else
762 twl4030->bypass_state &= ~(1 << 4);
763 } else {
764 /* Digital bypass */
765 if (reg & (0x7 << m->shift))
766 twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
767 else
768 twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
769 }
770
771 /* Enable master analog loopback mode if any analog switch is enabled*/
772 misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
773 if (twl4030->bypass_state & 0x1F)
774 misc |= TWL4030_FMLOOP_EN;
775 else
776 misc &= ~TWL4030_FMLOOP_EN;
777 twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
778
779 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
780 if (twl4030->bypass_state)
781 twl4030_codec_mute(w->codec, 0);
782 else
783 twl4030_codec_mute(w->codec, 1);
784 }
785 return 0;
786}
787
788/* 748/*
789 * Some of the gain controls in TWL (mostly those which are associated with 749 * Some of the gain controls in TWL (mostly those which are associated with
790 * the outputs) are implemented in an interesting way: 750 * the outputs) are implemented in an interesting way:
@@ -1192,32 +1152,28 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1192 SND_SOC_NOPM, 0, 0), 1152 SND_SOC_NOPM, 0, 0),
1193 1153
1194 /* Analog bypasses */ 1154 /* Analog bypasses */
1195 SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1155 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1196 &twl4030_dapm_abypassr1_control, bypass_event, 1156 &twl4030_dapm_abypassr1_control),
1197 SND_SOC_DAPM_POST_REG), 1157 SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1198 SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1158 &twl4030_dapm_abypassl1_control),
1199 &twl4030_dapm_abypassl1_control, 1159 SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1200 bypass_event, SND_SOC_DAPM_POST_REG), 1160 &twl4030_dapm_abypassr2_control),
1201 SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1161 SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1202 &twl4030_dapm_abypassr2_control, 1162 &twl4030_dapm_abypassl2_control),
1203 bypass_event, SND_SOC_DAPM_POST_REG), 1163 SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1204 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1164 &twl4030_dapm_abypassv_control),
1205 &twl4030_dapm_abypassl2_control, 1165
1206 bypass_event, SND_SOC_DAPM_POST_REG), 1166 /* Master analog loopback switch */
1207 SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0, 1167 SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
1208 &twl4030_dapm_abypassv_control, 1168 NULL, 0),
1209 bypass_event, SND_SOC_DAPM_POST_REG),
1210 1169
1211 /* Digital bypasses */ 1170 /* Digital bypasses */
1212 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, 1171 SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
1213 &twl4030_dapm_dbypassl_control, bypass_event, 1172 &twl4030_dapm_dbypassl_control),
1214 SND_SOC_DAPM_POST_REG), 1173 SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
1215 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, 1174 &twl4030_dapm_dbypassr_control),
1216 &twl4030_dapm_dbypassr_control, bypass_event, 1175 SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1217 SND_SOC_DAPM_POST_REG), 1176 &twl4030_dapm_dbypassv_control),
1218 SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1219 &twl4030_dapm_dbypassv_control, bypass_event,
1220 SND_SOC_DAPM_POST_REG),
1221 1177
1222 /* Digital mixers, power control for the physical DACs */ 1178 /* Digital mixers, power control for the physical DACs */
1223 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer", 1179 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
@@ -1243,6 +1199,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1243 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", 1199 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
1244 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0), 1200 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
1245 1201
1202 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1203 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1204
1246 /* Output MIXER controls */ 1205 /* Output MIXER controls */
1247 /* Earpiece */ 1206 /* Earpiece */
1248 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1207 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
@@ -1308,8 +1267,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1308 0, 0, NULL, 0, handsfreerpga_event, 1267 0, 0, NULL, 0, handsfreerpga_event,
1309 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1268 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1310 /* Vibra */ 1269 /* Vibra */
1311 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, 1270 SND_SOC_DAPM_MUX_E("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1312 &twl4030_dapm_vibra_control), 1271 &twl4030_dapm_vibra_control, vibramux_event,
1272 SND_SOC_DAPM_PRE_PMU),
1313 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0, 1273 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
1314 &twl4030_dapm_vibrapath_control), 1274 &twl4030_dapm_vibrapath_control),
1315 1275
@@ -1369,6 +1329,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1369 {"Digital R2 Playback Mixer", NULL, "DAC Right2"}, 1329 {"Digital R2 Playback Mixer", NULL, "DAC Right2"},
1370 {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, 1330 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1371 1331
1332 /* Supply for the digital part (APLL) */
1333 {"Digital R1 Playback Mixer", NULL, "APLL Enable"},
1334 {"Digital L1 Playback Mixer", NULL, "APLL Enable"},
1335 {"Digital R2 Playback Mixer", NULL, "APLL Enable"},
1336 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1337 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1338
1372 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, 1339 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1373 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, 1340 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1374 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, 1341 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
@@ -1482,6 +1449,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1482 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1449 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1483 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1450 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1484 1451
1452 {"ADC Virtual Left1", NULL, "APLL Enable"},
1453 {"ADC Virtual Right1", NULL, "APLL Enable"},
1454 {"ADC Virtual Left2", NULL, "APLL Enable"},
1455 {"ADC Virtual Right2", NULL, "APLL Enable"},
1456
1485 /* Analog bypass routes */ 1457 /* Analog bypass routes */
1486 {"Right1 Analog Loopback", "Switch", "Analog Right"}, 1458 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1487 {"Left1 Analog Loopback", "Switch", "Analog Left"}, 1459 {"Left1 Analog Loopback", "Switch", "Analog Left"},
@@ -1489,6 +1461,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1489 {"Left2 Analog Loopback", "Switch", "Analog Left"}, 1461 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1490 {"Voice Analog Loopback", "Switch", "Analog Left"}, 1462 {"Voice Analog Loopback", "Switch", "Analog Left"},
1491 1463
1464 /* Supply for the Analog loopbacks */
1465 {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
1466 {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
1467 {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
1468 {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
1469 {"Voice Analog Loopback", NULL, "FM Loop Enable"},
1470
1492 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1471 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1493 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1472 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1494 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, 1473 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
@@ -1520,25 +1499,14 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec)
1520static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1499static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1521 enum snd_soc_bias_level level) 1500 enum snd_soc_bias_level level)
1522{ 1501{
1523 struct twl4030_priv *twl4030 = codec->private_data;
1524
1525 switch (level) { 1502 switch (level) {
1526 case SND_SOC_BIAS_ON: 1503 case SND_SOC_BIAS_ON:
1527 twl4030_codec_mute(codec, 0);
1528 break; 1504 break;
1529 case SND_SOC_BIAS_PREPARE: 1505 case SND_SOC_BIAS_PREPARE:
1530 twl4030_power_up(codec);
1531 if (twl4030->bypass_state)
1532 twl4030_codec_mute(codec, 0);
1533 else
1534 twl4030_codec_mute(codec, 1);
1535 break; 1506 break;
1536 case SND_SOC_BIAS_STANDBY: 1507 case SND_SOC_BIAS_STANDBY:
1537 twl4030_power_up(codec); 1508 if (codec->bias_level == SND_SOC_BIAS_OFF)
1538 if (twl4030->bypass_state) 1509 twl4030_power_up(codec);
1539 twl4030_codec_mute(codec, 0);
1540 else
1541 twl4030_codec_mute(codec, 1);
1542 break; 1510 break;
1543 case SND_SOC_BIAS_OFF: 1511 case SND_SOC_BIAS_OFF:
1544 twl4030_power_down(codec); 1512 twl4030_power_down(codec);
@@ -1785,19 +1753,21 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1785{ 1753{
1786 struct snd_soc_codec *codec = codec_dai->codec; 1754 struct snd_soc_codec *codec = codec_dai->codec;
1787 struct twl4030_priv *twl4030 = codec->private_data; 1755 struct twl4030_priv *twl4030 = codec->private_data;
1788 u8 infreq; 1756 u8 apll_ctrl;
1789 1757
1758 apll_ctrl = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
1759 apll_ctrl &= ~TWL4030_APLL_INFREQ;
1790 switch (freq) { 1760 switch (freq) {
1791 case 19200000: 1761 case 19200000:
1792 infreq = TWL4030_APLL_INFREQ_19200KHZ; 1762 apll_ctrl |= TWL4030_APLL_INFREQ_19200KHZ;
1793 twl4030->sysclk = 19200; 1763 twl4030->sysclk = 19200;
1794 break; 1764 break;
1795 case 26000000: 1765 case 26000000:
1796 infreq = TWL4030_APLL_INFREQ_26000KHZ; 1766 apll_ctrl |= TWL4030_APLL_INFREQ_26000KHZ;
1797 twl4030->sysclk = 26000; 1767 twl4030->sysclk = 26000;
1798 break; 1768 break;
1799 case 38400000: 1769 case 38400000:
1800 infreq = TWL4030_APLL_INFREQ_38400KHZ; 1770 apll_ctrl |= TWL4030_APLL_INFREQ_38400KHZ;
1801 twl4030->sysclk = 38400; 1771 twl4030->sysclk = 38400;
1802 break; 1772 break;
1803 default: 1773 default:
@@ -1806,8 +1776,7 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1806 return -EINVAL; 1776 return -EINVAL;
1807 } 1777 }
1808 1778
1809 infreq |= TWL4030_APLL_EN; 1779 twl4030_write(codec, TWL4030_REG_APLL_CTL, apll_ctrl);
1810 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
1811 1780
1812 return 0; 1781 return 0;
1813} 1782}
@@ -1989,11 +1958,13 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1989 int clk_id, unsigned int freq, int dir) 1958 int clk_id, unsigned int freq, int dir)
1990{ 1959{
1991 struct snd_soc_codec *codec = codec_dai->codec; 1960 struct snd_soc_codec *codec = codec_dai->codec;
1992 u8 infreq; 1961 u8 apll_ctrl;
1993 1962
1963 apll_ctrl = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
1964 apll_ctrl &= ~TWL4030_APLL_INFREQ;
1994 switch (freq) { 1965 switch (freq) {
1995 case 26000000: 1966 case 26000000:
1996 infreq = TWL4030_APLL_INFREQ_26000KHZ; 1967 apll_ctrl |= TWL4030_APLL_INFREQ_26000KHZ;
1997 break; 1968 break;
1998 default: 1969 default:
1999 printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n", 1970 printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n",
@@ -2001,8 +1972,7 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
2001 return -EINVAL; 1972 return -EINVAL;
2002 } 1973 }
2003 1974
2004 infreq |= TWL4030_APLL_EN; 1975 twl4030_write(codec, TWL4030_REG_APLL_CTL, apll_ctrl);
2005 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
2006 1976
2007 return 0; 1977 return 0;
2008} 1978}
@@ -2121,7 +2091,7 @@ struct snd_soc_dai twl4030_dai[] = {
2121}; 2091};
2122EXPORT_SYMBOL_GPL(twl4030_dai); 2092EXPORT_SYMBOL_GPL(twl4030_dai);
2123 2093
2124static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) 2094static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state)
2125{ 2095{
2126 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2096 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2127 struct snd_soc_codec *codec = socdev->card->codec; 2097 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2131,7 +2101,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
2131 return 0; 2101 return 0;
2132} 2102}
2133 2103
2134static int twl4030_resume(struct platform_device *pdev) 2104static int twl4030_soc_resume(struct platform_device *pdev)
2135{ 2105{
2136 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2106 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2137 struct snd_soc_codec *codec = socdev->card->codec; 2107 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2141,32 +2111,21 @@ static int twl4030_resume(struct platform_device *pdev)
2141 return 0; 2111 return 0;
2142} 2112}
2143 2113
2144/* 2114static struct snd_soc_codec *twl4030_codec;
2145 * initialize the driver
2146 * register the mixer and dsp interfaces with the kernel
2147 */
2148 2115
2149static int twl4030_init(struct snd_soc_device *socdev) 2116static int twl4030_soc_probe(struct platform_device *pdev)
2150{ 2117{
2151 struct snd_soc_codec *codec = socdev->card->codec; 2118 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2152 struct twl4030_setup_data *setup = socdev->codec_data; 2119 struct twl4030_setup_data *setup = socdev->codec_data;
2153 struct twl4030_priv *twl4030 = codec->private_data; 2120 struct snd_soc_codec *codec;
2154 int ret = 0; 2121 struct twl4030_priv *twl4030;
2122 int ret;
2155 2123
2156 printk(KERN_INFO "TWL4030 Audio Codec init \n"); 2124 BUG_ON(!twl4030_codec);
2157 2125
2158 codec->name = "twl4030"; 2126 codec = twl4030_codec;
2159 codec->owner = THIS_MODULE; 2127 twl4030 = codec->private_data;
2160 codec->read = twl4030_read_reg_cache; 2128 socdev->card->codec = codec;
2161 codec->write = twl4030_write;
2162 codec->set_bias_level = twl4030_set_bias_level;
2163 codec->dai = twl4030_dai;
2164 codec->num_dai = ARRAY_SIZE(twl4030_dai),
2165 codec->reg_cache_size = sizeof(twl4030_reg);
2166 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2167 GFP_KERNEL);
2168 if (codec->reg_cache == NULL)
2169 return -ENOMEM;
2170 2129
2171 /* Configuration for headset ramp delay from setup data */ 2130 /* Configuration for headset ramp delay from setup data */
2172 if (setup) { 2131 if (setup) {
@@ -2188,100 +2147,148 @@ static int twl4030_init(struct snd_soc_device *socdev)
2188 /* register pcms */ 2147 /* register pcms */
2189 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2148 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2190 if (ret < 0) { 2149 if (ret < 0) {
2191 printk(KERN_ERR "twl4030: failed to create pcms\n"); 2150 dev_err(&pdev->dev, "failed to create pcms\n");
2192 goto pcm_err; 2151 return ret;
2193 } 2152 }
2194 2153
2195 twl4030_init_chip(codec);
2196
2197 /* power on device */
2198 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2199
2200 snd_soc_add_controls(codec, twl4030_snd_controls, 2154 snd_soc_add_controls(codec, twl4030_snd_controls,
2201 ARRAY_SIZE(twl4030_snd_controls)); 2155 ARRAY_SIZE(twl4030_snd_controls));
2202 twl4030_add_widgets(codec); 2156 twl4030_add_widgets(codec);
2203 2157
2204 ret = snd_soc_init_card(socdev); 2158 return 0;
2205 if (ret < 0) { 2159}
2206 printk(KERN_ERR "twl4030: failed to register card\n");
2207 goto card_err;
2208 }
2209 2160
2210 return ret; 2161static int twl4030_soc_remove(struct platform_device *pdev)
2162{
2163 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2164 struct snd_soc_codec *codec = socdev->card->codec;
2211 2165
2212card_err: 2166 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2213 snd_soc_free_pcms(socdev); 2167 snd_soc_free_pcms(socdev);
2214 snd_soc_dapm_free(socdev); 2168 snd_soc_dapm_free(socdev);
2215pcm_err: 2169 kfree(codec->private_data);
2216 kfree(codec->reg_cache); 2170 kfree(codec);
2217 return ret;
2218}
2219 2171
2220static struct snd_soc_device *twl4030_socdev; 2172 return 0;
2173}
2221 2174
2222static int twl4030_probe(struct platform_device *pdev) 2175static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2223{ 2176{
2224 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2177 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
2225 struct snd_soc_codec *codec; 2178 struct snd_soc_codec *codec;
2226 struct twl4030_priv *twl4030; 2179 struct twl4030_priv *twl4030;
2180 int ret;
2227 2181
2228 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 2182 if (!pdata || !(pdata->audio_mclk == 19200000 ||
2229 if (codec == NULL) 2183 pdata->audio_mclk == 26000000 ||
2230 return -ENOMEM; 2184 pdata->audio_mclk == 38400000)) {
2185 dev_err(&pdev->dev, "Invalid platform_data\n");
2186 return -EINVAL;
2187 }
2231 2188
2232 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2189 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2233 if (twl4030 == NULL) { 2190 if (twl4030 == NULL) {
2234 kfree(codec); 2191 dev_err(&pdev->dev, "Can not allocate memroy\n");
2235 return -ENOMEM; 2192 return -ENOMEM;
2236 } 2193 }
2237 2194
2195 codec = &twl4030->codec;
2238 codec->private_data = twl4030; 2196 codec->private_data = twl4030;
2239 socdev->card->codec = codec; 2197 codec->dev = &pdev->dev;
2198 twl4030_dai[0].dev = &pdev->dev;
2199 twl4030_dai[1].dev = &pdev->dev;
2200
2240 mutex_init(&codec->mutex); 2201 mutex_init(&codec->mutex);
2241 INIT_LIST_HEAD(&codec->dapm_widgets); 2202 INIT_LIST_HEAD(&codec->dapm_widgets);
2242 INIT_LIST_HEAD(&codec->dapm_paths); 2203 INIT_LIST_HEAD(&codec->dapm_paths);
2243 2204
2244 twl4030_socdev = socdev; 2205 codec->name = "twl4030";
2245 twl4030_init(socdev); 2206 codec->owner = THIS_MODULE;
2207 codec->read = twl4030_read_reg_cache;
2208 codec->write = twl4030_write;
2209 codec->set_bias_level = twl4030_set_bias_level;
2210 codec->dai = twl4030_dai;
2211 codec->num_dai = ARRAY_SIZE(twl4030_dai),
2212 codec->reg_cache_size = sizeof(twl4030_reg);
2213 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2214 GFP_KERNEL);
2215 if (codec->reg_cache == NULL) {
2216 ret = -ENOMEM;
2217 goto error_cache;
2218 }
2219
2220 platform_set_drvdata(pdev, twl4030);
2221 twl4030_codec = codec;
2222
2223 /* Set the defaults, and power up the codec */
2224 twl4030_init_chip(codec);
2225 codec->bias_level = SND_SOC_BIAS_OFF;
2226 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2227
2228 ret = snd_soc_register_codec(codec);
2229 if (ret != 0) {
2230 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2231 goto error_codec;
2232 }
2233
2234 ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2235 if (ret != 0) {
2236 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
2237 snd_soc_unregister_codec(codec);
2238 goto error_codec;
2239 }
2246 2240
2247 return 0; 2241 return 0;
2242
2243error_codec:
2244 twl4030_power_down(codec);
2245 kfree(codec->reg_cache);
2246error_cache:
2247 kfree(twl4030);
2248 return ret;
2248} 2249}
2249 2250
2250static int twl4030_remove(struct platform_device *pdev) 2251static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2251{ 2252{
2252 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2253 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
2253 struct snd_soc_codec *codec = socdev->card->codec;
2254 2254
2255 printk(KERN_INFO "TWL4030 Audio Codec remove\n"); 2255 kfree(twl4030);
2256 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2257 snd_soc_free_pcms(socdev);
2258 snd_soc_dapm_free(socdev);
2259 kfree(codec->private_data);
2260 kfree(codec);
2261 2256
2257 twl4030_codec = NULL;
2262 return 0; 2258 return 0;
2263} 2259}
2264 2260
2265struct snd_soc_codec_device soc_codec_dev_twl4030 = { 2261MODULE_ALIAS("platform:twl4030_codec_audio");
2266 .probe = twl4030_probe, 2262
2267 .remove = twl4030_remove, 2263static struct platform_driver twl4030_codec_driver = {
2268 .suspend = twl4030_suspend, 2264 .probe = twl4030_codec_probe,
2269 .resume = twl4030_resume, 2265 .remove = __devexit_p(twl4030_codec_remove),
2266 .driver = {
2267 .name = "twl4030_codec_audio",
2268 .owner = THIS_MODULE,
2269 },
2270}; 2270};
2271EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2272 2271
2273static int __init twl4030_modinit(void) 2272static int __init twl4030_modinit(void)
2274{ 2273{
2275 return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2274 return platform_driver_register(&twl4030_codec_driver);
2276} 2275}
2277module_init(twl4030_modinit); 2276module_init(twl4030_modinit);
2278 2277
2279static void __exit twl4030_exit(void) 2278static void __exit twl4030_exit(void)
2280{ 2279{
2281 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2280 platform_driver_unregister(&twl4030_codec_driver);
2282} 2281}
2283module_exit(twl4030_exit); 2282module_exit(twl4030_exit);
2284 2283
2284struct snd_soc_codec_device soc_codec_dev_twl4030 = {
2285 .probe = twl4030_soc_probe,
2286 .remove = twl4030_soc_remove,
2287 .suspend = twl4030_soc_suspend,
2288 .resume = twl4030_soc_resume,
2289};
2290EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2291
2285MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); 2292MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2286MODULE_AUTHOR("Steve Sakoman"); 2293MODULE_AUTHOR("Steve Sakoman");
2287MODULE_LICENSE("GPL"); 2294MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 2b4bfa23f985..dd6396ec9c79 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -22,245 +22,13 @@
22#ifndef __TWL4030_AUDIO_H__ 22#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__ 23#define __TWL4030_AUDIO_H__
24 24
25#define TWL4030_REG_CODEC_MODE 0x1 25/* Register descriptions are here */
26#define TWL4030_REG_OPTION 0x2 26#include <linux/mfd/twl4030-codec.h>
27#define TWL4030_REG_UNKNOWN 0x3
28#define TWL4030_REG_MICBIAS_CTL 0x4
29#define TWL4030_REG_ANAMICL 0x5
30#define TWL4030_REG_ANAMICR 0x6
31#define TWL4030_REG_AVADC_CTL 0x7
32#define TWL4030_REG_ADCMICSEL 0x8
33#define TWL4030_REG_DIGMIXING 0x9
34#define TWL4030_REG_ATXL1PGA 0xA
35#define TWL4030_REG_ATXR1PGA 0xB
36#define TWL4030_REG_AVTXL2PGA 0xC
37#define TWL4030_REG_AVTXR2PGA 0xD
38#define TWL4030_REG_AUDIO_IF 0xE
39#define TWL4030_REG_VOICE_IF 0xF
40#define TWL4030_REG_ARXR1PGA 0x10
41#define TWL4030_REG_ARXL1PGA 0x11
42#define TWL4030_REG_ARXR2PGA 0x12
43#define TWL4030_REG_ARXL2PGA 0x13
44#define TWL4030_REG_VRXPGA 0x14
45#define TWL4030_REG_VSTPGA 0x15
46#define TWL4030_REG_VRX2ARXPGA 0x16
47#define TWL4030_REG_AVDAC_CTL 0x17
48#define TWL4030_REG_ARX2VTXPGA 0x18
49#define TWL4030_REG_ARXL1_APGA_CTL 0x19
50#define TWL4030_REG_ARXR1_APGA_CTL 0x1A
51#define TWL4030_REG_ARXL2_APGA_CTL 0x1B
52#define TWL4030_REG_ARXR2_APGA_CTL 0x1C
53#define TWL4030_REG_ATX2ARXPGA 0x1D
54#define TWL4030_REG_BT_IF 0x1E
55#define TWL4030_REG_BTPGA 0x1F
56#define TWL4030_REG_BTSTPGA 0x20
57#define TWL4030_REG_EAR_CTL 0x21
58#define TWL4030_REG_HS_SEL 0x22
59#define TWL4030_REG_HS_GAIN_SET 0x23
60#define TWL4030_REG_HS_POPN_SET 0x24
61#define TWL4030_REG_PREDL_CTL 0x25
62#define TWL4030_REG_PREDR_CTL 0x26
63#define TWL4030_REG_PRECKL_CTL 0x27
64#define TWL4030_REG_PRECKR_CTL 0x28
65#define TWL4030_REG_HFL_CTL 0x29
66#define TWL4030_REG_HFR_CTL 0x2A
67#define TWL4030_REG_ALC_CTL 0x2B
68#define TWL4030_REG_ALC_SET1 0x2C
69#define TWL4030_REG_ALC_SET2 0x2D
70#define TWL4030_REG_BOOST_CTL 0x2E
71#define TWL4030_REG_SOFTVOL_CTL 0x2F
72#define TWL4030_REG_DTMF_FREQSEL 0x30
73#define TWL4030_REG_DTMF_TONEXT1H 0x31
74#define TWL4030_REG_DTMF_TONEXT1L 0x32
75#define TWL4030_REG_DTMF_TONEXT2H 0x33
76#define TWL4030_REG_DTMF_TONEXT2L 0x34
77#define TWL4030_REG_DTMF_TONOFF 0x35
78#define TWL4030_REG_DTMF_WANONOFF 0x36
79#define TWL4030_REG_I2S_RX_SCRAMBLE_H 0x37
80#define TWL4030_REG_I2S_RX_SCRAMBLE_M 0x38
81#define TWL4030_REG_I2S_RX_SCRAMBLE_L 0x39
82#define TWL4030_REG_APLL_CTL 0x3A
83#define TWL4030_REG_DTMF_CTL 0x3B
84#define TWL4030_REG_DTMF_PGA_CTL2 0x3C
85#define TWL4030_REG_DTMF_PGA_CTL1 0x3D
86#define TWL4030_REG_MISC_SET_1 0x3E
87#define TWL4030_REG_PCMBTMUX 0x3F
88#define TWL4030_REG_RX_PATH_SEL 0x43
89#define TWL4030_REG_VDL_APGA_CTL 0x44
90#define TWL4030_REG_VIBRA_CTL 0x45
91#define TWL4030_REG_VIBRA_SET 0x46
92#define TWL4030_REG_VIBRA_PWM_SET 0x47
93#define TWL4030_REG_ANAMIC_GAIN 0x48
94#define TWL4030_REG_MISC_SET_2 0x49
95#define TWL4030_REG_SW_SHADOW 0x4A
96 27
28/* Sgadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A
97#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
98 31
99/* Bitfield Definitions */
100
101/* TWL4030_CODEC_MODE (0x01) Fields */
102
103#define TWL4030_APLL_RATE 0xF0
104#define TWL4030_APLL_RATE_8000 0x00
105#define TWL4030_APLL_RATE_11025 0x10
106#define TWL4030_APLL_RATE_12000 0x20
107#define TWL4030_APLL_RATE_16000 0x40
108#define TWL4030_APLL_RATE_22050 0x50
109#define TWL4030_APLL_RATE_24000 0x60
110#define TWL4030_APLL_RATE_32000 0x80
111#define TWL4030_APLL_RATE_44100 0x90
112#define TWL4030_APLL_RATE_48000 0xA0
113#define TWL4030_APLL_RATE_96000 0xE0
114#define TWL4030_SEL_16K 0x08
115#define TWL4030_CODECPDZ 0x02
116#define TWL4030_OPT_MODE 0x01
117#define TWL4030_OPTION_1 (1 << 0)
118#define TWL4030_OPTION_2 (0 << 0)
119
120/* TWL4030_OPTION (0x02) Fields */
121
122#define TWL4030_ATXL1_EN (1 << 0)
123#define TWL4030_ATXR1_EN (1 << 1)
124#define TWL4030_ATXL2_VTXL_EN (1 << 2)
125#define TWL4030_ATXR2_VTXR_EN (1 << 3)
126#define TWL4030_ARXL1_VRX_EN (1 << 4)
127#define TWL4030_ARXR1_EN (1 << 5)
128#define TWL4030_ARXL2_EN (1 << 6)
129#define TWL4030_ARXR2_EN (1 << 7)
130
131/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
132
133#define TWL4030_MICBIAS2_CTL 0x40
134#define TWL4030_MICBIAS1_CTL 0x20
135#define TWL4030_HSMICBIAS_EN 0x04
136#define TWL4030_MICBIAS2_EN 0x02
137#define TWL4030_MICBIAS1_EN 0x01
138
139/* ANAMICL (0x05) Fields */
140
141#define TWL4030_CNCL_OFFSET_START 0x80
142#define TWL4030_OFFSET_CNCL_SEL 0x60
143#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
144#define TWL4030_OFFSET_CNCL_SEL_ARX2 0x20
145#define TWL4030_OFFSET_CNCL_SEL_VRX 0x40
146#define TWL4030_OFFSET_CNCL_SEL_ALL 0x60
147#define TWL4030_MICAMPL_EN 0x10
148#define TWL4030_CKMIC_EN 0x08
149#define TWL4030_AUXL_EN 0x04
150#define TWL4030_HSMIC_EN 0x02
151#define TWL4030_MAINMIC_EN 0x01
152
153/* ANAMICR (0x06) Fields */
154
155#define TWL4030_MICAMPR_EN 0x10
156#define TWL4030_AUXR_EN 0x04
157#define TWL4030_SUBMIC_EN 0x01
158
159/* AVADC_CTL (0x07) Fields */
160
161#define TWL4030_ADCL_EN 0x08
162#define TWL4030_AVADC_CLK_PRIORITY 0x04
163#define TWL4030_ADCR_EN 0x02
164
165/* TWL4030_REG_ADCMICSEL (0x08) Fields */
166
167#define TWL4030_DIGMIC1_EN 0x08
168#define TWL4030_TX2IN_SEL 0x04
169#define TWL4030_DIGMIC0_EN 0x02
170#define TWL4030_TX1IN_SEL 0x01
171
172/* AUDIO_IF (0x0E) Fields */
173
174#define TWL4030_AIF_SLAVE_EN 0x80
175#define TWL4030_DATA_WIDTH 0x60
176#define TWL4030_DATA_WIDTH_16S_16W 0x00
177#define TWL4030_DATA_WIDTH_32S_16W 0x40
178#define TWL4030_DATA_WIDTH_32S_24W 0x60
179#define TWL4030_AIF_FORMAT 0x18
180#define TWL4030_AIF_FORMAT_CODEC 0x00
181#define TWL4030_AIF_FORMAT_LEFT 0x08
182#define TWL4030_AIF_FORMAT_RIGHT 0x10
183#define TWL4030_AIF_FORMAT_TDM 0x18
184#define TWL4030_AIF_TRI_EN 0x04
185#define TWL4030_CLK256FS_EN 0x02
186#define TWL4030_AIF_EN 0x01
187
188/* VOICE_IF (0x0F) Fields */
189
190#define TWL4030_VIF_SLAVE_EN 0x80
191#define TWL4030_VIF_DIN_EN 0x40
192#define TWL4030_VIF_DOUT_EN 0x20
193#define TWL4030_VIF_SWAP 0x10
194#define TWL4030_VIF_FORMAT 0x08
195#define TWL4030_VIF_TRI_EN 0x04
196#define TWL4030_VIF_SUB_EN 0x02
197#define TWL4030_VIF_EN 0x01
198
199/* EAR_CTL (0x21) */
200#define TWL4030_EAR_GAIN 0x30
201
202/* HS_GAIN_SET (0x23) Fields */
203
204#define TWL4030_HSR_GAIN 0x0C
205#define TWL4030_HSR_GAIN_PWR_DOWN 0x00
206#define TWL4030_HSR_GAIN_PLUS_6DB 0x04
207#define TWL4030_HSR_GAIN_0DB 0x08
208#define TWL4030_HSR_GAIN_MINUS_6DB 0x0C
209#define TWL4030_HSL_GAIN 0x03
210#define TWL4030_HSL_GAIN_PWR_DOWN 0x00
211#define TWL4030_HSL_GAIN_PLUS_6DB 0x01
212#define TWL4030_HSL_GAIN_0DB 0x02
213#define TWL4030_HSL_GAIN_MINUS_6DB 0x03
214
215/* HS_POPN_SET (0x24) Fields */
216
217#define TWL4030_VMID_EN 0x40
218#define TWL4030_EXTMUTE 0x20
219#define TWL4030_RAMP_DELAY 0x1C
220#define TWL4030_RAMP_DELAY_20MS 0x00
221#define TWL4030_RAMP_DELAY_40MS 0x04
222#define TWL4030_RAMP_DELAY_81MS 0x08
223#define TWL4030_RAMP_DELAY_161MS 0x0C
224#define TWL4030_RAMP_DELAY_323MS 0x10
225#define TWL4030_RAMP_DELAY_645MS 0x14
226#define TWL4030_RAMP_DELAY_1291MS 0x18
227#define TWL4030_RAMP_DELAY_2581MS 0x1C
228#define TWL4030_RAMP_EN 0x02
229
230/* PREDL_CTL (0x25) */
231#define TWL4030_PREDL_GAIN 0x30
232
233/* PREDR_CTL (0x26) */
234#define TWL4030_PREDR_GAIN 0x30
235
236/* PRECKL_CTL (0x27) */
237#define TWL4030_PRECKL_GAIN 0x30
238
239/* PRECKR_CTL (0x28) */
240#define TWL4030_PRECKR_GAIN 0x30
241
242/* HFL_CTL (0x29, 0x2A) Fields */
243#define TWL4030_HF_CTL_HB_EN 0x04
244#define TWL4030_HF_CTL_LOOP_EN 0x08
245#define TWL4030_HF_CTL_RAMP_EN 0x10
246#define TWL4030_HF_CTL_REF_EN 0x20
247
248/* APLL_CTL (0x3A) Fields */
249
250#define TWL4030_APLL_EN 0x10
251#define TWL4030_APLL_INFREQ 0x0F
252#define TWL4030_APLL_INFREQ_19200KHZ 0x05
253#define TWL4030_APLL_INFREQ_26000KHZ 0x06
254#define TWL4030_APLL_INFREQ_38400KHZ 0x0F
255
256/* REG_MISC_SET_1 (0x3E) Fields */
257
258#define TWL4030_CLK64_EN 0x80
259#define TWL4030_SCRAMBLE_EN 0x40
260#define TWL4030_FMLOOP_EN 0x20
261#define TWL4030_SMOOTH_ANAVOL_EN 0x02
262#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
263
264/* TWL4030_REG_SW_SHADOW (0x4A) Fields */ 32/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
265#define TWL4030_HFL_EN 0x01 33#define TWL4030_HFL_EN 0x01
266#define TWL4030_HFR_EN 0x02 34#define TWL4030_HFR_EN 0x02
@@ -279,3 +47,5 @@ struct twl4030_setup_data {
279}; 47};
280 48
281#endif /* End of __TWL4030_AUDIO_H__ */ 49#endif /* End of __TWL4030_AUDIO_H__ */
50
51
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index c33b92edbded..aa40d985138f 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -562,17 +562,8 @@ static int uda134x_soc_probe(struct platform_device *pdev)
562 goto pcm_err; 562 goto pcm_err;
563 } 563 }
564 564
565 ret = snd_soc_init_card(socdev);
566 if (ret < 0) {
567 printk(KERN_ERR "UDA134X: failed to register card\n");
568 goto card_err;
569 }
570
571 return 0; 565 return 0;
572 566
573card_err:
574 snd_soc_free_pcms(socdev);
575 snd_soc_dapm_free(socdev);
576pcm_err: 567pcm_err:
577 kfree(codec->reg_cache); 568 kfree(codec->reg_cache);
578reg_err: 569reg_err:
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 92ec03442154..a42e47d94630 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -713,17 +713,9 @@ static int uda1380_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, uda1380_snd_controls, 713 snd_soc_add_controls(codec, uda1380_snd_controls,
714 ARRAY_SIZE(uda1380_snd_controls)); 714 ARRAY_SIZE(uda1380_snd_controls));
715 uda1380_add_widgets(codec); 715 uda1380_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 716
722 return ret; 717 return ret;
723 718
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 719pcm_err:
728 return ret; 720 return ret;
729} 721}
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 593d5b9c9f03..2e35a354b166 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1101,7 +1101,7 @@ static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
1101} 1101}
1102 1102
1103static int wm8350_set_fll(struct snd_soc_dai *codec_dai, 1103static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1104 int pll_id, unsigned int freq_in, 1104 int pll_id, int source, unsigned int freq_in,
1105 unsigned int freq_out) 1105 unsigned int freq_out)
1106{ 1106{
1107 struct snd_soc_codec *codec = codec_dai->codec; 1107 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1501,18 +1501,7 @@ static int wm8350_probe(struct platform_device *pdev)
1501 1501
1502 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1502 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1503 1503
1504 ret = snd_soc_init_card(socdev);
1505 if (ret < 0) {
1506 dev_err(&pdev->dev, "failed to register card\n");
1507 goto card_err;
1508 }
1509
1510 return 0; 1504 return 0;
1511
1512card_err:
1513 snd_soc_free_pcms(socdev);
1514 snd_soc_dapm_free(socdev);
1515 return ret;
1516} 1505}
1517 1506
1518static int wm8350_remove(struct platform_device *pdev) 1507static int wm8350_remove(struct platform_device *pdev)
@@ -1680,21 +1669,6 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1680 return 0; 1669 return 0;
1681} 1670}
1682 1671
1683#ifdef CONFIG_PM
1684static int wm8350_codec_suspend(struct platform_device *pdev, pm_message_t m)
1685{
1686 return snd_soc_suspend_device(&pdev->dev);
1687}
1688
1689static int wm8350_codec_resume(struct platform_device *pdev)
1690{
1691 return snd_soc_resume_device(&pdev->dev);
1692}
1693#else
1694#define wm8350_codec_suspend NULL
1695#define wm8350_codec_resume NULL
1696#endif
1697
1698static struct platform_driver wm8350_codec_driver = { 1672static struct platform_driver wm8350_codec_driver = {
1699 .driver = { 1673 .driver = {
1700 .name = "wm8350-codec", 1674 .name = "wm8350-codec",
@@ -1702,8 +1676,6 @@ static struct platform_driver wm8350_codec_driver = {
1702 }, 1676 },
1703 .probe = wm8350_codec_probe, 1677 .probe = wm8350_codec_probe,
1704 .remove = __devexit_p(wm8350_codec_remove), 1678 .remove = __devexit_p(wm8350_codec_remove),
1705 .suspend = wm8350_codec_suspend,
1706 .resume = wm8350_codec_resume,
1707}; 1679};
1708 1680
1709static __init int wm8350_init(void) 1681static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index b9ef4d915221..0e30997c8db0 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -1011,7 +1011,8 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
1011} 1011}
1012 1012
1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1014 unsigned int freq_in, unsigned int freq_out) 1014 int source, unsigned int freq_in,
1015 unsigned int freq_out)
1015{ 1016{
1016 struct snd_soc_codec *codec = codec_dai->codec; 1017 struct snd_soc_codec *codec = codec_dai->codec;
1017 struct wm8400_priv *wm8400 = codec->private_data; 1018 struct wm8400_priv *wm8400 = codec->private_data;
@@ -1399,12 +1400,6 @@ static int wm8400_probe(struct platform_device *pdev)
1399 wm8400_add_controls(codec); 1400 wm8400_add_controls(codec);
1400 wm8400_add_widgets(codec); 1401 wm8400_add_widgets(codec);
1401 1402
1402 ret = snd_soc_init_card(socdev);
1403 if (ret < 0) {
1404 dev_err(&pdev->dev, "failed to register card\n");
1405 goto card_err;
1406 }
1407
1408 return ret; 1403 return ret;
1409 1404
1410card_err: 1405card_err:
@@ -1558,21 +1553,6 @@ static int __exit wm8400_codec_remove(struct platform_device *dev)
1558 return 0; 1553 return 0;
1559} 1554}
1560 1555
1561#ifdef CONFIG_PM
1562static int wm8400_pdev_suspend(struct platform_device *pdev, pm_message_t msg)
1563{
1564 return snd_soc_suspend_device(&pdev->dev);
1565}
1566
1567static int wm8400_pdev_resume(struct platform_device *pdev)
1568{
1569 return snd_soc_resume_device(&pdev->dev);
1570}
1571#else
1572#define wm8400_pdev_suspend NULL
1573#define wm8400_pdev_resume NULL
1574#endif
1575
1576static struct platform_driver wm8400_codec_driver = { 1556static struct platform_driver wm8400_codec_driver = {
1577 .driver = { 1557 .driver = {
1578 .name = "wm8400-codec", 1558 .name = "wm8400-codec",
@@ -1580,8 +1560,6 @@ static struct platform_driver wm8400_codec_driver = {
1580 }, 1560 },
1581 .probe = wm8400_codec_probe, 1561 .probe = wm8400_codec_probe,
1582 .remove = __exit_p(wm8400_codec_remove), 1562 .remove = __exit_p(wm8400_codec_remove),
1583 .suspend = wm8400_pdev_suspend,
1584 .resume = wm8400_pdev_resume,
1585}; 1563};
1586 1564
1587static int __init wm8400_codec_init(void) 1565static int __init wm8400_codec_init(void)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 060d5d06ba95..e3c21ebcc08e 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -271,8 +271,8 @@ static void pll_factors(unsigned int target, unsigned int source)
271 pll_div.k = K; 271 pll_div.k = K;
272} 272}
273 273
274static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, 274static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
275 int pll_id, unsigned int freq_in, unsigned int freq_out) 275 int source, unsigned int freq_in, unsigned int freq_out)
276{ 276{
277 struct snd_soc_codec *codec = codec_dai->codec; 277 struct snd_soc_codec *codec = codec_dai->codec;
278 u16 reg; 278 u16 reg;
@@ -604,16 +604,9 @@ static int wm8510_init(struct snd_soc_device *socdev,
604 snd_soc_add_controls(codec, wm8510_snd_controls, 604 snd_soc_add_controls(codec, wm8510_snd_controls,
605 ARRAY_SIZE(wm8510_snd_controls)); 605 ARRAY_SIZE(wm8510_snd_controls));
606 wm8510_add_widgets(codec); 606 wm8510_add_widgets(codec);
607 ret = snd_soc_init_card(socdev); 607
608 if (ret < 0) {
609 printk(KERN_ERR "wm8510: failed to register card\n");
610 goto card_err;
611 }
612 return ret; 608 return ret;
613 609
614card_err:
615 snd_soc_free_pcms(socdev);
616 snd_soc_dapm_free(socdev);
617err: 610err:
618 kfree(codec->reg_cache); 611 kfree(codec->reg_cache);
619 return ret; 612 return ret;
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 25870a4652fb..2e2b01d6c82b 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -448,17 +448,9 @@ static int wm8523_probe(struct platform_device *pdev)
448 snd_soc_add_controls(codec, wm8523_snd_controls, 448 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls)); 449 ARRAY_SIZE(wm8523_snd_controls));
450 wm8523_add_widgets(codec); 450 wm8523_add_widgets(codec);
451 ret = snd_soc_init_card(socdev);
452 if (ret < 0) {
453 dev_err(codec->dev, "failed to register card: %d\n", ret);
454 goto card_err;
455 }
456 451
457 return ret; 452 return ret;
458 453
459card_err:
460 snd_soc_free_pcms(socdev);
461 snd_soc_dapm_free(socdev);
462pcm_err: 454pcm_err:
463 return ret; 455 return ret;
464} 456}
@@ -638,21 +630,6 @@ static __devexit int wm8523_i2c_remove(struct i2c_client *client)
638 return 0; 630 return 0;
639} 631}
640 632
641#ifdef CONFIG_PM
642static int wm8523_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
643{
644 return snd_soc_suspend_device(&i2c->dev);
645}
646
647static int wm8523_i2c_resume(struct i2c_client *i2c)
648{
649 return snd_soc_resume_device(&i2c->dev);
650}
651#else
652#define wm8523_i2c_suspend NULL
653#define wm8523_i2c_resume NULL
654#endif
655
656static const struct i2c_device_id wm8523_i2c_id[] = { 633static const struct i2c_device_id wm8523_i2c_id[] = {
657 { "wm8523", 0 }, 634 { "wm8523", 0 },
658 { } 635 { }
@@ -666,8 +643,6 @@ static struct i2c_driver wm8523_i2c_driver = {
666 }, 643 },
667 .probe = wm8523_i2c_probe, 644 .probe = wm8523_i2c_probe,
668 .remove = __devexit_p(wm8523_i2c_remove), 645 .remove = __devexit_p(wm8523_i2c_remove),
669 .suspend = wm8523_i2c_suspend,
670 .resume = wm8523_i2c_resume,
671 .id_table = wm8523_i2c_id, 646 .id_table = wm8523_i2c_id,
672}; 647};
673#endif 648#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 6bded8c78150..dde50d118181 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -407,8 +407,8 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
407 return 0; 407 return 0;
408} 408}
409 409
410static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, 410static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
411 int pll_id, unsigned int freq_in, unsigned int freq_out) 411 int source, unsigned int freq_in, unsigned int freq_out)
412{ 412{
413 int offset; 413 int offset;
414 struct snd_soc_codec *codec = codec_dai->codec; 414 struct snd_soc_codec *codec = codec_dai->codec;
@@ -800,17 +800,9 @@ static int wm8580_probe(struct platform_device *pdev)
800 snd_soc_add_controls(codec, wm8580_snd_controls, 800 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls)); 801 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec); 802 wm8580_add_widgets(codec);
803 ret = snd_soc_init_card(socdev);
804 if (ret < 0) {
805 dev_err(codec->dev, "failed to register card: %d\n", ret);
806 goto card_err;
807 }
808 803
809 return ret; 804 return ret;
810 805
811card_err:
812 snd_soc_free_pcms(socdev);
813 snd_soc_dapm_free(socdev);
814pcm_err: 806pcm_err:
815 return ret; 807 return ret;
816} 808}
@@ -961,21 +953,6 @@ static int wm8580_i2c_remove(struct i2c_client *client)
961 return 0; 953 return 0;
962} 954}
963 955
964#ifdef CONFIG_PM
965static int wm8580_i2c_suspend(struct i2c_client *client, pm_message_t msg)
966{
967 return snd_soc_suspend_device(&client->dev);
968}
969
970static int wm8580_i2c_resume(struct i2c_client *client)
971{
972 return snd_soc_resume_device(&client->dev);
973}
974#else
975#define wm8580_i2c_suspend NULL
976#define wm8580_i2c_resume NULL
977#endif
978
979static const struct i2c_device_id wm8580_i2c_id[] = { 956static const struct i2c_device_id wm8580_i2c_id[] = {
980 { "wm8580", 0 }, 957 { "wm8580", 0 },
981 { } 958 { }
@@ -989,8 +966,6 @@ static struct i2c_driver wm8580_i2c_driver = {
989 }, 966 },
990 .probe = wm8580_i2c_probe, 967 .probe = wm8580_i2c_probe,
991 .remove = wm8580_i2c_remove, 968 .remove = wm8580_i2c_remove,
992 .suspend = wm8580_i2c_suspend,
993 .resume = wm8580_i2c_resume,
994 .id_table = wm8580_i2c_id, 969 .id_table = wm8580_i2c_id,
995}; 970};
996#endif 971#endif
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
new file mode 100644
index 000000000000..70e0675b5d4a
--- /dev/null
+++ b/sound/soc/codecs/wm8711.c
@@ -0,0 +1,634 @@
1/*
2 * wm8711.c -- WM8711 ALSA SoC Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.c by Richard Purdie
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/tlv.h>
29#include <sound/initval.h>
30
31#include "wm8711.h"
32
33static struct snd_soc_codec *wm8711_codec;
34
35/* codec private data */
36struct wm8711_priv {
37 struct snd_soc_codec codec;
38 u16 reg_cache[WM8711_CACHEREGNUM];
39 unsigned int sysclk;
40};
41
42/*
43 * wm8711 register cache
44 * We can't read the WM8711 register space when we are
45 * using 2 wire for device control, so we cache them instead.
46 * There is no point in caching the reset register
47 */
48static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
49 0x0079, 0x0079, 0x000a, 0x0008,
50 0x009f, 0x000a, 0x0000, 0x0000
51};
52
53#define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0)
54
55static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
56
57static const struct snd_kcontrol_new wm8711_snd_controls[] = {
58
59SOC_DOUBLE_R_TLV("Master Playback Volume", WM8711_LOUT1V, WM8711_ROUT1V,
60 0, 127, 0, out_tlv),
61SOC_DOUBLE_R("Master Playback ZC Switch", WM8711_LOUT1V, WM8711_ROUT1V,
62 7, 1, 0),
63
64};
65
66/* Output Mixer */
67static const struct snd_kcontrol_new wm8711_output_mixer_controls[] = {
68SOC_DAPM_SINGLE("Line Bypass Switch", WM8711_APANA, 3, 1, 0),
69SOC_DAPM_SINGLE("HiFi Playback Switch", WM8711_APANA, 4, 1, 0),
70};
71
72static const struct snd_soc_dapm_widget wm8711_dapm_widgets[] = {
73SND_SOC_DAPM_MIXER("Output Mixer", WM8711_PWR, 4, 1,
74 &wm8711_output_mixer_controls[0],
75 ARRAY_SIZE(wm8711_output_mixer_controls)),
76SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8711_PWR, 3, 1),
77SND_SOC_DAPM_OUTPUT("LOUT"),
78SND_SOC_DAPM_OUTPUT("LHPOUT"),
79SND_SOC_DAPM_OUTPUT("ROUT"),
80SND_SOC_DAPM_OUTPUT("RHPOUT"),
81};
82
83static const struct snd_soc_dapm_route intercon[] = {
84 /* output mixer */
85 {"Output Mixer", "Line Bypass Switch", "Line Input"},
86 {"Output Mixer", "HiFi Playback Switch", "DAC"},
87
88 /* outputs */
89 {"RHPOUT", NULL, "Output Mixer"},
90 {"ROUT", NULL, "Output Mixer"},
91 {"LHPOUT", NULL, "Output Mixer"},
92 {"LOUT", NULL, "Output Mixer"},
93};
94
95static int wm8711_add_widgets(struct snd_soc_codec *codec)
96{
97 snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets,
98 ARRAY_SIZE(wm8711_dapm_widgets));
99
100 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
101
102 snd_soc_dapm_new_widgets(codec);
103 return 0;
104}
105
106struct _coeff_div {
107 u32 mclk;
108 u32 rate;
109 u16 fs;
110 u8 sr:4;
111 u8 bosr:1;
112 u8 usb:1;
113};
114
115/* codec mclk clock divider coefficients */
116static const struct _coeff_div coeff_div[] = {
117 /* 48k */
118 {12288000, 48000, 256, 0x0, 0x0, 0x0},
119 {18432000, 48000, 384, 0x0, 0x1, 0x0},
120 {12000000, 48000, 250, 0x0, 0x0, 0x1},
121
122 /* 32k */
123 {12288000, 32000, 384, 0x6, 0x0, 0x0},
124 {18432000, 32000, 576, 0x6, 0x1, 0x0},
125 {12000000, 32000, 375, 0x6, 0x0, 0x1},
126
127 /* 8k */
128 {12288000, 8000, 1536, 0x3, 0x0, 0x0},
129 {18432000, 8000, 2304, 0x3, 0x1, 0x0},
130 {11289600, 8000, 1408, 0xb, 0x0, 0x0},
131 {16934400, 8000, 2112, 0xb, 0x1, 0x0},
132 {12000000, 8000, 1500, 0x3, 0x0, 0x1},
133
134 /* 96k */
135 {12288000, 96000, 128, 0x7, 0x0, 0x0},
136 {18432000, 96000, 192, 0x7, 0x1, 0x0},
137 {12000000, 96000, 125, 0x7, 0x0, 0x1},
138
139 /* 44.1k */
140 {11289600, 44100, 256, 0x8, 0x0, 0x0},
141 {16934400, 44100, 384, 0x8, 0x1, 0x0},
142 {12000000, 44100, 272, 0x8, 0x1, 0x1},
143
144 /* 88.2k */
145 {11289600, 88200, 128, 0xf, 0x0, 0x0},
146 {16934400, 88200, 192, 0xf, 0x1, 0x0},
147 {12000000, 88200, 136, 0xf, 0x1, 0x1},
148};
149
150static inline int get_coeff(int mclk, int rate)
151{
152 int i;
153
154 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
155 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
156 return i;
157 }
158 return 0;
159}
160
161static int wm8711_hw_params(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params,
163 struct snd_soc_dai *dai)
164{
165 struct snd_soc_codec *codec = dai->codec;
166 struct wm8711_priv *wm8711 = codec->private_data;
167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
168 int i = get_coeff(wm8711->sysclk, params_rate(params));
169 u16 srate = (coeff_div[i].sr << 2) |
170 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
171
172 snd_soc_write(codec, WM8711_SRATE, srate);
173
174 /* bit size */
175 switch (params_format(params)) {
176 case SNDRV_PCM_FORMAT_S16_LE:
177 break;
178 case SNDRV_PCM_FORMAT_S20_3LE:
179 iface |= 0x0004;
180 break;
181 case SNDRV_PCM_FORMAT_S24_LE:
182 iface |= 0x0008;
183 break;
184 }
185
186 snd_soc_write(codec, WM8711_IFACE, iface);
187 return 0;
188}
189
190static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
192{
193 struct snd_soc_codec *codec = dai->codec;
194
195 /* set active */
196 snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
197
198 return 0;
199}
200
201static void wm8711_shutdown(struct snd_pcm_substream *substream,
202 struct snd_soc_dai *dai)
203{
204 struct snd_soc_codec *codec = dai->codec;
205
206 /* deactivate */
207 if (!codec->active) {
208 udelay(50);
209 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
210 }
211}
212
213static int wm8711_mute(struct snd_soc_dai *dai, int mute)
214{
215 struct snd_soc_codec *codec = dai->codec;
216 u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
217
218 if (mute)
219 snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
220 else
221 snd_soc_write(codec, WM8711_APDIGI, mute_reg);
222
223 return 0;
224}
225
226static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
227 int clk_id, unsigned int freq, int dir)
228{
229 struct snd_soc_codec *codec = codec_dai->codec;
230 struct wm8711_priv *wm8711 = codec->private_data;
231
232 switch (freq) {
233 case 11289600:
234 case 12000000:
235 case 12288000:
236 case 16934400:
237 case 18432000:
238 wm8711->sysclk = freq;
239 return 0;
240 }
241 return -EINVAL;
242}
243
244static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
245 unsigned int fmt)
246{
247 struct snd_soc_codec *codec = codec_dai->codec;
248 u16 iface = 0;
249
250 /* set master/slave audio interface */
251 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
252 case SND_SOC_DAIFMT_CBM_CFM:
253 iface |= 0x0040;
254 break;
255 case SND_SOC_DAIFMT_CBS_CFS:
256 break;
257 default:
258 return -EINVAL;
259 }
260
261 /* interface format */
262 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
263 case SND_SOC_DAIFMT_I2S:
264 iface |= 0x0002;
265 break;
266 case SND_SOC_DAIFMT_RIGHT_J:
267 break;
268 case SND_SOC_DAIFMT_LEFT_J:
269 iface |= 0x0001;
270 break;
271 case SND_SOC_DAIFMT_DSP_A:
272 iface |= 0x0003;
273 break;
274 case SND_SOC_DAIFMT_DSP_B:
275 iface |= 0x0013;
276 break;
277 default:
278 return -EINVAL;
279 }
280
281 /* clock inversion */
282 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
283 case SND_SOC_DAIFMT_NB_NF:
284 break;
285 case SND_SOC_DAIFMT_IB_IF:
286 iface |= 0x0090;
287 break;
288 case SND_SOC_DAIFMT_IB_NF:
289 iface |= 0x0080;
290 break;
291 case SND_SOC_DAIFMT_NB_IF:
292 iface |= 0x0010;
293 break;
294 default:
295 return -EINVAL;
296 }
297
298 /* set iface */
299 snd_soc_write(codec, WM8711_IFACE, iface);
300 return 0;
301}
302
303
304static int wm8711_set_bias_level(struct snd_soc_codec *codec,
305 enum snd_soc_bias_level level)
306{
307 u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
308
309 switch (level) {
310 case SND_SOC_BIAS_ON:
311 snd_soc_write(codec, WM8711_PWR, reg);
312 break;
313 case SND_SOC_BIAS_PREPARE:
314 break;
315 case SND_SOC_BIAS_STANDBY:
316 snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
317 break;
318 case SND_SOC_BIAS_OFF:
319 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
320 snd_soc_write(codec, WM8711_PWR, 0xffff);
321 break;
322 }
323 codec->bias_level = level;
324 return 0;
325}
326
327#define WM8711_RATES SNDRV_PCM_RATE_8000_96000
328
329#define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
330 SNDRV_PCM_FMTBIT_S24_LE)
331
332static struct snd_soc_dai_ops wm8711_ops = {
333 .prepare = wm8711_pcm_prepare,
334 .hw_params = wm8711_hw_params,
335 .shutdown = wm8711_shutdown,
336 .digital_mute = wm8711_mute,
337 .set_sysclk = wm8711_set_dai_sysclk,
338 .set_fmt = wm8711_set_dai_fmt,
339};
340
341struct snd_soc_dai wm8711_dai = {
342 .name = "WM8711",
343 .playback = {
344 .stream_name = "Playback",
345 .channels_min = 1,
346 .channels_max = 2,
347 .rates = WM8711_RATES,
348 .formats = WM8711_FORMATS,
349 },
350 .ops = &wm8711_ops,
351};
352EXPORT_SYMBOL_GPL(wm8711_dai);
353
354static int wm8711_suspend(struct platform_device *pdev, pm_message_t state)
355{
356 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
357 struct snd_soc_codec *codec = socdev->card->codec;
358
359 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
360 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
361 return 0;
362}
363
364static int wm8711_resume(struct platform_device *pdev)
365{
366 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
367 struct snd_soc_codec *codec = socdev->card->codec;
368 int i;
369 u8 data[2];
370 u16 *cache = codec->reg_cache;
371
372 /* Sync reg_cache with the hardware */
373 for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) {
374 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
375 data[1] = cache[i] & 0x00ff;
376 codec->hw_write(codec->control_data, data, 2);
377 }
378 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
379 wm8711_set_bias_level(codec, codec->suspend_bias_level);
380 return 0;
381}
382
383static int wm8711_probe(struct platform_device *pdev)
384{
385 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
386 struct snd_soc_codec *codec;
387 int ret = 0;
388
389 if (wm8711_codec == NULL) {
390 dev_err(&pdev->dev, "Codec device not registered\n");
391 return -ENODEV;
392 }
393
394 socdev->card->codec = wm8711_codec;
395 codec = wm8711_codec;
396
397 /* register pcms */
398 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
399 if (ret < 0) {
400 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
401 goto pcm_err;
402 }
403
404 snd_soc_add_controls(codec, wm8711_snd_controls,
405 ARRAY_SIZE(wm8711_snd_controls));
406 wm8711_add_widgets(codec);
407
408 return ret;
409
410pcm_err:
411 return ret;
412}
413
414/* power down chip */
415static int wm8711_remove(struct platform_device *pdev)
416{
417 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
418
419 snd_soc_free_pcms(socdev);
420 snd_soc_dapm_free(socdev);
421
422 return 0;
423}
424
425struct snd_soc_codec_device soc_codec_dev_wm8711 = {
426 .probe = wm8711_probe,
427 .remove = wm8711_remove,
428 .suspend = wm8711_suspend,
429 .resume = wm8711_resume,
430};
431EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
432
433static int wm8711_register(struct wm8711_priv *wm8711,
434 enum snd_soc_control_type control)
435{
436 int ret;
437 struct snd_soc_codec *codec = &wm8711->codec;
438 u16 reg;
439
440 if (wm8711_codec) {
441 dev_err(codec->dev, "Another WM8711 is registered\n");
442 return -EINVAL;
443 }
444
445 mutex_init(&codec->mutex);
446 INIT_LIST_HEAD(&codec->dapm_widgets);
447 INIT_LIST_HEAD(&codec->dapm_paths);
448
449 codec->private_data = wm8711;
450 codec->name = "WM8711";
451 codec->owner = THIS_MODULE;
452 codec->bias_level = SND_SOC_BIAS_OFF;
453 codec->set_bias_level = wm8711_set_bias_level;
454 codec->dai = &wm8711_dai;
455 codec->num_dai = 1;
456 codec->reg_cache_size = WM8711_CACHEREGNUM;
457 codec->reg_cache = &wm8711->reg_cache;
458
459 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
460
461 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
462 if (ret < 0) {
463 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
464 goto err;
465 }
466
467 ret = wm8711_reset(codec);
468 if (ret < 0) {
469 dev_err(codec->dev, "Failed to issue reset\n");
470 goto err;
471 }
472
473 wm8711_dai.dev = codec->dev;
474
475 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
476
477 /* Latch the update bits */
478 reg = snd_soc_read(codec, WM8711_LOUT1V);
479 snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100);
480 reg = snd_soc_read(codec, WM8711_ROUT1V);
481 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
482
483 wm8711_codec = codec;
484
485 ret = snd_soc_register_codec(codec);
486 if (ret != 0) {
487 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
488 goto err;
489 }
490
491 ret = snd_soc_register_dai(&wm8711_dai);
492 if (ret != 0) {
493 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
494 goto err_codec;
495 }
496
497 return 0;
498
499err_codec:
500 snd_soc_unregister_codec(codec);
501err:
502 kfree(wm8711);
503 return ret;
504}
505
506static void wm8711_unregister(struct wm8711_priv *wm8711)
507{
508 wm8711_set_bias_level(&wm8711->codec, SND_SOC_BIAS_OFF);
509 snd_soc_unregister_dai(&wm8711_dai);
510 snd_soc_unregister_codec(&wm8711->codec);
511 kfree(wm8711);
512 wm8711_codec = NULL;
513}
514
515#if defined(CONFIG_SPI_MASTER)
516static int __devinit wm8711_spi_probe(struct spi_device *spi)
517{
518 struct snd_soc_codec *codec;
519 struct wm8711_priv *wm8711;
520
521 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
522 if (wm8711 == NULL)
523 return -ENOMEM;
524
525 codec = &wm8711->codec;
526 codec->control_data = spi;
527 codec->dev = &spi->dev;
528
529 dev_set_drvdata(&spi->dev, wm8711);
530
531 return wm8711_register(wm8711, SND_SOC_SPI);
532}
533
534static int __devexit wm8711_spi_remove(struct spi_device *spi)
535{
536 struct wm8711_priv *wm8711 = dev_get_drvdata(&spi->dev);
537
538 wm8711_unregister(wm8711);
539
540 return 0;
541}
542
543static struct spi_driver wm8711_spi_driver = {
544 .driver = {
545 .name = "wm8711",
546 .bus = &spi_bus_type,
547 .owner = THIS_MODULE,
548 },
549 .probe = wm8711_spi_probe,
550 .remove = __devexit_p(wm8711_spi_remove),
551};
552#endif /* CONFIG_SPI_MASTER */
553
554#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
555static __devinit int wm8711_i2c_probe(struct i2c_client *i2c,
556 const struct i2c_device_id *id)
557{
558 struct wm8711_priv *wm8711;
559 struct snd_soc_codec *codec;
560
561 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
562 if (wm8711 == NULL)
563 return -ENOMEM;
564
565 codec = &wm8711->codec;
566 codec->hw_write = (hw_write_t)i2c_master_send;
567
568 i2c_set_clientdata(i2c, wm8711);
569 codec->control_data = i2c;
570
571 codec->dev = &i2c->dev;
572
573 return wm8711_register(wm8711, SND_SOC_I2C);
574}
575
576static __devexit int wm8711_i2c_remove(struct i2c_client *client)
577{
578 struct wm8711_priv *wm8711 = i2c_get_clientdata(client);
579 wm8711_unregister(wm8711);
580 return 0;
581}
582
583static const struct i2c_device_id wm8711_i2c_id[] = {
584 { "wm8711", 0 },
585 { }
586};
587MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
588
589static struct i2c_driver wm8711_i2c_driver = {
590 .driver = {
591 .name = "WM8711 I2C Codec",
592 .owner = THIS_MODULE,
593 },
594 .probe = wm8711_i2c_probe,
595 .remove = __devexit_p(wm8711_i2c_remove),
596 .id_table = wm8711_i2c_id,
597};
598#endif
599
600static int __init wm8711_modinit(void)
601{
602 int ret;
603#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
604 ret = i2c_add_driver(&wm8711_i2c_driver);
605 if (ret != 0) {
606 printk(KERN_ERR "Failed to register WM8711 I2C driver: %d\n",
607 ret);
608 }
609#endif
610#if defined(CONFIG_SPI_MASTER)
611 ret = spi_register_driver(&wm8711_spi_driver);
612 if (ret != 0) {
613 printk(KERN_ERR "Failed to register WM8711 SPI driver: %d\n",
614 ret);
615 }
616#endif
617 return 0;
618}
619module_init(wm8711_modinit);
620
621static void __exit wm8711_exit(void)
622{
623#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
624 i2c_del_driver(&wm8711_i2c_driver);
625#endif
626#if defined(CONFIG_SPI_MASTER)
627 spi_unregister_driver(&wm8711_spi_driver);
628#endif
629}
630module_exit(wm8711_exit);
631
632MODULE_DESCRIPTION("ASoC WM8711 driver");
633MODULE_AUTHOR("Mike Arthur");
634MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8711.h b/sound/soc/codecs/wm8711.h
new file mode 100644
index 000000000000..381e84a43816
--- /dev/null
+++ b/sound/soc/codecs/wm8711.h
@@ -0,0 +1,42 @@
1/*
2 * wm8711.h -- WM8711 Soc Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _WM8711_H
16#define _WM8711_H
17
18/* WM8711 register space */
19
20#define WM8711_LOUT1V 0x02
21#define WM8711_ROUT1V 0x03
22#define WM8711_APANA 0x04
23#define WM8711_APDIGI 0x05
24#define WM8711_PWR 0x06
25#define WM8711_IFACE 0x07
26#define WM8711_SRATE 0x08
27#define WM8711_ACTIVE 0x09
28#define WM8711_RESET 0x0f
29
30#define WM8711_CACHEREGNUM 8
31
32#define WM8711_SYSCLK 0
33#define WM8711_DAI 0
34
35struct wm8711_setup_data {
36 unsigned short i2c_address;
37};
38
39extern struct snd_soc_dai wm8711_dai;
40extern struct snd_soc_codec_device soc_codec_dev_wm8711;
41
42#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
new file mode 100644
index 000000000000..d8ffbd641d71
--- /dev/null
+++ b/sound/soc/codecs/wm8727.c
@@ -0,0 +1,135 @@
1/*
2 * wm8727.c
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/ac97_codec.h>
22#include <sound/initval.h>
23#include <sound/soc.h>
24
25#include "wm8727.h"
26/*
27 * Note this is a simple chip with no configuration interface, sample rate is
28 * determined automatically by examining the Master clock and Bit clock ratios
29 */
30#define WM8727_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
31 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
32 SNDRV_PCM_RATE_192000)
33
34
35struct snd_soc_dai wm8727_dai = {
36 .name = "WM8727",
37 .playback = {
38 .stream_name = "Playback",
39 .channels_min = 2,
40 .channels_max = 2,
41 .rates = WM8727_RATES,
42 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
43 },
44};
45EXPORT_SYMBOL_GPL(wm8727_dai);
46
47static int wm8727_soc_probe(struct platform_device *pdev)
48{
49 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
50 struct snd_soc_codec *codec;
51 int ret = 0;
52
53 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
54 if (codec == NULL)
55 return -ENOMEM;
56 mutex_init(&codec->mutex);
57 codec->name = "WM8727";
58 codec->owner = THIS_MODULE;
59 codec->dai = &wm8727_dai;
60 codec->num_dai = 1;
61 socdev->card->codec = codec;
62 INIT_LIST_HEAD(&codec->dapm_widgets);
63 INIT_LIST_HEAD(&codec->dapm_paths);
64
65 /* register pcms */
66 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
67 if (ret < 0) {
68 printk(KERN_ERR "wm8727: failed to create pcms\n");
69 goto pcm_err;
70 }
71
72 return ret;
73
74pcm_err:
75 kfree(socdev->card->codec);
76 socdev->card->codec = NULL;
77 return ret;
78}
79
80static int wm8727_soc_remove(struct platform_device *pdev)
81{
82 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
83 struct snd_soc_codec *codec = socdev->card->codec;
84
85 if (codec == NULL)
86 return 0;
87 snd_soc_free_pcms(socdev);
88 kfree(codec);
89 return 0;
90}
91
92struct snd_soc_codec_device soc_codec_dev_wm8727 = {
93 .probe = wm8727_soc_probe,
94 .remove = wm8727_soc_remove,
95};
96EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
97
98
99static __devinit int wm8727_platform_probe(struct platform_device *pdev)
100{
101 wm8727_dai.dev = &pdev->dev;
102 return snd_soc_register_dai(&wm8727_dai);
103}
104
105static int __devexit wm8727_platform_remove(struct platform_device *pdev)
106{
107 snd_soc_unregister_dai(&wm8727_dai);
108 return 0;
109}
110
111static struct platform_driver wm8727_codec_driver = {
112 .driver = {
113 .name = "wm8727-codec",
114 .owner = THIS_MODULE,
115 },
116
117 .probe = wm8727_platform_probe,
118 .remove = __devexit_p(wm8727_platform_remove),
119};
120
121static int __init wm8727_init(void)
122{
123 return platform_driver_register(&wm8727_codec_driver);
124}
125module_init(wm8727_init);
126
127static void __exit wm8727_exit(void)
128{
129 platform_driver_unregister(&wm8727_codec_driver);
130}
131module_exit(wm8727_exit);
132
133MODULE_DESCRIPTION("ASoC wm8727 driver");
134MODULE_AUTHOR("Neil Jones");
135MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8727.h b/sound/soc/codecs/wm8727.h
new file mode 100644
index 000000000000..ee19aa71bcdc
--- /dev/null
+++ b/sound/soc/codecs/wm8727.h
@@ -0,0 +1,21 @@
1/*
2 * wm8727.h
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#ifndef WM8727_H_
16#define WM8727_H_
17
18extern struct snd_soc_dai wm8727_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8727;
20
21#endif /* WM8727_H_ */
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 16e969a762c3..1252a8a486a6 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -287,17 +287,9 @@ static int wm8728_init(struct snd_soc_device *socdev,
287 snd_soc_add_controls(codec, wm8728_snd_controls, 287 snd_soc_add_controls(codec, wm8728_snd_controls,
288 ARRAY_SIZE(wm8728_snd_controls)); 288 ARRAY_SIZE(wm8728_snd_controls));
289 wm8728_add_widgets(codec); 289 wm8728_add_widgets(codec);
290 ret = snd_soc_init_card(socdev);
291 if (ret < 0) {
292 printk(KERN_ERR "wm8728: failed to register card\n");
293 goto card_err;
294 }
295 290
296 return ret; 291 return ret;
297 292
298card_err:
299 snd_soc_free_pcms(socdev);
300 snd_soc_dapm_free(socdev);
301err: 293err:
302 kfree(codec->reg_cache); 294 kfree(codec->reg_cache);
303 return ret; 295 return ret;
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index d3fd4f28d96e..e3675e7a9813 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
@@ -33,9 +34,18 @@
33static struct snd_soc_codec *wm8731_codec; 34static struct snd_soc_codec *wm8731_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8731; 35struct snd_soc_codec_device soc_codec_dev_wm8731;
35 36
37#define WM8731_NUM_SUPPLIES 4
38static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
39 "AVDD",
40 "HPVDD",
41 "DCVDD",
42 "DBVDD",
43};
44
36/* codec private data */ 45/* codec private data */
37struct wm8731_priv { 46struct wm8731_priv {
38 struct snd_soc_codec codec; 47 struct snd_soc_codec codec;
48 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
39 u16 reg_cache[WM8731_CACHEREGNUM]; 49 u16 reg_cache[WM8731_CACHEREGNUM];
40 unsigned int sysclk; 50 unsigned int sysclk;
41}; 51};
@@ -422,9 +432,12 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
422{ 432{
423 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 433 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
424 struct snd_soc_codec *codec = socdev->card->codec; 434 struct snd_soc_codec *codec = socdev->card->codec;
435 struct wm8731_priv *wm8731 = codec->private_data;
425 436
426 snd_soc_write(codec, WM8731_ACTIVE, 0x0); 437 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
427 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 438 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
439 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
440 wm8731->supplies);
428 return 0; 441 return 0;
429} 442}
430 443
@@ -432,10 +445,16 @@ static int wm8731_resume(struct platform_device *pdev)
432{ 445{
433 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 446 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
434 struct snd_soc_codec *codec = socdev->card->codec; 447 struct snd_soc_codec *codec = socdev->card->codec;
435 int i; 448 struct wm8731_priv *wm8731 = codec->private_data;
449 int i, ret;
436 u8 data[2]; 450 u8 data[2];
437 u16 *cache = codec->reg_cache; 451 u16 *cache = codec->reg_cache;
438 452
453 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
454 wm8731->supplies);
455 if (ret != 0)
456 return ret;
457
439 /* Sync reg_cache with the hardware */ 458 /* Sync reg_cache with the hardware */
440 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 459 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
441 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 460 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
@@ -444,6 +463,7 @@ static int wm8731_resume(struct platform_device *pdev)
444 } 463 }
445 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 464 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
446 wm8731_set_bias_level(codec, codec->suspend_bias_level); 465 wm8731_set_bias_level(codec, codec->suspend_bias_level);
466
447 return 0; 467 return 0;
448} 468}
449#else 469#else
@@ -475,17 +495,9 @@ static int wm8731_probe(struct platform_device *pdev)
475 snd_soc_add_controls(codec, wm8731_snd_controls, 495 snd_soc_add_controls(codec, wm8731_snd_controls,
476 ARRAY_SIZE(wm8731_snd_controls)); 496 ARRAY_SIZE(wm8731_snd_controls));
477 wm8731_add_widgets(codec); 497 wm8731_add_widgets(codec);
478 ret = snd_soc_init_card(socdev);
479 if (ret < 0) {
480 dev_err(codec->dev, "failed to register card: %d\n", ret);
481 goto card_err;
482 }
483 498
484 return ret; 499 return ret;
485 500
486card_err:
487 snd_soc_free_pcms(socdev);
488 snd_soc_dapm_free(socdev);
489pcm_err: 501pcm_err:
490 return ret; 502 return ret;
491} 503}
@@ -512,7 +524,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
512static int wm8731_register(struct wm8731_priv *wm8731, 524static int wm8731_register(struct wm8731_priv *wm8731,
513 enum snd_soc_control_type control) 525 enum snd_soc_control_type control)
514{ 526{
515 int ret; 527 int ret, i;
516 struct snd_soc_codec *codec = &wm8731->codec; 528 struct snd_soc_codec *codec = &wm8731->codec;
517 529
518 if (wm8731_codec) { 530 if (wm8731_codec) {
@@ -543,10 +555,27 @@ static int wm8731_register(struct wm8731_priv *wm8731,
543 goto err; 555 goto err;
544 } 556 }
545 557
558 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
559 wm8731->supplies[i].supply = wm8731_supply_names[i];
560
561 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8731->supplies),
562 wm8731->supplies);
563 if (ret != 0) {
564 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
565 goto err;
566 }
567
568 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
569 wm8731->supplies);
570 if (ret != 0) {
571 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
572 goto err_regulator_get;
573 }
574
546 ret = wm8731_reset(codec); 575 ret = wm8731_reset(codec);
547 if (ret < 0) { 576 if (ret < 0) {
548 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 577 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
549 goto err; 578 goto err_regulator_enable;
550 } 579 }
551 580
552 wm8731_dai.dev = codec->dev; 581 wm8731_dai.dev = codec->dev;
@@ -567,7 +596,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
567 ret = snd_soc_register_codec(codec); 596 ret = snd_soc_register_codec(codec);
568 if (ret != 0) { 597 if (ret != 0) {
569 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 598 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
570 goto err; 599 goto err_regulator_enable;
571 } 600 }
572 601
573 ret = snd_soc_register_dai(&wm8731_dai); 602 ret = snd_soc_register_dai(&wm8731_dai);
@@ -581,6 +610,10 @@ static int wm8731_register(struct wm8731_priv *wm8731,
581 610
582err_codec: 611err_codec:
583 snd_soc_unregister_codec(codec); 612 snd_soc_unregister_codec(codec);
613err_regulator_enable:
614 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
615err_regulator_get:
616 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
584err: 617err:
585 kfree(wm8731); 618 kfree(wm8731);
586 return ret; 619 return ret;
@@ -591,6 +624,8 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
591 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 624 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
592 snd_soc_unregister_dai(&wm8731_dai); 625 snd_soc_unregister_dai(&wm8731_dai);
593 snd_soc_unregister_codec(&wm8731->codec); 626 snd_soc_unregister_codec(&wm8731->codec);
627 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
628 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
594 kfree(wm8731); 629 kfree(wm8731);
595 wm8731_codec = NULL; 630 wm8731_codec = NULL;
596} 631}
@@ -623,21 +658,6 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
623 return 0; 658 return 0;
624} 659}
625 660
626#ifdef CONFIG_PM
627static int wm8731_spi_suspend(struct spi_device *spi, pm_message_t msg)
628{
629 return snd_soc_suspend_device(&spi->dev);
630}
631
632static int wm8731_spi_resume(struct spi_device *spi)
633{
634 return snd_soc_resume_device(&spi->dev);
635}
636#else
637#define wm8731_spi_suspend NULL
638#define wm8731_spi_resume NULL
639#endif
640
641static struct spi_driver wm8731_spi_driver = { 661static struct spi_driver wm8731_spi_driver = {
642 .driver = { 662 .driver = {
643 .name = "wm8731", 663 .name = "wm8731",
@@ -645,8 +665,6 @@ static struct spi_driver wm8731_spi_driver = {
645 .owner = THIS_MODULE, 665 .owner = THIS_MODULE,
646 }, 666 },
647 .probe = wm8731_spi_probe, 667 .probe = wm8731_spi_probe,
648 .suspend = wm8731_spi_suspend,
649 .resume = wm8731_spi_resume,
650 .remove = __devexit_p(wm8731_spi_remove), 668 .remove = __devexit_p(wm8731_spi_remove),
651}; 669};
652#endif /* CONFIG_SPI_MASTER */ 670#endif /* CONFIG_SPI_MASTER */
@@ -679,21 +697,6 @@ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
679 return 0; 697 return 0;
680} 698}
681 699
682#ifdef CONFIG_PM
683static int wm8731_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
684{
685 return snd_soc_suspend_device(&i2c->dev);
686}
687
688static int wm8731_i2c_resume(struct i2c_client *i2c)
689{
690 return snd_soc_resume_device(&i2c->dev);
691}
692#else
693#define wm8731_i2c_suspend NULL
694#define wm8731_i2c_resume NULL
695#endif
696
697static const struct i2c_device_id wm8731_i2c_id[] = { 700static const struct i2c_device_id wm8731_i2c_id[] = {
698 { "wm8731", 0 }, 701 { "wm8731", 0 },
699 { } 702 { }
@@ -707,8 +710,6 @@ static struct i2c_driver wm8731_i2c_driver = {
707 }, 710 },
708 .probe = wm8731_i2c_probe, 711 .probe = wm8731_i2c_probe,
709 .remove = __devexit_p(wm8731_i2c_remove), 712 .remove = __devexit_p(wm8731_i2c_remove),
710 .suspend = wm8731_i2c_suspend,
711 .resume = wm8731_i2c_resume,
712 .id_table = wm8731_i2c_id, 713 .id_table = wm8731_i2c_id,
713}; 714};
714#endif 715#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 4ba1e7e93fb4..50a3d6590588 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -772,16 +772,8 @@ static int wm8750_init(struct snd_soc_device *socdev,
772 snd_soc_add_controls(codec, wm8750_snd_controls, 772 snd_soc_add_controls(codec, wm8750_snd_controls,
773 ARRAY_SIZE(wm8750_snd_controls)); 773 ARRAY_SIZE(wm8750_snd_controls));
774 wm8750_add_widgets(codec); 774 wm8750_add_widgets(codec);
775 ret = snd_soc_init_card(socdev);
776 if (ret < 0) {
777 printk(KERN_ERR "wm8750: failed to register card\n");
778 goto card_err;
779 }
780 return ret; 775 return ret;
781 776
782card_err:
783 snd_soc_free_pcms(socdev);
784 snd_soc_dapm_free(socdev);
785err: 777err:
786 kfree(codec->reg_cache); 778 kfree(codec->reg_cache);
787 return ret; 779 return ret;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5ad677ce80da..c652bc04cc81 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -724,8 +724,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
724 pll_div->k = K; 724 pll_div->k = K;
725} 725}
726 726
727static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, 727static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
728 int pll_id, unsigned int freq_in, unsigned int freq_out) 728 int source, unsigned int freq_in, unsigned int freq_out)
729{ 729{
730 u16 reg, enable; 730 u16 reg, enable;
731 int offset; 731 int offset;
@@ -1583,18 +1583,9 @@ static int wm8753_probe(struct platform_device *pdev)
1583 snd_soc_add_controls(codec, wm8753_snd_controls, 1583 snd_soc_add_controls(codec, wm8753_snd_controls,
1584 ARRAY_SIZE(wm8753_snd_controls)); 1584 ARRAY_SIZE(wm8753_snd_controls));
1585 wm8753_add_widgets(codec); 1585 wm8753_add_widgets(codec);
1586 ret = snd_soc_init_card(socdev);
1587 if (ret < 0) {
1588 printk(KERN_ERR "wm8753: failed to register card\n");
1589 goto card_err;
1590 }
1591 1586
1592 return 0; 1587 return 0;
1593 1588
1594card_err:
1595 snd_soc_free_pcms(socdev);
1596 snd_soc_dapm_free(socdev);
1597
1598pcm_err: 1589pcm_err:
1599 return ret; 1590 return ret;
1600} 1591}
@@ -1767,21 +1758,6 @@ static int wm8753_i2c_remove(struct i2c_client *client)
1767 return 0; 1758 return 0;
1768} 1759}
1769 1760
1770#ifdef CONFIG_PM
1771static int wm8753_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1772{
1773 return snd_soc_suspend_device(&client->dev);
1774}
1775
1776static int wm8753_i2c_resume(struct i2c_client *client)
1777{
1778 return snd_soc_resume_device(&client->dev);
1779}
1780#else
1781#define wm8753_i2c_suspend NULL
1782#define wm8753_i2c_resume NULL
1783#endif
1784
1785static const struct i2c_device_id wm8753_i2c_id[] = { 1761static const struct i2c_device_id wm8753_i2c_id[] = {
1786 { "wm8753", 0 }, 1762 { "wm8753", 0 },
1787 { } 1763 { }
@@ -1795,8 +1771,6 @@ static struct i2c_driver wm8753_i2c_driver = {
1795 }, 1771 },
1796 .probe = wm8753_i2c_probe, 1772 .probe = wm8753_i2c_probe,
1797 .remove = wm8753_i2c_remove, 1773 .remove = wm8753_i2c_remove,
1798 .suspend = wm8753_i2c_suspend,
1799 .resume = wm8753_i2c_resume,
1800 .id_table = wm8753_i2c_id, 1774 .id_table = wm8753_i2c_id,
1801}; 1775};
1802#endif 1776#endif
@@ -1852,22 +1826,6 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1852 return 0; 1826 return 0;
1853} 1827}
1854 1828
1855#ifdef CONFIG_PM
1856static int wm8753_spi_suspend(struct spi_device *spi, pm_message_t msg)
1857{
1858 return snd_soc_suspend_device(&spi->dev);
1859}
1860
1861static int wm8753_spi_resume(struct spi_device *spi)
1862{
1863 return snd_soc_resume_device(&spi->dev);
1864}
1865
1866#else
1867#define wm8753_spi_suspend NULL
1868#define wm8753_spi_resume NULL
1869#endif
1870
1871static struct spi_driver wm8753_spi_driver = { 1829static struct spi_driver wm8753_spi_driver = {
1872 .driver = { 1830 .driver = {
1873 .name = "wm8753", 1831 .name = "wm8753",
@@ -1876,8 +1834,6 @@ static struct spi_driver wm8753_spi_driver = {
1876 }, 1834 },
1877 .probe = wm8753_spi_probe, 1835 .probe = wm8753_spi_probe,
1878 .remove = __devexit_p(wm8753_spi_remove), 1836 .remove = __devexit_p(wm8753_spi_remove),
1879 .suspend = wm8753_spi_suspend,
1880 .resume = wm8753_spi_resume,
1881}; 1837};
1882#endif 1838#endif
1883 1839
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index a9829aa26e53..ab2c0da18091 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -447,17 +447,8 @@ static int wm8776_probe(struct platform_device *pdev)
447 ARRAY_SIZE(wm8776_dapm_widgets)); 447 ARRAY_SIZE(wm8776_dapm_widgets));
448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
449 449
450 ret = snd_soc_init_card(socdev);
451 if (ret < 0) {
452 dev_err(codec->dev, "failed to register card: %d\n", ret);
453 goto card_err;
454 }
455
456 return ret; 450 return ret;
457 451
458card_err:
459 snd_soc_free_pcms(socdev);
460 snd_soc_dapm_free(socdev);
461pcm_err: 452pcm_err:
462 return ret; 453 return ret;
463} 454}
@@ -616,21 +607,6 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi)
616 return 0; 607 return 0;
617} 608}
618 609
619#ifdef CONFIG_PM
620static int wm8776_spi_suspend(struct spi_device *spi, pm_message_t msg)
621{
622 return snd_soc_suspend_device(&spi->dev);
623}
624
625static int wm8776_spi_resume(struct spi_device *spi)
626{
627 return snd_soc_resume_device(&spi->dev);
628}
629#else
630#define wm8776_spi_suspend NULL
631#define wm8776_spi_resume NULL
632#endif
633
634static struct spi_driver wm8776_spi_driver = { 610static struct spi_driver wm8776_spi_driver = {
635 .driver = { 611 .driver = {
636 .name = "wm8776", 612 .name = "wm8776",
@@ -638,8 +614,6 @@ static struct spi_driver wm8776_spi_driver = {
638 .owner = THIS_MODULE, 614 .owner = THIS_MODULE,
639 }, 615 },
640 .probe = wm8776_spi_probe, 616 .probe = wm8776_spi_probe,
641 .suspend = wm8776_spi_suspend,
642 .resume = wm8776_spi_resume,
643 .remove = __devexit_p(wm8776_spi_remove), 617 .remove = __devexit_p(wm8776_spi_remove),
644}; 618};
645#endif /* CONFIG_SPI_MASTER */ 619#endif /* CONFIG_SPI_MASTER */
@@ -673,21 +647,6 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client)
673 return 0; 647 return 0;
674} 648}
675 649
676#ifdef CONFIG_PM
677static int wm8776_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
678{
679 return snd_soc_suspend_device(&i2c->dev);
680}
681
682static int wm8776_i2c_resume(struct i2c_client *i2c)
683{
684 return snd_soc_resume_device(&i2c->dev);
685}
686#else
687#define wm8776_i2c_suspend NULL
688#define wm8776_i2c_resume NULL
689#endif
690
691static const struct i2c_device_id wm8776_i2c_id[] = { 650static const struct i2c_device_id wm8776_i2c_id[] = {
692 { "wm8776", 0 }, 651 { "wm8776", 0 },
693 { } 652 { }
@@ -701,8 +660,6 @@ static struct i2c_driver wm8776_i2c_driver = {
701 }, 660 },
702 .probe = wm8776_i2c_probe, 661 .probe = wm8776_i2c_probe,
703 .remove = __devexit_p(wm8776_i2c_remove), 662 .remove = __devexit_p(wm8776_i2c_remove),
704 .suspend = wm8776_i2c_suspend,
705 .resume = wm8776_i2c_resume,
706 .id_table = wm8776_i2c_id, 663 .id_table = wm8776_i2c_id,
707}; 664};
708#endif 665#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5e9c855c0036..0d185cb6418d 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -814,8 +814,8 @@ reenable:
814 return 0; 814 return 0;
815} 815}
816 816
817static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, 817static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
818 int pll_id, unsigned int freq_in, unsigned int freq_out) 818 int source, unsigned int freq_in, unsigned int freq_out)
819{ 819{
820 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out); 820 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
821} 821}
@@ -1312,21 +1312,6 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1312 return 0; 1312 return 0;
1313} 1313}
1314 1314
1315#ifdef CONFIG_PM
1316static int wm8900_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1317{
1318 return snd_soc_suspend_device(&client->dev);
1319}
1320
1321static int wm8900_i2c_resume(struct i2c_client *client)
1322{
1323 return snd_soc_resume_device(&client->dev);
1324}
1325#else
1326#define wm8900_i2c_suspend NULL
1327#define wm8900_i2c_resume NULL
1328#endif
1329
1330static const struct i2c_device_id wm8900_i2c_id[] = { 1315static const struct i2c_device_id wm8900_i2c_id[] = {
1331 { "wm8900", 0 }, 1316 { "wm8900", 0 },
1332 { } 1317 { }
@@ -1340,8 +1325,6 @@ static struct i2c_driver wm8900_i2c_driver = {
1340 }, 1325 },
1341 .probe = wm8900_i2c_probe, 1326 .probe = wm8900_i2c_probe,
1342 .remove = __devexit_p(wm8900_i2c_remove), 1327 .remove = __devexit_p(wm8900_i2c_remove),
1343 .suspend = wm8900_i2c_suspend,
1344 .resume = wm8900_i2c_resume,
1345 .id_table = wm8900_i2c_id, 1328 .id_table = wm8900_i2c_id,
1346}; 1329};
1347 1330
@@ -1370,12 +1353,6 @@ static int wm8900_probe(struct platform_device *pdev)
1370 ARRAY_SIZE(wm8900_snd_controls)); 1353 ARRAY_SIZE(wm8900_snd_controls));
1371 wm8900_add_widgets(codec); 1354 wm8900_add_widgets(codec);
1372 1355
1373 ret = snd_soc_init_card(socdev);
1374 if (ret < 0) {
1375 dev_err(&pdev->dev, "Failed to register card\n");
1376 goto card_err;
1377 }
1378
1379 return ret; 1356 return ret;
1380 1357
1381card_err: 1358card_err:
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fe1307b500cf..bfeff4ee5de9 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1655,21 +1655,6 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1655 return 0; 1655 return 0;
1656} 1656}
1657 1657
1658#ifdef CONFIG_PM
1659static int wm8903_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1660{
1661 return snd_soc_suspend_device(&client->dev);
1662}
1663
1664static int wm8903_i2c_resume(struct i2c_client *client)
1665{
1666 return snd_soc_resume_device(&client->dev);
1667}
1668#else
1669#define wm8903_i2c_suspend NULL
1670#define wm8903_i2c_resume NULL
1671#endif
1672
1673/* i2c codec control layer */ 1658/* i2c codec control layer */
1674static const struct i2c_device_id wm8903_i2c_id[] = { 1659static const struct i2c_device_id wm8903_i2c_id[] = {
1675 { "wm8903", 0 }, 1660 { "wm8903", 0 },
@@ -1684,8 +1669,6 @@ static struct i2c_driver wm8903_i2c_driver = {
1684 }, 1669 },
1685 .probe = wm8903_i2c_probe, 1670 .probe = wm8903_i2c_probe,
1686 .remove = __devexit_p(wm8903_i2c_remove), 1671 .remove = __devexit_p(wm8903_i2c_remove),
1687 .suspend = wm8903_i2c_suspend,
1688 .resume = wm8903_i2c_resume,
1689 .id_table = wm8903_i2c_id, 1672 .id_table = wm8903_i2c_id,
1690}; 1673};
1691 1674
@@ -1712,17 +1695,8 @@ static int wm8903_probe(struct platform_device *pdev)
1712 ARRAY_SIZE(wm8903_snd_controls)); 1695 ARRAY_SIZE(wm8903_snd_controls));
1713 wm8903_add_widgets(socdev->card->codec); 1696 wm8903_add_widgets(socdev->card->codec);
1714 1697
1715 ret = snd_soc_init_card(socdev);
1716 if (ret < 0) {
1717 dev_err(&pdev->dev, "wm8903: failed to register card\n");
1718 goto card_err;
1719 }
1720
1721 return ret; 1698 return ret;
1722 1699
1723card_err:
1724 snd_soc_free_pcms(socdev);
1725 snd_soc_dapm_free(socdev);
1726err: 1700err:
1727 return ret; 1701 return ret;
1728} 1702}
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 1ef2454c5205..fc80aa6c913c 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -536,8 +536,8 @@ static void pll_factors(unsigned int target, unsigned int source)
536} 536}
537 537
538/* Untested at the moment */ 538/* Untested at the moment */
539static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, 539static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
540 int pll_id, unsigned int freq_in, unsigned int freq_out) 540 int source, unsigned int freq_in, unsigned int freq_out)
541{ 541{
542 struct snd_soc_codec *codec = codec_dai->codec; 542 struct snd_soc_codec *codec = codec_dai->codec;
543 u16 reg; 543 u16 reg;
@@ -731,12 +731,6 @@ static int wm8940_probe(struct platform_device *pdev)
731 if (ret) 731 if (ret)
732 goto error_free_pcms; 732 goto error_free_pcms;
733 733
734 ret = snd_soc_init_card(socdev);
735 if (ret < 0) {
736 dev_err(codec->dev, "failed to register card: %d\n", ret);
737 goto error_free_pcms;
738 }
739
740 return ret; 734 return ret;
741 735
742error_free_pcms: 736error_free_pcms:
@@ -877,21 +871,6 @@ static int __devexit wm8940_i2c_remove(struct i2c_client *client)
877 return 0; 871 return 0;
878} 872}
879 873
880#ifdef CONFIG_PM
881static int wm8940_i2c_suspend(struct i2c_client *client, pm_message_t msg)
882{
883 return snd_soc_suspend_device(&client->dev);
884}
885
886static int wm8940_i2c_resume(struct i2c_client *client)
887{
888 return snd_soc_resume_device(&client->dev);
889}
890#else
891#define wm8940_i2c_suspend NULL
892#define wm8940_i2c_resume NULL
893#endif
894
895static const struct i2c_device_id wm8940_i2c_id[] = { 874static const struct i2c_device_id wm8940_i2c_id[] = {
896 { "wm8940", 0 }, 875 { "wm8940", 0 },
897 { } 876 { }
@@ -905,8 +884,6 @@ static struct i2c_driver wm8940_i2c_driver = {
905 }, 884 },
906 .probe = wm8940_i2c_probe, 885 .probe = wm8940_i2c_probe,
907 .remove = __devexit_p(wm8940_i2c_remove), 886 .remove = __devexit_p(wm8940_i2c_remove),
908 .suspend = wm8940_i2c_suspend,
909 .resume = wm8940_i2c_resume,
910 .id_table = wm8940_i2c_id, 887 .id_table = wm8940_i2c_id,
911}; 888};
912 889
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f59703be61c8..40390afa75f3 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -540,8 +540,8 @@ static int pll_factors(unsigned int source, unsigned int target,
540 return 0; 540 return 0;
541} 541}
542 542
543static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, 543static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
544 int pll_id, unsigned int freq_in, unsigned int freq_out) 544 int source, unsigned int freq_in, unsigned int freq_out)
545{ 545{
546 struct snd_soc_codec *codec = codec_dai->codec; 546 struct snd_soc_codec *codec = codec_dai->codec;
547 u16 reg; 547 u16 reg;
@@ -713,17 +713,9 @@ static int wm8960_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, wm8960_snd_controls, 713 snd_soc_add_controls(codec, wm8960_snd_controls,
714 ARRAY_SIZE(wm8960_snd_controls)); 714 ARRAY_SIZE(wm8960_snd_controls));
715 wm8960_add_widgets(codec); 715 wm8960_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 716
722 return ret; 717 return ret;
723 718
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 719pcm_err:
728 return ret; 720 return ret;
729} 721}
@@ -883,21 +875,6 @@ static __devexit int wm8960_i2c_remove(struct i2c_client *client)
883 return 0; 875 return 0;
884} 876}
885 877
886#ifdef CONFIG_PM
887static int wm8960_i2c_suspend(struct i2c_client *client, pm_message_t msg)
888{
889 return snd_soc_suspend_device(&client->dev);
890}
891
892static int wm8960_i2c_resume(struct i2c_client *client)
893{
894 return snd_soc_resume_device(&client->dev);
895}
896#else
897#define wm8960_i2c_suspend NULL
898#define wm8960_i2c_resume NULL
899#endif
900
901static const struct i2c_device_id wm8960_i2c_id[] = { 878static const struct i2c_device_id wm8960_i2c_id[] = {
902 { "wm8960", 0 }, 879 { "wm8960", 0 },
903 { } 880 { }
@@ -911,8 +888,6 @@ static struct i2c_driver wm8960_i2c_driver = {
911 }, 888 },
912 .probe = wm8960_i2c_probe, 889 .probe = wm8960_i2c_probe,
913 .remove = __devexit_p(wm8960_i2c_remove), 890 .remove = __devexit_p(wm8960_i2c_remove),
914 .suspend = wm8960_i2c_suspend,
915 .resume = wm8960_i2c_resume,
916 .id_table = wm8960_i2c_id, 891 .id_table = wm8960_i2c_id,
917}; 892};
918 893
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 503032085899..07e389574db1 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -988,17 +988,8 @@ static int wm8961_probe(struct platform_device *pdev)
988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
989 snd_soc_dapm_new_widgets(codec); 989 snd_soc_dapm_new_widgets(codec);
990 990
991 ret = snd_soc_init_card(socdev);
992 if (ret < 0) {
993 dev_err(codec->dev, "failed to register card: %d\n", ret);
994 goto card_err;
995 }
996
997 return ret; 991 return ret;
998 992
999card_err:
1000 snd_soc_free_pcms(socdev);
1001 snd_soc_dapm_free(socdev);
1002pcm_err: 993pcm_err:
1003 return ret; 994 return ret;
1004} 995}
@@ -1206,21 +1197,6 @@ static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1206 return 0; 1197 return 0;
1207} 1198}
1208 1199
1209#ifdef CONFIG_PM
1210static int wm8961_i2c_suspend(struct i2c_client *client, pm_message_t state)
1211{
1212 return snd_soc_suspend_device(&client->dev);
1213}
1214
1215static int wm8961_i2c_resume(struct i2c_client *client)
1216{
1217 return snd_soc_resume_device(&client->dev);
1218}
1219#else
1220#define wm8961_i2c_suspend NULL
1221#define wm8961_i2c_resume NULL
1222#endif
1223
1224static const struct i2c_device_id wm8961_i2c_id[] = { 1200static const struct i2c_device_id wm8961_i2c_id[] = {
1225 { "wm8961", 0 }, 1201 { "wm8961", 0 },
1226 { } 1202 { }
@@ -1234,8 +1210,6 @@ static struct i2c_driver wm8961_i2c_driver = {
1234 }, 1210 },
1235 .probe = wm8961_i2c_probe, 1211 .probe = wm8961_i2c_probe,
1236 .remove = __devexit_p(wm8961_i2c_remove), 1212 .remove = __devexit_p(wm8961_i2c_remove),
1237 .suspend = wm8961_i2c_suspend,
1238 .resume = wm8961_i2c_resume,
1239 .id_table = wm8961_i2c_id, 1213 .id_table = wm8961_i2c_id,
1240}; 1214};
1241 1215
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index d66efb0546ea..56a66e89ab91 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -703,16 +703,9 @@ static int wm8971_init(struct snd_soc_device *socdev,
703 snd_soc_add_controls(codec, wm8971_snd_controls, 703 snd_soc_add_controls(codec, wm8971_snd_controls,
704 ARRAY_SIZE(wm8971_snd_controls)); 704 ARRAY_SIZE(wm8971_snd_controls));
705 wm8971_add_widgets(codec); 705 wm8971_add_widgets(codec);
706 ret = snd_soc_init_card(socdev); 706
707 if (ret < 0) {
708 printk(KERN_ERR "wm8971: failed to register card\n");
709 goto card_err;
710 }
711 return ret; 707 return ret;
712 708
713card_err:
714 snd_soc_free_pcms(socdev);
715 snd_soc_dapm_free(socdev);
716err: 709err:
717 kfree(codec->reg_cache); 710 kfree(codec->reg_cache);
718 return ret; 711 return ret;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 98d663afc97d..c245f0ee0ec2 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -281,36 +281,38 @@ static int wm8974_add_widgets(struct snd_soc_codec *codec)
281} 281}
282 282
283struct pll_ { 283struct pll_ {
284 unsigned int pre_div:4; /* prescale - 1 */ 284 unsigned int pre_div:1;
285 unsigned int n:4; 285 unsigned int n:4;
286 unsigned int k; 286 unsigned int k;
287}; 287};
288 288
289static struct pll_ pll_div;
290
291/* The size in bits of the pll divide multiplied by 10 289/* The size in bits of the pll divide multiplied by 10
292 * to allow rounding later */ 290 * to allow rounding later */
293#define FIXED_PLL_SIZE ((1 << 24) * 10) 291#define FIXED_PLL_SIZE ((1 << 24) * 10)
294 292
295static void pll_factors(unsigned int target, unsigned int source) 293static void pll_factors(struct pll_ *pll_div,
294 unsigned int target, unsigned int source)
296{ 295{
297 unsigned long long Kpart; 296 unsigned long long Kpart;
298 unsigned int K, Ndiv, Nmod; 297 unsigned int K, Ndiv, Nmod;
299 298
299 /* There is a fixed divide by 4 in the output path */
300 target *= 4;
301
300 Ndiv = target / source; 302 Ndiv = target / source;
301 if (Ndiv < 6) { 303 if (Ndiv < 6) {
302 source >>= 1; 304 source /= 2;
303 pll_div.pre_div = 1; 305 pll_div->pre_div = 1;
304 Ndiv = target / source; 306 Ndiv = target / source;
305 } else 307 } else
306 pll_div.pre_div = 0; 308 pll_div->pre_div = 0;
307 309
308 if ((Ndiv < 6) || (Ndiv > 12)) 310 if ((Ndiv < 6) || (Ndiv > 12))
309 printk(KERN_WARNING 311 printk(KERN_WARNING
310 "WM8974 N value %u outwith recommended range!\n", 312 "WM8974 N value %u outwith recommended range!\n",
311 Ndiv); 313 Ndiv);
312 314
313 pll_div.n = Ndiv; 315 pll_div->n = Ndiv;
314 Nmod = target % source; 316 Nmod = target % source;
315 Kpart = FIXED_PLL_SIZE * (long long)Nmod; 317 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
316 318
@@ -325,13 +327,14 @@ static void pll_factors(unsigned int target, unsigned int source)
325 /* Move down to proper range now rounding is done */ 327 /* Move down to proper range now rounding is done */
326 K /= 10; 328 K /= 10;
327 329
328 pll_div.k = K; 330 pll_div->k = K;
329} 331}
330 332
331static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, 333static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
332 int pll_id, unsigned int freq_in, unsigned int freq_out) 334 int source, unsigned int freq_in, unsigned int freq_out)
333{ 335{
334 struct snd_soc_codec *codec = codec_dai->codec; 336 struct snd_soc_codec *codec = codec_dai->codec;
337 struct pll_ pll_div;
335 u16 reg; 338 u16 reg;
336 339
337 if (freq_in == 0 || freq_out == 0) { 340 if (freq_in == 0 || freq_out == 0) {
@@ -345,7 +348,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
345 return 0; 348 return 0;
346 } 349 }
347 350
348 pll_factors(freq_out*4, freq_in); 351 pll_factors(&pll_div, freq_out, freq_in);
349 352
350 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); 353 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
351 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18); 354 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
@@ -638,17 +641,9 @@ static int wm8974_probe(struct platform_device *pdev)
638 snd_soc_add_controls(codec, wm8974_snd_controls, 641 snd_soc_add_controls(codec, wm8974_snd_controls,
639 ARRAY_SIZE(wm8974_snd_controls)); 642 ARRAY_SIZE(wm8974_snd_controls));
640 wm8974_add_widgets(codec); 643 wm8974_add_widgets(codec);
641 ret = snd_soc_init_card(socdev);
642 if (ret < 0) {
643 dev_err(codec->dev, "failed to register card: %d\n", ret);
644 goto card_err;
645 }
646 644
647 return ret; 645 return ret;
648 646
649card_err:
650 snd_soc_free_pcms(socdev);
651 snd_soc_dapm_free(socdev);
652pcm_err: 647pcm_err:
653 return ret; 648 return ret;
654} 649}
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 3f530f8a972a..bee292e37d1b 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -792,17 +792,8 @@ static int wm8988_probe(struct platform_device *pdev)
792 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 792 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
793 snd_soc_dapm_new_widgets(codec); 793 snd_soc_dapm_new_widgets(codec);
794 794
795 ret = snd_soc_init_card(socdev);
796 if (ret < 0) {
797 dev_err(codec->dev, "failed to register card: %d\n", ret);
798 goto card_err;
799 }
800
801 return ret; 795 return ret;
802 796
803card_err:
804 snd_soc_free_pcms(socdev);
805 snd_soc_dapm_free(socdev);
806pcm_err: 797pcm_err:
807 return ret; 798 return ret;
808} 799}
@@ -944,21 +935,6 @@ static int wm8988_i2c_remove(struct i2c_client *client)
944 return 0; 935 return 0;
945} 936}
946 937
947#ifdef CONFIG_PM
948static int wm8988_i2c_suspend(struct i2c_client *client, pm_message_t msg)
949{
950 return snd_soc_suspend_device(&client->dev);
951}
952
953static int wm8988_i2c_resume(struct i2c_client *client)
954{
955 return snd_soc_resume_device(&client->dev);
956}
957#else
958#define wm8988_i2c_suspend NULL
959#define wm8988_i2c_resume NULL
960#endif
961
962static const struct i2c_device_id wm8988_i2c_id[] = { 938static const struct i2c_device_id wm8988_i2c_id[] = {
963 { "wm8988", 0 }, 939 { "wm8988", 0 },
964 { } 940 { }
@@ -972,8 +948,6 @@ static struct i2c_driver wm8988_i2c_driver = {
972 }, 948 },
973 .probe = wm8988_i2c_probe, 949 .probe = wm8988_i2c_probe,
974 .remove = wm8988_i2c_remove, 950 .remove = wm8988_i2c_remove,
975 .suspend = wm8988_i2c_suspend,
976 .resume = wm8988_i2c_resume,
977 .id_table = wm8988_i2c_id, 951 .id_table = wm8988_i2c_id,
978}; 952};
979#endif 953#endif
@@ -1006,21 +980,6 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi)
1006 return 0; 980 return 0;
1007} 981}
1008 982
1009#ifdef CONFIG_PM
1010static int wm8988_spi_suspend(struct spi_device *spi, pm_message_t msg)
1011{
1012 return snd_soc_suspend_device(&spi->dev);
1013}
1014
1015static int wm8988_spi_resume(struct spi_device *spi)
1016{
1017 return snd_soc_resume_device(&spi->dev);
1018}
1019#else
1020#define wm8988_spi_suspend NULL
1021#define wm8988_spi_resume NULL
1022#endif
1023
1024static struct spi_driver wm8988_spi_driver = { 983static struct spi_driver wm8988_spi_driver = {
1025 .driver = { 984 .driver = {
1026 .name = "wm8988", 985 .name = "wm8988",
@@ -1029,8 +988,6 @@ static struct spi_driver wm8988_spi_driver = {
1029 }, 988 },
1030 .probe = wm8988_spi_probe, 989 .probe = wm8988_spi_probe,
1031 .remove = __devexit_p(wm8988_spi_remove), 990 .remove = __devexit_p(wm8988_spi_remove),
1032 .suspend = wm8988_spi_suspend,
1033 .resume = wm8988_spi_resume,
1034}; 991};
1035#endif 992#endif
1036 993
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 2d702db4131d..e43cb2c8b915 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -972,8 +972,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
972 pll_div->k = K; 972 pll_div->k = K;
973} 973}
974 974
975static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, 975static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
976 int pll_id, unsigned int freq_in, unsigned int freq_out) 976 int source, unsigned int freq_in, unsigned int freq_out)
977{ 977{
978 u16 reg; 978 u16 reg;
979 struct snd_soc_codec *codec = codec_dai->codec; 979 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1409,16 +1409,9 @@ static int wm8990_init(struct snd_soc_device *socdev)
1409 snd_soc_add_controls(codec, wm8990_snd_controls, 1409 snd_soc_add_controls(codec, wm8990_snd_controls,
1410 ARRAY_SIZE(wm8990_snd_controls)); 1410 ARRAY_SIZE(wm8990_snd_controls));
1411 wm8990_add_widgets(codec); 1411 wm8990_add_widgets(codec);
1412 ret = snd_soc_init_card(socdev); 1412
1413 if (ret < 0) {
1414 printk(KERN_ERR "wm8990: failed to register card\n");
1415 goto card_err;
1416 }
1417 return ret; 1413 return ret;
1418 1414
1419card_err:
1420 snd_soc_free_pcms(socdev);
1421 snd_soc_dapm_free(socdev);
1422pcm_err: 1415pcm_err:
1423 kfree(codec->reg_cache); 1416 kfree(codec->reg_cache);
1424 return ret; 1417 return ret;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d9987999e92c..0d4d2be92b64 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -422,7 +422,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
422 return 0; 422 return 0;
423} 423}
424 424
425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, 425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
426 unsigned int Fref, unsigned int Fout) 426 unsigned int Fref, unsigned int Fout)
427{ 427{
428 struct snd_soc_codec *codec = dai->codec; 428 struct snd_soc_codec *codec = dai->codec;
@@ -1466,17 +1466,8 @@ static int wm8993_probe(struct platform_device *pdev)
1466 1466
1467 snd_soc_dapm_new_widgets(codec); 1467 snd_soc_dapm_new_widgets(codec);
1468 1468
1469 ret = snd_soc_init_card(socdev);
1470 if (ret < 0) {
1471 dev_err(codec->dev, "failed to register card\n");
1472 goto card_err;
1473 }
1474
1475 return ret; 1469 return ret;
1476 1470
1477card_err:
1478 snd_soc_free_pcms(socdev);
1479 snd_soc_dapm_free(socdev);
1480err: 1471err:
1481 return ret; 1472 return ret;
1482} 1473}
@@ -1572,33 +1563,15 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1572 /* Use automatic clock configuration */ 1563 /* Use automatic clock configuration */
1573 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0); 1564 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1574 1565
1575 if (!wm8993->pdata.lineout1_diff) 1566 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1576 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 1567 wm8993->pdata.lineout2_diff,
1577 WM8993_LINEOUT1_MODE, 1568 wm8993->pdata.lineout1fb,
1578 WM8993_LINEOUT1_MODE); 1569 wm8993->pdata.lineout2fb,
1579 if (!wm8993->pdata.lineout2_diff) 1570 wm8993->pdata.jd_scthr,
1580 snd_soc_update_bits(codec, WM8993_LINE_MIXER2, 1571 wm8993->pdata.jd_thr,
1581 WM8993_LINEOUT2_MODE, 1572 wm8993->pdata.micbias1_lvl,
1582 WM8993_LINEOUT2_MODE); 1573 wm8993->pdata.micbias2_lvl);
1583 1574
1584 if (wm8993->pdata.lineout1fb)
1585 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1586 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
1587
1588 if (wm8993->pdata.lineout2fb)
1589 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1590 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
1591
1592 /* Apply the microphone bias/detection configuration - the
1593 * platform data is directly applicable to the register. */
1594 snd_soc_update_bits(codec, WM8993_MICBIAS,
1595 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
1596 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
1597 wm8993->pdata.jd_scthr << WM8993_JD_SCTHR_SHIFT |
1598 wm8993->pdata.jd_thr << WM8993_JD_THR_SHIFT |
1599 wm8993->pdata.micbias1_lvl |
1600 wm8993->pdata.micbias1_lvl << 1);
1601
1602 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1575 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1603 if (ret != 0) 1576 if (ret != 0)
1604 goto err; 1577 goto err;
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 686e5aa97206..3f1f84421312 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1264,17 +1264,8 @@ static int wm9081_probe(struct platform_device *pdev)
1264 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1264 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1265 snd_soc_dapm_new_widgets(codec); 1265 snd_soc_dapm_new_widgets(codec);
1266 1266
1267 ret = snd_soc_init_card(socdev);
1268 if (ret < 0) {
1269 dev_err(codec->dev, "failed to register card: %d\n", ret);
1270 goto card_err;
1271 }
1272
1273 return ret; 1267 return ret;
1274 1268
1275card_err:
1276 snd_soc_free_pcms(socdev);
1277 snd_soc_dapm_free(socdev);
1278pcm_err: 1269pcm_err:
1279 return ret; 1270 return ret;
1280} 1271}
@@ -1452,21 +1443,6 @@ static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1452 return 0; 1443 return 0;
1453} 1444}
1454 1445
1455#ifdef CONFIG_PM
1456static int wm9081_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1457{
1458 return snd_soc_suspend_device(&client->dev);
1459}
1460
1461static int wm9081_i2c_resume(struct i2c_client *client)
1462{
1463 return snd_soc_resume_device(&client->dev);
1464}
1465#else
1466#define wm9081_i2c_suspend NULL
1467#define wm9081_i2c_resume NULL
1468#endif
1469
1470static const struct i2c_device_id wm9081_i2c_id[] = { 1446static const struct i2c_device_id wm9081_i2c_id[] = {
1471 { "wm9081", 0 }, 1447 { "wm9081", 0 },
1472 { } 1448 { }
@@ -1480,8 +1456,6 @@ static struct i2c_driver wm9081_i2c_driver = {
1480 }, 1456 },
1481 .probe = wm9081_i2c_probe, 1457 .probe = wm9081_i2c_probe,
1482 .remove = __devexit_p(wm9081_i2c_remove), 1458 .remove = __devexit_p(wm9081_i2c_remove),
1483 .suspend = wm9081_i2c_suspend,
1484 .resume = wm9081_i2c_resume,
1485 .id_table = wm9081_i2c_id, 1459 .id_table = wm9081_i2c_id,
1486}; 1460};
1487 1461
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index e7d2840d9e59..0e817b8705cd 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -403,16 +403,8 @@ static int wm9705_soc_probe(struct platform_device *pdev)
403 ARRAY_SIZE(wm9705_snd_ac97_controls)); 403 ARRAY_SIZE(wm9705_snd_ac97_controls));
404 wm9705_add_widgets(codec); 404 wm9705_add_widgets(codec);
405 405
406 ret = snd_soc_init_card(socdev);
407 if (ret < 0) {
408 printk(KERN_ERR "wm9705: failed to register card\n");
409 goto reset_err;
410 }
411
412 return 0; 406 return 0;
413 407
414reset_err:
415 snd_soc_free_pcms(socdev);
416pcm_err: 408pcm_err:
417 snd_soc_free_ac97_codec(codec); 409 snd_soc_free_ac97_codec(codec);
418codec_err: 410codec_err:
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 1fd4e88f50cf..155cacf124ea 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -695,17 +695,9 @@ static int wm9712_soc_probe(struct platform_device *pdev)
695 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 695 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
696 ARRAY_SIZE(wm9712_snd_ac97_controls)); 696 ARRAY_SIZE(wm9712_snd_ac97_controls));
697 wm9712_add_widgets(codec); 697 wm9712_add_widgets(codec);
698 ret = snd_soc_init_card(socdev);
699 if (ret < 0) {
700 printk(KERN_ERR "wm9712: failed to register card\n");
701 goto reset_err;
702 }
703 698
704 return 0; 699 return 0;
705 700
706reset_err:
707 snd_soc_free_pcms(socdev);
708
709pcm_err: 701pcm_err:
710 snd_soc_free_ac97_codec(codec); 702 snd_soc_free_ac97_codec(codec);
711 703
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index abed37acf787..5f81ecd20a81 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -800,8 +800,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
800 return 0; 800 return 0;
801} 801}
802 802
803static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, 803static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
804 int pll_id, unsigned int freq_in, unsigned int freq_out) 804 int source, unsigned int freq_in, unsigned int freq_out)
805{ 805{
806 struct snd_soc_codec *codec = codec_dai->codec; 806 struct snd_soc_codec *codec = codec_dai->codec;
807 return wm9713_set_pll(codec, pll_id, freq_in, freq_out); 807 return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
@@ -1247,13 +1247,8 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1247 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1247 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1248 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1248 ARRAY_SIZE(wm9713_snd_ac97_controls));
1249 wm9713_add_widgets(codec); 1249 wm9713_add_widgets(codec);
1250 ret = snd_soc_init_card(socdev);
1251 if (ret < 0)
1252 goto reset_err;
1253 return 0;
1254 1250
1255reset_err: 1251 return 0;
1256 snd_soc_free_pcms(socdev);
1257 1252
1258pcm_err: 1253pcm_err:
1259 snd_soc_free_ac97_codec(codec); 1254 snd_soc_free_ac97_codec(codec);
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e542027eea89..810a563d0ebf 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -738,6 +738,41 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
738} 738}
739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes); 739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
740 740
741int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
742 int lineout1_diff, int lineout2_diff,
743 int lineout1fb, int lineout2fb,
744 int jd_scthr, int jd_thr, int micbias1_lvl,
745 int micbias2_lvl)
746{
747 if (!lineout1_diff)
748 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
749 WM8993_LINEOUT1_MODE,
750 WM8993_LINEOUT1_MODE);
751 if (!lineout2_diff)
752 snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
753 WM8993_LINEOUT2_MODE,
754 WM8993_LINEOUT2_MODE);
755
756 if (lineout1fb)
757 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
758 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
759
760 if (lineout2fb)
761 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
762 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
763
764 snd_soc_update_bits(codec, WM8993_MICBIAS,
765 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
766 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
767 jd_scthr << WM8993_JD_SCTHR_SHIFT |
768 jd_thr << WM8993_JD_THR_SHIFT |
769 micbias1_lvl |
770 micbias2_lvl << WM8993_MICB2_LVL_SHIFT);
771
772 return 0;
773}
774EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
775
741MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 776MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
742MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 777MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
743MODULE_LICENSE("GPL"); 778MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index ec09cb6a2939..36d3fba1de8b 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -20,5 +20,10 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
20 20
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int); 22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
23extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
24 int lineout1_diff, int lineout2_diff,
25 int lineout1fb, int lineout2fb,
26 int jd_scthr, int jd_thr,
27 int micbias1_lvl, int micbias2_lvl);
23 28
24#endif 29#endif
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 4dfd4ad9d90e..047ee39418c0 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -13,9 +13,9 @@ config SND_DAVINCI_SOC_MCASP
13 tristate 13 tristate
14 14
15config SND_DAVINCI_SOC_EVM 15config SND_DAVINCI_SOC_EVM
16 tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM" 16 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
17 depends on SND_DAVINCI_SOC 17 depends on SND_DAVINCI_SOC
18 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM 18 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
19 select SND_DAVINCI_SOC_I2S 19 select SND_DAVINCI_SOC_I2S
20 select SND_SOC_TLV320AIC3X 20 select SND_SOC_TLV320AIC3X
21 help 21 help
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 67414f659405..7ccbe6684fc2 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -45,7 +45,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
45 unsigned sysclk; 45 unsigned sysclk;
46 46
47 /* ASP1 on DM355 EVM is clocked by an external oscillator */ 47 /* ASP1 on DM355 EVM is clocked by an external oscillator */
48 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm()) 48 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
49 machine_is_davinci_dm365_evm())
49 sysclk = 27000000; 50 sysclk = 27000000;
50 51
51 /* ASP0 in DM6446 EVM is clocked by U55, as configured by 52 /* ASP0 in DM6446 EVM is clocked by U55, as configured by
@@ -176,7 +177,7 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
176 .ops = &evm_ops, 177 .ops = &evm_ops,
177}; 178};
178 179
179/* davinci-evm audio machine driver */ 180/* davinci dm6446, dm355 or dm365 evm audio machine driver */
180static struct snd_soc_card snd_soc_card_evm = { 181static struct snd_soc_card snd_soc_card_evm = {
181 .name = "DaVinci EVM", 182 .name = "DaVinci EVM",
182 .platform = &davinci_soc_platform, 183 .platform = &davinci_soc_platform,
@@ -243,7 +244,7 @@ static int __init evm_init(void)
243 int index; 244 int index;
244 int ret; 245 int ret;
245 246
246 if (machine_is_davinci_evm()) { 247 if (machine_is_davinci_evm() || machine_is_davinci_dm365_evm()) {
247 evm_snd_dev_data = &evm_snd_devdata; 248 evm_snd_dev_data = &evm_snd_devdata;
248 index = 0; 249 index = 0;
249 } else if (machine_is_davinci_dm355_evm()) { 250 } else if (machine_is_davinci_dm355_evm()) {
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 4ae707048021..2ab809359c08 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -397,6 +397,8 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
397 } 397 }
398 398
399 dma_params->acnt = dma_params->data_type; 399 dma_params->acnt = dma_params->data_type;
400 dma_params->fifo_level = 0;
401
400 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1); 402 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1);
401 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1); 403 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1);
402 404
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 5d1f98a4c978..50ad0519a8fa 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -714,16 +714,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
714 struct davinci_pcm_dma_params *dma_params = 714 struct davinci_pcm_dma_params *dma_params =
715 &dev->dma_params[substream->stream]; 715 &dev->dma_params[substream->stream];
716 int word_length; 716 int word_length;
717 u8 numevt; 717 u8 fifo_level;
718 718
719 davinci_hw_common_param(dev, substream->stream); 719 davinci_hw_common_param(dev, substream->stream);
720 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 720 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
721 numevt = dev->txnumevt; 721 fifo_level = dev->txnumevt;
722 else 722 else
723 numevt = dev->rxnumevt; 723 fifo_level = dev->rxnumevt;
724
725 if (!numevt)
726 numevt = 1;
727 724
728 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) 725 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE)
729 davinci_hw_dit_param(dev); 726 davinci_hw_dit_param(dev);
@@ -751,12 +748,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
751 return -EINVAL; 748 return -EINVAL;
752 } 749 }
753 750
754 if (dev->version == MCASP_VERSION_2) { 751 if (dev->version == MCASP_VERSION_2 && !fifo_level)
755 dma_params->data_type *= numevt; 752 dma_params->acnt = 4;
756 dma_params->acnt = 4 * numevt; 753 else
757 } else
758 dma_params->acnt = dma_params->data_type; 754 dma_params->acnt = dma_params->data_type;
759 755
756 dma_params->fifo_level = fifo_level;
760 davinci_config_channel_size(dev, word_length); 757 davinci_config_channel_size(dev, word_length);
761 758
762 return 0; 759 return 0;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index c73a915f233f..fb10f1d63fdb 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -66,38 +66,53 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
66 dma_addr_t dma_pos; 66 dma_addr_t dma_pos;
67 dma_addr_t src, dst; 67 dma_addr_t src, dst;
68 unsigned short src_bidx, dst_bidx; 68 unsigned short src_bidx, dst_bidx;
69 unsigned short src_cidx, dst_cidx;
69 unsigned int data_type; 70 unsigned int data_type;
70 unsigned short acnt; 71 unsigned short acnt;
71 unsigned int count; 72 unsigned int count;
73 unsigned int fifo_level;
72 74
73 period_size = snd_pcm_lib_period_bytes(substream); 75 period_size = snd_pcm_lib_period_bytes(substream);
74 dma_offset = prtd->period * period_size; 76 dma_offset = prtd->period * period_size;
75 dma_pos = runtime->dma_addr + dma_offset; 77 dma_pos = runtime->dma_addr + dma_offset;
78 fifo_level = prtd->params->fifo_level;
76 79
77 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " 80 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
78 "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size); 81 "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size);
79 82
80 data_type = prtd->params->data_type; 83 data_type = prtd->params->data_type;
81 count = period_size / data_type; 84 count = period_size / data_type;
85 if (fifo_level)
86 count /= fifo_level;
82 87
83 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 88 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
84 src = dma_pos; 89 src = dma_pos;
85 dst = prtd->params->dma_addr; 90 dst = prtd->params->dma_addr;
86 src_bidx = data_type; 91 src_bidx = data_type;
87 dst_bidx = 0; 92 dst_bidx = 0;
93 src_cidx = data_type * fifo_level;
94 dst_cidx = 0;
88 } else { 95 } else {
89 src = prtd->params->dma_addr; 96 src = prtd->params->dma_addr;
90 dst = dma_pos; 97 dst = dma_pos;
91 src_bidx = 0; 98 src_bidx = 0;
92 dst_bidx = data_type; 99 dst_bidx = data_type;
100 src_cidx = 0;
101 dst_cidx = data_type * fifo_level;
93 } 102 }
94 103
95 acnt = prtd->params->acnt; 104 acnt = prtd->params->acnt;
96 edma_set_src(lch, src, INCR, W8BIT); 105 edma_set_src(lch, src, INCR, W8BIT);
97 edma_set_dest(lch, dst, INCR, W8BIT); 106 edma_set_dest(lch, dst, INCR, W8BIT);
98 edma_set_src_index(lch, src_bidx, 0); 107
99 edma_set_dest_index(lch, dst_bidx, 0); 108 edma_set_src_index(lch, src_bidx, src_cidx);
100 edma_set_transfer_params(lch, acnt, count, 1, 0, ASYNC); 109 edma_set_dest_index(lch, dst_bidx, dst_cidx);
110
111 if (!fifo_level)
112 edma_set_transfer_params(lch, acnt, count, 1, 0, ASYNC);
113 else
114 edma_set_transfer_params(lch, acnt, fifo_level, count,
115 fifo_level, ABSYNC);
101 116
102 prtd->period++; 117 prtd->period++;
103 if (unlikely(prtd->period >= runtime->periods)) 118 if (unlikely(prtd->period >= runtime->periods))
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 8746606efc89..c8b0d2baf05a 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -23,6 +23,7 @@ struct davinci_pcm_dma_params {
23 enum dma_event_q eventq_no; /* event queue number */ 23 enum dma_event_q eventq_no; /* event queue number */
24 unsigned char data_type; /* xfer data type */ 24 unsigned char data_type; /* xfer data type */
25 unsigned char convert_mono_stereo; 25 unsigned char convert_mono_stereo;
26 unsigned int fifo_level;
26}; 27};
27 28
28 29
diff --git a/sound/soc/imx/mx27vis_wm8974.c b/sound/soc/imx/mx27vis_wm8974.c
index e4dcb539108a..0267d2d91685 100644
--- a/sound/soc/imx/mx27vis_wm8974.c
+++ b/sound/soc/imx/mx27vis_wm8974.c
@@ -157,7 +157,7 @@ static int mx27vis_hifi_hw_params(struct snd_pcm_substream *substream,
157 157
158 158
159 /* codec PLL input is 25 MHz */ 159 /* codec PLL input is 25 MHz */
160 ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, 160 ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, IGNORED_ARG,
161 25000000, pll_out); 161 25000000, pll_out);
162 if (ret < 0) { 162 if (ret < 0) {
163 printk(KERN_ERR "Error when setting PLL input\n"); 163 printk(KERN_ERR "Error when setting PLL input\n");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 653a362425df..bb5731a22bed 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -66,6 +66,15 @@ config SND_OMAP_SOC_OMAP3EVM
66 help 66 help
67 Say Y if you want to add support for SoC audio on the omap3evm board. 67 Say Y if you want to add support for SoC audio on the omap3evm board.
68 68
69config SND_OMAP_SOC_AM3517EVM
70 tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
71 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
72 select SND_OMAP_SOC_MCBSP
73 select SND_SOC_TLV320AIC23
74 help
75 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
76 EVM.
77
69config SND_OMAP_SOC_SDP3430 78config SND_OMAP_SOC_SDP3430
70 tristate "SoC Audio support for Texas Instruments SDP3430" 79 tristate "SoC Audio support for Texas Instruments SDP3430"
71 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP 80 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 02d69471dcb5..0c78ae4e6b97 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -12,6 +12,7 @@ snd-soc-osk5912-objs := osk5912.o
12snd-soc-overo-objs := overo.o 12snd-soc-overo-objs := overo.o
13snd-soc-omap2evm-objs := omap2evm.o 13snd-soc-omap2evm-objs := omap2evm.o
14snd-soc-omap3evm-objs := omap3evm.o 14snd-soc-omap3evm-objs := omap3evm.o
15snd-soc-am3517evm-objs := am3517evm.o
15snd-soc-sdp3430-objs := sdp3430.o 16snd-soc-sdp3430-objs := sdp3430.o
16snd-soc-omap3pandora-objs := omap3pandora.o 17snd-soc-omap3pandora-objs := omap3pandora.o
17snd-soc-omap3beagle-objs := omap3beagle.o 18snd-soc-omap3beagle-objs := omap3beagle.o
@@ -23,6 +24,7 @@ obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
23obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o 24obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
24obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o 25obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
25obj-$(CONFIG_MACH_OMAP3EVM) += snd-soc-omap3evm.o 26obj-$(CONFIG_MACH_OMAP3EVM) += snd-soc-omap3evm.o
27obj-$(CONFIG_MACH_OMAP3517EVM) += snd-soc-am3517evm.o
26obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 28obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
27obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 29obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
28obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o 30obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
new file mode 100644
index 000000000000..135901b2ea11
--- /dev/null
+++ b/sound/soc/omap/am3517evm.c
@@ -0,0 +1,202 @@
1/*
2 * am3517evm.c -- ALSA SoC support for OMAP3517 / AM3517 EVM
3 *
4 * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
5 *
6 * Based on sound/soc/omap/beagle.c by Steve Sakoman
7 *
8 * Copyright (C) 2009 Texas Instruments Incorporated
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation version 2.
13 *
14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
15 * whether express or implied; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#include <linux/clk.h>
21#include <linux/platform_device.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include <mach/gpio.h>
30#include <plat/mcbsp.h>
31
32#include "omap-mcbsp.h"
33#include "omap-pcm.h"
34
35#include "../codecs/tlv320aic23.h"
36
37#define CODEC_CLOCK 12000000
38
39static int am3517evm_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params)
41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
44 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
45 int ret;
46
47 /* Set codec DAI configuration */
48 ret = snd_soc_dai_set_fmt(codec_dai,
49 SND_SOC_DAIFMT_DSP_B |
50 SND_SOC_DAIFMT_NB_NF |
51 SND_SOC_DAIFMT_CBM_CFM);
52 if (ret < 0) {
53 printk(KERN_ERR "can't set codec DAI configuration\n");
54 return ret;
55 }
56
57 /* Set cpu DAI configuration */
58 ret = snd_soc_dai_set_fmt(cpu_dai,
59 SND_SOC_DAIFMT_DSP_B |
60 SND_SOC_DAIFMT_NB_NF |
61 SND_SOC_DAIFMT_CBM_CFM);
62 if (ret < 0) {
63 printk(KERN_ERR "can't set cpu DAI configuration\n");
64 return ret;
65 }
66
67 /* Set the codec system clock for DAC and ADC */
68 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
69 CODEC_CLOCK, SND_SOC_CLOCK_IN);
70 if (ret < 0) {
71 printk(KERN_ERR "can't set codec system clock\n");
72 return ret;
73 }
74
75 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
76 SND_SOC_CLOCK_IN);
77 if (ret < 0) {
78 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
79 return ret;
80 }
81
82 snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
83 SND_SOC_CLOCK_IN);
84 if (ret < 0) {
85 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
86 return ret;
87 }
88
89 return 0;
90}
91
92static struct snd_soc_ops am3517evm_ops = {
93 .hw_params = am3517evm_hw_params,
94};
95
96/* am3517evm machine dapm widgets */
97static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
98 SND_SOC_DAPM_HP("Line Out", NULL),
99 SND_SOC_DAPM_LINE("Line In", NULL),
100 SND_SOC_DAPM_MIC("Mic In", NULL),
101};
102
103static const struct snd_soc_dapm_route audio_map[] = {
104 /* Line Out connected to LLOUT, RLOUT */
105 {"Line Out", NULL, "LOUT"},
106 {"Line Out", NULL, "ROUT"},
107
108 {"LLINEIN", NULL, "Line In"},
109 {"RLINEIN", NULL, "Line In"},
110
111 {"MICIN", NULL, "Mic In"},
112};
113
114static int am3517evm_aic23_init(struct snd_soc_codec *codec)
115{
116 /* Add am3517-evm specific widgets */
117 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
118 ARRAY_SIZE(tlv320aic23_dapm_widgets));
119
120 /* Set up davinci-evm specific audio path audio_map */
121 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
122
123 /* always connected */
124 snd_soc_dapm_enable_pin(codec, "Line Out");
125 snd_soc_dapm_enable_pin(codec, "Line In");
126 snd_soc_dapm_enable_pin(codec, "Mic In");
127
128 snd_soc_dapm_sync(codec);
129
130 return 0;
131}
132
133/* Digital audio interface glue - connects codec <--> CPU */
134static struct snd_soc_dai_link am3517evm_dai = {
135 .name = "TLV320AIC23",
136 .stream_name = "AIC23",
137 .cpu_dai = &omap_mcbsp_dai[0],
138 .codec_dai = &tlv320aic23_dai,
139 .init = am3517evm_aic23_init,
140 .ops = &am3517evm_ops,
141};
142
143/* Audio machine driver */
144static struct snd_soc_card snd_soc_am3517evm = {
145 .name = "am3517evm",
146 .platform = &omap_soc_platform,
147 .dai_link = &am3517evm_dai,
148 .num_links = 1,
149};
150
151/* Audio subsystem */
152static struct snd_soc_device am3517evm_snd_devdata = {
153 .card = &snd_soc_am3517evm,
154 .codec_dev = &soc_codec_dev_tlv320aic23,
155};
156
157static struct platform_device *am3517evm_snd_device;
158
159static int __init am3517evm_soc_init(void)
160{
161 int ret;
162
163 if (!machine_is_omap3517evm()) {
164 pr_err("Not OMAP3517 / AM3517 EVM!\n");
165 return -ENODEV;
166 }
167 pr_info("OMAP3517 / AM3517 EVM SoC init\n");
168
169 am3517evm_snd_device = platform_device_alloc("soc-audio", -1);
170 if (!am3517evm_snd_device) {
171 printk(KERN_ERR "Platform device allocation failed\n");
172 return -ENOMEM;
173 }
174
175 platform_set_drvdata(am3517evm_snd_device, &am3517evm_snd_devdata);
176 am3517evm_snd_devdata.dev = &am3517evm_snd_device->dev;
177 *(unsigned int *)am3517evm_dai.cpu_dai->private_data = 0; /* McBSP1 */
178
179 ret = platform_device_add(am3517evm_snd_device);
180 if (ret)
181 goto err1;
182
183 return 0;
184
185err1:
186 printk(KERN_ERR "Unable to add platform device\n");
187 platform_device_put(am3517evm_snd_device);
188
189 return ret;
190}
191
192static void __exit am3517evm_soc_exit(void)
193{
194 platform_device_unregister(am3517evm_snd_device);
195}
196
197module_init(am3517evm_soc_init);
198module_exit(am3517evm_soc_exit);
199
200MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
201MODULE_DESCRIPTION("ALSA SoC OMAP3517 / AM3517 EVM");
202MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 5a5166ac7279..ae0fc9b135d4 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -40,7 +40,7 @@
40 40
41 41
42/* Board specific DAPM widgets */ 42/* Board specific DAPM widgets */
43 const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { 43static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = {
44 /* Handset */ 44 /* Handset */
45 SND_SOC_DAPM_MIC("Mouthpiece", NULL), 45 SND_SOC_DAPM_MIC("Mouthpiece", NULL),
46 SND_SOC_DAPM_HP("Earpiece", NULL), 46 SND_SOC_DAPM_HP("Earpiece", NULL),
@@ -81,7 +81,7 @@ static const char *ams_delta_audio_mode[] =
81 (1 << AMS_DELTA_SPEAKER)) 81 (1 << AMS_DELTA_SPEAKER))
82#define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC)) 82#define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC))
83 83
84unsigned short ams_delta_audio_mode_pins[] = { 84static const unsigned short ams_delta_audio_mode_pins[] = {
85 AMS_DELTA_MIXED, 85 AMS_DELTA_MIXED,
86 AMS_DELTA_HANDSET, 86 AMS_DELTA_HANDSET,
87 AMS_DELTA_HANDSFREE, 87 AMS_DELTA_HANDSFREE,
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 9114c263077b..8deb59bb10b1 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -93,10 +93,17 @@ static struct snd_soc_card snd_soc_omap3evm = {
93 .num_links = 1, 93 .num_links = 1,
94}; 94};
95 95
96/* twl4030 setup */
97static struct twl4030_setup_data twl4030_setup = {
98 .ramp_delay_value = 4,
99 .sysclk = 26000,
100};
101
96/* Audio subsystem */ 102/* Audio subsystem */
97static struct snd_soc_device omap3evm_snd_devdata = { 103static struct snd_soc_device omap3evm_snd_devdata = {
98 .card = &snd_soc_omap3evm, 104 .card = &snd_soc_omap3evm,
99 .codec_dev = &soc_codec_dev_twl4030, 105 .codec_dev = &soc_codec_dev_twl4030,
106 .codec_data = &twl4030_setup,
100}; 107};
101 108
102static struct platform_device *omap3evm_snd_device; 109static struct platform_device *omap3evm_snd_device;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index dcb3181bb340..d4f4031afa33 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -90,7 +90,8 @@ config SND_PXA2XX_SOC_E800
90 90
91config SND_PXA2XX_SOC_EM_X270 91config SND_PXA2XX_SOC_EM_X270
92 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300" 92 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300"
93 depends on SND_PXA2XX_SOC && MACH_EM_X270 93 depends on SND_PXA2XX_SOC && (MACH_EM_X270 || MACH_EXEDA || \
94 MACH_CM_X300)
94 select SND_PXA2XX_SOC_AC97 95 select SND_PXA2XX_SOC_AC97
95 select SND_SOC_WM9712 96 select SND_SOC_WM9712
96 help 97 help
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 9f7c61e23daf..4c8d99a8d386 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -213,7 +213,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
213 return ret; 213 return ret;
214 214
215 /* set SSP audio pll clock */ 215 /* set SSP audio pll clock */
216 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, acps); 216 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, acps);
217 if (ret < 0) 217 if (ret < 0)
218 return ret; 218 return ret;
219 219
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d11a6d7e384a..3bd7712f029b 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -305,8 +305,8 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
305/* 305/*
306 * Configure the PLL frequency pxa27x and (afaik - pxa320 only) 306 * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
307 */ 307 */
308static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, 308static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
309 int pll_id, unsigned int freq_in, unsigned int freq_out) 309 int source, unsigned int freq_in, unsigned int freq_out)
310{ 310{
311 struct ssp_priv *priv = cpu_dai->private_data; 311 struct ssp_priv *priv = cpu_dai->private_data;
312 struct ssp_device *ssp = priv->dev.ssp; 312 struct ssp_device *ssp = priv->dev.ssp;
@@ -760,13 +760,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
760 .resume = pxa_ssp_resume, 760 .resume = pxa_ssp_resume,
761 .playback = { 761 .playback = {
762 .channels_min = 1, 762 .channels_min = 1,
763 .channels_max = 2, 763 .channels_max = 8,
764 .rates = PXA_SSP_RATES, 764 .rates = PXA_SSP_RATES,
765 .formats = PXA_SSP_FORMATS, 765 .formats = PXA_SSP_FORMATS,
766 }, 766 },
767 .capture = { 767 .capture = {
768 .channels_min = 1, 768 .channels_min = 1,
769 .channels_max = 2, 769 .channels_max = 8,
770 .rates = PXA_SSP_RATES, 770 .rates = PXA_SSP_RATES,
771 .formats = PXA_SSP_FORMATS, 771 .formats = PXA_SSP_FORMATS,
772 }, 772 },
@@ -780,13 +780,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
780 .resume = pxa_ssp_resume, 780 .resume = pxa_ssp_resume,
781 .playback = { 781 .playback = {
782 .channels_min = 1, 782 .channels_min = 1,
783 .channels_max = 2, 783 .channels_max = 8,
784 .rates = PXA_SSP_RATES, 784 .rates = PXA_SSP_RATES,
785 .formats = PXA_SSP_FORMATS, 785 .formats = PXA_SSP_FORMATS,
786 }, 786 },
787 .capture = { 787 .capture = {
788 .channels_min = 1, 788 .channels_min = 1,
789 .channels_max = 2, 789 .channels_max = 8,
790 .rates = PXA_SSP_RATES, 790 .rates = PXA_SSP_RATES,
791 .formats = PXA_SSP_FORMATS, 791 .formats = PXA_SSP_FORMATS,
792 }, 792 },
@@ -801,13 +801,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
801 .resume = pxa_ssp_resume, 801 .resume = pxa_ssp_resume,
802 .playback = { 802 .playback = {
803 .channels_min = 1, 803 .channels_min = 1,
804 .channels_max = 2, 804 .channels_max = 8,
805 .rates = PXA_SSP_RATES, 805 .rates = PXA_SSP_RATES,
806 .formats = PXA_SSP_FORMATS, 806 .formats = PXA_SSP_FORMATS,
807 }, 807 },
808 .capture = { 808 .capture = {
809 .channels_min = 1, 809 .channels_min = 1,
810 .channels_max = 2, 810 .channels_max = 8,
811 .rates = PXA_SSP_RATES, 811 .rates = PXA_SSP_RATES,
812 .formats = PXA_SSP_FORMATS, 812 .formats = PXA_SSP_FORMATS,
813 }, 813 },
@@ -822,13 +822,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
822 .resume = pxa_ssp_resume, 822 .resume = pxa_ssp_resume,
823 .playback = { 823 .playback = {
824 .channels_min = 1, 824 .channels_min = 1,
825 .channels_max = 2, 825 .channels_max = 8,
826 .rates = PXA_SSP_RATES, 826 .rates = PXA_SSP_RATES,
827 .formats = PXA_SSP_FORMATS, 827 .formats = PXA_SSP_FORMATS,
828 }, 828 },
829 .capture = { 829 .capture = {
830 .channels_min = 1, 830 .channels_min = 1,
831 .channels_max = 2, 831 .channels_max = 8,
832 .rates = PXA_SSP_RATES, 832 .rates = PXA_SSP_RATES,
833 .formats = PXA_SSP_FORMATS, 833 .formats = PXA_SSP_FORMATS,
834 }, 834 },
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 9a386b4c4ed1..dd678ae24398 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -74,7 +74,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
74static int zylonite_wm9713_init(struct snd_soc_codec *codec) 74static int zylonite_wm9713_init(struct snd_soc_codec *codec)
75{ 75{
76 if (clk_pout) 76 if (clk_pout)
77 snd_soc_dai_set_pll(&codec->dai[0], 0, clk_get_rate(pout), 0); 77 snd_soc_dai_set_pll(&codec->dai[0], 0, 0,
78 clk_get_rate(pout), 0);
78 79
79 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, 80 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
80 ARRAY_SIZE(zylonite_dapm_widgets)); 81 ARRAY_SIZE(zylonite_dapm_widgets));
@@ -128,7 +129,7 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
128 if (ret < 0) 129 if (ret < 0)
129 return ret; 130 return ret;
130 131
131 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, pll_out); 132 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, pll_out);
132 if (ret < 0) 133 if (ret < 0)
133 return ret; 134 return ret;
134 135
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 923428fc1adb..d7912f1e4627 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -56,6 +56,15 @@ config SND_S3C24XX_SOC_JIVE_WM8750
56 help 56 help
57 Sat Y if you want to add support for SoC audio on the Jive. 57 Sat Y if you want to add support for SoC audio on the Jive.
58 58
59config SND_S3C64XX_SOC_WM8580
60 tristate "SoC I2S Audio support for WM8580 on SMDK64XX"
61 depends on SND_S3C24XX_SOC && (MACH_SMDK6400 || MACH_SMDK6410)
62 depends on BROKEN
63 select SND_SOC_WM8580
64 select SND_S3C64XX_SOC_I2S
65 help
66 Sat Y if you want to add support for SoC audio on the SMDK64XX.
67
59config SND_S3C24XX_SOC_SMDK2443_WM9710 68config SND_S3C24XX_SOC_SMDK2443_WM9710
60 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 69 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
61 depends on SND_S3C24XX_SOC && MACH_SMDK2443 70 depends on SND_S3C24XX_SOC && MACH_SMDK2443
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 99f5a7dd3fc6..7790406f90b7 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -23,6 +23,7 @@ snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
23snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o 23snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
24snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o 24snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
25snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o 25snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
26snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
26 27
27obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o 28obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
28obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 29obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -33,4 +34,5 @@ obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
33obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o 34obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
34obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o 35obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
35obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o 36obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
37obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
36 38
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
index 0c52e36ddd87..26409a9cef9e 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
@@ -119,7 +119,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
119 return ret; 119 return ret;
120 120
121 /* codec PLL input is PCLK/4 */ 121 /* codec PLL input is PCLK/4 */
122 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 122 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
123 iis_clkrate / 4, pll_out); 123 iis_clkrate / 4, pll_out);
124 if (ret < 0) 124 if (ret < 0)
125 return ret; 125 return ret;
@@ -133,7 +133,7 @@ static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
133 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 133 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
134 134
135 /* disable the PLL */ 135 /* disable the PLL */
136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); 136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
137} 137}
138 138
139/* 139/*
@@ -183,7 +183,7 @@ static int neo1973_gta02_voice_hw_params(
183 return ret; 183 return ret;
184 184
185 /* configue and enable PLL for 12.288MHz output */ 185 /* configue and enable PLL for 12.288MHz output */
186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
187 iis_clkrate / 4, 12288000); 187 iis_clkrate / 4, 12288000);
188 if (ret < 0) 188 if (ret < 0)
189 return ret; 189 return ret;
@@ -197,7 +197,7 @@ static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
197 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 197 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
198 198
199 /* disable the PLL */ 199 /* disable the PLL */
200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); 200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
201} 201}
202 202
203static struct snd_soc_ops neo1973_gta02_voice_ops = { 203static struct snd_soc_ops neo1973_gta02_voice_ops = {
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 906709e6dd5f..77de6c5127d2 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -29,7 +29,6 @@
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 <plat/audio.h>
33#include <linux/io.h> 32#include <linux/io.h>
34#include <mach/spi-gpio.h> 33#include <mach/spi-gpio.h>
35 34
@@ -137,7 +136,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
137 return ret; 136 return ret;
138 137
139 /* codec PLL input is PCLK/4 */ 138 /* codec PLL input is PCLK/4 */
140 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 139 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
141 iis_clkrate / 4, pll_out); 140 iis_clkrate / 4, pll_out);
142 if (ret < 0) 141 if (ret < 0)
143 return ret; 142 return ret;
@@ -153,7 +152,7 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
153 pr_debug("Entered %s\n", __func__); 152 pr_debug("Entered %s\n", __func__);
154 153
155 /* disable the PLL */ 154 /* disable the PLL */
156 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); 155 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
157} 156}
158 157
159/* 158/*
@@ -203,7 +202,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
203 return ret; 202 return ret;
204 203
205 /* configue and enable PLL for 12.288MHz output */ 204 /* configue and enable PLL for 12.288MHz output */
206 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 205 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
207 iis_clkrate / 4, 12288000); 206 iis_clkrate / 4, 12288000);
208 if (ret < 0) 207 if (ret < 0)
209 return ret; 208 return ret;
@@ -219,7 +218,7 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
219 pr_debug("Entered %s\n", __func__); 218 pr_debug("Entered %s\n", __func__);
220 219
221 /* disable the PLL */ 220 /* disable the PLL */
222 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); 221 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
223} 222}
224 223
225static struct snd_soc_ops neo1973_voice_ops = { 224static struct snd_soc_ops neo1973_voice_ops = {
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 9bc4aa35caab..28b0ab255096 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -32,7 +32,6 @@
32 32
33#include <plat/regs-s3c2412-iis.h> 33#include <plat/regs-s3c2412-iis.h>
34 34
35#include <plat/audio.h>
36#include <mach/dma.h> 35#include <mach/dma.h>
37 36
38#include "s3c-i2s-v2.h" 37#include "s3c-i2s-v2.h"
@@ -312,12 +311,15 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
312 311
313 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 312 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
314 case SND_SOC_DAIFMT_RIGHT_J: 313 case SND_SOC_DAIFMT_RIGHT_J:
314 iismod |= S3C2412_IISMOD_LR_RLOW;
315 iismod |= S3C2412_IISMOD_SDF_MSB; 315 iismod |= S3C2412_IISMOD_SDF_MSB;
316 break; 316 break;
317 case SND_SOC_DAIFMT_LEFT_J: 317 case SND_SOC_DAIFMT_LEFT_J:
318 iismod |= S3C2412_IISMOD_LR_RLOW;
318 iismod |= S3C2412_IISMOD_SDF_LSB; 319 iismod |= S3C2412_IISMOD_SDF_LSB;
319 break; 320 break;
320 case SND_SOC_DAIFMT_I2S: 321 case SND_SOC_DAIFMT_I2S:
322 iismod &= ~S3C2412_IISMOD_LR_RLOW;
321 iismod |= S3C2412_IISMOD_SDF_IIS; 323 iismod |= S3C2412_IISMOD_SDF_IIS;
322 break; 324 break;
323 default: 325 default:
@@ -467,6 +469,31 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
467 469
468 switch (div_id) { 470 switch (div_id) {
469 case S3C_I2SV2_DIV_BCLK: 471 case S3C_I2SV2_DIV_BCLK:
472 if (div > 3) {
473 /* convert value to bit field */
474
475 switch (div) {
476 case 16:
477 div = S3C2412_IISMOD_BCLK_16FS;
478 break;
479
480 case 32:
481 div = S3C2412_IISMOD_BCLK_32FS;
482 break;
483
484 case 24:
485 div = S3C2412_IISMOD_BCLK_24FS;
486 break;
487
488 case 48:
489 div = S3C2412_IISMOD_BCLK_48FS;
490 break;
491
492 default:
493 return -EINVAL;
494 }
495 }
496
470 reg = readl(i2s->regs + S3C2412_IISMOD); 497 reg = readl(i2s->regs + S3C2412_IISMOD);
471 reg &= ~S3C2412_IISMOD_BCLK_MASK; 498 reg &= ~S3C2412_IISMOD_BCLK_MASK;
472 writel(reg | div, i2s->regs + S3C2412_IISMOD); 499 writel(reg | div, i2s->regs + S3C2412_IISMOD);
@@ -626,7 +653,7 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
626 } 653 }
627 654
628 i2s->iis_pclk = clk_get(dev, "iis"); 655 i2s->iis_pclk = clk_get(dev, "iis");
629 if (i2s->iis_pclk == NULL) { 656 if (IS_ERR(i2s->iis_pclk)) {
630 dev_err(dev, "failed to get iis_clock\n"); 657 dev_err(dev, "failed to get iis_clock\n");
631 iounmap(i2s->regs); 658 iounmap(i2s->regs);
632 return -ENOENT; 659 return -ENOENT;
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index a587ec40b449..ac5e47b082fb 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -34,7 +34,6 @@
34 34
35#include <plat/regs-s3c2412-iis.h> 35#include <plat/regs-s3c2412-iis.h>
36 36
37#include <plat/audio.h>
38#include <mach/regs-gpio.h> 37#include <mach/regs-gpio.h>
39#include <mach/dma.h> 38#include <mach/dma.h>
40 39
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index fc1beb0930b9..b25e9f968df9 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -32,7 +32,6 @@
32#include <plat/regs-ac97.h> 32#include <plat/regs-ac97.h>
33#include <mach/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h> 34#include <mach/regs-clock.h>
35#include <plat/audio.h>
36#include <asm/dma.h> 35#include <asm/dma.h>
37#include <mach/dma.h> 36#include <mach/dma.h>
38 37
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 40e2c4790f0d..c76b8bb214bc 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -32,7 +32,7 @@
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h> 34#include <mach/regs-clock.h>
35#include <plat/audio.h> 35
36#include <asm/dma.h> 36#include <asm/dma.h>
37#include <mach/dma.h> 37#include <mach/dma.h>
38 38
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index 1f35c6fcf5fd..151a69463269 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -29,7 +29,6 @@
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 <plat/audio.h>
33 32
34#include "s3c24xx-pcm.h" 33#include "s3c24xx-pcm.h"
35 34
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 105a77eeded0..d68cae15561c 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -31,7 +31,6 @@
31#include <plat/gpio-bank-d.h> 31#include <plat/gpio-bank-d.h>
32#include <plat/gpio-bank-e.h> 32#include <plat/gpio-bank-e.h>
33#include <plat/gpio-cfg.h> 33#include <plat/gpio-cfg.h>
34#include <plat/audio.h>
35 34
36#include <mach/map.h> 35#include <mach/map.h>
37#include <mach/dma.h> 36#include <mach/dma.h>
@@ -99,6 +98,19 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
99 iismod |= S3C64XX_IISMOD_IMS_SYSMUX; 98 iismod |= S3C64XX_IISMOD_IMS_SYSMUX;
100 break; 99 break;
101 100
101 case S3C64XX_CLKSRC_CDCLK:
102 switch (dir) {
103 case SND_SOC_CLOCK_IN:
104 iismod |= S3C64XX_IISMOD_CDCLKCON;
105 break;
106 case SND_SOC_CLOCK_OUT:
107 iismod &= ~S3C64XX_IISMOD_CDCLKCON;
108 break;
109 default:
110 return -EINVAL;
111 }
112 break;
113
102 default: 114 default:
103 return -EINVAL; 115 return -EINVAL;
104 } 116 }
@@ -111,8 +123,12 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
111struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) 123struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
112{ 124{
113 struct s3c_i2sv2_info *i2s = to_info(dai); 125 struct s3c_i2sv2_info *i2s = to_info(dai);
126 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
114 127
115 return i2s->iis_cclk; 128 if (iismod & S3C64XX_IISMOD_IMS_SYSMUX)
129 return i2s->iis_cclk;
130 else
131 return i2s->iis_pclk;
116} 132}
117EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); 133EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
118 134
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index 02148cee2613..abe7253b55fc 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -25,6 +25,7 @@ struct clk;
25 25
26#define S3C64XX_CLKSRC_PCLK (0) 26#define S3C64XX_CLKSRC_PCLK (0)
27#define S3C64XX_CLKSRC_MUX (1) 27#define S3C64XX_CLKSRC_MUX (1)
28#define S3C64XX_CLKSRC_CDCLK (2)
28 29
29extern struct snd_soc_dai s3c64xx_i2s_dai[]; 30extern struct snd_soc_dai s3c64xx_i2s_dai[];
30 31
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c
new file mode 100644
index 000000000000..cb8a9161b643
--- /dev/null
+++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c
@@ -0,0 +1,268 @@
1/*
2 * smdk64xx_wm8580.c
3 *
4 * Copyright (c) 2009 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/platform_device.h>
14#include <linux/clk.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20
21#include "../codecs/wm8580.h"
22#include "s3c24xx-pcm.h"
23#include "s3c64xx-i2s.h"
24
25#define S3C64XX_I2S_V4 2
26
27/* SMDK64XX has a 12MHZ crystal attached to WM8580 */
28#define SMDK64XX_WM8580_FREQ 12000000
29
30static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
31 struct snd_pcm_hw_params *params)
32{
33 struct snd_soc_pcm_runtime *rtd = substream->private_data;
34 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
35 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
36 unsigned int pll_out;
37 int bfs, rfs, ret;
38
39 switch (params_format(params)) {
40 case SNDRV_PCM_FORMAT_U8:
41 case SNDRV_PCM_FORMAT_S8:
42 bfs = 16;
43 break;
44 case SNDRV_PCM_FORMAT_U16_LE:
45 case SNDRV_PCM_FORMAT_S16_LE:
46 bfs = 32;
47 break;
48 default:
49 return -EINVAL;
50 }
51
52 /* The Fvco for WM8580 PLLs must fall within [90,100]MHz.
53 * This criterion can't be met if we request PLL output
54 * as {8000x256, 64000x256, 11025x256}Hz.
55 * As a wayout, we rather change rfs to a minimum value that
56 * results in (params_rate(params) * rfs), and itself, acceptable
57 * to both - the CODEC and the CPU.
58 */
59 switch (params_rate(params)) {
60 case 16000:
61 case 22050:
62 case 32000:
63 case 44100:
64 case 48000:
65 case 88200:
66 case 96000:
67 rfs = 256;
68 break;
69 case 64000:
70 rfs = 384;
71 break;
72 case 8000:
73 case 11025:
74 rfs = 512;
75 break;
76 default:
77 return -EINVAL;
78 }
79 pll_out = params_rate(params) * rfs;
80
81 /* Set the Codec DAI configuration */
82 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
83 | SND_SOC_DAIFMT_NB_NF
84 | SND_SOC_DAIFMT_CBM_CFM);
85 if (ret < 0)
86 return ret;
87
88 /* Set the AP DAI configuration */
89 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
90 | SND_SOC_DAIFMT_NB_NF
91 | SND_SOC_DAIFMT_CBM_CFM);
92 if (ret < 0)
93 return ret;
94
95 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK,
96 0, SND_SOC_CLOCK_IN);
97 if (ret < 0)
98 return ret;
99
100 /* We use PCLK for basic ops in SoC-Slave mode */
101 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
102 0, SND_SOC_CLOCK_IN);
103 if (ret < 0)
104 return ret;
105
106 /* Set WM8580 to drive MCLK from its PLLA */
107 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
108 WM8580_CLKSRC_PLLA);
109 if (ret < 0)
110 return ret;
111
112 /* Explicitly set WM8580-DAC to source from MCLK */
113 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_DAC_CLKSEL,
114 WM8580_CLKSRC_MCLK);
115 if (ret < 0)
116 return ret;
117
118 ret = snd_soc_dai_set_pll(codec_dai, 0, WM8580_PLLA,
119 SMDK64XX_WM8580_FREQ, pll_out);
120 if (ret < 0)
121 return ret;
122
123 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs);
124 if (ret < 0)
125 return ret;
126
127 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs);
128 if (ret < 0)
129 return ret;
130
131 return 0;
132}
133
134/*
135 * SMDK64XX WM8580 DAI operations.
136 */
137static struct snd_soc_ops smdk64xx_ops = {
138 .hw_params = smdk64xx_hw_params,
139};
140
141/* SMDK64xx Playback widgets */
142static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = {
143 SND_SOC_DAPM_HP("Front-L/R", NULL),
144 SND_SOC_DAPM_HP("Center/Sub", NULL),
145 SND_SOC_DAPM_HP("Rear-L/R", NULL),
146};
147
148/* SMDK64xx Capture widgets */
149static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = {
150 SND_SOC_DAPM_MIC("MicIn", NULL),
151 SND_SOC_DAPM_LINE("LineIn", NULL),
152};
153
154/* SMDK-PAIFTX connections */
155static const struct snd_soc_dapm_route audio_map_tx[] = {
156 /* MicIn feeds AINL */
157 {"AINL", NULL, "MicIn"},
158
159 /* LineIn feeds AINL/R */
160 {"AINL", NULL, "LineIn"},
161 {"AINR", NULL, "LineIn"},
162};
163
164/* SMDK-PAIFRX connections */
165static const struct snd_soc_dapm_route audio_map_rx[] = {
166 /* Front Left/Right are fed VOUT1L/R */
167 {"Front-L/R", NULL, "VOUT1L"},
168 {"Front-L/R", NULL, "VOUT1R"},
169
170 /* Center/Sub are fed VOUT2L/R */
171 {"Center/Sub", NULL, "VOUT2L"},
172 {"Center/Sub", NULL, "VOUT2R"},
173
174 /* Rear Left/Right are fed VOUT3L/R */
175 {"Rear-L/R", NULL, "VOUT3L"},
176 {"Rear-L/R", NULL, "VOUT3R"},
177};
178
179static int smdk64xx_wm8580_init_paiftx(struct snd_soc_codec *codec)
180{
181 /* Add smdk64xx specific Capture widgets */
182 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt,
183 ARRAY_SIZE(wm8580_dapm_widgets_cpt));
184
185 /* Set up PAIFTX audio path */
186 snd_soc_dapm_add_routes(codec, audio_map_tx, ARRAY_SIZE(audio_map_tx));
187
188 /* Enabling the microphone requires the fitting of a 0R
189 * resistor to connect the line from the microphone jack.
190 */
191 snd_soc_dapm_disable_pin(codec, "MicIn");
192
193 /* signal a DAPM event */
194 snd_soc_dapm_sync(codec);
195
196 return 0;
197}
198
199static int smdk64xx_wm8580_init_paifrx(struct snd_soc_codec *codec)
200{
201 /* Add smdk64xx specific Playback widgets */
202 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk,
203 ARRAY_SIZE(wm8580_dapm_widgets_pbk));
204
205 /* Set up PAIFRX audio path */
206 snd_soc_dapm_add_routes(codec, audio_map_rx, ARRAY_SIZE(audio_map_rx));
207
208 /* signal a DAPM event */
209 snd_soc_dapm_sync(codec);
210
211 return 0;
212}
213
214static struct snd_soc_dai_link smdk64xx_dai[] = {
215{ /* Primary Playback i/f */
216 .name = "WM8580 PAIF RX",
217 .stream_name = "Playback",
218 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4],
219 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX],
220 .init = smdk64xx_wm8580_init_paifrx,
221 .ops = &smdk64xx_ops,
222},
223{ /* Primary Capture i/f */
224 .name = "WM8580 PAIF TX",
225 .stream_name = "Capture",
226 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4],
227 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX],
228 .init = smdk64xx_wm8580_init_paiftx,
229 .ops = &smdk64xx_ops,
230},
231};
232
233static struct snd_soc_card smdk64xx = {
234 .name = "smdk64xx",
235 .platform = &s3c24xx_soc_platform,
236 .dai_link = smdk64xx_dai,
237 .num_links = ARRAY_SIZE(smdk64xx_dai),
238};
239
240static struct snd_soc_device smdk64xx_snd_devdata = {
241 .card = &smdk64xx,
242 .codec_dev = &soc_codec_dev_wm8580,
243};
244
245static struct platform_device *smdk64xx_snd_device;
246
247static int __init smdk64xx_audio_init(void)
248{
249 int ret;
250
251 smdk64xx_snd_device = platform_device_alloc("soc-audio", -1);
252 if (!smdk64xx_snd_device)
253 return -ENOMEM;
254
255 platform_set_drvdata(smdk64xx_snd_device, &smdk64xx_snd_devdata);
256 smdk64xx_snd_devdata.dev = &smdk64xx_snd_device->dev;
257 ret = platform_device_add(smdk64xx_snd_device);
258
259 if (ret)
260 platform_device_put(smdk64xx_snd_device);
261
262 return ret;
263}
264module_init(smdk64xx_audio_init);
265
266MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com");
267MODULE_DESCRIPTION("ALSA SoC SMDK64XX WM8580");
268MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 9154b4363db3..9e6976586554 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -23,7 +23,6 @@ config SND_SOC_SH4_SSI
23config SND_SOC_SH4_FSI 23config SND_SOC_SH4_FSI
24 tristate "SH4 FSI support" 24 tristate "SH4 FSI support"
25 depends on CPU_SUBTYPE_SH7724 25 depends on CPU_SUBTYPE_SH7724
26 select SH_DMA
27 help 26 help
28 This option enables FSI sound support 27 This option enables FSI sound support
29 28
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 44123248b630..e1a3d1a2b4c8 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -26,8 +26,6 @@
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/sh_fsi.h> 27#include <sound/sh_fsi.h>
28#include <asm/atomic.h> 28#include <asm/atomic.h>
29#include <asm/dma.h>
30#include <asm/dma-sh.h>
31 29
32#define DO_FMT 0x0000 30#define DO_FMT 0x0000
33#define DOFF_CTL 0x0004 31#define DOFF_CTL 0x0004
@@ -97,7 +95,6 @@ struct fsi_priv {
97 95
98 int fifo_max; 96 int fifo_max;
99 int chan; 97 int chan;
100 int dma_chan;
101 98
102 int byte_offset; 99 int byte_offset;
103 int period_len; 100 int period_len;
@@ -308,62 +305,6 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
308 return residue; 305 return residue;
309} 306}
310 307
311static int fsi_get_residue(struct fsi_priv *fsi, int is_play)
312{
313 int residue;
314 int width;
315 struct snd_pcm_runtime *runtime;
316
317 runtime = fsi->substream->runtime;
318
319 /* get 1 channel data width */
320 width = frames_to_bytes(runtime, 1) / fsi->chan;
321
322 if (2 == width)
323 residue = fsi_get_fifo_residue(fsi, is_play);
324 else
325 residue = get_dma_residue(fsi->dma_chan);
326
327 return residue;
328}
329
330/************************************************************************
331
332
333 basic dma function
334
335
336************************************************************************/
337#define PORTA_DMA 0
338#define PORTB_DMA 1
339
340static int fsi_get_dma_chan(void)
341{
342 if (0 != request_dma(PORTA_DMA, "fsia"))
343 return -EIO;
344
345 if (0 != request_dma(PORTB_DMA, "fsib")) {
346 free_dma(PORTA_DMA);
347 return -EIO;
348 }
349
350 master->fsia.dma_chan = PORTA_DMA;
351 master->fsib.dma_chan = PORTB_DMA;
352
353 return 0;
354}
355
356static void fsi_free_dma_chan(void)
357{
358 dma_wait_for_completion(PORTA_DMA);
359 dma_wait_for_completion(PORTB_DMA);
360 free_dma(PORTA_DMA);
361 free_dma(PORTB_DMA);
362
363 master->fsia.dma_chan = -1;
364 master->fsib.dma_chan = -1;
365}
366
367/************************************************************************ 308/************************************************************************
368 309
369 310
@@ -435,44 +376,6 @@ static void fsi_soft_all_reset(void)
435 mdelay(10); 376 mdelay(10);
436} 377}
437 378
438static void fsi_16data_push(struct fsi_priv *fsi,
439 struct snd_pcm_runtime *runtime,
440 int send)
441{
442 u16 *dma_start;
443 u32 snd;
444 int i;
445
446 /* get dma start position for FSI */
447 dma_start = (u16 *)runtime->dma_area;
448 dma_start += fsi->byte_offset / 2;
449
450 /*
451 * soft dma
452 * FSI can not use DMA when 16bpp
453 */
454 for (i = 0; i < send; i++) {
455 snd = (u32)dma_start[i];
456 fsi_reg_write(fsi, DODT, snd << 8);
457 }
458}
459
460static void fsi_32data_push(struct fsi_priv *fsi,
461 struct snd_pcm_runtime *runtime,
462 int send)
463{
464 u32 *dma_start;
465
466 /* get dma start position for FSI */
467 dma_start = (u32 *)runtime->dma_area;
468 dma_start += fsi->byte_offset / 4;
469
470 dma_wait_for_completion(fsi->dma_chan);
471 dma_configure_channel(fsi->dma_chan, (SM_INC|0x400|TS_32|TM_BUR));
472 dma_write(fsi->dma_chan, (u32)dma_start,
473 (u32)(fsi->base + DODT), send * 4);
474}
475
476/* playback interrupt */ 379/* playback interrupt */
477static int fsi_data_push(struct fsi_priv *fsi) 380static int fsi_data_push(struct fsi_priv *fsi)
478{ 381{
@@ -481,6 +384,8 @@ static int fsi_data_push(struct fsi_priv *fsi)
481 int send; 384 int send;
482 int fifo_free; 385 int fifo_free;
483 int width; 386 int width;
387 u8 *start;
388 int i;
484 389
485 if (!fsi || 390 if (!fsi ||
486 !fsi->substream || 391 !fsi->substream ||
@@ -515,12 +420,22 @@ static int fsi_data_push(struct fsi_priv *fsi)
515 if (fifo_free < send) 420 if (fifo_free < send)
516 send = fifo_free; 421 send = fifo_free;
517 422
518 if (2 == width) 423 start = runtime->dma_area;
519 fsi_16data_push(fsi, runtime, send); 424 start += fsi->byte_offset;
520 else if (4 == width) 425
521 fsi_32data_push(fsi, runtime, send); 426 switch (width) {
522 else 427 case 2:
428 for (i = 0; i < send; i++)
429 fsi_reg_write(fsi, DODT,
430 ((u32)*((u16 *)start + i) << 8));
431 break;
432 case 4:
433 for (i = 0; i < send; i++)
434 fsi_reg_write(fsi, DODT, *((u32 *)start + i));
435 break;
436 default:
523 return -EINVAL; 437 return -EINVAL;
438 }
524 439
525 fsi->byte_offset += send * width; 440 fsi->byte_offset += send * width;
526 441
@@ -532,6 +447,75 @@ static int fsi_data_push(struct fsi_priv *fsi)
532 return 0; 447 return 0;
533} 448}
534 449
450static int fsi_data_pop(struct fsi_priv *fsi)
451{
452 struct snd_pcm_runtime *runtime;
453 struct snd_pcm_substream *substream = NULL;
454 int free;
455 int fifo_fill;
456 int width;
457 u8 *start;
458 int i;
459
460 if (!fsi ||
461 !fsi->substream ||
462 !fsi->substream->runtime)
463 return -EINVAL;
464
465 runtime = fsi->substream->runtime;
466
467 /* FSI FIFO has limit.
468 * So, this driver can not send periods data at a time
469 */
470 if (fsi->byte_offset >=
471 fsi->period_len * (fsi->periods + 1)) {
472
473 substream = fsi->substream;
474 fsi->periods = (fsi->periods + 1) % runtime->periods;
475
476 if (0 == fsi->periods)
477 fsi->byte_offset = 0;
478 }
479
480 /* get 1 channel data width */
481 width = frames_to_bytes(runtime, 1) / fsi->chan;
482
483 /* get free space for alsa */
484 free = (fsi->buffer_len - fsi->byte_offset) / width;
485
486 /* get recv size */
487 fifo_fill = fsi_get_fifo_residue(fsi, 0);
488
489 if (free < fifo_fill)
490 fifo_fill = free;
491
492 start = runtime->dma_area;
493 start += fsi->byte_offset;
494
495 switch (width) {
496 case 2:
497 for (i = 0; i < fifo_fill; i++)
498 *((u16 *)start + i) =
499 (u16)(fsi_reg_read(fsi, DIDT) >> 8);
500 break;
501 case 4:
502 for (i = 0; i < fifo_fill; i++)
503 *((u32 *)start + i) = fsi_reg_read(fsi, DIDT);
504 break;
505 default:
506 return -EINVAL;
507 }
508
509 fsi->byte_offset += fifo_fill * width;
510
511 fsi_irq_enable(fsi, 0);
512
513 if (substream)
514 snd_pcm_period_elapsed(substream);
515
516 return 0;
517}
518
535static irqreturn_t fsi_interrupt(int irq, void *data) 519static irqreturn_t fsi_interrupt(int irq, void *data)
536{ 520{
537 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 521 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010;
@@ -545,6 +529,10 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
545 fsi_data_push(&master->fsia); 529 fsi_data_push(&master->fsia);
546 if (int_st & INT_B_OUT) 530 if (int_st & INT_B_OUT)
547 fsi_data_push(&master->fsib); 531 fsi_data_push(&master->fsib);
532 if (int_st & INT_A_IN)
533 fsi_data_pop(&master->fsia);
534 if (int_st & INT_B_IN)
535 fsi_data_pop(&master->fsib);
548 536
549 fsi_master_write(INT_ST, 0x0000000); 537 fsi_master_write(INT_ST, 0x0000000);
550 538
@@ -664,8 +652,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
664 } 652 }
665 653
666 fsi_reg_write(fsi, reg, data); 654 fsi_reg_write(fsi, reg, data);
667 dev_dbg(dai->dev, "use %s format (%d channel) use %d DMAC\n",
668 msg, fsi->chan, fsi->dma_chan);
669 655
670 /* 656 /*
671 * clear clk reset if master mode 657 * clear clk reset if master mode
@@ -699,16 +685,12 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
699 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 685 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
700 int ret = 0; 686 int ret = 0;
701 687
702 /* capture not supported */
703 if (!is_play)
704 return -ENODEV;
705
706 switch (cmd) { 688 switch (cmd) {
707 case SNDRV_PCM_TRIGGER_START: 689 case SNDRV_PCM_TRIGGER_START:
708 fsi_stream_push(fsi, substream, 690 fsi_stream_push(fsi, substream,
709 frames_to_bytes(runtime, runtime->buffer_size), 691 frames_to_bytes(runtime, runtime->buffer_size),
710 frames_to_bytes(runtime, runtime->period_size)); 692 frames_to_bytes(runtime, runtime->period_size));
711 ret = fsi_data_push(fsi); 693 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
712 break; 694 break;
713 case SNDRV_PCM_TRIGGER_STOP: 695 case SNDRV_PCM_TRIGGER_STOP:
714 fsi_irq_disable(fsi, is_play); 696 fsi_irq_disable(fsi, is_play);
@@ -780,10 +762,9 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
780{ 762{
781 struct snd_pcm_runtime *runtime = substream->runtime; 763 struct snd_pcm_runtime *runtime = substream->runtime;
782 struct fsi_priv *fsi = fsi_get(substream); 764 struct fsi_priv *fsi = fsi_get(substream);
783 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
784 long location; 765 long location;
785 766
786 location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play); 767 location = (fsi->byte_offset - 1);
787 if (location < 0) 768 if (location < 0)
788 location = 0; 769 location = 0;
789 770
@@ -845,7 +826,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
845 .channels_min = 1, 826 .channels_min = 1,
846 .channels_max = 8, 827 .channels_max = 8,
847 }, 828 },
848 /* capture not supported */ 829 .capture = {
830 .rates = FSI_RATES,
831 .formats = FSI_FMTS,
832 .channels_min = 1,
833 .channels_max = 8,
834 },
849 .ops = &fsi_dai_ops, 835 .ops = &fsi_dai_ops,
850 }, 836 },
851 { 837 {
@@ -857,7 +843,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
857 .channels_min = 1, 843 .channels_min = 1,
858 .channels_max = 8, 844 .channels_max = 8,
859 }, 845 },
860 /* capture not supported */ 846 .capture = {
847 .rates = FSI_RATES,
848 .formats = FSI_FMTS,
849 .channels_min = 1,
850 .channels_max = 8,
851 },
861 .ops = &fsi_dai_ops, 852 .ops = &fsi_dai_ops,
862 }, 853 },
863}; 854};
@@ -912,22 +903,13 @@ static int fsi_probe(struct platform_device *pdev)
912 master->fsia.base = master->base; 903 master->fsia.base = master->base;
913 master->fsib.base = master->base + 0x40; 904 master->fsib.base = master->base + 0x40;
914 905
915 master->fsia.dma_chan = -1;
916 master->fsib.dma_chan = -1;
917
918 ret = fsi_get_dma_chan();
919 if (ret < 0) {
920 dev_err(&pdev->dev, "cannot get dma api\n");
921 goto exit_iounmap;
922 }
923
924 /* FSI is based on SPU mstp */ 906 /* FSI is based on SPU mstp */
925 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id); 907 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
926 master->clk = clk_get(NULL, clk_name); 908 master->clk = clk_get(NULL, clk_name);
927 if (IS_ERR(master->clk)) { 909 if (IS_ERR(master->clk)) {
928 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name); 910 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
929 ret = -EIO; 911 ret = -EIO;
930 goto exit_free_dma; 912 goto exit_iounmap;
931 } 913 }
932 914
933 fsi_soc_dai[0].dev = &pdev->dev; 915 fsi_soc_dai[0].dev = &pdev->dev;
@@ -938,7 +920,7 @@ static int fsi_probe(struct platform_device *pdev)
938 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 920 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
939 if (ret) { 921 if (ret) {
940 dev_err(&pdev->dev, "irq request err\n"); 922 dev_err(&pdev->dev, "irq request err\n");
941 goto exit_free_dma; 923 goto exit_iounmap;
942 } 924 }
943 925
944 ret = snd_soc_register_platform(&fsi_soc_platform); 926 ret = snd_soc_register_platform(&fsi_soc_platform);
@@ -951,8 +933,6 @@ static int fsi_probe(struct platform_device *pdev)
951 933
952exit_free_irq: 934exit_free_irq:
953 free_irq(irq, master); 935 free_irq(irq, master);
954exit_free_dma:
955 fsi_free_dma_chan();
956exit_iounmap: 936exit_iounmap:
957 iounmap(master->base); 937 iounmap(master->base);
958exit_kfree: 938exit_kfree:
@@ -969,8 +949,6 @@ static int fsi_remove(struct platform_device *pdev)
969 949
970 clk_put(master->clk); 950 clk_put(master->clk);
971 951
972 fsi_free_dma_chan();
973
974 free_irq(master->irq, master); 952 free_irq(master->irq, master);
975 953
976 iounmap(master->base); 954 iounmap(master->base);
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index c8ceddc2a26c..d2505e8b06c9 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -77,6 +77,35 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
77#define snd_soc_7_9_spi_write NULL 77#define snd_soc_7_9_spi_write NULL
78#endif 78#endif
79 79
80static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value)
82{
83 u8 *cache = codec->reg_cache;
84 u8 data[2];
85
86 BUG_ON(codec->volatile_register);
87
88 data[0] = reg & 0xff;
89 data[1] = value & 0xff;
90
91 if (reg < codec->reg_cache_size)
92 cache[reg] = value;
93
94 if (codec->hw_write(codec->control_data, data, 2) == 2)
95 return 0;
96 else
97 return -EIO;
98}
99
100static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
101 unsigned int reg)
102{
103 u8 *cache = codec->reg_cache;
104 if (reg >= codec->reg_cache_size)
105 return -1;
106 return cache[reg];
107}
108
80static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, 109static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value) 110 unsigned int value)
82{ 111{
@@ -150,9 +179,20 @@ static struct {
150 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 179 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
151 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); 180 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
152} io_types[] = { 181} io_types[] = {
153 { 7, 9, snd_soc_7_9_write, snd_soc_7_9_spi_write, snd_soc_7_9_read }, 182 {
154 { 8, 16, snd_soc_8_16_write, NULL, snd_soc_8_16_read, 183 .addr_bits = 7, .data_bits = 9,
155 snd_soc_8_16_read_i2c }, 184 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
185 .spi_write = snd_soc_7_9_spi_write
186 },
187 {
188 .addr_bits = 8, .data_bits = 8,
189 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
190 },
191 {
192 .addr_bits = 8, .data_bits = 16,
193 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
194 .i2c_read = snd_soc_8_16_read_i2c,
195 },
156}; 196};
157 197
158/** 198/**
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 0a1b2f64bbee..e2b6d75f16e3 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -37,7 +37,6 @@
37#include <sound/initval.h> 37#include <sound/initval.h>
38 38
39static DEFINE_MUTEX(pcm_mutex); 39static DEFINE_MUTEX(pcm_mutex);
40static DEFINE_MUTEX(io_mutex);
41static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 40static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
42 41
43#ifdef CONFIG_DEBUG_FS 42#ifdef CONFIG_DEBUG_FS
@@ -81,6 +80,173 @@ static int run_delayed_work(struct delayed_work *dwork)
81 return ret; 80 return ret;
82} 81}
83 82
83/* codec register dump */
84static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
85{
86 int i, step = 1, count = 0;
87
88 if (!codec->reg_cache_size)
89 return 0;
90
91 if (codec->reg_cache_step)
92 step = codec->reg_cache_step;
93
94 count += sprintf(buf, "%s registers\n", codec->name);
95 for (i = 0; i < codec->reg_cache_size; i += step) {
96 if (codec->readable_register && !codec->readable_register(i))
97 continue;
98
99 count += sprintf(buf + count, "%2x: ", i);
100 if (count >= PAGE_SIZE - 1)
101 break;
102
103 if (codec->display_register)
104 count += codec->display_register(codec, buf + count,
105 PAGE_SIZE - count, i);
106 else
107 count += snprintf(buf + count, PAGE_SIZE - count,
108 "%4x", codec->read(codec, i));
109
110 if (count >= PAGE_SIZE - 1)
111 break;
112
113 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
114 if (count >= PAGE_SIZE - 1)
115 break;
116 }
117
118 /* Truncate count; min() would cause a warning */
119 if (count >= PAGE_SIZE)
120 count = PAGE_SIZE - 1;
121
122 return count;
123}
124static ssize_t codec_reg_show(struct device *dev,
125 struct device_attribute *attr, char *buf)
126{
127 struct snd_soc_device *devdata = dev_get_drvdata(dev);
128 return soc_codec_reg_show(devdata->card->codec, buf);
129}
130
131static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
132
133#ifdef CONFIG_DEBUG_FS
134static int codec_reg_open_file(struct inode *inode, struct file *file)
135{
136 file->private_data = inode->i_private;
137 return 0;
138}
139
140static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
141 size_t count, loff_t *ppos)
142{
143 ssize_t ret;
144 struct snd_soc_codec *codec = file->private_data;
145 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
146 if (!buf)
147 return -ENOMEM;
148 ret = soc_codec_reg_show(codec, buf);
149 if (ret >= 0)
150 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
151 kfree(buf);
152 return ret;
153}
154
155static ssize_t codec_reg_write_file(struct file *file,
156 const char __user *user_buf, size_t count, loff_t *ppos)
157{
158 char buf[32];
159 int buf_size;
160 char *start = buf;
161 unsigned long reg, value;
162 int step = 1;
163 struct snd_soc_codec *codec = file->private_data;
164
165 buf_size = min(count, (sizeof(buf)-1));
166 if (copy_from_user(buf, user_buf, buf_size))
167 return -EFAULT;
168 buf[buf_size] = 0;
169
170 if (codec->reg_cache_step)
171 step = codec->reg_cache_step;
172
173 while (*start == ' ')
174 start++;
175 reg = simple_strtoul(start, &start, 16);
176 if ((reg >= codec->reg_cache_size) || (reg % step))
177 return -EINVAL;
178 while (*start == ' ')
179 start++;
180 if (strict_strtoul(start, 16, &value))
181 return -EINVAL;
182 codec->write(codec, reg, value);
183 return buf_size;
184}
185
186static const struct file_operations codec_reg_fops = {
187 .open = codec_reg_open_file,
188 .read = codec_reg_read_file,
189 .write = codec_reg_write_file,
190};
191
192static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
193{
194 char codec_root[128];
195
196 if (codec->dev)
197 snprintf(codec_root, sizeof(codec_root),
198 "%s.%s", codec->name, dev_name(codec->dev));
199 else
200 snprintf(codec_root, sizeof(codec_root),
201 "%s", codec->name);
202
203 codec->debugfs_codec_root = debugfs_create_dir(codec_root,
204 debugfs_root);
205 if (!codec->debugfs_codec_root) {
206 printk(KERN_WARNING
207 "ASoC: Failed to create codec debugfs directory\n");
208 return;
209 }
210
211 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
212 codec->debugfs_codec_root,
213 codec, &codec_reg_fops);
214 if (!codec->debugfs_reg)
215 printk(KERN_WARNING
216 "ASoC: Failed to create codec register debugfs file\n");
217
218 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
219 codec->debugfs_codec_root,
220 &codec->pop_time);
221 if (!codec->debugfs_pop_time)
222 printk(KERN_WARNING
223 "Failed to create pop time debugfs file\n");
224
225 codec->debugfs_dapm = debugfs_create_dir("dapm",
226 codec->debugfs_codec_root);
227 if (!codec->debugfs_dapm)
228 printk(KERN_WARNING
229 "Failed to create DAPM debugfs directory\n");
230
231 snd_soc_dapm_debugfs_init(codec);
232}
233
234static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
235{
236 debugfs_remove_recursive(codec->debugfs_codec_root);
237}
238
239#else
240
241static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
242{
243}
244
245static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
246{
247}
248#endif
249
84#ifdef CONFIG_SND_SOC_AC97_BUS 250#ifdef CONFIG_SND_SOC_AC97_BUS
85/* unregister ac97 codec */ 251/* unregister ac97 codec */
86static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) 252static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
@@ -790,45 +956,6 @@ static int soc_resume(struct device *dev)
790 956
791 return 0; 957 return 0;
792} 958}
793
794/**
795 * snd_soc_suspend_device: Notify core of device suspend
796 *
797 * @dev: Device being suspended.
798 *
799 * In order to ensure that the entire audio subsystem is suspended in a
800 * coordinated fashion ASoC devices should suspend themselves when
801 * called by ASoC. When the standard kernel suspend process asks the
802 * device to suspend it should call this function to initiate a suspend
803 * of the entire ASoC card.
804 *
805 * \note Currently this function is stubbed out.
806 */
807int snd_soc_suspend_device(struct device *dev)
808{
809 return 0;
810}
811EXPORT_SYMBOL_GPL(snd_soc_suspend_device);
812
813/**
814 * snd_soc_resume_device: Notify core of device resume
815 *
816 * @dev: Device being resumed.
817 *
818 * In order to ensure that the entire audio subsystem is resumed in a
819 * coordinated fashion ASoC devices should resume themselves when called
820 * by ASoC. When the standard kernel resume process asks the device
821 * to resume it should call this function. Once all the components of
822 * the card have notified that they are ready to be resumed the card
823 * will be resumed.
824 *
825 * \note Currently this function is stubbed out.
826 */
827int snd_soc_resume_device(struct device *dev)
828{
829 return 0;
830}
831EXPORT_SYMBOL_GPL(snd_soc_resume_device);
832#else 959#else
833#define soc_suspend NULL 960#define soc_suspend NULL
834#define soc_resume NULL 961#define soc_resume NULL
@@ -843,6 +970,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
843 struct platform_device, 970 struct platform_device,
844 dev); 971 dev);
845 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev; 972 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
973 struct snd_soc_codec *codec;
846 struct snd_soc_platform *platform; 974 struct snd_soc_platform *platform;
847 struct snd_soc_dai *dai; 975 struct snd_soc_dai *dai;
848 int i, found, ret, ac97; 976 int i, found, ret, ac97;
@@ -931,6 +1059,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
931 if (ret < 0) 1059 if (ret < 0)
932 goto cpu_dai_err; 1060 goto cpu_dai_err;
933 } 1061 }
1062 codec = card->codec;
934 1063
935 if (platform->probe) { 1064 if (platform->probe) {
936 ret = platform->probe(pdev); 1065 ret = platform->probe(pdev);
@@ -945,10 +1074,72 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
945 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1074 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
946#endif 1075#endif
947 1076
1077 for (i = 0; i < card->num_links; i++) {
1078 if (card->dai_link[i].init) {
1079 ret = card->dai_link[i].init(codec);
1080 if (ret < 0) {
1081 printk(KERN_ERR "asoc: failed to init %s\n",
1082 card->dai_link[i].stream_name);
1083 continue;
1084 }
1085 }
1086 if (card->dai_link[i].codec_dai->ac97_control) {
1087 ac97 = 1;
1088 snd_ac97_dev_add_pdata(codec->ac97,
1089 card->dai_link[i].cpu_dai->ac97_pdata);
1090 }
1091 }
1092
1093 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1094 "%s", card->name);
1095 snprintf(codec->card->longname, sizeof(codec->card->longname),
1096 "%s (%s)", card->name, codec->name);
1097
1098 /* Make sure all DAPM widgets are instantiated */
1099 snd_soc_dapm_new_widgets(codec);
1100
1101 ret = snd_card_register(codec->card);
1102 if (ret < 0) {
1103 printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
1104 codec->name);
1105 goto card_err;
1106 }
1107
1108 mutex_lock(&codec->mutex);
1109#ifdef CONFIG_SND_SOC_AC97_BUS
1110 /* Only instantiate AC97 if not already done by the adaptor
1111 * for the generic AC97 subsystem.
1112 */
1113 if (ac97 && strcmp(codec->name, "AC97") != 0) {
1114 ret = soc_ac97_dev_register(codec);
1115 if (ret < 0) {
1116 printk(KERN_ERR "asoc: AC97 device register failed\n");
1117 snd_card_free(codec->card);
1118 mutex_unlock(&codec->mutex);
1119 goto card_err;
1120 }
1121 }
1122#endif
1123
1124 ret = snd_soc_dapm_sys_add(card->socdev->dev);
1125 if (ret < 0)
1126 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
1127
1128 ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg);
1129 if (ret < 0)
1130 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1131
1132 soc_init_codec_debugfs(codec);
1133 mutex_unlock(&codec->mutex);
1134
948 card->instantiated = 1; 1135 card->instantiated = 1;
949 1136
950 return; 1137 return;
951 1138
1139card_err:
1140 if (platform->remove)
1141 platform->remove(pdev);
1142
952platform_err: 1143platform_err:
953 if (codec_dev->remove) 1144 if (codec_dev->remove)
954 codec_dev->remove(pdev); 1145 codec_dev->remove(pdev);
@@ -1151,157 +1342,6 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg)
1151} 1342}
1152EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); 1343EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
1153 1344
1154/* codec register dump */
1155static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
1156{
1157 int i, step = 1, count = 0;
1158
1159 if (!codec->reg_cache_size)
1160 return 0;
1161
1162 if (codec->reg_cache_step)
1163 step = codec->reg_cache_step;
1164
1165 count += sprintf(buf, "%s registers\n", codec->name);
1166 for (i = 0; i < codec->reg_cache_size; i += step) {
1167 if (codec->readable_register && !codec->readable_register(i))
1168 continue;
1169
1170 count += sprintf(buf + count, "%2x: ", i);
1171 if (count >= PAGE_SIZE - 1)
1172 break;
1173
1174 if (codec->display_register)
1175 count += codec->display_register(codec, buf + count,
1176 PAGE_SIZE - count, i);
1177 else
1178 count += snprintf(buf + count, PAGE_SIZE - count,
1179 "%4x", codec->read(codec, i));
1180
1181 if (count >= PAGE_SIZE - 1)
1182 break;
1183
1184 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
1185 if (count >= PAGE_SIZE - 1)
1186 break;
1187 }
1188
1189 /* Truncate count; min() would cause a warning */
1190 if (count >= PAGE_SIZE)
1191 count = PAGE_SIZE - 1;
1192
1193 return count;
1194}
1195static ssize_t codec_reg_show(struct device *dev,
1196 struct device_attribute *attr, char *buf)
1197{
1198 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1199 return soc_codec_reg_show(devdata->card->codec, buf);
1200}
1201
1202static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
1203
1204#ifdef CONFIG_DEBUG_FS
1205static int codec_reg_open_file(struct inode *inode, struct file *file)
1206{
1207 file->private_data = inode->i_private;
1208 return 0;
1209}
1210
1211static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
1212 size_t count, loff_t *ppos)
1213{
1214 ssize_t ret;
1215 struct snd_soc_codec *codec = file->private_data;
1216 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1217 if (!buf)
1218 return -ENOMEM;
1219 ret = soc_codec_reg_show(codec, buf);
1220 if (ret >= 0)
1221 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1222 kfree(buf);
1223 return ret;
1224}
1225
1226static ssize_t codec_reg_write_file(struct file *file,
1227 const char __user *user_buf, size_t count, loff_t *ppos)
1228{
1229 char buf[32];
1230 int buf_size;
1231 char *start = buf;
1232 unsigned long reg, value;
1233 int step = 1;
1234 struct snd_soc_codec *codec = file->private_data;
1235
1236 buf_size = min(count, (sizeof(buf)-1));
1237 if (copy_from_user(buf, user_buf, buf_size))
1238 return -EFAULT;
1239 buf[buf_size] = 0;
1240
1241 if (codec->reg_cache_step)
1242 step = codec->reg_cache_step;
1243
1244 while (*start == ' ')
1245 start++;
1246 reg = simple_strtoul(start, &start, 16);
1247 if ((reg >= codec->reg_cache_size) || (reg % step))
1248 return -EINVAL;
1249 while (*start == ' ')
1250 start++;
1251 if (strict_strtoul(start, 16, &value))
1252 return -EINVAL;
1253 codec->write(codec, reg, value);
1254 return buf_size;
1255}
1256
1257static const struct file_operations codec_reg_fops = {
1258 .open = codec_reg_open_file,
1259 .read = codec_reg_read_file,
1260 .write = codec_reg_write_file,
1261};
1262
1263static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1264{
1265 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
1266 debugfs_root, codec,
1267 &codec_reg_fops);
1268 if (!codec->debugfs_reg)
1269 printk(KERN_WARNING
1270 "ASoC: Failed to create codec register debugfs file\n");
1271
1272 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
1273 debugfs_root,
1274 &codec->pop_time);
1275 if (!codec->debugfs_pop_time)
1276 printk(KERN_WARNING
1277 "Failed to create pop time debugfs file\n");
1278
1279 codec->debugfs_dapm = debugfs_create_dir("dapm", debugfs_root);
1280 if (!codec->debugfs_dapm)
1281 printk(KERN_WARNING
1282 "Failed to create DAPM debugfs directory\n");
1283
1284 snd_soc_dapm_debugfs_init(codec);
1285}
1286
1287static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1288{
1289 debugfs_remove_recursive(codec->debugfs_dapm);
1290 debugfs_remove(codec->debugfs_pop_time);
1291 debugfs_remove(codec->debugfs_reg);
1292}
1293
1294#else
1295
1296static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1297{
1298}
1299
1300static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1301{
1302}
1303#endif
1304
1305/** 1345/**
1306 * snd_soc_new_ac97_codec - initailise AC97 device 1346 * snd_soc_new_ac97_codec - initailise AC97 device
1307 * @codec: audio codec 1347 * @codec: audio codec
@@ -1369,19 +1409,41 @@ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
1369 int change; 1409 int change;
1370 unsigned int old, new; 1410 unsigned int old, new;
1371 1411
1372 mutex_lock(&io_mutex);
1373 old = snd_soc_read(codec, reg); 1412 old = snd_soc_read(codec, reg);
1374 new = (old & ~mask) | value; 1413 new = (old & ~mask) | value;
1375 change = old != new; 1414 change = old != new;
1376 if (change) 1415 if (change)
1377 snd_soc_write(codec, reg, new); 1416 snd_soc_write(codec, reg, new);
1378 1417
1379 mutex_unlock(&io_mutex);
1380 return change; 1418 return change;
1381} 1419}
1382EXPORT_SYMBOL_GPL(snd_soc_update_bits); 1420EXPORT_SYMBOL_GPL(snd_soc_update_bits);
1383 1421
1384/** 1422/**
1423 * snd_soc_update_bits_locked - update codec register bits
1424 * @codec: audio codec
1425 * @reg: codec register
1426 * @mask: register mask
1427 * @value: new value
1428 *
1429 * Writes new register value, and takes the codec mutex.
1430 *
1431 * Returns 1 for change else 0.
1432 */
1433static int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
1434 unsigned short reg, unsigned int mask,
1435 unsigned int value)
1436{
1437 int change;
1438
1439 mutex_lock(&codec->mutex);
1440 change = snd_soc_update_bits(codec, reg, mask, value);
1441 mutex_unlock(&codec->mutex);
1442
1443 return change;
1444}
1445
1446/**
1385 * snd_soc_test_bits - test register for change 1447 * snd_soc_test_bits - test register for change
1386 * @codec: audio codec 1448 * @codec: audio codec
1387 * @reg: codec register 1449 * @reg: codec register
@@ -1399,11 +1461,9 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
1399 int change; 1461 int change;
1400 unsigned int old, new; 1462 unsigned int old, new;
1401 1463
1402 mutex_lock(&io_mutex);
1403 old = snd_soc_read(codec, reg); 1464 old = snd_soc_read(codec, reg);
1404 new = (old & ~mask) | value; 1465 new = (old & ~mask) | value;
1405 change = old != new; 1466 change = old != new;
1406 mutex_unlock(&io_mutex);
1407 1467
1408 return change; 1468 return change;
1409} 1469}
@@ -1458,83 +1518,6 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1458EXPORT_SYMBOL_GPL(snd_soc_new_pcms); 1518EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1459 1519
1460/** 1520/**
1461 * snd_soc_init_card - register sound card
1462 * @socdev: the SoC audio device
1463 *
1464 * Register a SoC sound card. Also registers an AC97 device if the
1465 * codec is AC97 for ad hoc devices.
1466 *
1467 * Returns 0 for success, else error.
1468 */
1469int snd_soc_init_card(struct snd_soc_device *socdev)
1470{
1471 struct snd_soc_card *card = socdev->card;
1472 struct snd_soc_codec *codec = card->codec;
1473 int ret = 0, i, ac97 = 0, err = 0;
1474
1475 for (i = 0; i < card->num_links; i++) {
1476 if (card->dai_link[i].init) {
1477 err = card->dai_link[i].init(codec);
1478 if (err < 0) {
1479 printk(KERN_ERR "asoc: failed to init %s\n",
1480 card->dai_link[i].stream_name);
1481 continue;
1482 }
1483 }
1484 if (card->dai_link[i].codec_dai->ac97_control) {
1485 ac97 = 1;
1486 snd_ac97_dev_add_pdata(codec->ac97,
1487 card->dai_link[i].cpu_dai->ac97_pdata);
1488 }
1489 }
1490 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1491 "%s", card->name);
1492 snprintf(codec->card->longname, sizeof(codec->card->longname),
1493 "%s (%s)", card->name, codec->name);
1494
1495 /* Make sure all DAPM widgets are instantiated */
1496 snd_soc_dapm_new_widgets(codec);
1497
1498 ret = snd_card_register(codec->card);
1499 if (ret < 0) {
1500 printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
1501 codec->name);
1502 goto out;
1503 }
1504
1505 mutex_lock(&codec->mutex);
1506#ifdef CONFIG_SND_SOC_AC97_BUS
1507 /* Only instantiate AC97 if not already done by the adaptor
1508 * for the generic AC97 subsystem.
1509 */
1510 if (ac97 && strcmp(codec->name, "AC97") != 0) {
1511 ret = soc_ac97_dev_register(codec);
1512 if (ret < 0) {
1513 printk(KERN_ERR "asoc: AC97 device register failed\n");
1514 snd_card_free(codec->card);
1515 mutex_unlock(&codec->mutex);
1516 goto out;
1517 }
1518 }
1519#endif
1520
1521 err = snd_soc_dapm_sys_add(socdev->dev);
1522 if (err < 0)
1523 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
1524
1525 err = device_create_file(socdev->dev, &dev_attr_codec_reg);
1526 if (err < 0)
1527 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1528
1529 soc_init_codec_debugfs(codec);
1530 mutex_unlock(&codec->mutex);
1531
1532out:
1533 return ret;
1534}
1535EXPORT_SYMBOL_GPL(snd_soc_init_card);
1536
1537/**
1538 * snd_soc_free_pcms - free sound card and pcms 1521 * snd_soc_free_pcms - free sound card and pcms
1539 * @socdev: the SoC audio device 1522 * @socdev: the SoC audio device
1540 * 1523 *
@@ -1734,7 +1717,7 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1734 mask |= (bitmask - 1) << e->shift_r; 1717 mask |= (bitmask - 1) << e->shift_r;
1735 } 1718 }
1736 1719
1737 return snd_soc_update_bits(codec, e->reg, mask, val); 1720 return snd_soc_update_bits_locked(codec, e->reg, mask, val);
1738} 1721}
1739EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); 1722EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
1740 1723
@@ -1808,7 +1791,7 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
1808 mask |= e->mask << e->shift_r; 1791 mask |= e->mask << e->shift_r;
1809 } 1792 }
1810 1793
1811 return snd_soc_update_bits(codec, e->reg, mask, val); 1794 return snd_soc_update_bits_locked(codec, e->reg, mask, val);
1812} 1795}
1813EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double); 1796EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
1814 1797
@@ -1969,7 +1952,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1969 val_mask |= mask << rshift; 1952 val_mask |= mask << rshift;
1970 val |= val2 << rshift; 1953 val |= val2 << rshift;
1971 } 1954 }
1972 return snd_soc_update_bits(codec, reg, val_mask, val); 1955 return snd_soc_update_bits_locked(codec, reg, val_mask, val);
1973} 1956}
1974EXPORT_SYMBOL_GPL(snd_soc_put_volsw); 1957EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
1975 1958
@@ -2075,11 +2058,11 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
2075 val = val << shift; 2058 val = val << shift;
2076 val2 = val2 << shift; 2059 val2 = val2 << shift;
2077 2060
2078 err = snd_soc_update_bits(codec, reg, val_mask, val); 2061 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
2079 if (err < 0) 2062 if (err < 0)
2080 return err; 2063 return err;
2081 2064
2082 err = snd_soc_update_bits(codec, reg2, val_mask, val2); 2065 err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
2083 return err; 2066 return err;
2084} 2067}
2085EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); 2068EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
@@ -2158,7 +2141,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2158 val = (ucontrol->value.integer.value[0]+min) & 0xff; 2141 val = (ucontrol->value.integer.value[0]+min) & 0xff;
2159 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; 2142 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
2160 2143
2161 return snd_soc_update_bits(codec, reg, 0xffff, val); 2144 return snd_soc_update_bits_locked(codec, reg, 0xffff, val);
2162} 2145}
2163EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); 2146EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2164 2147
@@ -2205,16 +2188,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
2205 * snd_soc_dai_set_pll - configure DAI PLL. 2188 * snd_soc_dai_set_pll - configure DAI PLL.
2206 * @dai: DAI 2189 * @dai: DAI
2207 * @pll_id: DAI specific PLL ID 2190 * @pll_id: DAI specific PLL ID
2191 * @source: DAI specific source for the PLL
2208 * @freq_in: PLL input clock frequency in Hz 2192 * @freq_in: PLL input clock frequency in Hz
2209 * @freq_out: requested PLL output clock frequency in Hz 2193 * @freq_out: requested PLL output clock frequency in Hz
2210 * 2194 *
2211 * Configures and enables PLL to generate output clock based on input clock. 2195 * Configures and enables PLL to generate output clock based on input clock.
2212 */ 2196 */
2213int snd_soc_dai_set_pll(struct snd_soc_dai *dai, 2197int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2214 int pll_id, unsigned int freq_in, unsigned int freq_out) 2198 unsigned int freq_in, unsigned int freq_out)
2215{ 2199{
2216 if (dai->ops && dai->ops->set_pll) 2200 if (dai->ops && dai->ops->set_pll)
2217 return dai->ops->set_pll(dai, pll_id, freq_in, freq_out); 2201 return dai->ops->set_pll(dai, pll_id, source,
2202 freq_in, freq_out);
2218 else 2203 else
2219 return -EINVAL; 2204 return -EINVAL;
2220} 2205}
@@ -2259,6 +2244,30 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2259EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); 2244EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
2260 2245
2261/** 2246/**
2247 * snd_soc_dai_set_channel_map - configure DAI audio channel map
2248 * @dai: DAI
2249 * @tx_num: how many TX channels
2250 * @tx_slot: pointer to an array which imply the TX slot number channel
2251 * 0~num-1 uses
2252 * @rx_num: how many RX channels
2253 * @rx_slot: pointer to an array which imply the RX slot number channel
2254 * 0~num-1 uses
2255 *
2256 * configure the relationship between channel number and TDM slot number.
2257 */
2258int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
2259 unsigned int tx_num, unsigned int *tx_slot,
2260 unsigned int rx_num, unsigned int *rx_slot)
2261{
2262 if (dai->ops && dai->ops->set_channel_map)
2263 return dai->ops->set_channel_map(dai, tx_num, tx_slot,
2264 rx_num, rx_slot);
2265 else
2266 return -EINVAL;
2267}
2268EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
2269
2270/**
2262 * snd_soc_dai_set_tristate - configure DAI system or master clock. 2271 * snd_soc_dai_set_tristate - configure DAI system or master clock.
2263 * @dai: DAI 2272 * @dai: DAI
2264 * @tristate: tristate enable 2273 * @tristate: tristate enable
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d89f6dc00908..eaadb4b742f4 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -719,6 +719,10 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
719 719
720 /* Check if one of our outputs is connected */ 720 /* Check if one of our outputs is connected */
721 list_for_each_entry(path, &w->sinks, list_source) { 721 list_for_each_entry(path, &w->sinks, list_source) {
722 if (path->connected &&
723 !path->connected(path->source, path->sink))
724 continue;
725
722 if (path->sink && path->sink->power_check && 726 if (path->sink && path->sink->power_check &&
723 path->sink->power_check(path->sink)) { 727 path->sink->power_check(path->sink)) {
724 power = 1; 728 power = 1;
@@ -1138,6 +1142,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1138 w->active ? "active" : "inactive"); 1142 w->active ? "active" : "inactive");
1139 1143
1140 list_for_each_entry(p, &w->sources, list_sink) { 1144 list_for_each_entry(p, &w->sources, list_sink) {
1145 if (p->connected && !p->connected(w, p->sink))
1146 continue;
1147
1141 if (p->connect) 1148 if (p->connect)
1142 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1149 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1143 " in %s %s\n", 1150 " in %s %s\n",
@@ -1145,6 +1152,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1145 p->source->name); 1152 p->source->name);
1146 } 1153 }
1147 list_for_each_entry(p, &w->sinks, list_source) { 1154 list_for_each_entry(p, &w->sinks, list_source) {
1155 if (p->connected && !p->connected(w, p->sink))
1156 continue;
1157
1148 if (p->connect) 1158 if (p->connect)
1149 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1159 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1150 " out %s %s\n", 1160 " out %s %s\n",
@@ -1192,8 +1202,8 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1192 1202
1193/* test and update the power status of a mux widget */ 1203/* test and update the power status of a mux widget */
1194static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1204static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1195 struct snd_kcontrol *kcontrol, int mask, 1205 struct snd_kcontrol *kcontrol, int change,
1196 int mux, int val, struct soc_enum *e) 1206 int mux, struct soc_enum *e)
1197{ 1207{
1198 struct snd_soc_dapm_path *path; 1208 struct snd_soc_dapm_path *path;
1199 int found = 0; 1209 int found = 0;
@@ -1202,7 +1212,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1202 widget->id != snd_soc_dapm_value_mux) 1212 widget->id != snd_soc_dapm_value_mux)
1203 return -ENODEV; 1213 return -ENODEV;
1204 1214
1205 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val)) 1215 if (!change)
1206 return 0; 1216 return 0;
1207 1217
1208 /* find dapm widget path assoc with kcontrol */ 1218 /* find dapm widget path assoc with kcontrol */
@@ -1387,10 +1397,13 @@ int snd_soc_dapm_sync(struct snd_soc_codec *codec)
1387EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1397EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1388 1398
1389static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, 1399static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1390 const char *sink, const char *control, const char *source) 1400 const struct snd_soc_dapm_route *route)
1391{ 1401{
1392 struct snd_soc_dapm_path *path; 1402 struct snd_soc_dapm_path *path;
1393 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1403 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
1404 const char *sink = route->sink;
1405 const char *control = route->control;
1406 const char *source = route->source;
1394 int ret = 0; 1407 int ret = 0;
1395 1408
1396 /* find src and dest widgets */ 1409 /* find src and dest widgets */
@@ -1414,6 +1427,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1414 1427
1415 path->source = wsource; 1428 path->source = wsource;
1416 path->sink = wsink; 1429 path->sink = wsink;
1430 path->connected = route->connected;
1417 INIT_LIST_HEAD(&path->list); 1431 INIT_LIST_HEAD(&path->list);
1418 INIT_LIST_HEAD(&path->list_source); 1432 INIT_LIST_HEAD(&path->list_source);
1419 INIT_LIST_HEAD(&path->list_sink); 1433 INIT_LIST_HEAD(&path->list_sink);
@@ -1514,8 +1528,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
1514 int i, ret; 1528 int i, ret;
1515 1529
1516 for (i = 0; i < num; i++) { 1530 for (i = 0; i < num; i++) {
1517 ret = snd_soc_dapm_add_route(codec, route->sink, 1531 ret = snd_soc_dapm_add_route(codec, route);
1518 route->control, route->source);
1519 if (ret < 0) { 1532 if (ret < 0) {
1520 printk(KERN_ERR "Failed to add route %s->%s\n", 1533 printk(KERN_ERR "Failed to add route %s->%s\n",
1521 route->source, 1534 route->source,
@@ -1752,7 +1765,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1752{ 1765{
1753 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1766 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1754 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1767 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1755 unsigned int val, mux; 1768 unsigned int val, mux, change;
1756 unsigned int mask, bitmask; 1769 unsigned int mask, bitmask;
1757 int ret = 0; 1770 int ret = 0;
1758 1771
@@ -1772,20 +1785,21 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1772 1785
1773 mutex_lock(&widget->codec->mutex); 1786 mutex_lock(&widget->codec->mutex);
1774 widget->value = val; 1787 widget->value = val;
1775 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1788 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1776 if (widget->event) { 1789 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1777 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1790
1778 ret = widget->event(widget, 1791 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1779 kcontrol, SND_SOC_DAPM_PRE_REG); 1792 ret = widget->event(widget,
1780 if (ret < 0) 1793 kcontrol, SND_SOC_DAPM_PRE_REG);
1781 goto out; 1794 if (ret < 0)
1782 } 1795 goto out;
1783 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1796 }
1784 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1797
1785 ret = widget->event(widget, 1798 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1786 kcontrol, SND_SOC_DAPM_POST_REG); 1799
1787 } else 1800 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1788 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1801 ret = widget->event(widget,
1802 kcontrol, SND_SOC_DAPM_POST_REG);
1789 1803
1790out: 1804out:
1791 mutex_unlock(&widget->codec->mutex); 1805 mutex_unlock(&widget->codec->mutex);
@@ -1794,6 +1808,54 @@ out:
1794EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1808EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1795 1809
1796/** 1810/**
1811 * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux
1812 * @kcontrol: mixer control
1813 * @ucontrol: control element information
1814 *
1815 * Returns 0 for success.
1816 */
1817int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
1818 struct snd_ctl_elem_value *ucontrol)
1819{
1820 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1821
1822 ucontrol->value.enumerated.item[0] = widget->value;
1823
1824 return 0;
1825}
1826EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
1827
1828/**
1829 * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux
1830 * @kcontrol: mixer control
1831 * @ucontrol: control element information
1832 *
1833 * Returns 0 for success.
1834 */
1835int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
1836 struct snd_ctl_elem_value *ucontrol)
1837{
1838 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1839 struct soc_enum *e =
1840 (struct soc_enum *)kcontrol->private_value;
1841 int change;
1842 int ret = 0;
1843
1844 if (ucontrol->value.enumerated.item[0] >= e->max)
1845 return -EINVAL;
1846
1847 mutex_lock(&widget->codec->mutex);
1848
1849 change = widget->value != ucontrol->value.enumerated.item[0];
1850 widget->value = ucontrol->value.enumerated.item[0];
1851 dapm_mux_update_power(widget, kcontrol, change, widget->value, e);
1852
1853 mutex_unlock(&widget->codec->mutex);
1854 return ret;
1855}
1856EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
1857
1858/**
1797 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get 1859 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
1798 * callback 1860 * callback
1799 * @kcontrol: mixer control 1861 * @kcontrol: mixer control
@@ -1851,7 +1913,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1851{ 1913{
1852 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1914 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1853 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1915 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1854 unsigned int val, mux; 1916 unsigned int val, mux, change;
1855 unsigned int mask; 1917 unsigned int mask;
1856 int ret = 0; 1918 int ret = 0;
1857 1919
@@ -1869,20 +1931,21 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1869 1931
1870 mutex_lock(&widget->codec->mutex); 1932 mutex_lock(&widget->codec->mutex);
1871 widget->value = val; 1933 widget->value = val;
1872 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1934 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1873 if (widget->event) { 1935 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1874 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1936
1875 ret = widget->event(widget, 1937 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1876 kcontrol, SND_SOC_DAPM_PRE_REG); 1938 ret = widget->event(widget,
1877 if (ret < 0) 1939 kcontrol, SND_SOC_DAPM_PRE_REG);
1878 goto out; 1940 if (ret < 0)
1879 } 1941 goto out;
1880 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1942 }
1881 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1943
1882 ret = widget->event(widget, 1944 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1883 kcontrol, SND_SOC_DAPM_POST_REG); 1945
1884 } else 1946 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1885 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1947 ret = widget->event(widget,
1948 kcontrol, SND_SOC_DAPM_POST_REG);
1886 1949
1887out: 1950out:
1888 mutex_unlock(&widget->codec->mutex); 1951 mutex_unlock(&widget->codec->mutex);
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 1d455ab79490..12124149601e 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new);
58 */ 58 */
59void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) 59void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
60{ 60{
61 struct snd_soc_codec *codec = jack->card->codec; 61 struct snd_soc_codec *codec;
62 struct snd_soc_jack_pin *pin; 62 struct snd_soc_jack_pin *pin;
63 int enable; 63 int enable;
64 int oldstatus; 64 int oldstatus;
@@ -67,6 +67,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
67 WARN_ON_ONCE(!jack); 67 WARN_ON_ONCE(!jack);
68 return; 68 return;
69 } 69 }
70 codec = jack->card->codec;
70 71
71 mutex_lock(&codec->mutex); 72 mutex_lock(&codec->mutex);
72 73