aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-02-22 04:49:06 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-22 08:21:49 -0500
commit4564d10f3066a1abf5053936684e2c8495163def (patch)
tree622912c7aeb3b2aa1a8264954a355c3ea833ae9f /sound
parent91a38540f504cdde7cb62668f7a6d52e3bd0178b (diff)
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>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c78
1 files changed, 32 insertions, 46 deletions
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index ec1394415526..f974e61fa68c 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)
65 return true; 65 return true;
66} 66}
67 67
68static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, 68static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
69 struct snd_pcm_hw_params *params)
70{ 69{
71 struct snd_soc_pcm_runtime *rtd = substream->private_data; 70 struct snd_soc_pcm_runtime *rtd = substream->private_data;
72 struct imx_pcm_dma_params *dma_params; 71 struct imx_pcm_dma_params *dma_params;
73 struct snd_pcm_runtime *runtime = substream->runtime; 72 struct snd_pcm_runtime *runtime = substream->runtime;
74 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 73 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
75 struct dma_slave_config slave_config;
76 dma_cap_mask_t mask; 74 dma_cap_mask_t mask;
77 enum dma_slave_buswidth buswidth;
78 int ret;
79 75
80 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 76 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
81 77
@@ -84,13 +80,29 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
84 iprtd->dma_data.dma_request = dma_params->dma; 80 iprtd->dma_data.dma_request = dma_params->dma;
85 81
86 /* Try to grab a DMA channel */ 82 /* Try to grab a DMA channel */
87 if (!iprtd->dma_chan) { 83 dma_cap_zero(mask);
88 dma_cap_zero(mask); 84 dma_cap_set(DMA_SLAVE, mask);
89 dma_cap_set(DMA_SLAVE, mask); 85 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
90 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); 86 if (!iprtd->dma_chan)
91 if (!iprtd->dma_chan) 87 return -EINVAL;
92 return -EINVAL; 88
93 } 89 return 0;
90}
91
92static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
93 struct snd_pcm_hw_params *params)
94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct snd_pcm_runtime *runtime = substream->runtime;
97 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
98 struct dma_chan *chan = iprtd->dma_chan;
99 struct imx_pcm_dma_params *dma_params;
100 struct dma_slave_config slave_config;
101 enum dma_slave_buswidth buswidth;
102 unsigned long dma_addr;
103 int ret;
104
105 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
94 106
95 switch (params_format(params)) { 107 switch (params_format(params)) {
96 case SNDRV_PCM_FORMAT_S16_LE: 108 case SNDRV_PCM_FORMAT_S16_LE:
@@ -116,29 +128,10 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
116 slave_config.src_maxburst = dma_params->burstsize; 128 slave_config.src_maxburst = dma_params->burstsize;
117 } 129 }
118 130
119 ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); 131 ret = dmaengine_slave_config(chan, &slave_config);
120 if (ret) 132 if (ret)
121 return ret; 133 return ret;
122 134
123 return 0;
124}
125
126static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
127 struct snd_pcm_hw_params *params)
128{
129 struct snd_soc_pcm_runtime *rtd = substream->private_data;
130 struct snd_pcm_runtime *runtime = substream->runtime;
131 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
132 unsigned long dma_addr;
133 struct dma_chan *chan;
134 struct imx_pcm_dma_params *dma_params;
135 int ret;
136
137 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
138 ret = imx_ssi_dma_alloc(substream, params);
139 if (ret)
140 return ret;
141 chan = iprtd->dma_chan;
142 135
143 iprtd->periods = params_periods(params); 136 iprtd->periods = params_periods(params);
144 iprtd->period_bytes = params_period_bytes(params); 137 iprtd->period_bytes = params_period_bytes(params);
@@ -164,19 +157,6 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
164 return 0; 157 return 0;
165} 158}
166 159
167static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
168{
169 struct snd_pcm_runtime *runtime = substream->runtime;
170 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
171
172 if (iprtd->dma_chan) {
173 dma_release_channel(iprtd->dma_chan);
174 iprtd->dma_chan = NULL;
175 }
176
177 return 0;
178}
179
180static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 160static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
181{ 161{
182 struct snd_pcm_runtime *runtime = substream->runtime; 162 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -251,6 +231,12 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
251 return ret; 231 return ret;
252 } 232 }
253 233
234 ret = imx_ssi_dma_alloc(substream);
235 if (ret < 0) {
236 kfree(iprtd);
237 return ret;
238 }
239
254 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); 240 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
255 241
256 return 0; 242 return 0;
@@ -261,6 +247,7 @@ static int snd_imx_close(struct snd_pcm_substream *substream)
261 struct snd_pcm_runtime *runtime = substream->runtime; 247 struct snd_pcm_runtime *runtime = substream->runtime;
262 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 248 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
263 249
250 dma_release_channel(iprtd->dma_chan);
264 kfree(iprtd); 251 kfree(iprtd);
265 252
266 return 0; 253 return 0;
@@ -271,7 +258,6 @@ static struct snd_pcm_ops imx_pcm_ops = {
271 .close = snd_imx_close, 258 .close = snd_imx_close,
272 .ioctl = snd_pcm_lib_ioctl, 259 .ioctl = snd_pcm_lib_ioctl,
273 .hw_params = snd_imx_pcm_hw_params, 260 .hw_params = snd_imx_pcm_hw_params,
274 .hw_free = snd_imx_pcm_hw_free,
275 .trigger = snd_imx_pcm_trigger, 261 .trigger = snd_imx_pcm_trigger,
276 .pointer = snd_imx_pcm_pointer, 262 .pointer = snd_imx_pcm_pointer,
277 .mmap = snd_imx_pcm_mmap, 263 .mmap = snd_imx_pcm_mmap,