aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dmaengine-pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-dmaengine-pcm.c')
-rw-r--r--sound/soc/soc-dmaengine-pcm.c72
1 files changed, 49 insertions, 23 deletions
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)
254} 254}
255EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); 255EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer);
256 256
257static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd, 257static struct dma_chan *dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
258 dma_filter_fn filter_fn, void *filter_data) 258 void *filter_data)
259{ 259{
260 dma_cap_mask_t mask; 260 dma_cap_mask_t mask;
261 261
262 dma_cap_zero(mask); 262 dma_cap_zero(mask);
263 dma_cap_set(DMA_SLAVE, mask); 263 dma_cap_set(DMA_SLAVE, mask);
264 dma_cap_set(DMA_CYCLIC, mask); 264 dma_cap_set(DMA_CYCLIC, mask);
265 prtd->dma_chan = dma_request_channel(mask, filter_fn, filter_data);
266
267 if (!prtd->dma_chan)
268 return -ENXIO;
269 265
270 return 0; 266 return dma_request_channel(mask, filter_fn, filter_data);
271} 267}
272 268
273/** 269/**
274 * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream 270 * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream
275 * @substream: PCM substream 271 * @substream: PCM substream
276 * @filter_fn: Filter function used to request the DMA channel 272 * @chan: DMA channel to use for data transfers
277 * @filter_data: Data passed to the DMA filter function
278 * 273 *
279 * Returns 0 on success, a negative error code otherwise. 274 * Returns 0 on success, a negative error code otherwise.
280 * 275 *
281 * This function will request a DMA channel using the passed filter function and 276 * The function should usually be called from the pcm open callback. Note that
282 * data. The function should usually be called from the pcm open callback. 277 * this function will use private_data field of the substream's runtime. So it
283 * 278 * is not availabe to your pcm driver implementation.
284 * Note that this function will use private_data field of the substream's
285 * runtime. So it is not availabe to your pcm driver implementation. If you need
286 * to keep additional data attached to a substream use
287 * snd_dmaengine_pcm_{set,get}_data.
288 */ 279 */
289int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, 280int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
290 dma_filter_fn filter_fn, void *filter_data) 281 struct dma_chan *chan)
291{ 282{
292 struct dmaengine_pcm_runtime_data *prtd; 283 struct dmaengine_pcm_runtime_data *prtd;
293 int ret; 284 int ret;
294 285
286 if (!chan)
287 return -ENXIO;
288
295 ret = snd_pcm_hw_constraint_integer(substream->runtime, 289 ret = snd_pcm_hw_constraint_integer(substream->runtime,
296 SNDRV_PCM_HW_PARAM_PERIODS); 290 SNDRV_PCM_HW_PARAM_PERIODS);
297 if (ret < 0) 291 if (ret < 0)
@@ -301,11 +295,7 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
301 if (!prtd) 295 if (!prtd)
302 return -ENOMEM; 296 return -ENOMEM;
303 297
304 ret = dmaengine_pcm_request_channel(prtd, filter_fn, filter_data); 298 prtd->dma_chan = chan;
305 if (ret < 0) {
306 kfree(prtd);
307 return ret;
308 }
309 299
310 substream->runtime->private_data = prtd; 300 substream->runtime->private_data = prtd;
311 301
@@ -314,6 +304,27 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
314EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open); 304EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open);
315 305
316/** 306/**
307 * snd_dmaengine_pcm_open_request_chan - Open a dmaengine based PCM substream and request channel
308 * @substream: PCM substream
309 * @filter_fn: Filter function used to request the DMA channel
310 * @filter_data: Data passed to the DMA filter function
311 *
312 * Returns 0 on success, a negative error code otherwise.
313 *
314 * This function will request a DMA channel using the passed filter function and
315 * data. The function should usually be called from the pcm open callback. Note
316 * that this function will use private_data field of the substream's runtime. So
317 * it is not availabe to your pcm driver implementation.
318 */
319int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
320 dma_filter_fn filter_fn, void *filter_data)
321{
322 return snd_dmaengine_pcm_open(substream,
323 dmaengine_pcm_request_channel(filter_fn, filter_data));
324}
325EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan);
326
327/**
317 * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream 328 * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream
318 * @substream: PCM substream 329 * @substream: PCM substream
319 */ 330 */
@@ -321,11 +332,26 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
321{ 332{
322 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); 333 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
323 334
324 dma_release_channel(prtd->dma_chan);
325 kfree(prtd); 335 kfree(prtd);
326 336
327 return 0; 337 return 0;
328} 338}
329EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); 339EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close);
330 340
341/**
342 * snd_dmaengine_pcm_release_chan_close - Close a dmaengine based PCM substream and release channel
343 * @substream: PCM substream
344 *
345 * Releases the DMA channel associated with the PCM substream.
346 */
347int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream)
348{
349 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
350
351 dma_release_channel(prtd->dma_chan);
352
353 return snd_dmaengine_pcm_close(substream);
354}
355EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan);
356
331MODULE_LICENSE("GPL"); 357MODULE_LICENSE("GPL");