Commit 3a2ac12f authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/dma' into asoc-next

parents 7196be58 e4a899d9
...@@ -982,6 +982,7 @@ static void __init edma_chan_init(struct edma_cc *ecc, ...@@ -982,6 +982,7 @@ static void __init edma_chan_init(struct edma_cc *ecc,
#define EDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ #define EDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)) BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
static int edma_dma_device_slave_caps(struct dma_chan *dchan, static int edma_dma_device_slave_caps(struct dma_chan *dchan,
......
...@@ -299,6 +299,7 @@ enum dma_slave_buswidth { ...@@ -299,6 +299,7 @@ enum dma_slave_buswidth {
DMA_SLAVE_BUSWIDTH_UNDEFINED = 0, DMA_SLAVE_BUSWIDTH_UNDEFINED = 0,
DMA_SLAVE_BUSWIDTH_1_BYTE = 1, DMA_SLAVE_BUSWIDTH_1_BYTE = 1,
DMA_SLAVE_BUSWIDTH_2_BYTES = 2, DMA_SLAVE_BUSWIDTH_2_BYTES = 2,
DMA_SLAVE_BUSWIDTH_3_BYTES = 3,
DMA_SLAVE_BUSWIDTH_4_BYTES = 4, DMA_SLAVE_BUSWIDTH_4_BYTES = 4,
DMA_SLAVE_BUSWIDTH_8_BYTES = 8, DMA_SLAVE_BUSWIDTH_8_BYTES = 8,
}; };
......
...@@ -65,13 +65,15 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, ...@@ -65,13 +65,15 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
enum dma_slave_buswidth buswidth; enum dma_slave_buswidth buswidth;
int bits; int bits;
bits = snd_pcm_format_physical_width(params_format(params)); bits = params_physical_width(params);
if (bits < 8 || bits > 64) if (bits < 8 || bits > 64)
return -EINVAL; return -EINVAL;
else if (bits == 8) else if (bits == 8)
buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE; buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
else if (bits == 16) else if (bits == 16)
buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
else if (bits == 24)
buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES;
else if (bits <= 32) else if (bits <= 32)
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
else else
......
...@@ -119,7 +119,10 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea ...@@ -119,7 +119,10 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
struct snd_dmaengine_dai_dma_data *dma_data; struct snd_dmaengine_dai_dma_data *dma_data;
struct dma_slave_caps dma_caps; struct dma_slave_caps dma_caps;
struct snd_pcm_hardware hw; struct snd_pcm_hardware hw;
int ret; u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
int i, ret;
if (pcm->config && pcm->config->pcm_hardware) if (pcm->config && pcm->config->pcm_hardware)
return snd_soc_set_runtime_hwparams(substream, return snd_soc_set_runtime_hwparams(substream,
...@@ -146,6 +149,38 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea ...@@ -146,6 +149,38 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
hw.info |= SNDRV_PCM_INFO_BATCH; hw.info |= SNDRV_PCM_INFO_BATCH;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
addr_widths = dma_caps.dstn_addr_widths;
else
addr_widths = dma_caps.src_addr_widths;
}
/*
* 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); return snd_soc_set_runtime_hwparams(substream, &hw);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment