From e54e2f81da0aaf9e39d6f9b25fa08ce0bec9ca06 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen <lars@metafoo.de> Date: Tue, 21 Feb 2012 17:47:55 +0100 Subject: ASoC: imx-pcm: Remove empty prepare callback Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> --- sound/soc/imx/imx-pcm-dma-mx2.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'sound/soc/imx/imx-pcm-dma-mx2.c') diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 5780c9b9d56..bc1df166385 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -186,16 +186,6 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream) return 0; } -static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct imx_pcm_dma_params *dma_params; - - dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - return 0; -} - static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -291,7 +281,6 @@ static struct snd_pcm_ops imx_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_imx_pcm_hw_params, .hw_free = snd_imx_pcm_hw_free, - .prepare = snd_imx_pcm_prepare, .trigger = snd_imx_pcm_trigger, .pointer = snd_imx_pcm_pointer, .mmap = snd_imx_pcm_mmap, -- cgit v1.2.3-70-g09d2 From f6914024575fc3fd9773531ca74d1bcb0ddaf88f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen <lars@metafoo.de> Date: Tue, 21 Feb 2012 17:47:56 +0100 Subject: ASoC: imx-pcm: Remove unused fields from imx_pcm_runtime_data struct Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> --- sound/soc/imx/imx-pcm-dma-mx2.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'sound/soc/imx/imx-pcm-dma-mx2.c') diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index bc1df166385..ec139441552 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -35,11 +35,7 @@ struct imx_pcm_runtime_data { int period_bytes; int periods; - int dma; unsigned long offset; - unsigned long size; - void *buf; - int period_time; struct dma_async_tx_descriptor *desc; struct dma_chan *dma_chan; struct imx_dma_data dma_data; @@ -144,19 +140,14 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, return ret; chan = iprtd->dma_chan; - iprtd->size = params_buffer_bytes(params); iprtd->periods = params_periods(params); iprtd->period_bytes = params_period_bytes(params); iprtd->offset = 0; - iprtd->period_time = HZ / (params_rate(params) / - params_period_size(params)); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); dma_addr = runtime->dma_addr; - iprtd->buf = (unsigned int *)substream->dma_buffer.area; - iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr, iprtd->period_bytes * iprtd->periods, iprtd->period_bytes, -- cgit v1.2.3-70-g09d2 From 4564d10f3066a1abf5053936684e2c8495163def Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen <lars@metafoo.de> Date: Wed, 22 Feb 2012 10:49:06 +0100 Subject: ASoC: imx-pcm: Request DMA channel early Request the DMA channel in the pcm open callback. This allows us to let open fail if there is no dma channel available. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Tested-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> --- sound/soc/imx/imx-pcm-dma-mx2.c | 78 +++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 46 deletions(-) (limited to 'sound/soc/imx/imx-pcm-dma-mx2.c') diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index ec139441552..f974e61fa68 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -65,17 +65,13 @@ static bool filter(struct dma_chan *chan, void *param) return true; } -static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) +static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct imx_pcm_dma_params *dma_params; struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; - struct dma_slave_config slave_config; dma_cap_mask_t mask; - enum dma_slave_buswidth buswidth; - int ret; dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); @@ -84,13 +80,29 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, iprtd->dma_data.dma_request = dma_params->dma; /* Try to grab a DMA channel */ - if (!iprtd->dma_chan) { - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); - if (!iprtd->dma_chan) - return -EINVAL; - } + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); + if (!iprtd->dma_chan) + return -EINVAL; + + return 0; +} + +static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; + struct dma_chan *chan = iprtd->dma_chan; + struct imx_pcm_dma_params *dma_params; + struct dma_slave_config slave_config; + enum dma_slave_buswidth buswidth; + unsigned long dma_addr; + int ret; + + dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -116,29 +128,10 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, slave_config.src_maxburst = dma_params->burstsize; } - ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); + ret = dmaengine_slave_config(chan, &slave_config); if (ret) return ret; - return 0; -} - -static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - unsigned long dma_addr; - struct dma_chan *chan; - struct imx_pcm_dma_params *dma_params; - int ret; - - dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - ret = imx_ssi_dma_alloc(substream, params); - if (ret) - return ret; - chan = iprtd->dma_chan; iprtd->periods = params_periods(params); iprtd->period_bytes = params_period_bytes(params); @@ -164,19 +157,6 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } -static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - - if (iprtd->dma_chan) { - dma_release_channel(iprtd->dma_chan); - iprtd->dma_chan = NULL; - } - - return 0; -} - static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -251,6 +231,12 @@ static int snd_imx_open(struct snd_pcm_substream *substream) return ret; } + ret = imx_ssi_dma_alloc(substream); + if (ret < 0) { + kfree(iprtd); + return ret; + } + snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); return 0; @@ -261,6 +247,7 @@ static int snd_imx_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; + dma_release_channel(iprtd->dma_chan); kfree(iprtd); return 0; @@ -271,7 +258,6 @@ static struct snd_pcm_ops imx_pcm_ops = { .close = snd_imx_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_imx_pcm_hw_params, - .hw_free = snd_imx_pcm_hw_free, .trigger = snd_imx_pcm_trigger, .pointer = snd_imx_pcm_pointer, .mmap = snd_imx_pcm_mmap, -- cgit v1.2.3-70-g09d2 From c307e8e32e11aae0f561db02898a090c9b7c9b70 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen <lars@metafoo.de> Date: Wed, 22 Feb 2012 10:49:09 +0100 Subject: ASoC: imx-pcm-dma: Use dmaengine PCM helper functions Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Tested-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Vinod Koul <vinod.koul@linux.intel.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> --- sound/soc/imx/Kconfig | 1 + sound/soc/imx/imx-pcm-dma-mx2.c | 176 ++++++---------------------------------- 2 files changed, 28 insertions(+), 149 deletions(-) (limited to 'sound/soc/imx/imx-pcm-dma-mx2.c') diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index e89139ffbce..192861c2b4a 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig @@ -14,6 +14,7 @@ config SND_MXC_SOC_FIQ tristate config SND_MXC_SOC_MX2 + select SND_SOC_DMAENGINE_PCM tristate config SND_MXC_SOC_WM1133_EV1 diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index f974e61fa68..4cd5462049b 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -27,104 +27,42 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include <sound/dmaengine_pcm.h> #include <mach/dma.h> #include "imx-ssi.h" -struct imx_pcm_runtime_data { - int period_bytes; - int periods; - unsigned long offset; - struct dma_async_tx_descriptor *desc; - struct dma_chan *dma_chan; - struct imx_dma_data dma_data; -}; - -static void audio_dma_irq(void *data) -{ - struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data; - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - - iprtd->offset += iprtd->period_bytes; - iprtd->offset %= iprtd->period_bytes * iprtd->periods; - - snd_pcm_period_elapsed(substream); -} - static bool filter(struct dma_chan *chan, void *param) { - struct imx_pcm_runtime_data *iprtd = param; - if (!imx_dma_is_general_purpose(chan)) return false; - chan->private = &iprtd->dma_data; + chan->private = param; - return true; -} - -static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct imx_pcm_dma_params *dma_params; - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - dma_cap_mask_t mask; - - dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI; - iprtd->dma_data.priority = DMA_PRIO_HIGH; - iprtd->dma_data.dma_request = dma_params->dma; - - /* Try to grab a DMA channel */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); - if (!iprtd->dma_chan) - return -EINVAL; - - return 0; + return true; } static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - struct dma_chan *chan = iprtd->dma_chan; + struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); struct imx_pcm_dma_params *dma_params; struct dma_slave_config slave_config; - enum dma_slave_buswidth buswidth; - unsigned long dma_addr; int ret; dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - case SNDRV_PCM_FORMAT_S24_LE: - buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; - break; - default: - return 0; - } + ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config); + if (ret) + return ret; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - slave_config.direction = DMA_MEM_TO_DEV; slave_config.dst_addr = dma_params->dma_addr; - slave_config.dst_addr_width = buswidth; slave_config.dst_maxburst = dma_params->burstsize; } else { - slave_config.direction = DMA_DEV_TO_MEM; slave_config.src_addr = dma_params->dma_addr; - slave_config.src_addr_width = buswidth; slave_config.src_maxburst = dma_params->burstsize; } @@ -132,68 +70,11 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; - - iprtd->periods = params_periods(params); - iprtd->period_bytes = params_period_bytes(params); - iprtd->offset = 0; - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - dma_addr = runtime->dma_addr; - - iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr, - iprtd->period_bytes * iprtd->periods, - iprtd->period_bytes, - substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); - if (!iprtd->desc) { - dev_err(&chan->dev->device, "cannot prepare slave dma\n"); - return -EINVAL; - } - - iprtd->desc->callback = audio_dma_irq; - iprtd->desc->callback_param = substream; - - return 0; -} - -static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - dmaengine_submit(iprtd->desc); - - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - dmaengine_terminate_all(iprtd->dma_chan); - - break; - default: - return -EINVAL; - } - return 0; } -static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; - - pr_debug("%s: %ld %ld\n", __func__, iprtd->offset, - bytes_to_frames(substream->runtime, iprtd->offset)); - - return bytes_to_frames(substream->runtime, iprtd->offset); -} - static struct snd_pcm_hardware snd_imx_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -215,40 +96,37 @@ static struct snd_pcm_hardware snd_imx_hardware = { static int snd_imx_open(struct snd_pcm_substream *substream) { - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct imx_pcm_dma_params *dma_params; + struct imx_dma_data *dma_data; int ret; - iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); - if (iprtd == NULL) - return -ENOMEM; - runtime->private_data = iprtd; + snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); - ret = snd_pcm_hw_constraint_integer(substream->runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) { - kfree(iprtd); - return ret; - } + dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - ret = imx_ssi_dma_alloc(substream); - if (ret < 0) { - kfree(iprtd); - return ret; + dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); + dma_data->peripheral_type = 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 0; } - snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); + snd_dmaengine_pcm_set_data(substream, dma_data); return 0; } static int snd_imx_close(struct snd_pcm_substream *substream) { - struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; + struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); - dma_release_channel(iprtd->dma_chan); - kfree(iprtd); + snd_dmaengine_pcm_close(substream); + kfree(dma_data); return 0; } @@ -258,8 +136,8 @@ static struct snd_pcm_ops imx_pcm_ops = { .close = snd_imx_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_imx_pcm_hw_params, - .trigger = snd_imx_pcm_trigger, - .pointer = snd_imx_pcm_pointer, + .trigger = snd_dmaengine_pcm_trigger, + .pointer = snd_dmaengine_pcm_pointer, .mmap = snd_imx_pcm_mmap, }; -- cgit v1.2.3-70-g09d2 From 9a3a101c1a34b498f466409ce5a1bf0fcbcc476b Mon Sep 17 00:00:00 2001 From: Shawn Guo <shawn.guo@linaro.org> Date: Sat, 3 Mar 2012 23:19:49 +0800 Subject: ASoC: imx: initialize dma_params burstsize just in imx-ssi It's not necessary for imx-pcm-dma-mx2 to access imx_ssi.dma_params for burstsize initialization. Instead, it can just be done in imx-ssi probe function once. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> --- sound/soc/imx/imx-pcm-dma-mx2.c | 5 ----- sound/soc/imx/imx-ssi.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'sound/soc/imx/imx-pcm-dma-mx2.c') diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 4cd5462049b..471e2218c97 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -149,11 +149,6 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = { static int __devinit imx_soc_platform_probe(struct platform_device *pdev) { - struct imx_ssi *ssi = platform_get_drvdata(pdev); - - ssi->dma_params_tx.burstsize = 6; - ssi->dma_params_rx.burstsize = 4; - return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); } diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index dbf43f5f0ae..25c623115a9 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -668,7 +668,7 @@ static int imx_ssi_probe(struct platform_device *pdev) ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; - ssi->dma_params_tx.burstsize = 4; + ssi->dma_params_tx.burstsize = 6; ssi->dma_params_rx.burstsize = 4; res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); -- cgit v1.2.3-70-g09d2 From 4762fbab0b1cf1d4f3e02b78351dc6fa59ca564e Mon Sep 17 00:00:00 2001 From: Shawn Guo <shawn.guo@linaro.org> Date: Mon, 5 Mar 2012 22:30:55 +0800 Subject: ASoC: imx: separate imx-pcm bits from imx-ssi driver Currently the imx-ssi.c[h] accommodates the imx-pcm common bits which are shared between imx-pcm-dma-mx2 and imx-pcm-fiq drivers. It assumes that imx-pcm-dma-mx2 and imx-pcm-fiq will always be used together with imx-ssi driver. However this becomes untrue when we see that driver sound/soc/fsl/fsl_ssi could possibly work with imx-pcm-dma-mx2 too. The patch moves the imx-pcm common bits from imx-ssi.c[h] into new files imx-pcm.c[h], and let imx-pcm-dma-mx2 and imx-pcm-fiq drivers build it in, so that imx-pcm-dma-mx2 can work with no dependency on imx-ssi driver. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> --- sound/soc/imx/Kconfig | 7 ++- sound/soc/imx/Makefile | 9 ++-- sound/soc/imx/imx-pcm-dma-mx2.c | 2 +- sound/soc/imx/imx-pcm.c | 105 ++++++++++++++++++++++++++++++++++++++++ sound/soc/imx/imx-pcm.h | 32 ++++++++++++ sound/soc/imx/imx-ssi.c | 88 --------------------------------- sound/soc/imx/imx-ssi.h | 16 +----- 7 files changed, 150 insertions(+), 109 deletions(-) create mode 100644 sound/soc/imx/imx-pcm.c create mode 100644 sound/soc/imx/imx-pcm.h (limited to 'sound/soc/imx/imx-pcm-dma-mx2.c') diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index d3b716663d1..2566032a490 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig @@ -8,13 +8,18 @@ menuconfig SND_IMX_SOC if SND_IMX_SOC +config SND_SOC_IMX_PCM + tristate + config SND_MXC_SOC_FIQ - select FIQ tristate + select FIQ + select SND_SOC_IMX_PCM config SND_MXC_SOC_MX2 select SND_SOC_DMAENGINE_PCM tristate + select SND_SOC_IMX_PCM config SND_SOC_IMX_AUDMUX tristate diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile index 5c40541b831..e9ed362636e 100644 --- a/sound/soc/imx/Makefile +++ b/sound/soc/imx/Makefile @@ -1,14 +1,15 @@ # i.MX Platform Support snd-soc-imx-objs := imx-ssi.o -snd-soc-imx-fiq-objs := imx-pcm-fiq.o -snd-soc-imx-mx2-objs := imx-pcm-dma-mx2.o snd-soc-imx-audmux-objs := imx-audmux.o obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o -obj-$(CONFIG_SND_MXC_SOC_FIQ) += snd-soc-imx-fiq.o -obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o +obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o +snd-soc-imx-pcm-y := imx-pcm.o +snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o +snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o + # i.MX Machine Support snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o snd-soc-phycore-ac97-objs := phycore-ac97.o diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 471e2218c97..e43c8fa2788 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -31,7 +31,7 @@ #include <mach/dma.h> -#include "imx-ssi.h" +#include "imx-pcm.h" static bool filter(struct dma_chan *chan, void *param) { diff --git a/sound/soc/imx/imx-pcm.c b/sound/soc/imx/imx-pcm.c new file mode 100644 index 00000000000..93dc360b177 --- /dev/null +++ b/sound/soc/imx/imx-pcm.c @@ -0,0 +1,105 @@ +/* + * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de> + * + * This code is based on code copyrighted by Freescale, + * Liam Girdwood, Javier Martin and probably others. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/dma-mapping.h> +#include <linux/module.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include "imx-pcm.h" + +int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); + + pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); + return ret; +} +EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap); + +static int imx_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 = IMX_SSI_DMABUF_SIZE; + + 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 imx_pcm_dmamask = DMA_BIT_MASK(32); + +int imx_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 = &imx_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 = imx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + goto out; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { + ret = imx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) + goto out; + } + +out: + return ret; +} +EXPORT_SYMBOL_GPL(imx_pcm_new); + +void imx_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; + } +} +EXPORT_SYMBOL_GPL(imx_pcm_free); diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/imx/imx-pcm.h new file mode 100644 index 00000000000..b5f5c3acf34 --- /dev/null +++ b/sound/soc/imx/imx-pcm.h @@ -0,0 +1,32 @@ +/* + * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de> + * + * This code is based on code copyrighted by Freescale, + * Liam Girdwood, Javier Martin and probably others. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef _IMX_PCM_H +#define _IMX_PCM_H + +/* + * 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; +}; + +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); +void imx_pcm_free(struct snd_pcm *pcm); + +#endif /* _IMX_PCM_H */ diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 25c623115a9..9203cdd0a15 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -363,94 +363,6 @@ static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { .trigger = imx_ssi_trigger, }; -int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int ret; - - ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); - - pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); - return ret; -} -EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap); - -static int imx_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 = IMX_SSI_DMABUF_SIZE; - - 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 imx_pcm_dmamask = DMA_BIT_MASK(32); - -int imx_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 = &imx_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 = imx_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = imx_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - -out: - return ret; -} -EXPORT_SYMBOL_GPL(imx_pcm_new); - -void imx_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; - } -} -EXPORT_SYMBOL_GPL(imx_pcm_free); - static int imx_ssi_dai_probe(struct snd_soc_dai *dai) { struct imx_ssi *ssi = dev_get_drvdata(dai->dev); diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h index 1072dfb53e4..5744e86ca87 100644 --- a/sound/soc/imx/imx-ssi.h +++ b/sound/soc/imx/imx-ssi.h @@ -187,12 +187,7 @@ #include <linux/dmaengine.h> #include <mach/dma.h> - -struct imx_pcm_dma_params { - int dma; - unsigned long dma_addr; - int burstsize; -}; +#include "imx-pcm.h" struct imx_ssi { struct platform_device *ac97_dev; @@ -218,13 +213,4 @@ struct imx_ssi { struct platform_device *soc_platform_pdev_fiq; }; -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); -void imx_pcm_free(struct snd_pcm *pcm); - -/* - * Do not change this as the FIQ handler depends on this size - */ -#define IMX_SSI_DMABUF_SIZE (64 * 1024) - #endif /* _IMX_SSI_H */ -- cgit v1.2.3-70-g09d2