aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/mpc5200_dma.c
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/fsl/mpc5200_dma.c
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/fsl/mpc5200_dma.c')
-rw-r--r--sound/soc/fsl/mpc5200_dma.c66
1 files changed, 47 insertions, 19 deletions
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 1d4e7164e80a..dce6b551cd78 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -9,6 +9,8 @@
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/of_device.h> 10#include <linux/of_device.h>
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/of_device.h>
13#include <linux/of_platform.h>
12 14
13#include <sound/soc.h> 15#include <sound/soc.h>
14 16
@@ -107,7 +109,7 @@ static int psc_dma_hw_free(struct snd_pcm_substream *substream)
107static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd) 109static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
108{ 110{
109 struct snd_soc_pcm_runtime *rtd = substream->private_data; 111 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 112 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
111 struct snd_pcm_runtime *runtime = substream->runtime; 113 struct snd_pcm_runtime *runtime = substream->runtime;
112 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma); 114 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
113 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; 115 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
@@ -212,7 +214,7 @@ static int psc_dma_open(struct snd_pcm_substream *substream)
212{ 214{
213 struct snd_pcm_runtime *runtime = substream->runtime; 215 struct snd_pcm_runtime *runtime = substream->runtime;
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 216 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 217 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
216 struct psc_dma_stream *s; 218 struct psc_dma_stream *s;
217 int rc; 219 int rc;
218 220
@@ -239,7 +241,7 @@ static int psc_dma_open(struct snd_pcm_substream *substream)
239static int psc_dma_close(struct snd_pcm_substream *substream) 241static int psc_dma_close(struct snd_pcm_substream *substream)
240{ 242{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data; 243 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 244 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
243 struct psc_dma_stream *s; 245 struct psc_dma_stream *s;
244 246
245 dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream); 247 dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream);
@@ -264,7 +266,7 @@ static snd_pcm_uframes_t
264psc_dma_pointer(struct snd_pcm_substream *substream) 266psc_dma_pointer(struct snd_pcm_substream *substream)
265{ 267{
266 struct snd_soc_pcm_runtime *rtd = substream->private_data; 268 struct snd_soc_pcm_runtime *rtd = substream->private_data;
267 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 269 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
268 struct psc_dma_stream *s; 270 struct psc_dma_stream *s;
269 dma_addr_t count; 271 dma_addr_t count;
270 272
@@ -302,11 +304,11 @@ static int psc_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
302 struct snd_pcm *pcm) 304 struct snd_pcm *pcm)
303{ 305{
304 struct snd_soc_pcm_runtime *rtd = pcm->private_data; 306 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
305 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 307 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
306 size_t size = psc_dma_hardware.buffer_bytes_max; 308 size_t size = psc_dma_hardware.buffer_bytes_max;
307 int rc = 0; 309 int rc = 0;
308 310
309 dev_dbg(rtd->socdev->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n", 311 dev_dbg(rtd->platform->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
310 card, dai, pcm); 312 card, dai, pcm);
311 313
312 if (!card->dev->dma_mask) 314 if (!card->dev->dma_mask)
@@ -328,8 +330,8 @@ static int psc_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
328 goto capture_alloc_err; 330 goto capture_alloc_err;
329 } 331 }
330 332
331 if (rtd->socdev->card->codec->ac97) 333 if (rtd->codec->ac97)
332 rtd->socdev->card->codec->ac97->private_data = psc_dma; 334 rtd->codec->ac97->private_data = psc_dma;
333 335
334 return 0; 336 return 0;
335 337
@@ -349,7 +351,7 @@ static void psc_dma_free(struct snd_pcm *pcm)
349 struct snd_pcm_substream *substream; 351 struct snd_pcm_substream *substream;
350 int stream; 352 int stream;
351 353
352 dev_dbg(rtd->socdev->dev, "psc_dma_free(pcm=%p)\n", pcm); 354 dev_dbg(rtd->platform->dev, "psc_dma_free(pcm=%p)\n", pcm);
353 355
354 for (stream = 0; stream < 2; stream++) { 356 for (stream = 0; stream < 2; stream++) {
355 substream = pcm->streams[stream].substream; 357 substream = pcm->streams[stream].substream;
@@ -361,15 +363,14 @@ static void psc_dma_free(struct snd_pcm *pcm)
361 } 363 }
362} 364}
363 365
364struct snd_soc_platform mpc5200_audio_dma_platform = { 366static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
365 .name = "mpc5200-psc-audio", 367 .ops = &psc_dma_ops,
366 .pcm_ops = &psc_dma_ops,
367 .pcm_new = &psc_dma_new, 368 .pcm_new = &psc_dma_new,
368 .pcm_free = &psc_dma_free, 369 .pcm_free = &psc_dma_free,
369}; 370};
370EXPORT_SYMBOL_GPL(mpc5200_audio_dma_platform);
371 371
372int mpc5200_audio_dma_create(struct of_device *op) 372static int mpc5200_hpcd_probe(struct of_device *op,
373 const struct of_device_id *match)
373{ 374{
374 phys_addr_t fifo; 375 phys_addr_t fifo;
375 struct psc_dma *psc_dma; 376 struct psc_dma *psc_dma;
@@ -475,7 +476,7 @@ int mpc5200_audio_dma_create(struct of_device *op)
475 dev_set_drvdata(&op->dev, psc_dma); 476 dev_set_drvdata(&op->dev, psc_dma);
476 477
477 /* Tell the ASoC OF helpers about it */ 478 /* Tell the ASoC OF helpers about it */
478 return snd_soc_register_platform(&mpc5200_audio_dma_platform); 479 return snd_soc_register_platform(&op->dev, &mpc5200_audio_dma_platform);
479out_irq: 480out_irq:
480 free_irq(psc_dma->irq, psc_dma); 481 free_irq(psc_dma->irq, psc_dma);
481 free_irq(psc_dma->capture.irq, &psc_dma->capture); 482 free_irq(psc_dma->capture.irq, &psc_dma->capture);
@@ -486,15 +487,14 @@ out_unmap:
486 iounmap(regs); 487 iounmap(regs);
487 return ret; 488 return ret;
488} 489}
489EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
490 490
491int mpc5200_audio_dma_destroy(struct of_device *op) 491static int mpc5200_hpcd_remove(struct of_device *op)
492{ 492{
493 struct psc_dma *psc_dma = dev_get_drvdata(&op->dev); 493 struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
494 494
495 dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n"); 495 dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n");
496 496
497 snd_soc_unregister_platform(&mpc5200_audio_dma_platform); 497 snd_soc_unregister_platform(&op->dev);
498 498
499 bcom_gen_bd_rx_release(psc_dma->capture.bcom_task); 499 bcom_gen_bd_rx_release(psc_dma->capture.bcom_task);
500 bcom_gen_bd_tx_release(psc_dma->playback.bcom_task); 500 bcom_gen_bd_tx_release(psc_dma->playback.bcom_task);
@@ -510,7 +510,35 @@ int mpc5200_audio_dma_destroy(struct of_device *op)
510 510
511 return 0; 511 return 0;
512} 512}
513EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy); 513
514static struct of_device_id mpc5200_hpcd_match[] = {
515 {
516 .compatible = "fsl,mpc5200-pcm",
517 },
518 {}
519};
520MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match);
521
522static struct of_platform_driver mpc5200_hpcd_of_driver = {
523 .owner = THIS_MODULE,
524 .name = "mpc5200-pcm-audio",
525 .match_table = mpc5200_hpcd_match,
526 .probe = mpc5200_hpcd_probe,
527 .remove = mpc5200_hpcd_remove,
528};
529
530static int __init mpc5200_hpcd_init(void)
531{
532 return of_register_platform_driver(&mpc5200_hpcd_of_driver);
533}
534
535static void __exit mpc5200_hpcd_exit(void)
536{
537 of_unregister_platform_driver(&mpc5200_hpcd_of_driver);
538}
539
540module_init(mpc5200_hpcd_init);
541module_exit(mpc5200_hpcd_exit);
514 542
515MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); 543MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
516MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver"); 544MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");