diff options
Diffstat (limited to 'sound/soc/imx/imx-pcm-dma-mx2.c')
-rw-r--r-- | sound/soc/imx/imx-pcm-dma-mx2.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 19452e44afdc..2b31ac673ea4 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
24 | #include <sound/initval.h> | 25 | #include <sound/initval.h> |
@@ -70,7 +71,12 @@ static void imx_ssi_dma_callback(int channel, void *data) | |||
70 | 71 | ||
71 | static void snd_imx_dma_err_callback(int channel, void *data, int err) | 72 | static void snd_imx_dma_err_callback(int channel, void *data, int err) |
72 | { | 73 | { |
73 | pr_err("DMA error callback called\n"); | 74 | struct snd_pcm_substream *substream = data; |
75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
76 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | ||
77 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
78 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
79 | int ret; | ||
74 | 80 | ||
75 | pr_err("DMA timeout on channel %d -%s%s%s%s\n", | 81 | pr_err("DMA timeout on channel %d -%s%s%s%s\n", |
76 | channel, | 82 | channel, |
@@ -78,16 +84,26 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) | |||
78 | err & IMX_DMA_ERR_REQUEST ? " request" : "", | 84 | err & IMX_DMA_ERR_REQUEST ? " request" : "", |
79 | err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", | 85 | err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", |
80 | err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); | 86 | err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); |
87 | |||
88 | imx_dma_disable(iprtd->dma); | ||
89 | ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, | ||
90 | IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, | ||
91 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
92 | DMA_MODE_WRITE : DMA_MODE_READ); | ||
93 | if (!ret) | ||
94 | imx_dma_enable(iprtd->dma); | ||
81 | } | 95 | } |
82 | 96 | ||
83 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) | 97 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) |
84 | { | 98 | { |
85 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 99 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
86 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 100 | struct imx_pcm_dma_params *dma_params; |
87 | struct snd_pcm_runtime *runtime = substream->runtime; | 101 | struct snd_pcm_runtime *runtime = substream->runtime; |
88 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 102 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
89 | int ret; | 103 | int ret; |
90 | 104 | ||
105 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | ||
106 | |||
91 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); | 107 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); |
92 | if (iprtd->dma < 0) { | 108 | if (iprtd->dma < 0) { |
93 | pr_err("Failed to claim the audio DMA\n"); | 109 | pr_err("Failed to claim the audio DMA\n"); |
@@ -192,10 +208,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) | |||
192 | { | 208 | { |
193 | struct snd_pcm_runtime *runtime = substream->runtime; | 209 | struct snd_pcm_runtime *runtime = substream->runtime; |
194 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 210 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
195 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 211 | struct imx_pcm_dma_params *dma_params; |
196 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 212 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
197 | int err; | 213 | int err; |
198 | 214 | ||
215 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | ||
216 | |||
199 | iprtd->substream = substream; | 217 | iprtd->substream = substream; |
200 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; | 218 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; |
201 | iprtd->period_cnt = 0; | 219 | iprtd->period_cnt = 0; |