From ddd17531ad9089ca1a758cd53fb698f396665cb5 Mon Sep 17 00:00:00 2001 From: Sebastien Guiriec Date: Wed, 13 Feb 2013 08:21:54 +0100 Subject: ASoC: omap-mcpdm: Clean up with devm_* function Clean up McPDM driver with devm_ function. Signed-off-by: Sebastien Guiriec Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 5ca11bd..079f277 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -369,7 +369,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) pm_runtime_get_sync(mcpdm->dev); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); - ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, + ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler, 0, "McPDM", (void *)mcpdm); pm_runtime_put_sync(mcpdm->dev); @@ -389,7 +389,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); - free_irq(mcpdm->irq, (void *)mcpdm); pm_runtime_disable(mcpdm->dev); return 0; @@ -465,14 +464,11 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) if (res == NULL) return -ENOMEM; - if (!devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), "McPDM")) - return -EBUSY; - - mcpdm->io_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!mcpdm->io_base) + mcpdm->io_base = devm_request_and_ioremap(&pdev->dev, res); + if (!mcpdm->io_base) { + dev_err(&pdev->dev, "cannot remap\n"); return -ENOMEM; + } mcpdm->irq = platform_get_irq(pdev, 0); if (mcpdm->irq < 0) -- cgit v1.1 From 4f224c612438e0c2067594636c6998ce5048d228 Mon Sep 17 00:00:00 2001 From: Sebastien Guiriec Date: Wed, 13 Feb 2013 08:22:07 +0100 Subject: ASoC: omap-dmic: Clean up with devm_request_and_ioremap Clean up dmic code with devm_request_and_ioremap function. Signed-off-by: Sebastien Guiriec Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index ba49ccd..77e9e7e 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -493,16 +493,9 @@ static int asoc_dmic_probe(struct platform_device *pdev) goto err_put_clk; } - if (!devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), pdev->name)) { - dev_err(dmic->dev, "memory region already claimed\n"); - ret = -ENODEV; - goto err_put_clk; - } - - dmic->io_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); + dmic->io_base = devm_request_and_ioremap(&pdev->dev, res); if (!dmic->io_base) { + dev_err(&pdev->dev, "cannot remap\n"); ret = -ENOMEM; goto err_put_clk; } -- cgit v1.1 From dd194b48465ba9c4eef7f16a4815b7761a8172ce Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 2 Mar 2013 15:47:55 +0800 Subject: ASoC: omap: Check regulator enable for DAC on Pandora This will probably never fail but it's better style. Signed-off-by: Mark Brown Acked-by: Peter Ujfalusi Acked-by: Jarkko Nikula --- sound/soc/omap/omap3pandora.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 805512f..10ced9d 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -80,12 +80,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream, static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { + int ret; + /* * The PCM1773 DAC datasheet requires 1ms delay between switching * VCC power on/off and /PD pin high/low */ if (SND_SOC_DAPM_EVENT_ON(event)) { - regulator_enable(omap3pandora_dac_reg); + ret = regulator_enable(omap3pandora_dac_reg); + if (ret) { + dev_err(w->dapm.dev, "Failed to power DAC: %d\n", ret); + return ret; + } mdelay(1); gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); } else { -- cgit v1.1 From e37e04307c2921ee83b192cbeb65d21897d0c6e8 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 5 Mar 2013 15:24:16 +0100 Subject: ASoC: omap3pandora: Fix compilation error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: sound/soc/omap/omap3pandora.c: In function ‘omap3pandora_dac_event’: sound/soc/omap/omap3pandora.c:92:19: error: request for member ‘dev’ in something not a structure or union make[3]: *** [sound/soc/omap/omap3pandora.o] Error 1 Which is introduced by: dd194b4 ASoC: omap: Check regulator enable for DAC on Pandora Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap3pandora.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 10ced9d..9e46e1d 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -89,7 +89,7 @@ static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, if (SND_SOC_DAPM_EVENT_ON(event)) { ret = regulator_enable(omap3pandora_dac_reg); if (ret) { - dev_err(w->dapm.dev, "Failed to power DAC: %d\n", ret); + dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret); return ret; } mdelay(1); -- cgit v1.1 From 77c641d3468a66377752ee9ae06e65dee41fe804 Mon Sep 17 00:00:00 2001 From: Silviu-Mihai Popescu Date: Mon, 11 Mar 2013 17:58:57 +0200 Subject: ASoC: omap: convert to devm_ioremap_resource() Convert all uses of devm_request_and_ioremap() to the newly introduced devm_ioremap_resource() which provides more consistent error handling. devm_ioremap_resource() provides its own error messages so all explicit error messages can be removed from the failure code paths. Signed-off-by: Silviu-Mihai Popescu Acked-by: Jarkko Nikula Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 9 +++------ sound/soc/omap/omap-mcpdm.c | 8 +++----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 77e9e7e..8ebaf11 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -493,12 +493,9 @@ static int asoc_dmic_probe(struct platform_device *pdev) goto err_put_clk; } - dmic->io_base = devm_request_and_ioremap(&pdev->dev, res); - if (!dmic->io_base) { - dev_err(&pdev->dev, "cannot remap\n"); - ret = -ENOMEM; - goto err_put_clk; - } + dmic->io_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dmic->io_base)) + return PTR_ERR(dmic->io_base); ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai); if (ret) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 079f277..ddfcc18 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -464,11 +464,9 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) if (res == NULL) return -ENOMEM; - mcpdm->io_base = devm_request_and_ioremap(&pdev->dev, res); - if (!mcpdm->io_base) { - dev_err(&pdev->dev, "cannot remap\n"); - return -ENOMEM; - } + mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mcpdm->io_base)) + return PTR_ERR(mcpdm->io_base); mcpdm->irq = platform_get_irq(pdev, 0); if (mcpdm->irq < 0) -- cgit v1.1 From 623766318aeb5f8dee83b2e8926c39cf83568197 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 20 Mar 2013 10:47:12 +0100 Subject: ASoC: omap-mcpdm: Collect link direction configuration under a struct mcpdm_link_config will collect the link direction related configurations like channel masks, FIFO threshold. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index ddfcc18..6e19f44 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -45,6 +45,11 @@ #define OMAP44XX_MCPDM_L3_BASE 0x49032000 +struct mcpdm_link_config { + u32 link_mask; /* channel mask for the direction */ + u32 threshold; /* FIFO threshold */ +}; + struct omap_mcpdm { struct device *dev; unsigned long phys_base; @@ -53,13 +58,8 @@ struct omap_mcpdm { struct mutex mutex; - /* channel data */ - u32 dn_channels; - u32 up_channels; - - /* McPDM FIFO thresholds */ - u32 dn_threshold; - u32 up_threshold; + /* Playback/Capture configuration */ + struct mcpdm_link_config config[2]; /* McPDM dn offsets for rx1, and 2 channels */ u32 dn_rx_offset; @@ -130,11 +130,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {} static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) { u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); + u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask; ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); - ctrl |= mcpdm->dn_channels | mcpdm->up_channels; + ctrl |= link_mask; omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); @@ -148,11 +149,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) { u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); + u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask; ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); - ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels); + ctrl &= ~(link_mask); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); @@ -188,8 +190,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm) omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); } - omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); - omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold); + omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, + mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold); + omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, + mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold); omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); @@ -296,6 +300,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); int stream = substream->stream; struct omap_pcm_dma_data *dma_data; + u32 threshold; int channels; int link_mask = 0; @@ -325,15 +330,16 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, dma_data = snd_soc_dai_get_dma_data(dai, substream); + threshold = mcpdm->config[stream].threshold; /* Configure McPDM channels, and DMA packet size */ if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - mcpdm->dn_channels = link_mask << 3; + link_mask <<= 3; dma_data->packet_size = - (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels; + (MCPDM_DN_THRES_MAX - threshold) * channels; } else { - mcpdm->up_channels = link_mask << 0; - dma_data->packet_size = mcpdm->up_threshold * channels; + dma_data->packet_size = threshold * channels; } + mcpdm->config[stream].link_mask = link_mask; return 0; } @@ -380,8 +386,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) } /* Configure McPDM threshold values */ - mcpdm->dn_threshold = 2; - mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3; + mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2; + mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold = + MCPDM_UP_THRES_MAX - 3; return ret; } -- cgit v1.1 From 81054b226b76145628670a962674ab312690ab86 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 20 Mar 2013 10:47:13 +0100 Subject: ASoC: omap-mcpdm: Fix for full duplex audio use case Due to HW limitation within OMAP McPDM IP uplink and downlink need to be started at the same time. This causes issues when we have two streams running, for example: arecord | aplay In this case the playback stream would have no channels enabled since at the capture start we are not aware that a playback is going to start. The workaround is to configure the other direction to stereo when the first stream is started. When the second stream is coming we check the new stream's number of channels against the pre-configured channels. If it does not match we stop and restart McPDM to update the configuration. This might result a small pop. If the coming stream is a match we do nothing in the McPDM driver. This workaround can handle most use cases without the need to restart McPDM. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 6e19f44..cd0e2ec 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -63,6 +63,9 @@ struct omap_mcpdm { /* McPDM dn offsets for rx1, and 2 channels */ u32 dn_rx_offset; + + /* McPDM needs to be restarted due to runtime reconfiguration */ + bool restart; }; /* @@ -149,7 +152,7 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) { u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); - u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask; + u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK; ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); @@ -287,6 +290,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, if (omap_mcpdm_active(mcpdm)) { omap_mcpdm_stop(mcpdm); omap_mcpdm_close_streams(mcpdm); + mcpdm->config[0].link_mask = 0; + mcpdm->config[1].link_mask = 0; } } @@ -334,11 +339,26 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, /* Configure McPDM channels, and DMA packet size */ if (stream == SNDRV_PCM_STREAM_PLAYBACK) { link_mask <<= 3; + + /* If capture is not running assume a stereo stream to come */ + if (!mcpdm->config[!stream].link_mask) + mcpdm->config[!stream].link_mask = 0x3; + dma_data->packet_size = (MCPDM_DN_THRES_MAX - threshold) * channels; } else { + /* If playback is not running assume a stereo stream to come */ + if (!mcpdm->config[!stream].link_mask) + mcpdm->config[!stream].link_mask = (0x3 << 3); + dma_data->packet_size = threshold * channels; } + + /* Check if we need to restart McPDM with this stream */ + if (mcpdm->config[stream].link_mask && + mcpdm->config[stream].link_mask != link_mask) + mcpdm->restart = true; + mcpdm->config[stream].link_mask = link_mask; return 0; @@ -352,6 +372,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, if (!omap_mcpdm_active(mcpdm)) { omap_mcpdm_start(mcpdm); omap_mcpdm_reg_dump(mcpdm); + } else if (mcpdm->restart) { + omap_mcpdm_stop(mcpdm); + omap_mcpdm_start(mcpdm); + mcpdm->restart = false; + omap_mcpdm_reg_dump(mcpdm); } return 0; -- cgit v1.1 From 167b5b93a4d53f29d4fda55f96116f525b2eb3d6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 20 Mar 2013 10:47:14 +0100 Subject: ASoC: omap-mcpdm: Remove leftower define for IO address The IO address is no longer hardwired into the driver. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index cd0e2ec..e1d3998 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -43,8 +43,6 @@ #include "omap-mcpdm.h" #include "omap-pcm.h" -#define OMAP44XX_MCPDM_L3_BASE 0x49032000 - struct mcpdm_link_config { u32 link_mask; /* channel mask for the direction */ u32 threshold; /* FIFO threshold */ -- cgit v1.1 From abe99370b3c583cd0fc4185e7a776b7bb48311c3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 25 Mar 2013 16:58:16 +0100 Subject: ASoC: omap: Call omap_mcbsp_set_threshold() from mcbsp hw_params The omap PCM driver provides a set_threshold callback which gets called by the PCM driver when either playback or capture is started. The only DAI driver which sets this callback is the mcbsp driver. This patch removes the callback from the PCM driver and moves the invocation of the omap_mcbsp_set_threshold() function to the mcbsp hw_params callback since this is the only place where the threshold size can change. Doing so allows us to use the default dmaengine PCM trigger callback in the omap PCM driver. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 12 +++++------- sound/soc/omap/omap-pcm.c | 33 +-------------------------------- sound/soc/omap/omap-pcm.h | 1 - 3 files changed, 6 insertions(+), 40 deletions(-) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 8d2defd..406fc87 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -62,24 +62,22 @@ enum { * Stream DMA parameters. DMA request line and port address are set runtime * since they are different between OMAP1 and later OMAPs */ -static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) +static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream, + unsigned int packet_size) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); - struct omap_pcm_dma_data *dma_data; int words; - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - /* * Configure McBSP threshold based on either: * packet_size, when the sDMA is in packet mode, or based on the * period size in THRESHOLD mode, otherwise use McBSP threshold = 1 * for mono streams. */ - if (dma_data->packet_size) - words = dma_data->packet_size; + if (packet_size) + words = packet_size; else words = 1; @@ -245,7 +243,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } if (mcbsp->pdata->buffer_size) { - dma_data->set_threshold = omap_mcbsp_set_threshold; if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { int period_words, max_thrsh; int divider = 0; @@ -276,6 +273,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, /* Use packet mode for non mono streams */ pkt_size = channels; } + omap_mcbsp_set_threshold(substream, pkt_size); } dma_data->packet_size = pkt_size; diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index c722c2e..1626fb7 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -129,37 +129,6 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream) return 0; } -static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct omap_pcm_dma_data *dma_data; - int ret = 0; - - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - /* Configure McBSP internal buffer usage */ - if (dma_data->set_threshold) - dma_data->set_threshold(substream); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - break; - default: - ret = -EINVAL; - } - - if (ret == 0) - ret = snd_dmaengine_pcm_trigger(substream, cmd); - - return ret; -} - static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) { snd_pcm_uframes_t offset; @@ -208,7 +177,7 @@ static struct snd_pcm_ops omap_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = omap_pcm_hw_params, .hw_free = omap_pcm_hw_free, - .trigger = omap_pcm_trigger, + .trigger = snd_dmaengine_pcm_trigger, .pointer = omap_pcm_pointer, .mmap = omap_pcm_mmap, }; diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h index cabe74c..39e6e45 100644 --- a/sound/soc/omap/omap-pcm.h +++ b/sound/soc/omap/omap-pcm.h @@ -31,7 +31,6 @@ struct omap_pcm_dma_data { char *name; /* stream identifier */ int dma_req; /* DMA request line */ unsigned long port_addr; /* transmit/receive register */ - void (*set_threshold)(struct snd_pcm_substream *substream); int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm * to decide the sDMA data type */ int packet_size; /* packet size only in PACKET mode */ -- cgit v1.1 From cb20d5757bbe79d9c9e4210e232934792be2336e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:01 +0100 Subject: ASoC: ux500_pcm: Remove duplicated SNDRV_PCM_HW_PARAM_PERIODS constraint The generic dmaengine based PCM driver code takes care of setting this constraint, there is no need of doing it manually in the ux500 driver. Signed-off-by: Lars-Peter Clausen Acked-by: Ola Lilja Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_pcm.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 846fa82..375ca6b 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -111,15 +111,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw_capture); - /* ensure that buffer size is a multiple of period size */ - ret = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) { - dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n", - __func__, ret); - return ret; - } - dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__, snd_pcm_stream_str(substream)); runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? -- cgit v1.1 From 023934b4052b1a955ac8d68c8d4b216d1c55c611 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:02 +0100 Subject: ASoC: spear_pcm: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Acked-by: Rajeev Kumar Signed-off-by: Mark Brown --- sound/soc/spear/spear_pcm.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 9b76cc5..32431d6 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -73,14 +73,6 @@ static int spear_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int spear_pcm_close(struct snd_pcm_substream *substream) -{ - - snd_dmaengine_pcm_close(substream); - - return 0; -} - static int spear_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { @@ -93,7 +85,7 @@ static int spear_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops spear_pcm_ops = { .open = spear_pcm_open, - .close = spear_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = spear_pcm_hw_params, .hw_free = spear_pcm_hw_free, -- cgit v1.1 From 340af748bc4004982a1a11ea2d81a4bffe6eb975 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:03 +0100 Subject: ASoC: omap-pcm: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/omap-pcm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 1626fb7..6c842c7 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -154,12 +154,6 @@ static int omap_pcm_open(struct snd_pcm_substream *substream) &dma_data->dma_req); } -static int omap_pcm_close(struct snd_pcm_substream *substream) -{ - snd_dmaengine_pcm_close(substream); - return 0; -} - static int omap_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { @@ -173,7 +167,7 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops omap_pcm_ops = { .open = omap_pcm_open, - .close = omap_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = omap_pcm_hw_params, .hw_free = omap_pcm_hw_free, -- cgit v1.1 From 3021bd38ed31380df5e270451162feca83aef40f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:04 +0100 Subject: ASoC: tegra_pcm: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Acked-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_pcm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index c925ab0..e67af0b 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -75,12 +75,6 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int tegra_pcm_close(struct snd_pcm_substream *substream) -{ - snd_dmaengine_pcm_close(substream); - return 0; -} - static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -160,7 +154,7 @@ static int tegra_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops tegra_pcm_ops = { .open = tegra_pcm_open, - .close = tegra_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = tegra_pcm_hw_params, .hw_free = tegra_pcm_hw_free, -- cgit v1.1 From 8c4e56fd5595105128077c2bbdfde3c15a4c2d91 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:05 +0100 Subject: ASoC: ux500_pcm: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Acked-by: Ola Lilja Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_pcm.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 375ca6b..d000ba2 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -160,18 +160,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int ux500_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *dai = rtd->cpu_dai; - - dev_dbg(dai->dev, "%s: Enter\n", __func__); - - snd_dmaengine_pcm_close(substream); - - return 0; -} - static int ux500_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { @@ -246,7 +234,7 @@ static int ux500_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops ux500_pcm_ops = { .open = ux500_pcm_open, - .close = ux500_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = ux500_pcm_hw_params, .hw_free = ux500_pcm_hw_free, -- cgit v1.1 From a85fc1b073406b3848661fcbb452497930dcc8af Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:06 +0100 Subject: ASoC: atmel-pcm-dma: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Tested-by: Bo Shen Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm-dma.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 30184a4..396bf78 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -199,16 +199,9 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int atmel_pcm_close(struct snd_pcm_substream *substream) -{ - snd_dmaengine_pcm_close(substream); - - return 0; -} - static struct snd_pcm_ops atmel_pcm_ops = { .open = atmel_pcm_open, - .close = atmel_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = atmel_pcm_hw_params, .prepare = atmel_pcm_dma_prepare, -- cgit v1.1 From ebd59b07ecd9d35d5bc88c91a4878fbb4549ed42 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:07 +0100 Subject: ASoC: ux500_pcm: No need to use snd_dmaengine_pcm_set_data() The driver never uses snd_dmaengine_pcm_get_data(), so there is no need to use snd_dmaengine_pcm_set_data(). Signed-off-by: Lars-Peter Clausen Acked-by: Ola Lilja Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_pcm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index d000ba2..1ab36fa 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -155,8 +155,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) return ret; } - snd_dmaengine_pcm_set_data(substream, dma_cfg); - return 0; } -- cgit v1.1 From 593b66fbbcac78b73ec17270c874f6db8eabd97c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:08 +0100 Subject: ASoC: speaer_pcm: No need to use snd_dmaengine_pcm_set_data() The driver never uses snd_dmaengine_pcm_get_data(), so there is no need to use snd_dmaengine_pcm_set_data(). Signed-off-by: Lars-Peter Clausen Acked-by: Rajeev Kumar Signed-off-by: Mark Brown --- sound/soc/spear/spear_pcm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 32431d6..db75d72 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -64,13 +64,7 @@ static int spear_pcm_open(struct snd_pcm_substream *substream) if (ret) return ret; - ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data); - if (ret) - return ret; - - snd_dmaengine_pcm_set_data(substream, dma_data); - - return 0; + return snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data) } static int spear_pcm_mmap(struct snd_pcm_substream *substream, -- cgit v1.1 From 5fe668a1d2c27223fea4991ebf90ee28b7d1941c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:09 +0100 Subject: ASoC: atmel-pcm-dma: Do not use snd_dmaengine_pcm_{set,get}_data() We want to get rid of snd_dmaengine_pcm_{set,get}_data(). All instances of snd_dmaengine_pcm_get_data() in the atmel pcm driver can easily be replaced with snd_soc_dai_get_dma_data(). Signed-off-by: Lars-Peter Clausen Tested-by: Bo Shen Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm-dma.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 396bf78..b8570e3 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -67,9 +67,10 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { static void atmel_pcm_dma_irq(u32 ssc_sr, struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_pcm_dma_params *prtd; - prtd = snd_dmaengine_pcm_get_data(substream); + prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); if (ssc_sr & prtd->mask->ssc_error) { if (snd_pcm_running(substream)) @@ -104,15 +105,13 @@ static bool filter(struct dma_chan *chan, void *slave) } static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd) { - struct atmel_pcm_dma_params *prtd; struct ssc_device *ssc; struct dma_chan *dma_chan; struct dma_slave_config slave_config; int ret; - prtd = snd_dmaengine_pcm_get_data(substream); ssc = prtd->ssc; ret = snd_hwparams_to_dma_slave_config(substream, params, @@ -164,9 +163,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - snd_dmaengine_pcm_set_data(substream, prtd); - - ret = atmel_pcm_configure_dma(substream, params); + ret = atmel_pcm_configure_dma(substream, params, prtd); if (ret) { pr_err("atmel-pcm: failed to configure dmai\n"); goto err; @@ -182,9 +179,10 @@ err: static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_pcm_dma_params *prtd; - prtd = snd_dmaengine_pcm_get_data(substream); + prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); -- cgit v1.1 From 453807f3006757a5661c4000262d7d9284b5214c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:10 +0100 Subject: ASoC: ep93xx: Use ep93xx_dma_params instead of ep93xx_pcm_dma_params Currently the ep93xx_dma_params struct which is passed to the dmaengine driver is constructed at runtime from the ep93xx_pcm_dma_params that gets passed to the ep93xx PCM driver from one of the ep93xx DAI drivers. The ep93xx_pcm_dma_params struct is almost identical to the ep93xx_dma_params struct. The only missing field is the 'direction' field, which is computed at runtime in the PCM driver based on the current substream. Since we know in advance which ep93xx_pcm_dma_params struct is being used for which substream at compile time, we also already know which direction to use at compile time. So we can easily replace all instances of ep93xx_pcm_dma_params with their ep93xx_dma_params counterpart. This allows us to simplify the code in the ep93xx pcm driver quite a bit. Signed-off-by: Lars-Peter Clausen Reviewed-by: Ryan Mallon Signed-off-by: Mark Brown --- sound/soc/cirrus/edb93xx.c | 1 - sound/soc/cirrus/ep93xx-ac97.c | 9 +++++---- sound/soc/cirrus/ep93xx-i2s.c | 12 ++++++------ sound/soc/cirrus/ep93xx-pcm.c | 37 +++---------------------------------- sound/soc/cirrus/ep93xx-pcm.h | 20 -------------------- sound/soc/cirrus/simone.c | 2 -- sound/soc/cirrus/snappercl15.c | 1 - 7 files changed, 14 insertions(+), 68 deletions(-) delete mode 100644 sound/soc/cirrus/ep93xx-pcm.h diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index 5db68cf..c43fb21 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c @@ -27,7 +27,6 @@ #include #include #include -#include "ep93xx-pcm.h" static int edb93xx_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index 1738d28..8d308864 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -23,7 +23,6 @@ #include #include -#include "ep93xx-pcm.h" /* * Per channel (1-4) registers. @@ -101,14 +100,16 @@ struct ep93xx_ac97_info { /* currently ALSA only supports a single AC97 device */ static struct ep93xx_ac97_info *ep93xx_ac97_info; -static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = { +static struct ep93xx_dma_data ep93xx_ac97_pcm_out = { .name = "ac97-pcm-out", .dma_port = EP93XX_DMA_AAC1, + .direction = DMA_MEM_TO_DEV, }; -static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = { +static struct ep93xx_dma_data ep93xx_ac97_pcm_in = { .name = "ac97-pcm-in", .dma_port = EP93XX_DMA_AAC1, + .direction = DMA_DEV_TO_MEM, }; static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info, @@ -316,7 +317,7 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct ep93xx_pcm_dma_params *dma_data; + struct ep93xx_dma_data *dma_data; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) dma_data = &ep93xx_ac97_pcm_out; diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 323ed69..aa124f8 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -30,8 +30,6 @@ #include #include -#include "ep93xx-pcm.h" - #define EP93XX_I2S_TXCLKCFG 0x00 #define EP93XX_I2S_RXCLKCFG 0x04 #define EP93XX_I2S_GLCTRL 0x0C @@ -62,18 +60,20 @@ struct ep93xx_i2s_info { struct clk *mclk; struct clk *sclk; struct clk *lrclk; - struct ep93xx_pcm_dma_params *dma_params; + struct ep93xx_dma_data *dma_data; void __iomem *regs; }; -struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = { +struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { [SNDRV_PCM_STREAM_PLAYBACK] = { .name = "i2s-pcm-out", .dma_port = EP93XX_DMA_I2S1, + .direction = DMA_MEM_TO_DEV, }, [SNDRV_PCM_STREAM_CAPTURE] = { .name = "i2s-pcm-in", .dma_port = EP93XX_DMA_I2S1, + .direction = DMA_DEV_TO_MEM, }, }; @@ -147,7 +147,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; snd_soc_dai_set_dma_data(cpu_dai, substream, - &info->dma_params[substream->stream]); + &info->dma_data[substream->stream]); return 0; } @@ -403,7 +403,7 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) } dev_set_drvdata(&pdev->dev, info); - info->dma_params = ep93xx_i2s_dma_params; + info->dma_data = ep93xx_i2s_dma_data; err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai); if (err) diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index 72eb7a4..298946f 100644 --- a/sound/soc/cirrus/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c @@ -29,8 +29,6 @@ #include #include -#include "ep93xx-pcm.h" - static const struct snd_pcm_hardware ep93xx_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -68,40 +66,11 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) static int ep93xx_pcm_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct ep93xx_pcm_dma_params *dma_params; - struct ep93xx_dma_data *dma_data; - int ret; snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); - dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL); - if (!dma_data) - return -ENOMEM; - - dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); - dma_data->port = dma_params->dma_port; - dma_data->name = dma_params->name; - dma_data->direction = snd_pcm_substream_to_dma_direction(substream); - - ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data); - if (ret) { - kfree(dma_data); - return ret; - } - - snd_dmaengine_pcm_set_data(substream, dma_data); - - return 0; -} - -static int ep93xx_pcm_close(struct snd_pcm_substream *substream) -{ - struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); - - snd_dmaengine_pcm_close(substream); - kfree(dma_data); - return 0; + return snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); } static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, @@ -131,7 +100,7 @@ static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops ep93xx_pcm_ops = { .open = ep93xx_pcm_open, - .close = ep93xx_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = ep93xx_pcm_hw_params, .hw_free = ep93xx_pcm_hw_free, diff --git a/sound/soc/cirrus/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h deleted file mode 100644 index 111e112..0000000 --- a/sound/soc/cirrus/ep93xx-pcm.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface - * - * Copyright (C) 2006 Lennert Buytenhek - * Copyright (C) 2006 Applied Data Systems - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _EP93XX_SND_SOC_PCM_H -#define _EP93XX_SND_SOC_PCM_H - -struct ep93xx_pcm_dma_params { - char *name; - int dma_port; -}; - -#endif /* _EP93XX_SND_SOC_PCM_H */ diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c index a397bb0..4d094d0 100644 --- a/sound/soc/cirrus/simone.c +++ b/sound/soc/cirrus/simone.c @@ -21,8 +21,6 @@ #include #include -#include "ep93xx-pcm.h" - static struct snd_soc_dai_link simone_dai = { .name = "AC97", .stream_name = "AC97 HiFi", diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index 9d77fe2..6904107 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c @@ -21,7 +21,6 @@ #include #include "../codecs/tlv320aic23.h" -#include "ep93xx-pcm.h" #define CODEC_CLOCK 5644800 -- cgit v1.1 From ac581e60dfb4cc55ac20cca18202c7689d324aa7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:11 +0100 Subject: ASoC: mmp-pcm: Allocate dma filter parameters on the stack The dma filter parameters are only used within filter callback, so there is no need to allocate them on the heap and keep them around until the PCM has been closed. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/pxa/mmp-pcm.c | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 190eb0b..6c39802 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -118,9 +118,8 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct platform_device *pdev = to_platform_device(rtd->platform->dev); struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct mmp_dma_data *dma_data; + struct mmp_dma_data dma_data; struct resource *r; - int ret; r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream); if (!r) @@ -128,33 +127,11 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &mmp_pcm_hardware[substream->stream]); - dma_data = devm_kzalloc(&pdev->dev, - sizeof(struct mmp_dma_data), GFP_KERNEL); - if (dma_data == NULL) - return -ENOMEM; - dma_data->dma_res = r; - dma_data->ssp_id = cpu_dai->id; + dma_data.dma_res = r; + dma_data.ssp_id = cpu_dai->id; - ret = snd_dmaengine_pcm_open(substream, filter, dma_data); - if (ret) { - devm_kfree(&pdev->dev, dma_data); - return ret; - } - - snd_dmaengine_pcm_set_data(substream, dma_data); - return 0; -} - -static int mmp_pcm_close(struct snd_pcm_substream *substream) -{ - struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct platform_device *pdev = to_platform_device(rtd->platform->dev); - - snd_dmaengine_pcm_close(substream); - devm_kfree(&pdev->dev, dma_data); - return 0; + return snd_dmaengine_pcm_open(substream, filter, &dma_data); } static int mmp_pcm_mmap(struct snd_pcm_substream *substream, @@ -171,7 +148,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream, struct snd_pcm_ops mmp_pcm_ops = { .open = mmp_pcm_open, - .close = mmp_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = mmp_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, -- cgit v1.1 From 312bb4f626328fdc246c8d13082ab00e26e7d048 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:12 +0100 Subject: ASoC: imx-pcm: Embed the imx_dma_data struct in the dma_params struct Currently the imx_dma_data struct, which gets passed to the dmaengine driver, is allocated and constructed in the pcm driver from the data stored in the dma_params struct. The dma_params struct gets passed to the pcm driver from the dai driver. Instead of going this route of indirection embed the dma_data struct directly into the dma_params struct and let the dai driver fill it in. This allows us to simplify the imx-pcm-dma driver quite a bit, since it doesn't have care about memory managing the imx_dma_data struct anymore. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 17 +++++++++-------- sound/soc/fsl/imx-pcm-dma.c | 35 ++--------------------------------- sound/soc/fsl/imx-pcm.h | 17 +++++++++++++++-- sound/soc/fsl/imx-ssi.c | 12 ++++++++---- 4 files changed, 34 insertions(+), 47 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 7decbd9..2cce1ce 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -649,6 +649,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) const uint32_t *iprop; struct resource res; char name[64]; + bool shared; /* SSIs that are not connected on the board should have a * status = "disabled" @@ -755,14 +756,14 @@ static int fsl_ssi_probe(struct platform_device *pdev) dev_err(&pdev->dev, "could not get dma events\n"); goto error_clk; } - ssi_private->dma_params_tx.dma = dma_events[0]; - ssi_private->dma_params_rx.dma = dma_events[1]; - - ssi_private->dma_params_tx.shared_peripheral = - of_device_is_compatible(of_get_parent(np), - "fsl,spba-bus"); - ssi_private->dma_params_rx.shared_peripheral = - ssi_private->dma_params_tx.shared_peripheral; + + shared = of_device_is_compatible(of_get_parent(np), + "fsl,spba-bus"); + + imx_pcm_dma_params_init_data(&ssi_private->dma_params_tx, + dma_events[0], shared); + imx_pcm_dma_params_init_data(&ssi_private->dma_params_rx, + dma_events[1], shared); } /* Initialize the the device_attribute structure */ diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index 500f8ce..6832c49 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -30,8 +30,6 @@ #include #include -#include - #include "imx-pcm.h" static bool filter(struct dma_chan *chan, void *param) @@ -101,46 +99,17 @@ static int snd_imx_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct imx_pcm_dma_params *dma_params; - struct imx_dma_data *dma_data; - int ret; snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); - if (!dma_data) - return -ENOMEM; - - dma_data->peripheral_type = dma_params->shared_peripheral ? - IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI; - dma_data->priority = DMA_PRIO_HIGH; - dma_data->dma_request = dma_params->dma; - - ret = snd_dmaengine_pcm_open(substream, filter, dma_data); - if (ret) { - kfree(dma_data); - return ret; - } - - snd_dmaengine_pcm_set_data(substream, dma_data); - - return 0; -} - -static int snd_imx_close(struct snd_pcm_substream *substream) -{ - struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); - - snd_dmaengine_pcm_close(substream); - kfree(dma_data); - - return 0; + return snd_dmaengine_pcm_open(substream, filter, &dma_params->dma_data); } static struct snd_pcm_ops imx_pcm_ops = { .open = snd_imx_open, - .close = snd_imx_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_imx_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h index 5ae13a1..16eaf5a 100644 --- a/sound/soc/fsl/imx-pcm.h +++ b/sound/soc/fsl/imx-pcm.h @@ -13,18 +13,31 @@ #ifndef _IMX_PCM_H #define _IMX_PCM_H +#include + /* * Do not change this as the FIQ handler depends on this size */ #define IMX_SSI_DMABUF_SIZE (64 * 1024) struct imx_pcm_dma_params { - int dma; unsigned long dma_addr; int burstsize; - bool shared_peripheral; /* The peripheral is on SPBA bus */ + struct imx_dma_data dma_data; }; +static inline void +imx_pcm_dma_params_init_data(struct imx_pcm_dma_params *params, + int dma, bool shared) +{ + params->dma_data.dma_request = dma; + params->dma_data.priority = DMA_PRIO_HIGH; + if (shared) + params->dma_data.peripheral_type = IMX_DMATYPE_SSI_SP; + else + params->dma_data.peripheral_type = IMX_DMATYPE_SSI; +} + int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma); int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 55464a5..14018c4 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -577,12 +577,16 @@ static int imx_ssi_probe(struct platform_device *pdev) ssi->dma_params_rx.burstsize = 4; res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); - if (res) - ssi->dma_params_tx.dma = res->start; + if (res) { + imx_pcm_dma_params_init_data(&ssi->dma_params_tx, res->start, + false); + } res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0"); - if (res) - ssi->dma_params_rx.dma = res->start; + if (res) { + imx_pcm_dma_params_init_data(&ssi->dma_params_rx, res->start, + false); + } platform_set_drvdata(pdev, ssi); -- cgit v1.1 From b7e5e91210fc9d40f93f87e386823e4ba9b32805 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:13 +0100 Subject: ASoC: mxs: Embed the mxs_dma_data struct in the mxs_pcm_dma_params struct Currently the mxs_dma_data struct, which gets passed to the dmaengine driver, is allocated in the pcm driver's open callback. The mxs_dma_data struct has exactly one field which is initialized from the the same field in the mxs_pcm_dma_params struct. The mxs_pcm_dma_params struct gets passed to the pcm driver from the dai driver. Instead of taking this indirection embed the mxs_dma_data struct directly in the mxs_pcm_dma_params struct. This allows us to simplify the pcm driver quite a bit, since we don't have to care about memory managing the mxs_dma_data struct anymore. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-pcm.c | 43 +++++-------------------------------------- sound/soc/mxs/mxs-pcm.h | 4 +++- sound/soc/mxs/mxs-saif.c | 6 +++--- 3 files changed, 11 insertions(+), 42 deletions(-) diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 564b5b6..ebbef85 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -39,11 +38,6 @@ #include "mxs-pcm.h" -struct mxs_pcm_dma_data { - struct mxs_dma_data dma_data; - struct mxs_pcm_dma_params *dma_params; -}; - static struct snd_pcm_hardware snd_mxs_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -66,8 +60,7 @@ static struct snd_pcm_hardware snd_mxs_hardware = { static bool filter(struct dma_chan *chan, void *param) { - struct mxs_pcm_dma_data *pcm_dma_data = param; - struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params; + struct mxs_pcm_dma_params *dma_params = param; if (!mxs_dma_is_apbx(chan)) return false; @@ -75,7 +68,7 @@ static bool filter(struct dma_chan *chan, void *param) if (chan->chan_id != dma_params->chan_num) return false; - chan->private = &pcm_dma_data->dma_data; + chan->private = &dma_params->dma_data; return true; } @@ -91,37 +84,11 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, static int snd_mxs_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct mxs_pcm_dma_data *pcm_dma_data; - int ret; - - pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL); - if (pcm_dma_data == NULL) - return -ENOMEM; - - pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq; - - ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data); - if (ret) { - kfree(pcm_dma_data); - return ret; - } snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); - snd_dmaengine_pcm_set_data(substream, pcm_dma_data); - - return 0; -} - -static int snd_mxs_close(struct snd_pcm_substream *substream) -{ - struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream); - - snd_dmaengine_pcm_close(substream); - kfree(pcm_dma_data); - - return 0; + return snd_dmaengine_pcm_open(substream, filter, + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); } static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, @@ -137,7 +104,7 @@ static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops mxs_pcm_ops = { .open = snd_mxs_open, - .close = snd_mxs_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_mxs_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h index 35ba2ca..3aa918f 100644 --- a/sound/soc/mxs/mxs-pcm.h +++ b/sound/soc/mxs/mxs-pcm.h @@ -19,8 +19,10 @@ #ifndef _MXS_PCM_H #define _MXS_PCM_H +#include + struct mxs_pcm_dma_params { - int chan_irq; + struct mxs_dma_data dma_data; int chan_num; }; diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 3a2aa1d..f13bd87 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -753,9 +753,9 @@ static int mxs_saif_probe(struct platform_device *pdev) return ret; } - saif->dma_param.chan_irq = platform_get_irq(pdev, 1); - if (saif->dma_param.chan_irq < 0) { - ret = saif->dma_param.chan_irq; + saif->dma_param.dma_data.chan_irq = platform_get_irq(pdev, 1); + if (saif->dma_param.dma_data.chan_irq < 0) { + ret = saif->dma_param.dma_data.chan_irq; dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", ret); return ret; -- cgit v1.1 From b1bd7f62cf2b854316a9a8b2442a8014dbe29a47 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:14 +0100 Subject: ASoC: dmaengine-pcm: Remove snd_dmaengine_pcm_{set,get}_data These functions were initially added to be able to support some oddball dma drivers, but all users have been updated to deal with the situation without the help of snd_dmaengine_pcm_{set,get}_data, so these two functions can be removed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 3 --- sound/soc/soc-dmaengine-pcm.c | 29 ----------------------------- 2 files changed, 32 deletions(-) diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index b877334..f8a7031 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -32,9 +32,6 @@ snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream) return DMA_DEV_TO_MEM; } -void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data); -void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream); - int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd); diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 111b7d92..e8b1215 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -33,8 +33,6 @@ struct dmaengine_pcm_runtime_data { dma_cookie_t cookie; unsigned int pos; - - void *data; }; static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( @@ -43,33 +41,6 @@ static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( return substream->runtime->private_data; } -/** - * snd_dmaengine_pcm_set_data - Set dmaengine substream private data - * @substream: PCM substream - * @data: Data to set - */ -void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data) -{ - struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - - prtd->data = data; -} -EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data); - -/** - * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data - * @substream: PCM substream - * - * Returns the data previously set with snd_dmaengine_pcm_set_data - */ -void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream) -{ - struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - - return prtd->data; -} -EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data); - struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) { struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); -- cgit v1.1 From 5fa70f71dbf33603b0d29b33d8da128b266eb733 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 3 Apr 2013 11:02:56 +0200 Subject: ASoC: dmaengine_pcm: Setup device_fc in snd_hwparams_to_dma_slave_config Usually device_fc should be set to false for audio DMAs. Initialize it in a common place so drivers don't have to do this manually. Signed-off-by: Lars-Peter Clausen Tested-by: Peter Ujfalusi Acked-by: Nicolas Ferre Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm-dma.c | 2 -- sound/soc/fsl/imx-pcm-dma.c | 2 -- sound/soc/soc-dmaengine-pcm.c | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index b8570e3..bb07989 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -129,8 +129,6 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, slave_config.src_maxburst = 1; } - slave_config.device_fc = false; - dma_chan = snd_dmaengine_pcm_get_chan(substream); if (dmaengine_slave_config(dma_chan, &slave_config)) { pr_err("atmel-pcm: failed to configure dma channel\n"); diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index 6832c49..64af573 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -57,8 +57,6 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; - slave_config.device_fc = false; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { slave_config.dst_addr = dma_params->dma_addr; slave_config.dst_maxburst = dma_params->burstsize; diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index e8b1215..7c24ded 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -89,6 +89,8 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, slave_config->src_addr_width = buswidth; } + slave_config->device_fc = false; + return 0; } EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); -- cgit v1.1 From 85c9f9c5f9d09ea43daf4f1a8b81d3c7b7394d27 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 3 Apr 2013 11:06:02 +0200 Subject: ASoC: dmaengine-pcm: Add a common DAI DMA data struct This patch adds a common DMA data struct which can be used by DAI drivers to communicate their DMA configuration requirements to the DMA pcm driver. Having a common data structure for this allows us to implement common functions on top of them, which can be used by multiple platforms. This patch also introduces a new function to initialize certain fields of a dma_slave_config struct from the common DAI DMA data struct. Signed-off-by: Lars-Peter Clausen Reviewed-by: Stephen Warren Tested-by: Stephen Warren Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 24 ++++++++++++++++++++++++ sound/soc/soc-dmaengine-pcm.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index f8a7031..9562042 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -44,4 +44,28 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream); struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream); +/** + * struct snd_dmaengine_dai_dma_data - DAI DMA configuration data + * @addr: Address of the DAI data source or destination register. + * @addr_width: Width of the DAI data source or destination register. + * @maxburst: Maximum number of words(note: words, as in units of the + * src_addr_width member, not bytes) that can be send to or received from the + * DAI in one burst. + * @slave_id: Slave requester id for the DMA channel. + * @filter_data: Custom DMA channel filter data, this will usually be used when + * requesting the DMA channel. + */ +struct snd_dmaengine_dai_dma_data { + dma_addr_t addr; + enum dma_slave_buswidth addr_width; + u32 maxburst; + unsigned int slave_id; + void *filter_data; +}; + +void snd_dmaengine_pcm_set_config_from_dai_data( + const struct snd_pcm_substream *substream, + const struct snd_dmaengine_dai_dma_data *dma_data, + struct dma_slave_config *config); + #endif diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 7c24ded..a9a300a 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -95,6 +95,43 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, } EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); +/** + * snd_dmaengine_pcm_set_config_from_dai_data() - Initializes a dma slave config + * using DAI DMA data. + * @substream: PCM substream + * @dma_data: DAI DMA data + * @slave_config: DMA slave configuration + * + * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and + * slave_id fields of the DMA slave config from the same fields of the DAI DMA + * data struct. The src and dst fields will be initialized depending on the + * direction of the substream. If the substream is a playback stream the dst + * fields will be initialized, if it is a capture stream the src fields will be + * initialized. The {dst,src}_addr_width field will only be initialized if the + * addr_width field of the DAI DMA data struct is not equal to + * DMA_SLAVE_BUSWIDTH_UNDEFINED. + */ +void snd_dmaengine_pcm_set_config_from_dai_data( + const struct snd_pcm_substream *substream, + const struct snd_dmaengine_dai_dma_data *dma_data, + struct dma_slave_config *slave_config) +{ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + slave_config->dst_addr = dma_data->addr; + slave_config->dst_maxburst = dma_data->maxburst; + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED) + slave_config->dst_addr_width = dma_data->addr_width; + } else { + slave_config->src_addr = dma_data->addr; + slave_config->src_maxburst = dma_data->maxburst; + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED) + slave_config->src_addr_width = dma_data->addr_width; + } + + slave_config->slave_id = dma_data->slave_id; +} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); + static void dmaengine_pcm_dma_complete(void *arg) { struct snd_pcm_substream *substream = arg; -- cgit v1.1 From 09ae3aaf3cd28422d76b7b78d9491b17330b276a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 3 Apr 2013 11:06:05 +0200 Subject: ASoC: omap: Use common DAI DMA data Use the common DAI DMA data struct for omap, this allows us to use the common helper function to configure the DMA slave config based on the DAI DMA data. For omap-dmic and omap-mcpdm also move the DMA data from a global variable to the driver state struct. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/am3517evm.c | 1 - sound/soc/omap/ams-delta.c | 1 - sound/soc/omap/mcbsp.c | 14 +++++++------ sound/soc/omap/mcbsp.h | 7 ++++--- sound/soc/omap/n810.c | 1 - sound/soc/omap/omap-abe-twl6040.c | 1 - sound/soc/omap/omap-dmic.c | 22 ++++++++++---------- sound/soc/omap/omap-hdmi.c | 24 ++++++++++------------ sound/soc/omap/omap-mcbsp.c | 6 +++--- sound/soc/omap/omap-mcpdm.c | 31 +++++++++++++---------------- sound/soc/omap/omap-pcm.c | 42 +++++---------------------------------- sound/soc/omap/omap-pcm.h | 39 ------------------------------------ sound/soc/omap/omap-twl4030.c | 1 - sound/soc/omap/omap3pandora.c | 1 - sound/soc/omap/osk5912.c | 1 - sound/soc/omap/rx51.c | 1 - 16 files changed, 54 insertions(+), 139 deletions(-) delete mode 100644 sound/soc/omap/omap-pcm.h diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index c1900b2..994dcf3 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -28,7 +28,6 @@ #include #include "omap-mcbsp.h" -#include "omap-pcm.h" #include "../codecs/tlv320aic23.h" diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 2600447..6294464 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -36,7 +36,6 @@ #include #include "omap-mcbsp.h" -#include "omap-pcm.h" #include "../codecs/cx20442.h" diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 285c836..eb68c7d 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c @@ -1018,9 +1018,10 @@ int omap_mcbsp_init(struct platform_device *pdev) return -ENODEV; } /* RX DMA request number, and port address configuration */ - mcbsp->dma_data[1].name = "Audio Capture"; - mcbsp->dma_data[1].dma_req = res->start; - mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1); + 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; res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); if (!res) { @@ -1028,9 +1029,10 @@ int omap_mcbsp_init(struct platform_device *pdev) return -ENODEV; } /* TX DMA request number, and port address configuration */ - mcbsp->dma_data[0].name = "Audio Playback"; - mcbsp->dma_data[0].dma_req = res->start; - mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0); + 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->fclk = clk_get(&pdev->dev, "fck"); if (IS_ERR(mcbsp->fclk)) { diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index f93e0b0..96d1b08 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h @@ -24,14 +24,14 @@ #ifndef __ASOC_MCBSP_H #define __ASOC_MCBSP_H -#include "omap-pcm.h" - #ifdef CONFIG_ARCH_OMAP1 #define mcbsp_omap1() 1 #else #define mcbsp_omap1() 0 #endif +#include + /* McBSP register numbers. Register address offset = num * reg_step */ enum { /* Common registers */ @@ -312,7 +312,8 @@ struct omap_mcbsp { struct omap_mcbsp_platform_data *pdata; struct omap_mcbsp_st_data *st_data; struct omap_mcbsp_reg_cfg cfg_regs; - struct omap_pcm_dma_data dma_data[2]; + struct snd_dmaengine_dai_dma_data dma_data[2]; + unsigned int dma_req[2]; int dma_op_mode; u16 max_tx_thres; u16 max_rx_thres; diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index ee7cd53..5e8d640 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -34,7 +34,6 @@ #include #include "omap-mcbsp.h" -#include "omap-pcm.h" #define N810_HEADSET_AMP_GPIO 10 #define N810_SPEAKER_AMP_GPIO 101 diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index e7d93fa..70cd5c7 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -34,7 +34,6 @@ #include "omap-dmic.h" #include "omap-mcpdm.h" -#include "omap-pcm.h" #include "../codecs/twl6040.h" struct abe_twl6040 { diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 8ebaf11..a2597fa 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -39,8 +39,8 @@ #include #include #include +#include -#include "omap-pcm.h" #include "omap-dmic.h" struct omap_dmic { @@ -55,13 +55,9 @@ struct omap_dmic { u32 ch_enabled; bool active; struct mutex mutex; -}; -/* - * Stream DMA parameters - */ -static struct omap_pcm_dma_data omap_dmic_dai_dma_params = { - .name = "DMIC capture", + 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) @@ -118,7 +114,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, mutex_unlock(&dmic->mutex); - snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); + snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data); return ret; } @@ -203,7 +199,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); - struct omap_pcm_dma_data *dma_data; + struct snd_dmaengine_dai_dma_data *dma_data; int channels; dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); @@ -230,7 +226,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, /* packet size is threshold * channels */ dma_data = snd_soc_dai_get_dma_data(dai, substream); - dma_data->packet_size = dmic->threshold * channels; + dma_data->maxburst = dmic->threshold * channels; return 0; } @@ -476,7 +472,7 @@ static int asoc_dmic_probe(struct platform_device *pdev) ret = -ENODEV; goto err_put_clk; } - omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG; + dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG; res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { @@ -484,7 +480,9 @@ static int asoc_dmic_probe(struct platform_device *pdev) ret = -ENODEV; goto err_put_clk; } - omap_dmic_dai_dma_params.dma_req = res->start; + + dmic->dma_req = res->start; + dmic->dma_data.filter_data = &dmic->dma_req; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); if (!res) { diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index 32fa840..b4bfab9 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -32,15 +32,16 @@ #include #include #include +#include #include