diff options
author | Jiada Wang <jiada_wang@mentor.com> | 2019-10-22 20:55:18 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-10-23 18:44:53 +0200 |
commit | d4d9360bf702890b5d3b1b62d8619a2690dd3278 (patch) | |
tree | a34bd92ab6e2e797fbe1452c0e8ebb72dd711148 /sound/soc/sh | |
parent | ASoC: soc-core: add for_each_rtd_components() and replace (diff) | |
download | linux-d4d9360bf702890b5d3b1b62d8619a2690dd3278.tar.xz linux-d4d9360bf702890b5d3b1b62d8619a2690dd3278.zip |
ASoC: rsnd: dma: set bus width to data width for monaural data
According to R-Car3 HW manual 40.3.3 (Data Format on Audio Local Bus),
in case of monaural data writing or reading through Audio-DMAC,
it's always in Left Justified format, so both src and dst
DMA Bus width should be equal to physical data width.
Therefore set src and dst's DMA bus width to:
- [monaural case] data width
- [non-monaural case] 32bits (as prior applying the patch)
Cc: Andrew Gabbasov <andrew_gabbasov@mentor.com>
Cc: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Link: https://lore.kernel.org/r/20191022185518.12838-1-erosca@de.adit-jv.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sh')
-rw-r--r-- | sound/soc/sh/rcar/dma.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 0324a5c39619..bcb6d5960661 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -165,14 +165,40 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod, struct device *dev = rsnd_priv_to_dev(priv); struct dma_async_tx_descriptor *desc; struct dma_slave_config cfg = {}; + enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; int is_play = rsnd_io_is_play(io); int ret; + /* + * in case of monaural data writing or reading through Audio-DMAC + * data is always in Left Justified format, so both src and dst + * DMA Bus width need to be set equal to physical data width. + */ + if (rsnd_runtime_channel_original(io) == 1) { + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + int bits = snd_pcm_format_physical_width(runtime->format); + + switch (bits) { + case 8: + buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE; + break; + case 16: + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; + break; + case 32: + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; + break; + default: + dev_err(dev, "invalid format width %d\n", bits); + return -EINVAL; + } + } + cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; cfg.src_addr = dma->src_addr; cfg.dst_addr = dma->dst_addr; - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.src_addr_width = buswidth; + cfg.dst_addr_width = buswidth; dev_dbg(dev, "%s %pad -> %pad\n", rsnd_mod_name(mod), |