[alsa-devel] [PATCH 00/13] ASoC: dma: ARM: ux500: Obtain DMA data from Device Tree
At this moment in time the Ux500 ASoC driver obtains its DMA information via AUXDATA platform data passing. To make the driver more independent we have to start extracting it from the Device Tree.
Ideally this patch-set should stay together, so can you guys either agree to take it through a single tree, or create a non-disputable branch that you can all pull from after the Acks have been collected please? In fact, I can do that for you if that makes things easier.
Kind regards, Lee
Lee Jones (13): dma: ste_dma40: Expand DT binding to accept 'high-priority channel' flag dma: ste_dma40: Parse flags property for new 'high priority channel' request ARM: ux500: Don't use enums for MSP IDs - for easy DT conversion ARM: ux500: Add DMA config bindings for MSP devices ARM: ux500: Add ID properties to 'simply' differentiate between MSPs ASoC: ux500_pcm: Extend ux500 MSP binding for enumeration ASoC: ux500_pcm: Extract MSP IDs from Device Tree ASoC: generic-dmaengine-pcm: Clear slave_config memory ASoC: Ux500: Match platform by device node when booting Device Tree ASoC: ux500_pcm: Extend Device Tree support to deal with DMA data ASoC: ux500: Store DMA data in the DAI differently in the pdata and DT case ASoC: ux500_pcm: Differentiate between pdata and DT initialisation ASoC: ux500_pcm: Take out pointless dev_dbg() call
.../devicetree/bindings/dma/ste-dma40.txt | 3 ++ .../devicetree/bindings/sound/ux500-msp.txt | 3 ++ arch/arm/boot/dts/ste-dbx5x0.dtsi | 23 ++++++++ arch/arm/mach-ux500/board-mop500-audio.c | 8 +-- drivers/dma/ste_dma40.c | 4 ++ include/linux/platform_data/asoc-ux500-msp.h | 9 +--- sound/soc/soc-generic-dmaengine-pcm.c | 2 + sound/soc/ux500/mop500.c | 2 + sound/soc/ux500/ux500_msp_dai.c | 41 ++++++++++++++- sound/soc/ux500/ux500_msp_i2s.c | 61 +++++++++++++++++----- sound/soc/ux500/ux500_msp_i2s.h | 2 +- sound/soc/ux500/ux500_pcm.c | 32 ++++++++---- 12 files changed, 152 insertions(+), 38 deletions(-)
This is required for indexing pre-defined channel configuration structures.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org --- sound/soc/ux500/ux500_msp_i2s.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index 1ca8b08..0a99372 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c @@ -665,6 +665,13 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, sizeof(struct msp_i2s_platform_data), GFP_KERNEL); if (!platform_data) return -ENOMEM; + + if (!of_property_read_u32(np, "id", + &platform_data->id)) { + dev_err(&pdev->dev, + "No 'id' property found in DT\n"); + return -EINVAL; + } } } else if (!platform_data)
On Wed, Nov 6, 2013 at 11:16 AM, Lee Jones lee.jones@linaro.org wrote:
This is required for indexing pre-defined channel configuration structures.
Acked-by: Linus Walleij linus.walleij@linaro.org
Yours, Linus Walleij
We currently assume that the DMA Slave Config will be fully populated by the platform, however some DMA Engines make decisions based on zero (default) flags such as DMA_SLAVE_BUSWIDTH_UNDEFINED and as this is a static declaration we need to memset it to clear the data area.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org --- sound/soc/soc-generic-dmaengine-pcm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index ee07903..6ad4c7a 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -90,6 +90,8 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream, struct dma_slave_config slave_config; int ret;
+ memset(&slave_config, 0, sizeof(slave_config)); + if (!pcm->config) prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config; else
On 11/06/2013 11:16 AM, Lee Jones wrote:
We currently assume that the DMA Slave Config will be fully populated by the platform, however some DMA Engines make decisions based on zero (default) flags such as DMA_SLAVE_BUSWIDTH_UNDEFINED and as this is a static declaration we need to memset it to clear the data area.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org
Acked-by: Lars-Peter Clausen lars@metafoo.de
Thanks.
sound/soc/soc-generic-dmaengine-pcm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index ee07903..6ad4c7a 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -90,6 +90,8 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream, struct dma_slave_config slave_config; int ret;
- memset(&slave_config, 0, sizeof(slave_config));
- if (!pcm->config) prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config; else
On Wed, Nov 06, 2013 at 10:16:20AM +0000, Lee Jones wrote:
We currently assume that the DMA Slave Config will be fully populated by the platform, however some DMA Engines make decisions based on zero (default) flags such as DMA_SLAVE_BUSWIDTH_UNDEFINED and as this is a static declaration we need to memset it to clear the data area.
Applied, thanks - given how near we are to the merge window the whole series isn't going to go in for v3.13 but this ought to do so.
We're getting closer to fully enabling the Ux500 ASoC driver for Device Tree. When we switch over from using AUXDATA we'll need to match platform by only Device Tree nodes. In this patch we NULL out the platform_name, and supply nodes for each platform device.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org --- sound/soc/ux500/mop500.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 178d1ba..4dc7b81 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -90,7 +90,9 @@ static int mop500_of_probe(struct platform_device *pdev,
for (i = 0; i < 2; i++) { mop500_dai_links[i].cpu_of_node = msp_np[i]; + mop500_dai_links[i].platform_of_node = msp_np[i]; mop500_dai_links[i].cpu_dai_name = NULL; + mop500_dai_links[i].platform_name = NULL; mop500_dai_links[i].codec_of_node = codec_np; mop500_dai_links[i].codec_name = NULL; }
On Wed, Nov 6, 2013 at 11:16 AM, Lee Jones lee.jones@linaro.org wrote:
We're getting closer to fully enabling the Ux500 ASoC driver for Device Tree. When we switch over from using AUXDATA we'll need to match platform by only Device Tree nodes. In this patch we NULL out the platform_name, and supply nodes for each platform device.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org
Acked-by: Linus Walleij linus.walleij@linaro.org
Yours, Linus Walleij
Soon we will strip out pdata support from the Ux500 set of ASoC drivers. When this happens it will have to supply a DMA slave_config to the dmaengine. At the moment a great deal of this comes from pdata via AUXDATA. We need to become independent of this soon. This patch starts the process by allocating memory for the associated data structures and fetches the MSP id used for const struct indexing.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org --- sound/soc/ux500/ux500_msp_i2s.c | 68 ++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 21 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index 0a99372..2e916d1 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c @@ -646,6 +646,41 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
}
+int ux500_msp_i2s_of_init_msp(struct platform_device *pdev, + struct ux500_msp *msp, + struct msp_i2s_platform_data **platform_data) +{ + struct device_node *np = pdev->dev.of_node; + struct msp_i2s_platform_data *pdata; + + *platform_data = devm_kzalloc(&pdev->dev, + sizeof(struct msp_i2s_platform_data), + GFP_KERNEL); + pdata = *platform_data; + if (!pdata) + return -ENOMEM; + + msp->playback_dma_data.dma_cfg = devm_kzalloc(&pdev->dev, + sizeof(struct stedma40_chan_cfg), + GFP_KERNEL); + if (!msp->playback_dma_data.dma_cfg) + return -ENOMEM; + + msp->capture_dma_data.dma_cfg = devm_kzalloc(&pdev->dev, + sizeof(struct stedma40_chan_cfg), + GFP_KERNEL); + if (!msp->capture_dma_data.dma_cfg) + return -ENOMEM; + + if (of_property_read_u32(np, "id", &pdata->id)) { + dev_err(&pdev->dev, + "No 'id' property found in DT\n"); + return -EINVAL; + } + + return 0; +} + int ux500_msp_i2s_init_msp(struct platform_device *pdev, struct ux500_msp **msp_p, struct msp_i2s_platform_data *platform_data) @@ -653,37 +688,28 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, struct resource *res = NULL; struct device_node *np = pdev->dev.of_node; struct ux500_msp *msp; + int ret;
*msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); msp = *msp_p; if (!msp) return -ENOMEM;
- if (np) { - if (!platform_data) { - platform_data = devm_kzalloc(&pdev->dev, - sizeof(struct msp_i2s_platform_data), GFP_KERNEL); - if (!platform_data) - return -ENOMEM; - - if (!of_property_read_u32(np, "id", - &platform_data->id)) { - dev_err(&pdev->dev, - "No 'id' property found in DT\n"); - return -EINVAL; - } - } - } else - if (!platform_data) + if (!platform_data) { + if (np) { + ret = ux500_msp_i2s_of_init_msp(pdev, msp, + &platform_data); + if (ret) + return ret; + } else return -EINVAL; - - dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__, - pdev->name, platform_data->id); + } else { + msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx; + msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx; + }
msp->id = platform_data->id; msp->dev = &pdev->dev; - msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx; - msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) {
On Wed, Nov 6, 2013 at 11:16 AM, Lee Jones lee.jones@linaro.org wrote:
Soon we will strip out pdata support from the Ux500 set of ASoC drivers. When this happens it will have to supply a DMA slave_config to the dmaengine. At the moment a great deal of this comes from pdata via AUXDATA. We need to become independent of this soon. This patch starts the process by allocating memory for the associated data structures and fetches the MSP id used for const struct indexing.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org
Acked-by: Linus Walleij linus.walleij@linaro.org
Yours, Linus Walleij
In this patch we do two things. Firstly, instead of open coding the store of DMA data in to the DAI for later use, we use the API provided. Secondly we create and store similar DMA data for the DT case, only this time we use 'struct snd_dmaengine_dai_dma_data' which is provided by the core for this very reason.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org --- sound/soc/ux500/ux500_msp_dai.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index c6fb5cc..35187d8 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -17,12 +17,14 @@ #include <linux/bitops.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <linux/mfd/dbx500-prcmu.h> #include <linux/platform_data/asoc-ux500-msp.h>
#include <sound/soc.h> #include <sound/soc-dai.h> +#include <sound/dmaengine_pcm.h>
#include "ux500_msp_i2s.h" #include "ux500_msp_dai.h" @@ -654,16 +656,51 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream, return ret; }
+static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai) +{ + struct snd_dmaengine_dai_dma_data *playback_dma_data; + struct snd_dmaengine_dai_dma_data *capture_dma_data; + + playback_dma_data = devm_kzalloc(dai->dev, + sizeof(*playback_dma_data), + GFP_KERNEL); + if (!playback_dma_data) + return -ENOMEM; + + capture_dma_data = devm_kzalloc(dai->dev, + sizeof(*capture_dma_data), + GFP_KERNEL); + if (!capture_dma_data) + return -ENOMEM; + + playback_dma_data->addr = drvdata->msp->playback_dma_data.tx_rx_addr; + capture_dma_data->addr = drvdata->msp->capture_dma_data.tx_rx_addr; + + playback_dma_data->maxburst = 4; + capture_dma_data->maxburst = 4; + + snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data); + + return 0; +} + static int ux500_msp_dai_probe(struct snd_soc_dai *dai) { struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); + struct device_node *np = dai->dev->of_node; + int ret;
- dai->playback_dma_data = &drvdata->msp->playback_dma_data; - dai->capture_dma_data = &drvdata->msp->capture_dma_data; + if (np) { + ret = ux500_msp_dai_of_probe(dai); + return ret; + }
drvdata->msp->playback_dma_data.data_size = drvdata->slot_width; drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;
+ snd_soc_dai_init_dma_data(dai, + &drvdata->msp->playback_dma_data, + &drvdata->msp->capture_dma_data); return 0; }
On Wed, Nov 6, 2013 at 11:16 AM, Lee Jones lee.jones@linaro.org wrote:
In this patch we do two things. Firstly, instead of open coding the store of DMA data in to the DAI for later use, we use the API provided. Secondly we create and store similar DMA data for the DT case, only this time we use 'struct snd_dmaengine_dai_dma_data' which is provided by the core for this very reason.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org
Acked-by: Linus Walleij linus.walleij@linaro.org
Yours, Linus Walleij
If booting with full DT support (i.e. DMA too, the last piece of the puzzle), then we don't need to use the compatible request channel call back and, due to the work we laid down earlier in this patch-set, we can use core function calls to populate the DMA slave_config. We also require slightly different flags to inform the core that we 'are' booting with DT.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org --- sound/soc/ux500/ux500_pcm.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index ce554de..acfec98 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -139,15 +139,33 @@ static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = { .prepare_slave_config = ux500_pcm_prepare_slave_config, };
+static const struct snd_dmaengine_pcm_config ux500_dmaengine_of_pcm_config = { + .pcm_hardware = &ux500_pcm_hw, + .prealloc_buffer_size = 128 * 1024, + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, +}; + int ux500_pcm_register_platform(struct platform_device *pdev) { + const struct snd_dmaengine_pcm_config *pcm_config; + struct device_node *np = pdev->dev.of_node; + unsigned int pcm_flags; int ret;
- ret = snd_dmaengine_pcm_register(&pdev->dev, - &ux500_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | - SND_DMAENGINE_PCM_FLAG_COMPAT | - SND_DMAENGINE_PCM_FLAG_NO_DT); + if (np) { + pcm_config = &ux500_dmaengine_of_pcm_config; + + pcm_flags = SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + SND_DMAENGINE_PCM_FLAG_COMPAT; + } else { + pcm_config = &ux500_dmaengine_pcm_config; + + pcm_flags = SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + SND_DMAENGINE_PCM_FLAG_NO_DT | + SND_DMAENGINE_PCM_FLAG_COMPAT; + } + + ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, pcm_flags); if (ret < 0) { dev_err(&pdev->dev, "%s: ERROR: Failed to register platform '%s' (%d)!\n",
On Wed, Nov 6, 2013 at 11:16 AM, Lee Jones lee.jones@linaro.org wrote:
If booting with full DT support (i.e. DMA too, the last piece of the puzzle), then we don't need to use the compatible request channel call back and, due to the work we laid down earlier in this patch-set, we can use core function calls to populate the DMA slave_config. We also require slightly different flags to inform the core that we 'are' booting with DT.
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org
Acked-by: Linus Walleij linus.walleij@linaro.org
Yours, Linus Walleij
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org --- sound/soc/ux500/ux500_pcm.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index acfec98..fd7f12e 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -65,14 +65,10 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_substream *substream) { struct snd_soc_dai *dai = rtd->cpu_dai; - struct device *dev = dai->dev; u16 per_data_width, mem_data_width; struct stedma40_chan_cfg *dma_cfg; struct ux500_msp_dma_params *dma_params;
- dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, - snd_pcm_stream_str(substream)); - dma_params = snd_soc_dai_get_dma_data(dai, substream); dma_cfg = dma_params->dma_cfg;
On Wed, Nov 6, 2013 at 11:16 AM, Lee Jones lee.jones@linaro.org wrote:
Cc: alsa-devel@alsa-project.org Cc: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org
Acked-by: Linus Walleij linus.walleij@linaro.org
Yours, Linus Walleij
participants (4)
-
Lars-Peter Clausen
-
Lee Jones
-
Linus Walleij
-
Mark Brown