aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci/davinci-i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/davinci/davinci-i2s.c')
-rw-r--r--sound/soc/davinci/davinci-i2s.c85
1 files changed, 47 insertions, 38 deletions
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 9e8932abf158..d0d60b8a54d4 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -183,8 +183,7 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
183 struct snd_pcm_substream *substream) 183 struct snd_pcm_substream *substream)
184{ 184{
185 struct snd_soc_pcm_runtime *rtd = substream->private_data; 185 struct snd_soc_pcm_runtime *rtd = substream->private_data;
186 struct snd_soc_device *socdev = rtd->socdev; 186 struct snd_soc_platform *platform = rtd->platform;
187 struct snd_soc_platform *platform = socdev->card->platform;
188 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 187 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
189 u32 spcr; 188 u32 spcr;
190 u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST; 189 u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
@@ -205,8 +204,8 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
205 if (playback) { 204 if (playback) {
206 /* Stop the DMA to avoid data loss */ 205 /* Stop the DMA to avoid data loss */
207 /* while the transmitter is out of reset to handle XSYNCERR */ 206 /* while the transmitter is out of reset to handle XSYNCERR */
208 if (platform->pcm_ops->trigger) { 207 if (platform->driver->ops->trigger) {
209 int ret = platform->pcm_ops->trigger(substream, 208 int ret = platform->driver->ops->trigger(substream,
210 SNDRV_PCM_TRIGGER_STOP); 209 SNDRV_PCM_TRIGGER_STOP);
211 if (ret < 0) 210 if (ret < 0)
212 printk(KERN_DEBUG "Playback DMA stop failed\n"); 211 printk(KERN_DEBUG "Playback DMA stop failed\n");
@@ -227,8 +226,8 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
227 toggle_clock(dev, playback); 226 toggle_clock(dev, playback);
228 227
229 /* Restart the DMA */ 228 /* Restart the DMA */
230 if (platform->pcm_ops->trigger) { 229 if (platform->driver->ops->trigger) {
231 int ret = platform->pcm_ops->trigger(substream, 230 int ret = platform->driver->ops->trigger(substream,
232 SNDRV_PCM_TRIGGER_START); 231 SNDRV_PCM_TRIGGER_START);
233 if (ret < 0) 232 if (ret < 0)
234 printk(KERN_DEBUG "Playback DMA start failed\n"); 233 printk(KERN_DEBUG "Playback DMA start failed\n");
@@ -263,7 +262,7 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
263static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 262static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
264 unsigned int fmt) 263 unsigned int fmt)
265{ 264{
266 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 265 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
267 unsigned int pcr; 266 unsigned int pcr;
268 unsigned int srgr; 267 unsigned int srgr;
269 /* Attention srgr is updated by hw_params! */ 268 /* Attention srgr is updated by hw_params! */
@@ -404,7 +403,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
404static int davinci_i2s_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, 403static int davinci_i2s_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
405 int div_id, int div) 404 int div_id, int div)
406{ 405{
407 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 406 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
408 407
409 if (div_id != DAVINCI_MCBSP_CLKGDV) 408 if (div_id != DAVINCI_MCBSP_CLKGDV)
410 return -ENODEV; 409 return -ENODEV;
@@ -417,7 +416,7 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
417 struct snd_pcm_hw_params *params, 416 struct snd_pcm_hw_params *params,
418 struct snd_soc_dai *dai) 417 struct snd_soc_dai *dai)
419{ 418{
420 struct davinci_mcbsp_dev *dev = dai->private_data; 419 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
421 struct davinci_pcm_dma_params *dma_params = 420 struct davinci_pcm_dma_params *dma_params =
422 &dev->dma_params[substream->stream]; 421 &dev->dma_params[substream->stream];
423 struct snd_interval *i = NULL; 422 struct snd_interval *i = NULL;
@@ -569,24 +568,18 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
569static int davinci_i2s_prepare(struct snd_pcm_substream *substream, 568static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
570 struct snd_soc_dai *dai) 569 struct snd_soc_dai *dai)
571{ 570{
572 struct davinci_mcbsp_dev *dev = dai->private_data; 571 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
573 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 572 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
574 davinci_mcbsp_stop(dev, playback); 573 davinci_mcbsp_stop(dev, playback);
575 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0) {
576 /* codec is master */
577 davinci_mcbsp_start(dev, substream);
578 }
579 return 0; 574 return 0;
580} 575}
581 576
582static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 577static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
583 struct snd_soc_dai *dai) 578 struct snd_soc_dai *dai)
584{ 579{
585 struct davinci_mcbsp_dev *dev = dai->private_data; 580 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
586 int ret = 0; 581 int ret = 0;
587 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 582 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
588 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0)
589 return 0; /* return if codec is master */
590 583
591 switch (cmd) { 584 switch (cmd) {
592 case SNDRV_PCM_TRIGGER_START: 585 case SNDRV_PCM_TRIGGER_START:
@@ -605,10 +598,19 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
605 return ret; 598 return ret;
606} 599}
607 600
601static int davinci_i2s_startup(struct snd_pcm_substream *substream,
602 struct snd_soc_dai *dai)
603{
604 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
605
606 snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
607 return 0;
608}
609
608static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, 610static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
609 struct snd_soc_dai *dai) 611 struct snd_soc_dai *dai)
610{ 612{
611 struct davinci_mcbsp_dev *dev = dai->private_data; 613 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
612 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 614 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
613 davinci_mcbsp_stop(dev, playback); 615 davinci_mcbsp_stop(dev, playback);
614} 616}
@@ -616,6 +618,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
616#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 618#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
617 619
618static struct snd_soc_dai_ops davinci_i2s_dai_ops = { 620static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
621 .startup = davinci_i2s_startup,
619 .shutdown = davinci_i2s_shutdown, 622 .shutdown = davinci_i2s_shutdown,
620 .prepare = davinci_i2s_prepare, 623 .prepare = davinci_i2s_prepare,
621 .trigger = davinci_i2s_trigger, 624 .trigger = davinci_i2s_trigger,
@@ -625,9 +628,7 @@ static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
625 628
626}; 629};
627 630
628struct snd_soc_dai davinci_i2s_dai = { 631static struct snd_soc_dai_driver davinci_i2s_dai = {
629 .name = "davinci-i2s",
630 .id = 0,
631 .playback = { 632 .playback = {
632 .channels_min = 2, 633 .channels_min = 2,
633 .channels_max = 2, 634 .channels_max = 2,
@@ -641,7 +642,6 @@ struct snd_soc_dai davinci_i2s_dai = {
641 .ops = &davinci_i2s_dai_ops, 642 .ops = &davinci_i2s_dai_ops,
642 643
643}; 644};
644EXPORT_SYMBOL_GPL(davinci_i2s_dai);
645 645
646static int davinci_i2s_probe(struct platform_device *pdev) 646static int davinci_i2s_probe(struct platform_device *pdev)
647{ 647{
@@ -658,7 +658,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
658 return -ENODEV; 658 return -ENODEV;
659 } 659 }
660 660
661 ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, 661 ioarea = request_mem_region(mem->start, resource_size(mem),
662 pdev->name); 662 pdev->name);
663 if (!ioarea) { 663 if (!ioarea) {
664 dev_err(&pdev->dev, "McBSP region already claimed\n"); 664 dev_err(&pdev->dev, "McBSP region already claimed\n");
@@ -694,20 +694,25 @@ static int davinci_i2s_probe(struct platform_device *pdev)
694 } 694 }
695 clk_enable(dev->clk); 695 clk_enable(dev->clk);
696 696
697 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 697 dev->base = ioremap(mem->start, resource_size(mem));
698 if (!dev->base) {
699 dev_err(&pdev->dev, "ioremap failed\n");
700 ret = -ENOMEM;
701 goto err_release_clk;
702 }
698 703
699 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = 704 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
700 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); 705 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
701 706
702 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = 707 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
703 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); 708 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
704 709
705 /* first TX, then RX */ 710 /* first TX, then RX */
706 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 711 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
707 if (!res) { 712 if (!res) {
708 dev_err(&pdev->dev, "no DMA resource\n"); 713 dev_err(&pdev->dev, "no DMA resource\n");
709 ret = -ENXIO; 714 ret = -ENXIO;
710 goto err_free_mem; 715 goto err_iounmap;
711 } 716 }
712 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start; 717 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
713 718
@@ -715,40 +720,44 @@ static int davinci_i2s_probe(struct platform_device *pdev)
715 if (!res) { 720 if (!res) {
716 dev_err(&pdev->dev, "no DMA resource\n"); 721 dev_err(&pdev->dev, "no DMA resource\n");
717 ret = -ENXIO; 722 ret = -ENXIO;
718 goto err_free_mem; 723 goto err_iounmap;
719 } 724 }
720 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 725 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
721 dev->dev = &pdev->dev; 726 dev->dev = &pdev->dev;
722 727
723 davinci_i2s_dai.private_data = dev; 728 dev_set_drvdata(&pdev->dev, dev);
724 davinci_i2s_dai.capture.dma_data = dev->dma_params; 729
725 davinci_i2s_dai.playback.dma_data = dev->dma_params; 730 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai);
726 ret = snd_soc_register_dai(&davinci_i2s_dai);
727 if (ret != 0) 731 if (ret != 0)
728 goto err_free_mem; 732 goto err_iounmap;
729 733
730 return 0; 734 return 0;
731 735
736err_iounmap:
737 iounmap(dev->base);
738err_release_clk:
739 clk_disable(dev->clk);
740 clk_put(dev->clk);
732err_free_mem: 741err_free_mem:
733 kfree(dev); 742 kfree(dev);
734err_release_region: 743err_release_region:
735 release_mem_region(mem->start, (mem->end - mem->start) + 1); 744 release_mem_region(mem->start, resource_size(mem));
736 745
737 return ret; 746 return ret;
738} 747}
739 748
740static int davinci_i2s_remove(struct platform_device *pdev) 749static int davinci_i2s_remove(struct platform_device *pdev)
741{ 750{
742 struct davinci_mcbsp_dev *dev = davinci_i2s_dai.private_data; 751 struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
743 struct resource *mem; 752 struct resource *mem;
744 753
745 snd_soc_unregister_dai(&davinci_i2s_dai); 754 snd_soc_unregister_dai(&pdev->dev);
746 clk_disable(dev->clk); 755 clk_disable(dev->clk);
747 clk_put(dev->clk); 756 clk_put(dev->clk);
748 dev->clk = NULL; 757 dev->clk = NULL;
749 kfree(dev); 758 kfree(dev);
750 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 759 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
751 release_mem_region(mem->start, (mem->end - mem->start) + 1); 760 release_mem_region(mem->start, resource_size(mem));
752 761
753 return 0; 762 return 0;
754} 763}
@@ -757,7 +766,7 @@ static struct platform_driver davinci_mcbsp_driver = {
757 .probe = davinci_i2s_probe, 766 .probe = davinci_i2s_probe,
758 .remove = davinci_i2s_remove, 767 .remove = davinci_i2s_remove,
759 .driver = { 768 .driver = {
760 .name = "davinci-asp", 769 .name = "davinci-mcbsp",
761 .owner = THIS_MODULE, 770 .owner = THIS_MODULE,
762 }, 771 },
763}; 772};