diff options
| -rw-r--r-- | sound/soc/soc-generic-dmaengine-pcm.c | 27 |
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 | ||
| 192 | static 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 | |||
| 190 | static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) | 207 | static 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; |
