[alsa-devel] [PATCH 0/6] ASoC: Regression fix for OMAP in DT boot (3.11)
Hi,
I just noticed in mainline kernel (pre 3.11-rc1) that OMAP4 audio is not probing anymore. This is because OMAP4 also moved to DT only mode (3.10 DT boot was fine). The issue underneath is that we can not use platform_get_resource_byname() for DMA resources when booted with devicetree.
In case of DT boot we can use the DMA name to request the channel.
Due to technical issues OMAP can not be moved to generic dmaengine pcm as other SoCs did.
Mark: can you queue this series for 3.11? Thank you.
Regards, Peter --- Peter Ujfalusi (6): ASoC: dmaengine_pcm: Add dma_name to snd_dmaengine_dai_dma_data ASoC: omap-pcm: Request the DMA channel by name when dma_name is set for the dai ASoC: omap-mcpdm: Do not use platform_get_resource_byname() for DMA ASoC: omap-dmic: Do not use platform_get_resource_byname() for DMA ASoC: omap-mcbsp: Use different method for DMA request when booted with DT ASoC: omap-dmic: Cleanup the probe function
include/sound/dmaengine_pcm.h | 1 + sound/soc/omap/mcbsp.c | 39 ++++++++++++++++++++++----------------- sound/soc/omap/omap-dmic.c | 35 ++++++++++------------------------- sound/soc/omap/omap-mcpdm.c | 16 ++-------------- sound/soc/omap/omap-pcm.c | 16 +++++++++++++--- 5 files changed, 48 insertions(+), 59 deletions(-)
DAI drivers can set the dma_name to the desired one instead of filter_data when booting with device tree in order to be able to get the correct DMA channel in DT boot. When booting with devicetree the platform_get_resource_byname() is not available for DMA resources.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- include/sound/dmaengine_pcm.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index f11c35c..85a3286 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -68,6 +68,7 @@ struct snd_dmaengine_dai_dma_data { u32 maxburst; unsigned int slave_id; void *filter_data; + const char *dma_name; };
void snd_dmaengine_pcm_set_config_from_dai_data(
When booting with DT the platform_get_resource_byname() is not available to get the DMA resource. In this case the DAI drivers will configure the dma_name and omap-pcm can use this name to request the DMA channel.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/omap/omap-pcm.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index c28e042..00168ab 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -113,14 +113,24 @@ static int omap_pcm_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_dmaengine_dai_dma_data *dma_data; + int ret;
snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
- return snd_dmaengine_pcm_open_request_chan(substream, - omap_dma_filter_fn, - dma_data->filter_data); + if (dma_data->dma_name) { + struct dma_chan *chan; + + chan = dma_request_slave_channel(rtd->cpu_dai->dev, + dma_data->dma_name); + ret = snd_dmaengine_pcm_open(substream, chan); + } else { + ret = snd_dmaengine_pcm_open_request_chan(substream, + omap_dma_filter_fn, + dma_data->filter_data); + } + return ret; }
static int omap_pcm_mmap(struct snd_pcm_substream *substream,
On 07/11/2013 12:18 PM, Peter Ujfalusi wrote:
I'd prefer not having to have to add a field for a OMAP specific hack to the generic struct. Two options which are in my opinion better:
1) Just use filter_data in both cases and check rtd->cpu_dai->dev.of_node to see whether to use it as the name to dma_request_slave_channel or as filter_data for snd_dmaengine_pcm_open_request_chan.
2) Add a omap_pcm_filter_data struct which looks like this
struct omap_pcm_filter_data { int req; const char *dma_name; }
And use that as the filter_data.
On 07/11/2013 01:13 PM, Lars-Peter Clausen wrote:
I'd prefer not having to have to add a field for a OMAP specific hack to the generic struct.
I thought that it might be usable for others later, but yeah. It is OMAP specific right now.
I'll stick with this one since I do not want to create a header file just for the omap_pcm_filter_data... I'll send the v2 in a couple of minutes (I have already tested it).
Thanks, Péter
The DMA resource no longer available via this API when booting with DT. McPDM is only available on OMAP4/5 and both can boot with DT only. Configure the dma_data.dma_name so omap-pcm can use different path to request the DMA channel.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/omap/omap-mcpdm.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-)
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index eb05c7e..4f376cb 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -66,7 +66,6 @@ struct omap_mcpdm { bool restart;
struct snd_dmaengine_dai_dma_data dma_data[2]; - unsigned int dma_req[2]; };
/* @@ -477,19 +476,8 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) mcpdm->dma_data[0].addr = res->start + MCPDM_REG_DN_DATA; mcpdm->dma_data[1].addr = res->start + MCPDM_REG_UP_DATA;
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link"); - if (!res) - return -ENODEV; - - mcpdm->dma_req[0] = res->start; - mcpdm->dma_data[0].filter_data = &mcpdm->dma_req[0]; - - res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link"); - if (!res) - return -ENODEV; - - mcpdm->dma_req[1] = res->start; - mcpdm->dma_data[1].filter_data = &mcpdm->dma_req[1]; + mcpdm->dma_data[0].dma_name = "dn_link"; + mcpdm->dma_data[1].dma_name = "up_link";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); if (res == NULL)
The DMA resource no longer available via this API when booting with DT. DMIC is only available on OMAP4/5 and both can boot with DT only. Configure the dma_data.dma_name so omap-pcm can use different path to request the DMA channel.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/omap/omap-dmic.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 2ad0370..f66b033 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -57,7 +57,6 @@ struct omap_dmic { struct mutex mutex;
struct snd_dmaengine_dai_dma_data dma_data; - unsigned int dma_req; };
static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) @@ -478,15 +477,7 @@ static int asoc_dmic_probe(struct platform_device *pdev) } dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG;
- res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(dmic->dev, "invalid dma resource\n"); - ret = -ENODEV; - goto err_put_clk; - } - - dmic->dma_req = res->start; - dmic->dma_data.filter_data = &dmic->dma_req; + dmic->dma_data.dma_name = "up_link";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); if (!res) {
The DMA resource no longer available via this API when booting with DT. When the board is booted with DT do not use platform_get_resource_byname(), instead configure the dma_data.dma_name so omap-pcm can use different path to request the DMA channel.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/omap/mcbsp.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index eb68c7d..c2f20d1 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c @@ -1012,28 +1012,33 @@ int omap_mcbsp_init(struct platform_device *pdev) } }
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); - if (!res) { - dev_err(&pdev->dev, "invalid rx DMA channel\n"); - return -ENODEV; - } - /* RX DMA request number, and port address configuration */ - mcbsp->dma_req[1] = res->start; - mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1]; - mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1); - mcbsp->dma_data[1].maxburst = 4; + if (!pdev->dev.of_node) { + res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); + if (!res) { + dev_err(&pdev->dev, "invalid tx DMA channel\n"); + return -ENODEV; + } + mcbsp->dma_req[0] = res->start; + mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
- res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); - if (!res) { - dev_err(&pdev->dev, "invalid tx DMA channel\n"); - return -ENODEV; + res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); + if (!res) { + dev_err(&pdev->dev, "invalid rx DMA channel\n"); + return -ENODEV; + } + mcbsp->dma_req[1] = res->start; + mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1]; + } else { + mcbsp->dma_data[0].dma_name = "tx"; + mcbsp->dma_data[1].dma_name = "rx"; } - /* TX DMA request number, and port address configuration */ - mcbsp->dma_req[0] = res->start; - mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0]; + mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0); mcbsp->dma_data[0].maxburst = 4;
+ mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1); + mcbsp->dma_data[1].maxburst = 4; + mcbsp->fclk = clk_get(&pdev->dev, "fck"); if (IS_ERR(mcbsp->fclk)) { ret = PTR_ERR(mcbsp->fclk);
Move the clk_get later in the function. In this way we do not need to use goto in other error cases.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/omap/omap-dmic.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index f66b033..1b6c507 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -463,17 +463,10 @@ static int asoc_dmic_probe(struct platform_device *pdev)
mutex_init(&dmic->mutex);
- dmic->fclk = clk_get(dmic->dev, "fck"); - if (IS_ERR(dmic->fclk)) { - dev_err(dmic->dev, "cant get fck\n"); - return -ENODEV; - } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma"); if (!res) { dev_err(dmic->dev, "invalid dma memory resource\n"); - ret = -ENODEV; - goto err_put_clk; + return -ENODEV; } dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG;
@@ -482,23 +475,24 @@ static int asoc_dmic_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); if (!res) { dev_err(dmic->dev, "invalid memory resource\n"); - ret = -ENODEV; - goto err_put_clk; + return -ENODEV; }
dmic->io_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dmic->io_base)) return PTR_ERR(dmic->io_base);
+ dmic->fclk = clk_get(dmic->dev, "fck"); + if (IS_ERR(dmic->fclk)) { + dev_err(dmic->dev, "cant get fck\n"); + return -ENODEV; + } + ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component, &omap_dmic_dai, 1); if (ret) - goto err_put_clk; - - return 0; + clk_put(dmic->fclk);
-err_put_clk: - clk_put(dmic->fclk); return ret; }
participants (2)
-
Lars-Peter Clausen
-
Peter Ujfalusi