aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/atmel
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180 /sound/soc/atmel
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: multi-component - ASoC Multi-Component Support
This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/atmel')
-rw-r--r--sound/soc/atmel/atmel-pcm.c59
-rw-r--r--sound/soc/atmel/atmel-pcm.h3
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c97
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.h1
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c65
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c51
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c35
7 files changed, 139 insertions, 172 deletions
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index dc5249fba85c..d0e75323ec19 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -179,7 +179,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
179 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 179 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
180 runtime->dma_bytes = params_buffer_bytes(params); 180 runtime->dma_bytes = params_buffer_bytes(params);
181 181
182 prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 182 prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
183 prtd->params->dma_intr_handler = atmel_pcm_dma_irq; 183 prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
184 184
185 prtd->dma_buffer = runtime->dma_addr; 185 prtd->dma_buffer = runtime->dma_addr;
@@ -374,14 +374,14 @@ static int atmel_pcm_new(struct snd_card *card,
374 if (!card->dev->coherent_dma_mask) 374 if (!card->dev->coherent_dma_mask)
375 card->dev->coherent_dma_mask = 0xffffffff; 375 card->dev->coherent_dma_mask = 0xffffffff;
376 376
377 if (dai->playback.channels_min) { 377 if (dai->driver->playback.channels_min) {
378 ret = atmel_pcm_preallocate_dma_buffer(pcm, 378 ret = atmel_pcm_preallocate_dma_buffer(pcm,
379 SNDRV_PCM_STREAM_PLAYBACK); 379 SNDRV_PCM_STREAM_PLAYBACK);
380 if (ret) 380 if (ret)
381 goto out; 381 goto out;
382 } 382 }
383 383
384 if (dai->capture.channels_min) { 384 if (dai->driver->capture.channels_min) {
385 pr_debug("at32-pcm:" 385 pr_debug("at32-pcm:"
386 "Allocating PCM capture DMA buffer\n"); 386 "Allocating PCM capture DMA buffer\n");
387 ret = atmel_pcm_preallocate_dma_buffer(pcm, 387 ret = atmel_pcm_preallocate_dma_buffer(pcm,
@@ -414,12 +414,9 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
414} 414}
415 415
416#ifdef CONFIG_PM 416#ifdef CONFIG_PM
417static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link) 417static int atmel_pcm_suspend(struct snd_soc_dai *dai)
418{ 418{
419 struct snd_pcm *pcm = dai_link->pcm; 419 struct snd_pcm_runtime *runtime = dai->runtime;
420 struct snd_pcm_str *stream = &pcm->streams[0];
421 struct snd_pcm_substream *substream = stream->substream;
422 struct snd_pcm_runtime *runtime = substream->runtime;
423 struct atmel_runtime_data *prtd; 420 struct atmel_runtime_data *prtd;
424 struct atmel_pcm_dma_params *params; 421 struct atmel_pcm_dma_params *params;
425 422
@@ -441,12 +438,9 @@ static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link)
441 return 0; 438 return 0;
442} 439}
443 440
444static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link) 441static int atmel_pcm_resume(struct snd_soc_dai *dai)
445{ 442{
446 struct snd_pcm *pcm = dai_link->pcm; 443 struct snd_pcm_runtime *runtime = dai->runtime;
447 struct snd_pcm_str *stream = &pcm->streams[0];
448 struct snd_pcm_substream *substream = stream->substream;
449 struct snd_pcm_runtime *runtime = substream->runtime;
450 struct atmel_runtime_data *prtd; 444 struct atmel_runtime_data *prtd;
451 struct atmel_pcm_dma_params *params; 445 struct atmel_pcm_dma_params *params;
452 446
@@ -470,27 +464,46 @@ static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link)
470#define atmel_pcm_resume NULL 464#define atmel_pcm_resume NULL
471#endif 465#endif
472 466
473struct snd_soc_platform atmel_soc_platform = { 467static struct snd_soc_platform_driver atmel_soc_platform = {
474 .name = "atmel-audio", 468 .ops = &atmel_pcm_ops,
475 .pcm_ops = &atmel_pcm_ops,
476 .pcm_new = atmel_pcm_new, 469 .pcm_new = atmel_pcm_new,
477 .pcm_free = atmel_pcm_free_dma_buffers, 470 .pcm_free = atmel_pcm_free_dma_buffers,
478 .suspend = atmel_pcm_suspend, 471 .suspend = atmel_pcm_suspend,
479 .resume = atmel_pcm_resume, 472 .resume = atmel_pcm_resume,
480}; 473};
481EXPORT_SYMBOL_GPL(atmel_soc_platform);
482 474
483static int __init atmel_pcm_modinit(void) 475static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
476{
477 return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
478}
479
480static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
481{
482 snd_soc_unregister_platform(&pdev->dev);
483 return 0;
484}
485
486static struct platform_driver atmel_pcm_driver = {
487 .driver = {
488 .name = "atmel-pcm-audio",
489 .owner = THIS_MODULE,
490 },
491
492 .probe = atmel_soc_platform_probe,
493 .remove = __devexit_p(atmel_soc_platform_remove),
494};
495
496static int __init snd_atmel_pcm_init(void)
484{ 497{
485 return snd_soc_register_platform(&atmel_soc_platform); 498 return platform_driver_register(&atmel_pcm_driver);
486} 499}
487module_init(atmel_pcm_modinit); 500module_init(snd_atmel_pcm_init);
488 501
489static void __exit atmel_pcm_modexit(void) 502static void __exit snd_atmel_pcm_exit(void)
490{ 503{
491 snd_soc_unregister_platform(&atmel_soc_platform); 504 platform_driver_unregister(&atmel_pcm_driver);
492} 505}
493module_exit(atmel_pcm_modexit); 506module_exit(snd_atmel_pcm_exit);
494 507
495MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); 508MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
496MODULE_DESCRIPTION("Atmel PCM module"); 509MODULE_DESCRIPTION("Atmel PCM module");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index ec9b2824b663..2597329302e7 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -74,9 +74,6 @@ struct atmel_pcm_dma_params {
74 void (*dma_intr_handler)(u32, struct snd_pcm_substream *); 74 void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
75}; 75};
76 76
77extern struct snd_soc_platform atmel_soc_platform;
78
79
80/* 77/*
81 * SSC register access (since ssc_writel() / ssc_readl() require literal name) 78 * SSC register access (since ssc_writel() / ssc_readl() require literal name)
82 */ 79 */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index c85844d4845b..eabf66af12cd 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -205,8 +205,7 @@ static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
205static int atmel_ssc_startup(struct snd_pcm_substream *substream, 205static int atmel_ssc_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai) 206 struct snd_soc_dai *dai)
207{ 207{
208 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 208 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
209 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
210 int dir_mask; 209 int dir_mask;
211 210
212 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n", 211 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
@@ -235,8 +234,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
235static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, 234static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *dai) 235 struct snd_soc_dai *dai)
237{ 236{
238 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 237 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
239 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
240 struct atmel_pcm_dma_params *dma_params; 238 struct atmel_pcm_dma_params *dma_params;
241 int dir, dir_mask; 239 int dir, dir_mask;
242 240
@@ -338,7 +336,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
338 struct snd_soc_dai *dai) 336 struct snd_soc_dai *dai)
339{ 337{
340 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 338 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
341 int id = rtd->dai->cpu_dai->id; 339 int id = dai->id;
342 struct atmel_ssc_info *ssc_p = &ssc_info[id]; 340 struct atmel_ssc_info *ssc_p = &ssc_info[id];
343 struct atmel_pcm_dma_params *dma_params; 341 struct atmel_pcm_dma_params *dma_params;
344 int dir, channels, bits; 342 int dir, channels, bits;
@@ -368,7 +366,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
368 * function. It should not be used for other purposes 366 * function. It should not be used for other purposes
369 * as it is common to all substreams. 367 * as it is common to all substreams.
370 */ 368 */
371 snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params); 369 snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_params);
372 370
373 channels = params_channels(params); 371 channels = params_channels(params);
374 372
@@ -605,8 +603,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
605static int atmel_ssc_prepare(struct snd_pcm_substream *substream, 603static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
606 struct snd_soc_dai *dai) 604 struct snd_soc_dai *dai)
607{ 605{
608 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 606 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
609 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
610 struct atmel_pcm_dma_params *dma_params; 607 struct atmel_pcm_dma_params *dma_params;
611 int dir; 608 int dir;
612 609
@@ -690,6 +687,32 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
690# define atmel_ssc_resume NULL 687# define atmel_ssc_resume NULL
691#endif /* CONFIG_PM */ 688#endif /* CONFIG_PM */
692 689
690static int atmel_ssc_probe(struct snd_soc_dai *dai)
691{
692 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
693 int ret = 0;
694
695 snd_soc_dai_set_drvdata(dai, ssc_p);
696
697 /*
698 * Request SSC device
699 */
700 ssc_p->ssc = ssc_request(dai->id);
701 if (IS_ERR(ssc_p->ssc)) {
702 printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
703 ret = PTR_ERR(ssc_p->ssc);
704 }
705
706 return ret;
707}
708
709static int atmel_ssc_remove(struct snd_soc_dai *dai)
710{
711 struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
712
713 ssc_free(ssc_p->ssc);
714 return 0;
715}
693 716
694#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000) 717#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
695 718
@@ -705,9 +728,11 @@ static struct snd_soc_dai_ops atmel_ssc_dai_ops = {
705 .set_clkdiv = atmel_ssc_set_dai_clkdiv, 728 .set_clkdiv = atmel_ssc_set_dai_clkdiv,
706}; 729};
707 730
708struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = { 731static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
709 { .name = "atmel-ssc0", 732 {
710 .id = 0, 733 .name = "atmel-ssc-dai.0",
734 .probe = atmel_ssc_probe,
735 .remove = atmel_ssc_remove,
711 .suspend = atmel_ssc_suspend, 736 .suspend = atmel_ssc_suspend,
712 .resume = atmel_ssc_resume, 737 .resume = atmel_ssc_resume,
713 .playback = { 738 .playback = {
@@ -721,11 +746,12 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
721 .rates = ATMEL_SSC_RATES, 746 .rates = ATMEL_SSC_RATES,
722 .formats = ATMEL_SSC_FORMATS,}, 747 .formats = ATMEL_SSC_FORMATS,},
723 .ops = &atmel_ssc_dai_ops, 748 .ops = &atmel_ssc_dai_ops,
724 .private_data = &ssc_info[0],
725 }, 749 },
726#if NUM_SSC_DEVICES == 3 750#if NUM_SSC_DEVICES == 3
727 { .name = "atmel-ssc1", 751 {
728 .id = 1, 752 .name = "atmel-ssc-dai.1",
753 .probe = atmel_ssc_probe,
754 .remove = atmel_ssc_remove,
729 .suspend = atmel_ssc_suspend, 755 .suspend = atmel_ssc_suspend,
730 .resume = atmel_ssc_resume, 756 .resume = atmel_ssc_resume,
731 .playback = { 757 .playback = {
@@ -739,10 +765,11 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
739 .rates = ATMEL_SSC_RATES, 765 .rates = ATMEL_SSC_RATES,
740 .formats = ATMEL_SSC_FORMATS,}, 766 .formats = ATMEL_SSC_FORMATS,},
741 .ops = &atmel_ssc_dai_ops, 767 .ops = &atmel_ssc_dai_ops,
742 .private_data = &ssc_info[1],
743 }, 768 },
744 { .name = "atmel-ssc2", 769 {
745 .id = 2, 770 .name = "atmel-ssc-dai.2",
771 .probe = atmel_ssc_probe,
772 .remove = atmel_ssc_remove,
746 .suspend = atmel_ssc_suspend, 773 .suspend = atmel_ssc_suspend,
747 .resume = atmel_ssc_resume, 774 .resume = atmel_ssc_resume,
748 .playback = { 775 .playback = {
@@ -756,23 +783,43 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
756 .rates = ATMEL_SSC_RATES, 783 .rates = ATMEL_SSC_RATES,
757 .formats = ATMEL_SSC_FORMATS,}, 784 .formats = ATMEL_SSC_FORMATS,},
758 .ops = &atmel_ssc_dai_ops, 785 .ops = &atmel_ssc_dai_ops,
759 .private_data = &ssc_info[2],
760 }, 786 },
761#endif 787#endif
762}; 788};
763EXPORT_SYMBOL_GPL(atmel_ssc_dai);
764 789
765static int __init atmel_ssc_modinit(void) 790static __devinit int asoc_ssc_probe(struct platform_device *pdev)
791{
792 return snd_soc_register_dais(&pdev->dev, atmel_ssc_dai,
793 ARRAY_SIZE(atmel_ssc_dai));
794}
795
796static int __devexit asoc_ssc_remove(struct platform_device *pdev)
797{
798 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(atmel_ssc_dai));
799 return 0;
800}
801
802static struct platform_driver asoc_ssc_driver = {
803 .driver = {
804 .name = "atmel-ssc-dai",
805 .owner = THIS_MODULE,
806 },
807
808 .probe = asoc_ssc_probe,
809 .remove = __devexit_p(asoc_ssc_remove),
810};
811
812static int __init snd_atmel_ssc_init(void)
766{ 813{
767 return snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai)); 814 return platform_driver_register(&asoc_ssc_driver);
768} 815}
769module_init(atmel_ssc_modinit); 816module_init(snd_atmel_ssc_init);
770 817
771static void __exit atmel_ssc_modexit(void) 818static void __exit snd_atmel_ssc_exit(void)
772{ 819{
773 snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai)); 820 platform_driver_unregister(&asoc_ssc_driver);
774} 821}
775module_exit(atmel_ssc_modexit); 822module_exit(snd_atmel_ssc_exit);
776 823
777/* Module information */ 824/* Module information */
778MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com"); 825MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
index 391135f9c6c1..392a46953112 100644
--- a/sound/soc/atmel/atmel_ssc_dai.h
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -116,6 +116,5 @@ struct atmel_ssc_info {
116 struct atmel_pcm_dma_params *dma_params[2]; 116 struct atmel_pcm_dma_params *dma_params[2];
117 struct atmel_ssc_state ssc_state; 117 struct atmel_ssc_state ssc_state;
118}; 118};
119extern struct snd_soc_dai atmel_ssc_dai[];
120 119
121#endif /* _AT91_SSC_DAI_H */ 120#endif /* _AT91_SSC_DAI_H */
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 9df4c68ef000..5f4e59f4461c 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -83,7 +83,7 @@ static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
83 struct snd_pcm_hw_params *params, 83 struct snd_pcm_hw_params *params,
84 struct snd_soc_dai *cpu_dai) 84 struct snd_soc_dai *cpu_dai)
85{ 85{
86 struct at32_ssc_info *ssc_p = cpu_dai->private_data; 86 struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
87 struct ssc_device *ssc = ssc_p->ssc; 87 struct ssc_device *ssc = ssc_p->ssc;
88 struct ssc_clock_data cd; 88 struct ssc_clock_data cd;
89 unsigned int rate, width_bits, channels; 89 unsigned int rate, width_bits, channels;
@@ -131,9 +131,9 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
131 struct snd_pcm_hw_params *params) 131 struct snd_pcm_hw_params *params)
132{ 132{
133 struct snd_soc_pcm_runtime *rtd = substream->private_data; 133 struct snd_soc_pcm_runtime *rtd = substream->private_data;
134 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 134 struct snd_soc_dai *codec_dai = rtd->codec_dai;
135 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 135 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
136 struct at32_ssc_info *ssc_p = cpu_dai->private_data; 136 struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
137 struct ssc_device *ssc = ssc_p->ssc; 137 struct ssc_device *ssc = ssc_p->ssc;
138 unsigned int pll_out = 0, bclk = 0, mclk_div = 0; 138 unsigned int pll_out = 0, bclk = 0, mclk_div = 0;
139 int ret; 139 int ret;
@@ -315,8 +315,9 @@ static const struct snd_soc_dapm_route intercon[] = {
315 315
316 316
317 317
318static int playpaq_wm8510_init(struct snd_soc_codec *codec) 318static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
319{ 319{
320 struct snd_soc_codec *codec = rtd->codec;
320 int i; 321 int i;
321 322
322 /* 323 /*
@@ -342,7 +343,7 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
342 343
343 344
344 /* Make CSB show PLL rate */ 345 /* Make CSB show PLL rate */
345 snd_soc_dai_set_clkdiv(codec->dai, WM8510_OPCLKDIV, 346 snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV,
346 WM8510_OPCLKDIV_1 | 4); 347 WM8510_OPCLKDIV_1 | 4);
347 348
348 return 0; 349 return 0;
@@ -353,8 +354,10 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
353static struct snd_soc_dai_link playpaq_wm8510_dai = { 354static struct snd_soc_dai_link playpaq_wm8510_dai = {
354 .name = "WM8510", 355 .name = "WM8510",
355 .stream_name = "WM8510 PCM", 356 .stream_name = "WM8510 PCM",
356 .cpu_dai = &at32_ssc_dai[0], 357 .cpu_dai_name= "atmel-ssc-dai.0",
357 .codec_dai = &wm8510_dai, 358 .platform_name = "atmel-pcm-audio",
359 .codec_name = "wm8510-codec.0-0x1a",
360 .codec_dai_name = "wm8510-hifi",
358 .init = playpaq_wm8510_init, 361 .init = playpaq_wm8510_init,
359 .ops = &playpaq_wm8510_ops, 362 .ops = &playpaq_wm8510_ops,
360}; 363};
@@ -363,46 +366,16 @@ static struct snd_soc_dai_link playpaq_wm8510_dai = {
363 366
364static struct snd_soc_card snd_soc_playpaq = { 367static struct snd_soc_card snd_soc_playpaq = {
365 .name = "LRS_PlayPaq_WM8510", 368 .name = "LRS_PlayPaq_WM8510",
366 .platform = &at32_soc_platform,
367 .dai_link = &playpaq_wm8510_dai, 369 .dai_link = &playpaq_wm8510_dai,
368 .num_links = 1, 370 .num_links = 1,
369}; 371};
370 372
371
372
373static struct wm8510_setup_data playpaq_wm8510_setup = {
374 .i2c_bus = 0,
375 .i2c_address = 0x1a,
376};
377
378
379
380static struct snd_soc_device playpaq_wm8510_snd_devdata = {
381 .card = &snd_soc_playpaq,
382 .codec_dev = &soc_codec_dev_wm8510,
383 .codec_data = &playpaq_wm8510_setup,
384};
385
386static struct platform_device *playpaq_snd_device; 373static struct platform_device *playpaq_snd_device;
387 374
388 375
389static int __init playpaq_asoc_init(void) 376static int __init playpaq_asoc_init(void)
390{ 377{
391 int ret = 0; 378 int ret = 0;
392 struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
393 struct ssc_device *ssc = NULL;
394
395
396 /*
397 * Request SSC device
398 */
399 ssc = ssc_request(0);
400 if (IS_ERR(ssc)) {
401 ret = PTR_ERR(ssc);
402 goto err_ssc;
403 }
404 ssc_p->ssc = ssc;
405
406 379
407 /* 380 /*
408 * Configure MCLK for WM8510 381 * Configure MCLK for WM8510
@@ -439,8 +412,7 @@ static int __init playpaq_asoc_init(void)
439 goto err_device_alloc; 412 goto err_device_alloc;
440 } 413 }
441 414
442 platform_set_drvdata(playpaq_snd_device, &playpaq_wm8510_snd_devdata); 415 platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq);
443 playpaq_wm8510_snd_devdata.dev = &playpaq_snd_device->dev;
444 416
445 ret = platform_device_add(playpaq_snd_device); 417 ret = platform_device_add(playpaq_snd_device);
446 if (ret) { 418 if (ret) {
@@ -468,25 +440,12 @@ err_pll0:
468 clk_put(_gclk0); 440 clk_put(_gclk0);
469 _gclk0 = NULL; 441 _gclk0 = NULL;
470 } 442 }
471err_gclk0:
472 ssc_free(ssc);
473err_ssc:
474 return ret; 443 return ret;
475} 444}
476 445
477 446
478static void __exit playpaq_asoc_exit(void) 447static void __exit playpaq_asoc_exit(void)
479{ 448{
480 struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
481 struct ssc_device *ssc;
482
483 if (ssc_p != NULL) {
484 ssc = ssc_p->ssc;
485 if (ssc != NULL)
486 ssc_free(ssc);
487 ssc_p->ssc = NULL;
488 }
489
490 if (_gclk0 != NULL) { 449 if (_gclk0 != NULL) {
491 clk_put(_gclk0); 450 clk_put(_gclk0);
492 _gclk0 = NULL; 451 _gclk0 = NULL;
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index e028744c32ce..66a6f1879689 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -69,8 +69,8 @@ static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
69 struct snd_pcm_hw_params *params) 69 struct snd_pcm_hw_params *params)
70{ 70{
71 struct snd_soc_pcm_runtime *rtd = substream->private_data; 71 struct snd_soc_pcm_runtime *rtd = substream->private_data;
72 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 72 struct snd_soc_dai *codec_dai = rtd->codec_dai;
73 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 73 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
74 int ret; 74 int ret;
75 75
76 /* set codec DAI configuration */ 76 /* set codec DAI configuration */
@@ -136,9 +136,10 @@ static const struct snd_soc_dapm_route intercon[] = {
136/* 136/*
137 * Logic for a wm8731 as connected on a at91sam9g20ek board. 137 * Logic for a wm8731 as connected on a at91sam9g20ek board.
138 */ 138 */
139static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec) 139static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
140{ 140{
141 struct snd_soc_dai *codec_dai = &codec->dai[0]; 141 struct snd_soc_codec *codec = rtd->codec;
142 struct snd_soc_dai *codec_dai = rtd->codec_dai;
142 int ret; 143 int ret;
143 144
144 printk(KERN_DEBUG 145 printk(KERN_DEBUG
@@ -179,31 +180,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
179static struct snd_soc_dai_link at91sam9g20ek_dai = { 180static struct snd_soc_dai_link at91sam9g20ek_dai = {
180 .name = "WM8731", 181 .name = "WM8731",
181 .stream_name = "WM8731 PCM", 182 .stream_name = "WM8731 PCM",
182 .cpu_dai = &atmel_ssc_dai[0], 183 .cpu_dai_name = "atmel-ssc-dai.0",
183 .codec_dai = &wm8731_dai, 184 .codec_dai_name = "wm8731-hifi",
184 .init = at91sam9g20ek_wm8731_init, 185 .init = at91sam9g20ek_wm8731_init,
186 .platform_name = "atmel_pcm-audio",
187 .codec_name = "wm8731-codec.0-001a",
185 .ops = &at91sam9g20ek_ops, 188 .ops = &at91sam9g20ek_ops,
186}; 189};
187 190
188static struct snd_soc_card snd_soc_at91sam9g20ek = { 191static struct snd_soc_card snd_soc_at91sam9g20ek = {
189 .name = "AT91SAMG20-EK", 192 .name = "AT91SAMG20-EK",
190 .platform = &atmel_soc_platform,
191 .dai_link = &at91sam9g20ek_dai, 193 .dai_link = &at91sam9g20ek_dai,
192 .num_links = 1, 194 .num_links = 1,
193 .set_bias_level = at91sam9g20ek_set_bias_level, 195 .set_bias_level = at91sam9g20ek_set_bias_level,
194}; 196};
195 197
196static struct snd_soc_device at91sam9g20ek_snd_devdata = {
197 .card = &snd_soc_at91sam9g20ek,
198 .codec_dev = &soc_codec_dev_wm8731,
199};
200
201static struct platform_device *at91sam9g20ek_snd_device; 198static struct platform_device *at91sam9g20ek_snd_device;
202 199
203static int __init at91sam9g20ek_init(void) 200static int __init at91sam9g20ek_init(void)
204{ 201{
205 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
206 struct ssc_device *ssc = NULL;
207 struct clk *pllb; 202 struct clk *pllb;
208 int ret; 203 int ret;
209 204
@@ -235,18 +230,6 @@ static int __init at91sam9g20ek_init(void)
235 230
236 clk_set_rate(mclk, MCLK_RATE); 231 clk_set_rate(mclk, MCLK_RATE);
237 232
238 /*
239 * Request SSC device
240 */
241 ssc = ssc_request(0);
242 if (IS_ERR(ssc)) {
243 printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
244 ret = PTR_ERR(ssc);
245 ssc = NULL;
246 goto err_ssc;
247 }
248 ssc_p->ssc = ssc;
249
250 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); 233 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
251 if (!at91sam9g20ek_snd_device) { 234 if (!at91sam9g20ek_snd_device) {
252 printk(KERN_ERR "ASoC: Platform device allocation failed\n"); 235 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
@@ -254,8 +237,7 @@ static int __init at91sam9g20ek_init(void)
254 } 237 }
255 238
256 platform_set_drvdata(at91sam9g20ek_snd_device, 239 platform_set_drvdata(at91sam9g20ek_snd_device,
257 &at91sam9g20ek_snd_devdata); 240 &snd_soc_at91sam9g20ek);
258 at91sam9g20ek_snd_devdata.dev = &at91sam9g20ek_snd_device->dev;
259 241
260 ret = platform_device_add(at91sam9g20ek_snd_device); 242 ret = platform_device_add(at91sam9g20ek_snd_device);
261 if (ret) { 243 if (ret) {
@@ -265,9 +247,6 @@ static int __init at91sam9g20ek_init(void)
265 247
266 return ret; 248 return ret;
267 249
268err_ssc:
269 ssc_free(ssc);
270 ssc_p->ssc = NULL;
271err_mclk: 250err_mclk:
272 clk_put(mclk); 251 clk_put(mclk);
273 mclk = NULL; 252 mclk = NULL;
@@ -277,16 +256,6 @@ err:
277 256
278static void __exit at91sam9g20ek_exit(void) 257static void __exit at91sam9g20ek_exit(void)
279{ 258{
280 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
281 struct ssc_device *ssc;
282
283 if (ssc_p != NULL) {
284 ssc = ssc_p->ssc;
285 if (ssc != NULL)
286 ssc_free(ssc);
287 ssc_p->ssc = NULL;
288 }
289
290 platform_device_unregister(at91sam9g20ek_snd_device); 259 platform_device_unregister(at91sam9g20ek_snd_device);
291 at91sam9g20ek_snd_device = NULL; 260 at91sam9g20ek_snd_device = NULL;
292 clk_put(mclk); 261 clk_put(mclk);
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 23349de27313..e3d283561c19 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -46,8 +46,8 @@ static int afeb9260_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params) 46 struct snd_pcm_hw_params *params)
47{ 47{
48 struct snd_soc_pcm_runtime *rtd = substream->private_data; 48 struct snd_soc_pcm_runtime *rtd = substream->private_data;
49 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 49 struct snd_soc_dai *codec_dai = rtd->codec_dai;
50 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51 int err; 51 int err;
52 52
53 /* Set codec DAI configuration */ 53 /* Set codec DAI configuration */
@@ -102,8 +102,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
102 {"MICIN", NULL, "Mic Jack"}, 102 {"MICIN", NULL, "Mic Jack"},
103}; 103};
104 104
105static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec) 105static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
106{ 106{
107 struct snd_soc_codec *codec = rtd->codec;
107 108
108 /* Add afeb9260 specific widgets */ 109 /* Add afeb9260 specific widgets */
109 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 110 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
@@ -125,8 +126,10 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec)
125static struct snd_soc_dai_link afeb9260_dai = { 126static struct snd_soc_dai_link afeb9260_dai = {
126 .name = "TLV320AIC23", 127 .name = "TLV320AIC23",
127 .stream_name = "AIC23", 128 .stream_name = "AIC23",
128 .cpu_dai = &atmel_ssc_dai[0], 129 .cpu_dai_name = "atmel-ssc-dai.0",
129 .codec_dai = &tlv320aic23_dai, 130 .codec_dai_name = "tlv320aic23-hifi",
131 .platform_name = "atmel_pcm-audio",
132 .codec_name = "tlv320aic23-codec.0-0x1a",
130 .init = afeb9260_tlv320aic23_init, 133 .init = afeb9260_tlv320aic23_init,
131 .ops = &afeb9260_ops, 134 .ops = &afeb9260_ops,
132}; 135};
@@ -134,37 +137,20 @@ static struct snd_soc_dai_link afeb9260_dai = {
134/* Audio machine driver */ 137/* Audio machine driver */
135static struct snd_soc_card snd_soc_machine_afeb9260 = { 138static struct snd_soc_card snd_soc_machine_afeb9260 = {
136 .name = "AFEB9260", 139 .name = "AFEB9260",
137 .platform = &atmel_soc_platform,
138 .dai_link = &afeb9260_dai, 140 .dai_link = &afeb9260_dai,
139 .num_links = 1, 141 .num_links = 1,
140}; 142};
141 143
142/* Audio subsystem */
143static struct snd_soc_device afeb9260_snd_devdata = {
144 .card = &snd_soc_machine_afeb9260,
145 .codec_dev = &soc_codec_dev_tlv320aic23,
146};
147
148static struct platform_device *afeb9260_snd_device; 144static struct platform_device *afeb9260_snd_device;
149 145
150static int __init afeb9260_soc_init(void) 146static int __init afeb9260_soc_init(void)
151{ 147{
152 int err; 148 int err;
153 struct device *dev; 149 struct device *dev;
154 struct atmel_ssc_info *ssc_p = afeb9260_dai.cpu_dai->private_data;
155 struct ssc_device *ssc = NULL;
156 150
157 if (!(machine_is_afeb9260())) 151 if (!(machine_is_afeb9260()))
158 return -ENODEV; 152 return -ENODEV;
159 153
160 ssc = ssc_request(0);
161 if (IS_ERR(ssc)) {
162 printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
163 err = PTR_ERR(ssc);
164 ssc = NULL;
165 goto err_ssc;
166 }
167 ssc_p->ssc = ssc;
168 154
169 afeb9260_snd_device = platform_device_alloc("soc-audio", -1); 155 afeb9260_snd_device = platform_device_alloc("soc-audio", -1);
170 if (!afeb9260_snd_device) { 156 if (!afeb9260_snd_device) {
@@ -172,8 +158,7 @@ static int __init afeb9260_soc_init(void)
172 return -ENOMEM; 158 return -ENOMEM;
173 } 159 }
174 160
175 platform_set_drvdata(afeb9260_snd_device, &afeb9260_snd_devdata); 161 platform_set_drvdata(afeb9260_snd_device, &snd_soc_machine_afeb9260);
176 afeb9260_snd_devdata.dev = &afeb9260_snd_device->dev;
177 err = platform_device_add(afeb9260_snd_device); 162 err = platform_device_add(afeb9260_snd_device);
178 if (err) 163 if (err)
179 goto err1; 164 goto err1;
@@ -184,9 +169,7 @@ static int __init afeb9260_soc_init(void)
184err1: 169err1:
185 platform_device_del(afeb9260_snd_device); 170 platform_device_del(afeb9260_snd_device);
186 platform_device_put(afeb9260_snd_device); 171 platform_device_put(afeb9260_snd_device);
187err_ssc:
188 return err; 172 return err;
189
190} 173}
191 174
192static void __exit afeb9260_soc_exit(void) 175static void __exit afeb9260_soc_exit(void)