aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 4e2bed89a4a4..560a7787d8a7 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -144,6 +144,8 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
144 if (ret == 0) { 144 if (ret == 0) {
145 if (dma_caps.cmd_pause) 145 if (dma_caps.cmd_pause)
146 hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; 146 hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
147 if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
148 hw.info |= SNDRV_PCM_INFO_BATCH;
147 } 149 }
148 150
149 return snd_soc_set_runtime_hwparams(substream, &hw); 151 return snd_soc_set_runtime_hwparams(substream, &hw);
@@ -187,6 +189,21 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel(
187 dma_data->filter_data); 189 dma_data->filter_data);
188} 190}
189 191
192static bool dmaengine_pcm_can_report_residue(struct dma_chan *chan)
193{
194 struct dma_slave_caps dma_caps;
195 int ret;
196
197 ret = dma_get_slave_caps(chan, &dma_caps);
198 if (ret != 0)
199 return true;
200
201 if (dma_caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR)
202 return false;
203
204 return true;
205}
206
190static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) 207static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
191{ 208{
192 struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); 209 struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
@@ -239,6 +256,16 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
239 max_buffer_size); 256 max_buffer_size);
240 if (ret) 257 if (ret)
241 goto err_free; 258 goto err_free;
259
260 /*
261 * This will only return false if we know for sure that at least
262 * one channel does not support residue reporting. If the DMA
263 * driver does not implement the slave_caps API we rely having
264 * the NO_RESIDUE flag set manually in case residue reporting is
265 * not supported.
266 */
267 if (!dmaengine_pcm_can_report_residue(pcm->chan[i]))
268 pcm->flags |= SND_DMAENGINE_PCM_FLAG_NO_RESIDUE;
242 } 269 }
243 270
244 return 0; 271 return 0;