Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Peter Ujfalusi and committed by
Mark Brown
453c4990 4dcb5a0b

+47 -7
+1
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
··· 5 5 "ti,dm646x-mcasp-audio" : for DM646x platforms 6 6 "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms 7 7 "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx) 8 + "ti,dra7-mcasp-audio" : for DRA7xx platforms 8 9 9 10 - reg : Should contain reg specifiers for the entries in the reg-names property. 10 11 - reg-names : Should contain:
+1
include/linux/platform_data/davinci_asp.h
··· 92 92 MCASP_VERSION_1 = 0, /* DM646x */ 93 93 MCASP_VERSION_2, /* DA8xx/OMAPL1x */ 94 94 MCASP_VERSION_3, /* TI81xx/AM33xx */ 95 + MCASP_VERSION_4, /* DRA7xxx */ 95 96 }; 96 97 97 98 enum mcbsp_clk_input_pin {
+45 -7
sound/soc/davinci/davinci-mcasp.c
··· 31 31 #include <sound/pcm_params.h> 32 32 #include <sound/initval.h> 33 33 #include <sound/soc.h> 34 + #include <sound/dmaengine_pcm.h> 34 35 35 36 #include "davinci-pcm.h" 36 37 #include "davinci-mcasp.h" 37 38 38 39 struct davinci_mcasp { 39 40 struct davinci_pcm_dma_params dma_params[2]; 41 + struct snd_dmaengine_dai_dma_data dma_data[2]; 40 42 void __iomem *base; 41 43 u32 fifo_base; 42 44 struct device *dev; ··· 460 458 u8 max_active_serializers = (channels + slots - 1) / slots; 461 459 u32 reg; 462 460 /* Default configuration */ 463 - mcasp_set_bits(mcasp->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); 461 + if (mcasp->version != MCASP_VERSION_4) 462 + mcasp_set_bits(mcasp->base + DAVINCI_MCASP_PWREMUMGT_REG, 463 + MCASP_SOFT); 464 464 465 465 /* All PINS as McASP */ 466 466 mcasp_set_reg(mcasp->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000); ··· 609 605 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); 610 606 struct davinci_pcm_dma_params *dma_params = 611 607 &mcasp->dma_params[substream->stream]; 608 + struct snd_dmaengine_dai_dma_data *dma_data = 609 + &mcasp->dma_data[substream->stream]; 612 610 int word_length; 613 611 u8 fifo_level; 614 612 u8 slots = mcasp->tdm_slots; ··· 672 666 dma_params->acnt = dma_params->data_type; 673 667 674 668 dma_params->fifo_level = fifo_level; 669 + dma_data->maxburst = fifo_level; 670 + 675 671 davinci_config_channel_size(mcasp, word_length); 676 672 677 673 return 0; ··· 719 711 { 720 712 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); 721 713 722 - snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); 714 + if (mcasp->version == MCASP_VERSION_4) 715 + snd_soc_dai_set_dma_data(dai, substream, 716 + &mcasp->dma_data[substream->stream]); 717 + else 718 + snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); 719 + 723 720 return 0; 724 721 } 725 722 ··· 807 794 .version = MCASP_VERSION_3, 808 795 }; 809 796 797 + static struct snd_platform_data dra7_mcasp_pdata = { 798 + .tx_dma_offset = 0x200, 799 + .rx_dma_offset = 0x284, 800 + .asp_chan_q = EVENTQ_0, 801 + .version = MCASP_VERSION_4, 802 + }; 803 + 810 804 static const struct of_device_id mcasp_dt_ids[] = { 811 805 { 812 806 .compatible = "ti,dm646x-mcasp-audio", ··· 826 806 { 827 807 .compatible = "ti,am33xx-mcasp-audio", 828 808 .data = &omap2_mcasp_pdata, 809 + }, 810 + { 811 + .compatible = "ti,dra7-mcasp-audio", 812 + .data = &dra7_mcasp_pdata, 829 813 }, 830 814 { /* sentinel */ } 831 815 }; ··· 1023 999 else 1024 1000 dma_data->dma_addr = mem->start + pdata->tx_dma_offset; 1025 1001 1002 + /* Unconditional dmaengine stuff */ 1003 + mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_data->dma_addr; 1004 + 1026 1005 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1027 1006 if (res) 1028 1007 dma_data->channel = res->start; ··· 1042 1015 else 1043 1016 dma_data->dma_addr = mem->start + pdata->rx_dma_offset; 1044 1017 1018 + /* Unconditional dmaengine stuff */ 1019 + mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_data->dma_addr; 1020 + 1045 1021 if (mcasp->version < MCASP_VERSION_3) { 1046 1022 mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; 1047 1023 /* dma_data->dma_addr is pointing to the data port address */ ··· 1059 1029 else 1060 1030 dma_data->channel = pdata->rx_dma_channel; 1061 1031 1032 + /* Unconditional dmaengine stuff */ 1033 + mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx"; 1034 + mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx"; 1035 + 1062 1036 dev_set_drvdata(&pdev->dev, mcasp); 1063 1037 ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, 1064 1038 &davinci_mcasp_dai[pdata->op_mode], 1); ··· 1070 1036 if (ret != 0) 1071 1037 goto err_release_clk; 1072 1038 1073 - ret = davinci_soc_platform_register(&pdev->dev); 1074 - if (ret) { 1075 - dev_err(&pdev->dev, "register PCM failed: %d\n", ret); 1076 - goto err_unregister_component; 1039 + if (mcasp->version != MCASP_VERSION_4) { 1040 + ret = davinci_soc_platform_register(&pdev->dev); 1041 + if (ret) { 1042 + dev_err(&pdev->dev, "register PCM failed: %d\n", ret); 1043 + goto err_unregister_component; 1044 + } 1077 1045 } 1078 1046 1079 1047 return 0; ··· 1090 1054 1091 1055 static int davinci_mcasp_remove(struct platform_device *pdev) 1092 1056 { 1057 + struct davinci_mcasp *mcasp = dev_get_drvdata(&pdev->dev); 1093 1058 1094 1059 snd_soc_unregister_component(&pdev->dev); 1095 - davinci_soc_platform_unregister(&pdev->dev); 1060 + if (mcasp->version != MCASP_VERSION_4) 1061 + davinci_soc_platform_unregister(&pdev->dev); 1096 1062 1097 1063 pm_runtime_put_sync(&pdev->dev); 1098 1064 pm_runtime_disable(&pdev->dev);