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(-) (limited to 'sound/soc/mxs') diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 564b5b60319d..ebbef8597554 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 35ba2ca42384..3aa918f9ed3e 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 3a2aa1d19b93..f13bd8730b0f 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.2.3-70-g09d2 From 026240bb155bb8f83b9425812f52661fcbaa0629 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:33:02 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on mxs saif Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc/mxs') diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 3a2aa1d19b93..3e78ba866681 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -627,6 +627,10 @@ static struct snd_soc_dai_driver mxs_saif_dai = { .ops = &mxs_saif_dai_ops, }; +static const struct snd_soc_component_driver mxs_saif_component = { + .name = "mxs-saif", +}; + static irqreturn_t mxs_saif_irq(int irq, void *dev_id) { struct mxs_saif *saif = dev_id; @@ -763,7 +767,8 @@ static int mxs_saif_probe(struct platform_device *pdev) platform_set_drvdata(pdev, saif); - ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); + ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component, + &mxs_saif_dai, 1); if (ret) { dev_err(&pdev->dev, "register DAI failed\n"); return ret; @@ -778,7 +783,7 @@ static int mxs_saif_probe(struct platform_device *pdev) return 0; failed_pdev_alloc: - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return ret; } @@ -786,7 +791,7 @@ failed_pdev_alloc: static int mxs_saif_remove(struct platform_device *pdev) { mxs_pcm_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3-70-g09d2 From 7c1c1d4a7b4ca1266057a3632d27450f5575caf9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 15 Apr 2013 19:19:48 +0200 Subject: ASoC: dmaengine-pcm: Make requesting the DMA channel at PCM open optional Refactor the dmaengine PCM library to allow the DMA channel to be requested before opening a PCM substream. snd_dmaengine_pcm_open() now expects a DMA channel instead of a filter function and filter parameter as its parameters. snd_dmaengine_pcm_close() is updated to not release the DMA channel. This allows a dmaengine based PCM driver to request its channels before the substream is opened. The patch also introduces two new functions, snd_dmaengine_pcm_open_request_chan() and snd_dmaengine_pcm_close_release_chan(), which have the same signature and behaviour of the old snd_dmaengine_pcm_{open,close}() and internally use the new variants of these functions. All users of snd_dmaengine_pcm_{open,close}() are updated to use snd_dmaengine_pcm_open_request_chan() and snd_dmaengine_pcm_close_release_chan(). Signed-off-by: Lars-Peter Clausen Tested-by: Stephen Warren Tested-by: Shawn Guo Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 6 +++- sound/soc/atmel/atmel-pcm-dma.c | 6 ++-- sound/soc/cirrus/ep93xx-pcm.c | 5 +-- sound/soc/fsl/imx-pcm-dma.c | 2 +- sound/soc/mxs/mxs-pcm.c | 4 +-- sound/soc/omap/omap-pcm.c | 7 ++-- sound/soc/pxa/mmp-pcm.c | 5 +-- sound/soc/soc-dmaengine-pcm.c | 72 ++++++++++++++++++++++++++++------------- sound/soc/spear/spear_pcm.c | 5 +-- sound/soc/tegra/tegra_pcm.c | 4 +-- sound/soc/ux500/ux500_pcm.c | 6 ++-- 11 files changed, 78 insertions(+), 44 deletions(-) (limited to 'sound/soc/mxs') diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 95620428a59b..d015d67e75c3 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -39,9 +39,13 @@ snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream); int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, - dma_filter_fn filter_fn, void *filter_data); + struct dma_chan *chan); int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream); +int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream, + dma_filter_fn filter_fn, void *filter_data); +int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream); + struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream); /** diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index bb07989762d5..1d38fd0bc4e2 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -155,7 +155,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, if (ssc->pdev) sdata = ssc->pdev->dev.platform_data; - ret = snd_dmaengine_pcm_open(substream, filter, sdata); + ret = snd_dmaengine_pcm_open_request_chan(substream, filter, sdata); if (ret) { pr_err("atmel-pcm: dmaengine pcm open failed\n"); return -EINVAL; @@ -171,7 +171,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, return 0; err: - snd_dmaengine_pcm_close(substream); + snd_dmaengine_pcm_close_release_chan(substream); return ret; } @@ -197,7 +197,7 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream) static struct snd_pcm_ops atmel_pcm_ops = { .open = atmel_pcm_open, - .close = snd_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = atmel_pcm_hw_params, .prepare = atmel_pcm_dma_prepare, diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index 298946f790eb..488032690378 100644 --- a/sound/soc/cirrus/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c @@ -69,7 +69,8 @@ static int ep93xx_pcm_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); - return snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, + return snd_dmaengine_pcm_open_request_chan(substream, + ep93xx_pcm_dma_filter, snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); } @@ -100,7 +101,7 @@ static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops ep93xx_pcm_ops = { .open = ep93xx_pcm_open, - .close = snd_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = ep93xx_pcm_hw_params, .hw_free = ep93xx_pcm_hw_free, diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index ee838c8a3b11..c6647825bdd5 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -100,7 +100,7 @@ static int snd_imx_open(struct snd_pcm_substream *substream) static struct snd_pcm_ops imx_pcm_ops = { .open = snd_imx_open, - .close = snd_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_imx_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index ebbef8597554..7bceb16d0fd9 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -87,7 +87,7 @@ static int snd_mxs_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); - return snd_dmaengine_pcm_open(substream, filter, + return snd_dmaengine_pcm_open_request_chan(substream, filter, snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); } @@ -104,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_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_mxs_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index c8e272f9c2de..c28e042f2208 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -118,8 +118,9 @@ static int omap_pcm_open(struct snd_pcm_substream *substream) dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - return snd_dmaengine_pcm_open(substream, omap_dma_filter_fn, - dma_data->filter_data); + return snd_dmaengine_pcm_open_request_chan(substream, + omap_dma_filter_fn, + dma_data->filter_data); } static int omap_pcm_mmap(struct snd_pcm_substream *substream, @@ -135,7 +136,7 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops omap_pcm_ops = { .open = omap_pcm_open, - .close = snd_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = omap_pcm_hw_params, .hw_free = omap_pcm_hw_free, diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 6c3980252bf6..349930015264 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -131,7 +131,8 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream) dma_data.dma_res = r; dma_data.ssp_id = cpu_dai->id; - return snd_dmaengine_pcm_open(substream, filter, &dma_data); + return snd_dmaengine_pcm_open_request_chan(substream, filter, + &dma_data); } static int mmp_pcm_mmap(struct snd_pcm_substream *substream, @@ -148,7 +149,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream, struct snd_pcm_ops mmp_pcm_ops = { .open = mmp_pcm_open, - .close = snd_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = mmp_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index a9a300acb506..b0420a75f412 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -254,44 +254,38 @@ snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); -static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd, - dma_filter_fn filter_fn, void *filter_data) +static struct dma_chan *dmaengine_pcm_request_channel(dma_filter_fn filter_fn, + void *filter_data) { dma_cap_mask_t mask; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); dma_cap_set(DMA_CYCLIC, mask); - prtd->dma_chan = dma_request_channel(mask, filter_fn, filter_data); - - if (!prtd->dma_chan) - return -ENXIO; - return 0; + return dma_request_channel(mask, filter_fn, filter_data); } /** * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream * @substream: PCM substream - * @filter_fn: Filter function used to request the DMA channel - * @filter_data: Data passed to the DMA filter function + * @chan: DMA channel to use for data transfers * * Returns 0 on success, a negative error code otherwise. * - * This function will request a DMA channel using the passed filter function and - * data. The function should usually be called from the pcm open callback. - * - * Note that this function will use private_data field of the substream's - * runtime. So it is not availabe to your pcm driver implementation. If you need - * to keep additional data attached to a substream use - * snd_dmaengine_pcm_{set,get}_data. + * The function should usually be called from the pcm open callback. Note that + * this function will use private_data field of the substream's runtime. So it + * is not availabe to your pcm driver implementation. */ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, - dma_filter_fn filter_fn, void *filter_data) + struct dma_chan *chan) { struct dmaengine_pcm_runtime_data *prtd; int ret; + if (!chan) + return -ENXIO; + ret = snd_pcm_hw_constraint_integer(substream->runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) @@ -301,11 +295,7 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, if (!prtd) return -ENOMEM; - ret = dmaengine_pcm_request_channel(prtd, filter_fn, filter_data); - if (ret < 0) { - kfree(prtd); - return ret; - } + prtd->dma_chan = chan; substream->runtime->private_data = prtd; @@ -313,6 +303,27 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open); +/** + * snd_dmaengine_pcm_open_request_chan - Open a dmaengine based PCM substream and request channel + * @substream: PCM substream + * @filter_fn: Filter function used to request the DMA channel + * @filter_data: Data passed to the DMA filter function + * + * Returns 0 on success, a negative error code otherwise. + * + * This function will request a DMA channel using the passed filter function and + * data. The function should usually be called from the pcm open callback. Note + * that this function will use private_data field of the substream's runtime. So + * it is not availabe to your pcm driver implementation. + */ +int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream, + dma_filter_fn filter_fn, void *filter_data) +{ + return snd_dmaengine_pcm_open(substream, + dmaengine_pcm_request_channel(filter_fn, filter_data)); +} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan); + /** * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream * @substream: PCM substream @@ -321,11 +332,26 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream) { struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - dma_release_channel(prtd->dma_chan); kfree(prtd); return 0; } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); +/** + * snd_dmaengine_pcm_release_chan_close - Close a dmaengine based PCM substream and release channel + * @substream: PCM substream + * + * Releases the DMA channel associated with the PCM substream. + */ +int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream) +{ + struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); + + dma_release_channel(prtd->dma_chan); + + return snd_dmaengine_pcm_close(substream); +} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan); + MODULE_LICENSE("GPL"); diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index db75d72c4805..ba66a3f370a3 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -64,7 +64,8 @@ static int spear_pcm_open(struct snd_pcm_substream *substream) if (ret) return ret; - return snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data) + return snd_dmaengine_pcm_open_request_chan(substream, dma_data->filter, + dma_data); } static int spear_pcm_mmap(struct snd_pcm_substream *substream, @@ -79,7 +80,7 @@ static int spear_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops spear_pcm_ops = { .open = spear_pcm_open, - .close = snd_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = spear_pcm_hw_params, .hw_free = spear_pcm_hw_free, diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index f91d08bc1753..32d08119dd87 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -66,7 +66,7 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) /* Set HW params now that initialization is complete */ snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); - ret = snd_dmaengine_pcm_open(substream, NULL, NULL); + ret = snd_dmaengine_pcm_open_request_chan(substream, NULL, NULL); if (ret) { dev_err(dev, "dmaengine pcm open failed with err %d\n", ret); return ret; @@ -144,7 +144,7 @@ static int tegra_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops tegra_pcm_ops = { .open = tegra_pcm_open, - .close = snd_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = tegra_pcm_hw_params, .hw_free = tegra_pcm_hw_free, diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 09b5364e5095..a7d4f04e5964 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -125,8 +125,8 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) dma_cfg->dst_info.data_width = mem_data_width; } - - ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg); + ret = snd_dmaengine_pcm_open_request_chan(substream, stedma40_filter, + dma_cfg); if (ret) { dev_dbg(dai->dev, "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n", @@ -211,7 +211,7 @@ static int ux500_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops ux500_pcm_ops = { .open = ux500_pcm_open, - .close = snd_dmaengine_pcm_close, + .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, .hw_params = ux500_pcm_hw_params, .hw_free = ux500_pcm_hw_free, -- cgit v1.2.3-70-g09d2 From 57364f9ae24c3a29163c23d5219bccef7bccc96a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 20 Apr 2013 19:29:01 +0200 Subject: ASoC: mxs-pcm: Set SNDRV_PCM_INFO_HALF_DUPLEX The MXS SAIF is only half-duplex so set the SNDRV_PCM_INFO_HALF_DUPLEX flag for the PCM in order to prevent playback and capture from running at the same time. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-pcm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/soc/mxs') diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 7bceb16d0fd9..907cdb1f989d 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -43,7 +43,8 @@ static struct snd_pcm_hardware snd_mxs_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_INTERLEAVED, + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_HALF_DUPLEX, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, -- cgit v1.2.3-70-g09d2 From 8c1bb4ecbca575ec89310a50c3d3dd475bf81fd0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 20 Apr 2013 19:29:02 +0200 Subject: ASoC: mxs: Setup dma data in DAI probe This allows us to access the DAI DMA data when we create the PCM. We'll use this when converting mxs to generic DMA engine PCM driver. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/soc/mxs') diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index f13bd8730b0f..d796a393968d 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -369,7 +369,6 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); - snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param); /* clear error status to 0 for each re-open */ saif->fifo_underrun = 0; @@ -605,6 +604,8 @@ static int mxs_saif_dai_probe(struct snd_soc_dai *dai) struct mxs_saif *saif = dev_get_drvdata(dai->dev); snd_soc_dai_set_drvdata(dai, saif); + dai->playback_dma_data = &saif->dma_param; + dai->capture_dma_data = &saif->dma_param; return 0; } -- cgit v1.2.3-70-g09d2 From a8956908bf03418d7264de79e1e988628183f537 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 20 Apr 2013 19:29:03 +0200 Subject: ASoC: mxs: Use generic dmaengine PCM Use the generic dmaengine PCM driver instead of a custom implementation. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/mxs/Kconfig | 2 +- sound/soc/mxs/mxs-pcm.c | 136 ++++-------------------------------------------- 2 files changed, 12 insertions(+), 126 deletions(-) (limited to 'sound/soc/mxs') diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig index b6fa77678d97..78d321cbe8b4 100644 --- a/sound/soc/mxs/Kconfig +++ b/sound/soc/mxs/Kconfig @@ -1,7 +1,7 @@ menuconfig SND_MXS_SOC tristate "SoC Audio for Freescale MXS CPUs" depends on ARCH_MXS - select SND_SOC_DMAENGINE_PCM + select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to the MXS SAIF interface. diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 907cdb1f989d..b41fffc056fb 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -18,27 +18,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include -#include #include -#include #include -#include #include -#include -#include -#include #include -#include #include -#include #include #include #include "mxs-pcm.h" -static struct snd_pcm_hardware snd_mxs_hardware = { +static const struct snd_pcm_hardware snd_mxs_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | @@ -56,7 +47,6 @@ static struct snd_pcm_hardware snd_mxs_hardware = { .periods_max = 52, .buffer_bytes_max = 64 * 1024, .fifo_size = 32, - }; static bool filter(struct dma_chan *chan, void *param) @@ -74,129 +64,25 @@ static bool filter(struct dma_chan *chan, void *param) return true; } -static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - - return 0; -} - -static int snd_mxs_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - - snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); - - return snd_dmaengine_pcm_open_request_chan(substream, filter, - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); -} - -static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static struct snd_pcm_ops mxs_pcm_ops = { - .open = snd_mxs_open, - .close = snd_dmaengine_pcm_close_release_chan, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_mxs_pcm_hw_params, - .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer_no_residue, - .mmap = snd_mxs_pcm_mmap, -}; - -static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = snd_mxs_hardware.buffer_bytes_max; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - if (!buf->area) - return -ENOMEM; - buf->bytes = size; - - return 0; -} - -static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32); -static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret = 0; - - if (!card->dev->dma_mask) - card->dev->dma_mask = &mxs_pcm_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = mxs_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = mxs_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - -out: - return ret; -} - -static void mxs_pcm_free(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_writecombine(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - } -} - -static struct snd_soc_platform_driver mxs_soc_platform = { - .ops = &mxs_pcm_ops, - .pcm_new = mxs_pcm_new, - .pcm_free = mxs_pcm_free, +static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { + .pcm_hardware = &snd_mxs_hardware, + .compat_filter_fn = filter, + .prealloc_buffer_size = 64 * 1024, }; int mxs_pcm_platform_register(struct device *dev) { - return snd_soc_register_platform(dev, &mxs_soc_platform); + return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + SND_DMAENGINE_PCM_FLAG_NO_DT | + SND_DMAENGINE_PCM_FLAG_COMPAT | + SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); } EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); void mxs_pcm_platform_unregister(struct device *dev) { - snd_soc_unregister_platform(dev); + snd_dmaengine_pcm_unregister(dev); } EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); -- cgit v1.2.3-70-g09d2