aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2013-12-03 16:26:34 -0500
committerMark Brown <broonie@linaro.org>2013-12-09 13:45:01 -0500
commit194c7dea00c68c1b1f8ff26304fa937a006f66dd (patch)
tree5490b3298d3db2ae76ba2dbdc0ca8c7ffaefd3f4 /sound
parenta715d01e9c8177634bd7c22e67c9088282744569 (diff)
ASoC: dmaengine: add custom DMA config to snd_dmaengine_pcm_config
Add fields to struct snd_dmaengine_pcm_config to allow custom: - DMA channel names. This is useful when the default "tx" and "rx" channel names don't apply, for example if a HW module supports multiple channels, each having different DMA channel names. This is the case with the FIFOs in Tegra's AHUB. This new facility can replace SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME. - DMA device This allows requesting DMA channels for a device other than the device which is registering the "PCM" driver. This is quite unusual, but is currently useful on Tegra. In much HW, and in Tegra20, each DAI HW module contains its own FIFOs which DMA writes to. However, in Tegra30, the DMA FIFOs were split out AHUB HW module, which then routes the data through a cross-bar, and into the DAI HW modules. However, the current ASoC driver structure does not expose this detail, and acts as if the FIFOs are still part of the DAI HW modules. Consequently, the "PCM" driver is registered with the DAI HW module, yet the DMA channels must be looked up in the AHUB HW module's device tree node. This new config field allows that to happen. Eventually, the Tegra drivers will be reworked to fully expose the AHUB, and this config field can be removed. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c18
1 files changed, 16 insertions, 2 deletions
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
290static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, 290static 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,