diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2012-03-16 04:56:43 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-04-01 06:28:27 -0400 |
commit | 09ce1111f3893106463559ed62f27fe999ace5d6 (patch) | |
tree | f02cdf770ff2a7234518a567913867fa2a10f4b8 | |
parent | dfa1a10785cf861c725aed0492f0ab69662bffea (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.c | 77 |
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 | ||
815 | done: | ||
759 | return 0; | 816 | return 0; |
760 | 817 | ||
761 | error_dai: | 818 | error_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 | ||
764 | error_dev: | 823 | error_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 | ||
800 | static const struct of_device_id fsl_ssi_ids[] = { | 862 | static 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 | }; |
804 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); | 867 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); |