提交 4564d10f 编写于 作者: L Lars-Peter Clausen 提交者: Mark Brown

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: NLars-Peter Clausen <lars@metafoo.de>
Tested-by: NShawn Guo <shawn.guo@linaro.org>
Signed-off-by: NMark Brown <broonie@opensource.wolfsonmicro.com>
上级 91a38540
...@@ -65,17 +65,13 @@ static bool filter(struct dma_chan *chan, void *param) ...@@ -65,17 +65,13 @@ static bool filter(struct dma_chan *chan, void *param)
return true; return true;
} }
static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_dma_params *dma_params; struct imx_pcm_dma_params *dma_params;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
struct dma_slave_config slave_config;
dma_cap_mask_t mask; dma_cap_mask_t mask;
enum dma_slave_buswidth buswidth;
int ret;
dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 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, ...@@ -84,13 +80,29 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
iprtd->dma_data.dma_request = dma_params->dma; iprtd->dma_data.dma_request = dma_params->dma;
/* Try to grab a DMA channel */ /* Try to grab a DMA channel */
if (!iprtd->dma_chan) { dma_cap_zero(mask);
dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_SLAVE, mask); iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); if (!iprtd->dma_chan)
if (!iprtd->dma_chan) return -EINVAL;
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)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
...@@ -116,29 +128,10 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, ...@@ -116,29 +128,10 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
slave_config.src_maxburst = dma_params->burstsize; 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) if (ret)
return 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->periods = params_periods(params);
iprtd->period_bytes = params_period_bytes(params); iprtd->period_bytes = params_period_bytes(params);
...@@ -164,19 +157,6 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -164,19 +157,6 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
return 0; 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) static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
...@@ -251,6 +231,12 @@ static int snd_imx_open(struct snd_pcm_substream *substream) ...@@ -251,6 +231,12 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
return ret; return ret;
} }
ret = imx_ssi_dma_alloc(substream);
if (ret < 0) {
kfree(iprtd);
return ret;
}
snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
return 0; return 0;
...@@ -261,6 +247,7 @@ static int snd_imx_close(struct snd_pcm_substream *substream) ...@@ -261,6 +247,7 @@ static int snd_imx_close(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
dma_release_channel(iprtd->dma_chan);
kfree(iprtd); kfree(iprtd);
return 0; return 0;
...@@ -271,7 +258,6 @@ static struct snd_pcm_ops imx_pcm_ops = { ...@@ -271,7 +258,6 @@ static struct snd_pcm_ops imx_pcm_ops = {
.close = snd_imx_close, .close = snd_imx_close,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_imx_pcm_hw_params, .hw_params = snd_imx_pcm_hw_params,
.hw_free = snd_imx_pcm_hw_free,
.trigger = snd_imx_pcm_trigger, .trigger = snd_imx_pcm_trigger,
.pointer = snd_imx_pcm_pointer, .pointer = snd_imx_pcm_pointer,
.mmap = snd_imx_pcm_mmap, .mmap = snd_imx_pcm_mmap,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册