aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/s3c24xx/s3c-pcm.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/s3c24xx/s3c-pcm.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/s3c24xx/s3c-pcm.c')
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.c41
1 files changed, 16 insertions, 25 deletions
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c
index 326f0a9e7e30..653ffa270915 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/s3c24xx/s3c-pcm.c
@@ -64,11 +64,6 @@ static struct s3c_dma_params s3c_pcm_stereo_in[] = {
64 64
65static struct s3c_pcm_info s3c_pcm[2]; 65static struct s3c_pcm_info s3c_pcm[2];
66 66
67static inline struct s3c_pcm_info *to_info(struct snd_soc_dai *cpu_dai)
68{
69 return cpu_dai->private_data;
70}
71
72static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on) 67static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on)
73{ 68{
74 void __iomem *regs = pcm->regs; 69 void __iomem *regs = pcm->regs;
@@ -132,7 +127,7 @@ static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
132 struct snd_soc_dai *dai) 127 struct snd_soc_dai *dai)
133{ 128{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data; 129 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct s3c_pcm_info *pcm = to_info(rtd->dai->cpu_dai); 130 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
136 unsigned long flags; 131 unsigned long flags;
137 132
138 dev_dbg(pcm->dev, "Entered %s\n", __func__); 133 dev_dbg(pcm->dev, "Entered %s\n", __func__);
@@ -176,8 +171,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
176 struct snd_soc_dai *socdai) 171 struct snd_soc_dai *socdai)
177{ 172{
178 struct snd_soc_pcm_runtime *rtd = substream->private_data; 173 struct snd_soc_pcm_runtime *rtd = substream->private_data;
179 struct snd_soc_dai_link *dai = rtd->dai; 174 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
180 struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
181 struct s3c_dma_params *dma_data; 175 struct s3c_dma_params *dma_data;
182 void __iomem *regs = pcm->regs; 176 void __iomem *regs = pcm->regs;
183 struct clk *clk; 177 struct clk *clk;
@@ -192,7 +186,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
192 else 186 else
193 dma_data = pcm->dma_capture; 187 dma_data = pcm->dma_capture;
194 188
195 snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); 189 snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
196 190
197 /* Strictly check for sample size */ 191 /* Strictly check for sample size */
198 switch (params_format(params)) { 192 switch (params_format(params)) {
@@ -242,7 +236,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
242static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai, 236static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai,
243 unsigned int fmt) 237 unsigned int fmt)
244{ 238{
245 struct s3c_pcm_info *pcm = to_info(cpu_dai); 239 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
246 void __iomem *regs = pcm->regs; 240 void __iomem *regs = pcm->regs;
247 unsigned long flags; 241 unsigned long flags;
248 int ret = 0; 242 int ret = 0;
@@ -313,7 +307,7 @@ exit:
313static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai, 307static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai,
314 int div_id, int div) 308 int div_id, int div)
315{ 309{
316 struct s3c_pcm_info *pcm = to_info(cpu_dai); 310 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
317 311
318 switch (div_id) { 312 switch (div_id) {
319 case S3C_PCM_SCLK_PER_FS: 313 case S3C_PCM_SCLK_PER_FS:
@@ -330,7 +324,7 @@ static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai,
330static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai, 324static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai,
331 int clk_id, unsigned int freq, int dir) 325 int clk_id, unsigned int freq, int dir)
332{ 326{
333 struct s3c_pcm_info *pcm = to_info(cpu_dai); 327 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
334 void __iomem *regs = pcm->regs; 328 void __iomem *regs = pcm->regs;
335 u32 clkctl = readl(regs + S3C_PCM_CLKCTL); 329 u32 clkctl = readl(regs + S3C_PCM_CLKCTL);
336 330
@@ -366,10 +360,9 @@ static struct snd_soc_dai_ops s3c_pcm_dai_ops = {
366 360
367#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 361#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000
368 362
369#define S3C_PCM_DECLARE(n) \ 363#define S3C_PCM_DAI_DECLARE \
370{ \ 364{ \
371 .name = "samsung-pcm", \ 365 .name = "samsung-dai", \
372 .id = (n), \
373 .symmetric_rates = 1, \ 366 .symmetric_rates = 1, \
374 .ops = &s3c_pcm_dai_ops, \ 367 .ops = &s3c_pcm_dai_ops, \
375 .playback = { \ 368 .playback = { \
@@ -386,16 +379,15 @@ static struct snd_soc_dai_ops s3c_pcm_dai_ops = {
386 }, \ 379 }, \
387} 380}
388 381
389struct snd_soc_dai s3c_pcm_dai[] = { 382struct snd_soc_dai_driver s3c_pcm_dai[] = {
390 S3C_PCM_DECLARE(0), 383 S3C_PCM_DAI_DECLARE,
391 S3C_PCM_DECLARE(1), 384 S3C_PCM_DAI_DECLARE,
392}; 385};
393EXPORT_SYMBOL_GPL(s3c_pcm_dai); 386EXPORT_SYMBOL_GPL(s3c_pcm_dai);
394 387
395static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) 388static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
396{ 389{
397 struct s3c_pcm_info *pcm; 390 struct s3c_pcm_info *pcm;
398 struct snd_soc_dai *dai;
399 struct resource *mem_res, *dmatx_res, *dmarx_res; 391 struct resource *mem_res, *dmatx_res, *dmarx_res;
400 struct s3c_audio_pdata *pcm_pdata; 392 struct s3c_audio_pdata *pcm_pdata;
401 int ret; 393 int ret;
@@ -437,9 +429,6 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
437 429
438 spin_lock_init(&pcm->lock); 430 spin_lock_init(&pcm->lock);
439 431
440 dai = &s3c_pcm_dai[pdev->id];
441 dai->dev = &pdev->dev;
442
443 /* Default is 128fs */ 432 /* Default is 128fs */
444 pcm->sclk_per_fs = 128; 433 pcm->sclk_per_fs = 128;
445 434
@@ -452,7 +441,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
452 clk_enable(pcm->cclk); 441 clk_enable(pcm->cclk);
453 442
454 /* record our pcm structure for later use in the callbacks */ 443 /* record our pcm structure for later use in the callbacks */
455 dai->private_data = pcm; 444 dev_set_drvdata(&pdev->dev, pcm);
456 445
457 if (!request_mem_region(mem_res->start, 446 if (!request_mem_region(mem_res->start,
458 resource_size(mem_res), "samsung-pcm")) { 447 resource_size(mem_res), "samsung-pcm")) {
@@ -476,7 +465,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
476 } 465 }
477 clk_enable(pcm->pclk); 466 clk_enable(pcm->pclk);
478 467
479 ret = snd_soc_register_dai(dai); 468 ret = snd_soc_register_dai(&pdev->dev, s3c_pcm_dai);
480 if (ret != 0) { 469 if (ret != 0) {
481 dev_err(&pdev->dev, "failed to get pcm_clock\n"); 470 dev_err(&pdev->dev, "failed to get pcm_clock\n");
482 goto err5; 471 goto err5;
@@ -514,6 +503,8 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev)
514 struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; 503 struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
515 struct resource *mem_res; 504 struct resource *mem_res;
516 505
506 snd_soc_unregister_dai(&pdev->dev);
507
517 iounmap(pcm->regs); 508 iounmap(pcm->regs);
518 509
519 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 510 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -531,7 +522,7 @@ static struct platform_driver s3c_pcm_driver = {
531 .probe = s3c_pcm_dev_probe, 522 .probe = s3c_pcm_dev_probe,
532 .remove = s3c_pcm_dev_remove, 523 .remove = s3c_pcm_dev_remove,
533 .driver = { 524 .driver = {
534 .name = "samsung-pcm", 525 .name = "samsung-pcm-audio",
535 .owner = THIS_MODULE, 526 .owner = THIS_MODULE,
536 }, 527 },
537}; 528};