diff options
-rw-r--r-- | include/sound/dmaengine_pcm.h | 6 | ||||
-rw-r--r-- | sound/soc/soc-generic-dmaengine-pcm.c | 18 |
2 files changed, 22 insertions, 2 deletions
diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 4ef986cab182..eb73a3a39ec2 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h | |||
@@ -114,6 +114,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data( | |||
114 | * @compat_filter_fn: Will be used as the filter function when requesting a | 114 | * @compat_filter_fn: Will be used as the filter function when requesting a |
115 | * channel for platforms which do not use devicetree. The filter parameter | 115 | * channel for platforms which do not use devicetree. The filter parameter |
116 | * will be the DAI's DMA data. | 116 | * will be the DAI's DMA data. |
117 | * @dma_dev: If set, request DMA channel on this device rather than the DAI | ||
118 | * device. | ||
119 | * @chan_names: If set, these custom DMA channel names will be requested at | ||
120 | * registration time. | ||
117 | * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM. | 121 | * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM. |
118 | * @prealloc_buffer_size: Size of the preallocated audio buffer. | 122 | * @prealloc_buffer_size: Size of the preallocated audio buffer. |
119 | * | 123 | * |
@@ -130,6 +134,8 @@ struct snd_dmaengine_pcm_config { | |||
130 | struct snd_soc_pcm_runtime *rtd, | 134 | struct snd_soc_pcm_runtime *rtd, |
131 | struct snd_pcm_substream *substream); | 135 | struct snd_pcm_substream *substream); |
132 | dma_filter_fn compat_filter_fn; | 136 | dma_filter_fn compat_filter_fn; |
137 | struct device *dma_dev; | ||
138 | const char *chan_names[SNDRV_PCM_STREAM_LAST + 1]; | ||
133 | 139 | ||
134 | const struct snd_pcm_hardware *pcm_hardware; | 140 | const struct snd_pcm_hardware *pcm_hardware; |
135 | unsigned int prealloc_buffer_size; | 141 | unsigned int prealloc_buffer_size; |
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 1cb3494cf278..5b70c556fba3 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c | |||
@@ -288,7 +288,7 @@ static const char * const dmaengine_pcm_dma_channel_names[] = { | |||
288 | }; | 288 | }; |
289 | 289 | ||
290 | static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, | 290 | static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, |
291 | struct device *dev) | 291 | struct device *dev, const struct snd_dmaengine_pcm_config *config) |
292 | { | 292 | { |
293 | unsigned int i; | 293 | unsigned int i; |
294 | const char *name; | 294 | const char *name; |
@@ -298,12 +298,26 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, | |||
298 | !dev->of_node) | 298 | !dev->of_node) |
299 | return; | 299 | return; |
300 | 300 | ||
301 | if (config->dma_dev) { | ||
302 | /* | ||
303 | * If this warning is seen, it probably means that your Linux | ||
304 | * device structure does not match your HW device structure. | ||
305 | * It would be best to refactor the Linux device structure to | ||
306 | * correctly match the HW structure. | ||
307 | */ | ||
308 | dev_warn(dev, "DMA channels sourced from device %s", | ||
309 | dev_name(config->dma_dev)); | ||
310 | dev = config->dma_dev; | ||
311 | } | ||
312 | |||
301 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; | 313 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; |
302 | i++) { | 314 | i++) { |
303 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) | 315 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) |
304 | name = "rx-tx"; | 316 | name = "rx-tx"; |
305 | else | 317 | else |
306 | name = dmaengine_pcm_dma_channel_names[i]; | 318 | name = dmaengine_pcm_dma_channel_names[i]; |
319 | if (config->chan_names[i]) | ||
320 | name = config->chan_names[i]; | ||
307 | pcm->chan[i] = dma_request_slave_channel(dev, name); | 321 | pcm->chan[i] = dma_request_slave_channel(dev, name); |
308 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) | 322 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) |
309 | break; | 323 | break; |
@@ -346,7 +360,7 @@ int snd_dmaengine_pcm_register(struct device *dev, | |||
346 | pcm->config = config; | 360 | pcm->config = config; |
347 | pcm->flags = flags; | 361 | pcm->flags = flags; |
348 | 362 | ||
349 | dmaengine_pcm_request_chan_of(pcm, dev); | 363 | dmaengine_pcm_request_chan_of(pcm, dev, config); |
350 | 364 | ||
351 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) | 365 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) |
352 | ret = snd_soc_add_platform(dev, &pcm->platform, | 366 | ret = snd_soc_add_platform(dev, &pcm->platform, |