diff options
-rw-r--r-- | sound/soc/soc-generic-dmaengine-pcm.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 5bace124ef43..6307f85e871b 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c | |||
@@ -119,7 +119,10 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea | |||
119 | struct snd_dmaengine_dai_dma_data *dma_data; | 119 | struct snd_dmaengine_dai_dma_data *dma_data; |
120 | struct dma_slave_caps dma_caps; | 120 | struct dma_slave_caps dma_caps; |
121 | struct snd_pcm_hardware hw; | 121 | struct snd_pcm_hardware hw; |
122 | int ret; | 122 | u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
123 | BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | | ||
124 | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); | ||
125 | int i, ret; | ||
123 | 126 | ||
124 | if (pcm->config && pcm->config->pcm_hardware) | 127 | if (pcm->config && pcm->config->pcm_hardware) |
125 | return snd_soc_set_runtime_hwparams(substream, | 128 | return snd_soc_set_runtime_hwparams(substream, |
@@ -146,6 +149,38 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea | |||
146 | hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; | 149 | hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; |
147 | if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) | 150 | if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) |
148 | hw.info |= SNDRV_PCM_INFO_BATCH; | 151 | hw.info |= SNDRV_PCM_INFO_BATCH; |
152 | |||
153 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
154 | addr_widths = dma_caps.dstn_addr_widths; | ||
155 | else | ||
156 | addr_widths = dma_caps.src_addr_widths; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Prepare formats mask for valid/allowed sample types. If the dma does | ||
161 | * not have support for the given physical word size, it needs to be | ||
162 | * masked out so user space can not use the format which produces | ||
163 | * corrupted audio. | ||
164 | * In case the dma driver does not implement the slave_caps the default | ||
165 | * assumption is that it supports 1, 2 and 4 bytes widths. | ||
166 | */ | ||
167 | for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { | ||
168 | int bits = snd_pcm_format_physical_width(i); | ||
169 | |||
170 | /* Enable only samples with DMA supported physical widths */ | ||
171 | switch (bits) { | ||
172 | case 8: | ||
173 | case 16: | ||
174 | case 24: | ||
175 | case 32: | ||
176 | case 64: | ||
177 | if (addr_widths & (1 << (bits / 8))) | ||
178 | hw.formats |= (1LL << i); | ||
179 | break; | ||
180 | default: | ||
181 | /* Unsupported types */ | ||
182 | break; | ||
183 | } | ||
149 | } | 184 | } |
150 | 185 | ||
151 | return snd_soc_set_runtime_hwparams(substream, &hw); | 186 | return snd_soc_set_runtime_hwparams(substream, &hw); |