summaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-generic-dmaengine-pcm.c
diff options
context:
space:
mode:
authorMatthias Reichl <hias@horus.com>2016-04-27 15:26:51 +0200
committerMark Brown <broonie@kernel.org>2016-04-27 18:34:11 +0200
commit73fe01cfb3babff01748a9fbc95cc3ea2079cc7f (patch)
treef3f6b72b1fa9e2d0374f9417c9e97f1779d5af4a /sound/soc/soc-generic-dmaengine-pcm.c
parentLinux 4.6-rc1 (diff)
downloadlinux-73fe01cfb3babff01748a9fbc95cc3ea2079cc7f.tar.xz
linux-73fe01cfb3babff01748a9fbc95cc3ea2079cc7f.zip
ASoC: dmaengine_pcm: Add support for packed transfers
dmaengine_pcm currently only supports setups where FIFO reads/writes correspond to exactly one sample, eg 16-bit sample data is transferred via 16-bit FIFO accesses, 32-bit data via 32-bit accesses. This patch adds support for setups with fixed width FIFOs where multiple samples are packed into a larger word. For example setups with a 32-bit wide FIFO register that expect 16-bit sample transfers to be done with the left+right sample data packed into a 32-bit word. Support for packed transfers is controlled via the SND_DMAENGINE_PCM_DAI_FLAG_PACK flag in snd_dmaengine_dai_dma_data.flags If this flag is set dmaengine_pcm doesn't put any restriction on the supported formats and sets the DMA transfer width to undefined. This means control over the constraints is now transferred to the DAI driver and it's responsible to provide proper configuration and check for possible corner cases that aren't handled by the ALSA core. Signed-off-by: Matthias Reichl <hias@horus.com> Acked-by: Lars-Peter Clausen <lars@metafoo.de> Tested-by: Martin Sperl <kernel@martin.sperl.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/soc-generic-dmaengine-pcm.c')
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c57
1 files changed, 34 insertions, 23 deletions
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 6fd1906af387..6cef3977507a 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -163,31 +163,42 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
}
/*
- * Prepare formats mask for valid/allowed sample types. If the dma does
- * not have support for the given physical word size, it needs to be
- * masked out so user space can not use the format which produces
- * corrupted audio.
- * In case the dma driver does not implement the slave_caps the default
- * assumption is that it supports 1, 2 and 4 bytes widths.
+ * If SND_DMAENGINE_PCM_DAI_FLAG_PACK is set keep
+ * hw.formats set to 0, meaning no restrictions are in place.
+ * In this case it's the responsibility of the DAI driver to
+ * provide the supported format information.
*/
- for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
- int bits = snd_pcm_format_physical_width(i);
-
- /* Enable only samples with DMA supported physical widths */
- switch (bits) {
- case 8:
- case 16:
- case 24:
- case 32:
- case 64:
- if (addr_widths & (1 << (bits / 8)))
- hw.formats |= (1LL << i);
- break;
- default:
- /* Unsupported types */
- break;
+ if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK))
+ /*
+ * Prepare formats mask for valid/allowed sample types. If the
+ * dma does not have support for the given physical word size,
+ * it needs to be masked out so user space can not use the
+ * format which produces corrupted audio.
+ * In case the dma driver does not implement the slave_caps the
+ * default assumption is that it supports 1, 2 and 4 bytes
+ * widths.
+ */
+ for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+ int bits = snd_pcm_format_physical_width(i);
+
+ /*
+ * Enable only samples with DMA supported physical
+ * widths
+ */
+ switch (bits) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ case 64:
+ if (addr_widths & (1 << (bits / 8)))
+ hw.formats |= (1LL << i);
+ break;
+ default:
+ /* Unsupported types */
+ break;
+ }
}
- }
return snd_soc_set_runtime_hwparams(substream, &hw);
}