aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2012-03-16 04:56:43 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-01 06:28:27 -0400
commit09ce1111f3893106463559ed62f27fe999ace5d6 (patch)
treef02cdf770ff2a7234518a567913867fa2a10f4b8
parentdfa1a10785cf861c725aed0492f0ab69662bffea (diff)
ASoC: fsl: let fsl_ssi work with imx pcm and machine drivers
Makes necessary changes on fsl_ssi to let it work with imx pcm and machine drivers. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: Timur Tabi <timur@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/fsl/fsl_ssi.c77
1 files changed, 70 insertions, 7 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index db9a73404385..30ff605144c6 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -28,6 +28,7 @@
28#include <sound/soc.h> 28#include <sound/soc.h>
29 29
30#include "fsl_ssi.h" 30#include "fsl_ssi.h"
31#include "imx-pcm.h"
31 32
32#ifdef PPC 33#ifdef PPC
33#define read_ssi(addr) in_be32(addr) 34#define read_ssi(addr) in_be32(addr)
@@ -116,6 +117,12 @@ struct fsl_ssi_private {
116 struct device_attribute dev_attr; 117 struct device_attribute dev_attr;
117 struct platform_device *pdev; 118 struct platform_device *pdev;
118 119
120 bool new_binding;
121 bool ssi_on_imx;
122 struct platform_device *imx_pcm_pdev;
123 struct imx_pcm_dma_params dma_params_tx;
124 struct imx_pcm_dma_params dma_params_rx;
125
119 struct { 126 struct {
120 unsigned int rfrc; 127 unsigned int rfrc;
121 unsigned int tfrc; 128 unsigned int tfrc;
@@ -413,6 +420,12 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
413 ssi_private->second_stream = substream; 420 ssi_private->second_stream = substream;
414 } 421 }
415 422
423 if (ssi_private->ssi_on_imx)
424 snd_soc_dai_set_dma_data(dai, substream,
425 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
426 &ssi_private->dma_params_tx :
427 &ssi_private->dma_params_rx);
428
416 return 0; 429 return 0;
417} 430}
418 431
@@ -642,12 +655,6 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
642 if (!of_device_is_available(np)) 655 if (!of_device_is_available(np))
643 return -ENODEV; 656 return -ENODEV;
644 657
645 /* Check for a codec-handle property. */
646 if (!of_get_property(np, "codec-handle", NULL)) {
647 dev_err(&pdev->dev, "missing codec-handle property\n");
648 return -ENODEV;
649 }
650
651 /* We only support the SSI in "I2S Slave" mode */ 658 /* We only support the SSI in "I2S Slave" mode */
652 sprop = of_get_property(np, "fsl,mode", NULL); 659 sprop = of_get_property(np, "fsl,mode", NULL);
653 if (!sprop || strcmp(sprop, "i2s-slave")) { 660 if (!sprop || strcmp(sprop, "i2s-slave")) {
@@ -712,6 +719,35 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
712 /* Older 8610 DTs didn't have the fifo-depth property */ 719 /* Older 8610 DTs didn't have the fifo-depth property */
713 ssi_private->fifo_depth = 8; 720 ssi_private->fifo_depth = 8;
714 721
722 if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
723 u32 dma_events[2];
724 ssi_private->ssi_on_imx = true;
725 /*
726 * We have burstsize be "fifo_depth - 2" to match the SSI
727 * watermark setting in fsl_ssi_startup().
728 */
729 ssi_private->dma_params_tx.burstsize =
730 ssi_private->fifo_depth - 2;
731 ssi_private->dma_params_rx.burstsize =
732 ssi_private->fifo_depth - 2;
733 ssi_private->dma_params_tx.dma_addr =
734 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
735 ssi_private->dma_params_rx.dma_addr =
736 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
737 /*
738 * TODO: This is a temporary solution and should be changed
739 * to use generic DMA binding later when the helplers get in.
740 */
741 ret = of_property_read_u32_array(pdev->dev.of_node,
742 "fsl,ssi-dma-events", dma_events, 2);
743 if (ret) {
744 dev_err(&pdev->dev, "could not get dma events\n");
745 goto error_irq;
746 }
747 ssi_private->dma_params_tx.dma = dma_events[0];
748 ssi_private->dma_params_rx.dma = dma_events[1];
749 }
750
715 /* Initialize the the device_attribute structure */ 751 /* Initialize the the device_attribute structure */
716 dev_attr = &ssi_private->dev_attr; 752 dev_attr = &ssi_private->dev_attr;
717 sysfs_attr_init(&dev_attr->attr); 753 sysfs_attr_init(&dev_attr->attr);
@@ -735,6 +771,26 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
735 goto error_dev; 771 goto error_dev;
736 } 772 }
737 773
774 if (ssi_private->ssi_on_imx) {
775 ssi_private->imx_pcm_pdev =
776 platform_device_register_simple("imx-pcm-audio",
777 -1, NULL, 0);
778 if (IS_ERR(ssi_private->imx_pcm_pdev)) {
779 ret = PTR_ERR(ssi_private->imx_pcm_pdev);
780 goto error_dev;
781 }
782 }
783
784 /*
785 * If codec-handle property is missing from SSI node, we assume
786 * that the machine driver uses new binding which does not require
787 * SSI driver to trigger machine driver's probe.
788 */
789 if (!of_get_property(np, "codec-handle", NULL)) {
790 ssi_private->new_binding = true;
791 goto done;
792 }
793
738 /* Trigger the machine driver's probe function. The platform driver 794 /* Trigger the machine driver's probe function. The platform driver
739 * name of the machine driver is taken from /compatible property of the 795 * name of the machine driver is taken from /compatible property of the
740 * device tree. We also pass the address of the CPU DAI driver 796 * device tree. We also pass the address of the CPU DAI driver
@@ -756,9 +812,12 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
756 goto error_dai; 812 goto error_dai;
757 } 813 }
758 814
815done:
759 return 0; 816 return 0;
760 817
761error_dai: 818error_dai:
819 if (ssi_private->ssi_on_imx)
820 platform_device_unregister(ssi_private->imx_pcm_pdev);
762 snd_soc_unregister_dai(&pdev->dev); 821 snd_soc_unregister_dai(&pdev->dev);
763 822
764error_dev: 823error_dev:
@@ -784,7 +843,10 @@ static int fsl_ssi_remove(struct platform_device *pdev)
784{ 843{
785 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); 844 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
786 845
787 platform_device_unregister(ssi_private->pdev); 846 if (!ssi_private->new_binding)
847 platform_device_unregister(ssi_private->pdev);
848 if (ssi_private->ssi_on_imx)
849 platform_device_unregister(ssi_private->imx_pcm_pdev);
788 snd_soc_unregister_dai(&pdev->dev); 850 snd_soc_unregister_dai(&pdev->dev);
789 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 851 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
790 852
@@ -799,6 +861,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
799 861
800static const struct of_device_id fsl_ssi_ids[] = { 862static const struct of_device_id fsl_ssi_ids[] = {
801 { .compatible = "fsl,mpc8610-ssi", }, 863 { .compatible = "fsl,mpc8610-ssi", },
864 { .compatible = "fsl,imx21-ssi", },
802 {} 865 {}
803}; 866};
804MODULE_DEVICE_TABLE(of, fsl_ssi_ids); 867MODULE_DEVICE_TABLE(of, fsl_ssi_ids);