diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2013-11-14 04:35:34 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-12-10 06:22:16 -0500 |
commit | 453c499028bf2ecf3b31ccb7c3657fe1b0b28943 (patch) | |
tree | 3ee1cdd4eff179dd30104d8ccba3873ddc9d06c9 | |
parent | 4dcb5a0bffaa7dc51e738c4f651a31993b1eb08b (diff) |
ASoC: davinci-mcasp: Support for McASP version found in DRA7xx
The IP in DRA7xx is similar to the IP found in TI81xxAM3xxx/AM4xxx type of
SoCs but it is is integrated with sDMA instead of eDMA. The suitable pcm
driver for DRA7xx is the omap-pcm driver which is using dmaengine.
In the driver we can configure both dma related structures used for eDMA and
sDMA. The only thing we need to make sure that we set the correct dma_data
at startup with snd_soc_dai_set_dma_data()
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt | 1 | ||||
-rw-r--r-- | include/linux/platform_data/davinci_asp.h | 1 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 52 |
3 files changed, 47 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt index 1eed972d4719..990fa71ce804 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt | |||
@@ -5,6 +5,7 @@ Required properties: | |||
5 | "ti,dm646x-mcasp-audio" : for DM646x platforms | 5 | "ti,dm646x-mcasp-audio" : for DM646x platforms |
6 | "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms | 6 | "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms |
7 | "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx) | 7 | "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx) |
8 | "ti,dra7-mcasp-audio" : for DRA7xx platforms | ||
8 | 9 | ||
9 | - reg : Should contain reg specifiers for the entries in the reg-names property. | 10 | - reg : Should contain reg specifiers for the entries in the reg-names property. |
10 | - reg-names : Should contain: | 11 | - reg-names : Should contain: |
diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h index 689a856b86f9..5245992b0367 100644 --- a/include/linux/platform_data/davinci_asp.h +++ b/include/linux/platform_data/davinci_asp.h | |||
@@ -92,6 +92,7 @@ enum { | |||
92 | MCASP_VERSION_1 = 0, /* DM646x */ | 92 | MCASP_VERSION_1 = 0, /* DM646x */ |
93 | MCASP_VERSION_2, /* DA8xx/OMAPL1x */ | 93 | MCASP_VERSION_2, /* DA8xx/OMAPL1x */ |
94 | MCASP_VERSION_3, /* TI81xx/AM33xx */ | 94 | MCASP_VERSION_3, /* TI81xx/AM33xx */ |
95 | MCASP_VERSION_4, /* DRA7xxx */ | ||
95 | }; | 96 | }; |
96 | 97 | ||
97 | enum mcbsp_clk_input_pin { | 98 | enum mcbsp_clk_input_pin { |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 93f2e294d649..fc8c13d2f31e 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -31,12 +31,14 @@ | |||
31 | #include <sound/pcm_params.h> | 31 | #include <sound/pcm_params.h> |
32 | #include <sound/initval.h> | 32 | #include <sound/initval.h> |
33 | #include <sound/soc.h> | 33 | #include <sound/soc.h> |
34 | #include <sound/dmaengine_pcm.h> | ||
34 | 35 | ||
35 | #include "davinci-pcm.h" | 36 | #include "davinci-pcm.h" |
36 | #include "davinci-mcasp.h" | 37 | #include "davinci-mcasp.h" |
37 | 38 | ||
38 | struct davinci_mcasp { | 39 | struct davinci_mcasp { |
39 | struct davinci_pcm_dma_params dma_params[2]; | 40 | struct davinci_pcm_dma_params dma_params[2]; |
41 | struct snd_dmaengine_dai_dma_data dma_data[2]; | ||
40 | void __iomem *base; | 42 | void __iomem *base; |
41 | u32 fifo_base; | 43 | u32 fifo_base; |
42 | struct device *dev; | 44 | struct device *dev; |
@@ -458,7 +460,9 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | |||
458 | u8 max_active_serializers = (channels + slots - 1) / slots; | 460 | u8 max_active_serializers = (channels + slots - 1) / slots; |
459 | u32 reg; | 461 | u32 reg; |
460 | /* Default configuration */ | 462 | /* Default configuration */ |
461 | mcasp_set_bits(mcasp->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); | 463 | if (mcasp->version != MCASP_VERSION_4) |
464 | mcasp_set_bits(mcasp->base + DAVINCI_MCASP_PWREMUMGT_REG, | ||
465 | MCASP_SOFT); | ||
462 | 466 | ||
463 | /* All PINS as McASP */ | 467 | /* All PINS as McASP */ |
464 | mcasp_set_reg(mcasp->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000); | 468 | mcasp_set_reg(mcasp->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000); |
@@ -605,6 +609,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
605 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); | 609 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); |
606 | struct davinci_pcm_dma_params *dma_params = | 610 | struct davinci_pcm_dma_params *dma_params = |
607 | &mcasp->dma_params[substream->stream]; | 611 | &mcasp->dma_params[substream->stream]; |
612 | struct snd_dmaengine_dai_dma_data *dma_data = | ||
613 | &mcasp->dma_data[substream->stream]; | ||
608 | int word_length; | 614 | int word_length; |
609 | u8 fifo_level; | 615 | u8 fifo_level; |
610 | u8 slots = mcasp->tdm_slots; | 616 | u8 slots = mcasp->tdm_slots; |
@@ -666,6 +672,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
666 | dma_params->acnt = dma_params->data_type; | 672 | dma_params->acnt = dma_params->data_type; |
667 | 673 | ||
668 | dma_params->fifo_level = fifo_level; | 674 | dma_params->fifo_level = fifo_level; |
675 | dma_data->maxburst = fifo_level; | ||
676 | |||
669 | davinci_config_channel_size(mcasp, word_length); | 677 | davinci_config_channel_size(mcasp, word_length); |
670 | 678 | ||
671 | return 0; | 679 | return 0; |
@@ -711,7 +719,12 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | |||
711 | { | 719 | { |
712 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); | 720 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); |
713 | 721 | ||
714 | snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); | 722 | if (mcasp->version == MCASP_VERSION_4) |
723 | snd_soc_dai_set_dma_data(dai, substream, | ||
724 | &mcasp->dma_data[substream->stream]); | ||
725 | else | ||
726 | snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); | ||
727 | |||
715 | return 0; | 728 | return 0; |
716 | } | 729 | } |
717 | 730 | ||
@@ -794,6 +807,13 @@ static struct snd_platform_data omap2_mcasp_pdata = { | |||
794 | .version = MCASP_VERSION_3, | 807 | .version = MCASP_VERSION_3, |
795 | }; | 808 | }; |
796 | 809 | ||
810 | static struct snd_platform_data dra7_mcasp_pdata = { | ||
811 | .tx_dma_offset = 0x200, | ||
812 | .rx_dma_offset = 0x284, | ||
813 | .asp_chan_q = EVENTQ_0, | ||
814 | .version = MCASP_VERSION_4, | ||
815 | }; | ||
816 | |||
797 | static const struct of_device_id mcasp_dt_ids[] = { | 817 | static const struct of_device_id mcasp_dt_ids[] = { |
798 | { | 818 | { |
799 | .compatible = "ti,dm646x-mcasp-audio", | 819 | .compatible = "ti,dm646x-mcasp-audio", |
@@ -807,6 +827,10 @@ static const struct of_device_id mcasp_dt_ids[] = { | |||
807 | .compatible = "ti,am33xx-mcasp-audio", | 827 | .compatible = "ti,am33xx-mcasp-audio", |
808 | .data = &omap2_mcasp_pdata, | 828 | .data = &omap2_mcasp_pdata, |
809 | }, | 829 | }, |
830 | { | ||
831 | .compatible = "ti,dra7-mcasp-audio", | ||
832 | .data = &dra7_mcasp_pdata, | ||
833 | }, | ||
810 | { /* sentinel */ } | 834 | { /* sentinel */ } |
811 | }; | 835 | }; |
812 | MODULE_DEVICE_TABLE(of, mcasp_dt_ids); | 836 | MODULE_DEVICE_TABLE(of, mcasp_dt_ids); |
@@ -999,6 +1023,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
999 | else | 1023 | else |
1000 | dma_data->dma_addr = mem->start + pdata->tx_dma_offset; | 1024 | dma_data->dma_addr = mem->start + pdata->tx_dma_offset; |
1001 | 1025 | ||
1026 | /* Unconditional dmaengine stuff */ | ||
1027 | mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_data->dma_addr; | ||
1028 | |||
1002 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 1029 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
1003 | if (res) | 1030 | if (res) |
1004 | dma_data->channel = res->start; | 1031 | dma_data->channel = res->start; |
@@ -1015,6 +1042,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1015 | else | 1042 | else |
1016 | dma_data->dma_addr = mem->start + pdata->rx_dma_offset; | 1043 | dma_data->dma_addr = mem->start + pdata->rx_dma_offset; |
1017 | 1044 | ||
1045 | /* Unconditional dmaengine stuff */ | ||
1046 | mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_data->dma_addr; | ||
1047 | |||
1018 | if (mcasp->version < MCASP_VERSION_3) { | 1048 | if (mcasp->version < MCASP_VERSION_3) { |
1019 | mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; | 1049 | mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; |
1020 | /* dma_data->dma_addr is pointing to the data port address */ | 1050 | /* dma_data->dma_addr is pointing to the data port address */ |
@@ -1029,6 +1059,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1029 | else | 1059 | else |
1030 | dma_data->channel = pdata->rx_dma_channel; | 1060 | dma_data->channel = pdata->rx_dma_channel; |
1031 | 1061 | ||
1062 | /* Unconditional dmaengine stuff */ | ||
1063 | mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx"; | ||
1064 | mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx"; | ||
1065 | |||
1032 | dev_set_drvdata(&pdev->dev, mcasp); | 1066 | dev_set_drvdata(&pdev->dev, mcasp); |
1033 | ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, | 1067 | ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, |
1034 | &davinci_mcasp_dai[pdata->op_mode], 1); | 1068 | &davinci_mcasp_dai[pdata->op_mode], 1); |
@@ -1036,10 +1070,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1036 | if (ret != 0) | 1070 | if (ret != 0) |
1037 | goto err_release_clk; | 1071 | goto err_release_clk; |
1038 | 1072 | ||
1039 | ret = davinci_soc_platform_register(&pdev->dev); | 1073 | if (mcasp->version != MCASP_VERSION_4) { |
1040 | if (ret) { | 1074 | ret = davinci_soc_platform_register(&pdev->dev); |
1041 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | 1075 | if (ret) { |
1042 | goto err_unregister_component; | 1076 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); |
1077 | goto err_unregister_component; | ||
1078 | } | ||
1043 | } | 1079 | } |
1044 | 1080 | ||
1045 | return 0; | 1081 | return 0; |
@@ -1054,9 +1090,11 @@ err_release_clk: | |||
1054 | 1090 | ||
1055 | static int davinci_mcasp_remove(struct platform_device *pdev) | 1091 | static int davinci_mcasp_remove(struct platform_device *pdev) |
1056 | { | 1092 | { |
1093 | struct davinci_mcasp *mcasp = dev_get_drvdata(&pdev->dev); | ||
1057 | 1094 | ||
1058 | snd_soc_unregister_component(&pdev->dev); | 1095 | snd_soc_unregister_component(&pdev->dev); |
1059 | davinci_soc_platform_unregister(&pdev->dev); | 1096 | if (mcasp->version != MCASP_VERSION_4) |
1097 | davinci_soc_platform_unregister(&pdev->dev); | ||
1060 | 1098 | ||
1061 | pm_runtime_put_sync(&pdev->dev); | 1099 | pm_runtime_put_sync(&pdev->dev); |
1062 | pm_runtime_disable(&pdev->dev); | 1100 | pm_runtime_disable(&pdev->dev); |