forked from Minki/linux
ASoC: generic-dmaengine-pcm: Check DMA residue granularity
The dmaengine framework now exposes the granularity with which it is able to report the transfer residue for a certain DMA channel. Check the granularity in the generic dmaengine PCM driver and a) Set the SNDRV_PCM_INFO_BATCH if the granularity is per period or worse. b) Fallback to the (race condition prone) period counting if the driver does not support any residue reporting. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
93b943edfc
commit
478028e088
@ -144,6 +144,8 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
|
||||
if (ret == 0) {
|
||||
if (dma_caps.cmd_pause)
|
||||
hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
|
||||
if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
|
||||
hw.info |= SNDRV_PCM_INFO_BATCH;
|
||||
}
|
||||
|
||||
return snd_soc_set_runtime_hwparams(substream, &hw);
|
||||
@ -187,6 +189,21 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel(
|
||||
dma_data->filter_data);
|
||||
}
|
||||
|
||||
static bool dmaengine_pcm_can_report_residue(struct dma_chan *chan)
|
||||
{
|
||||
struct dma_slave_caps dma_caps;
|
||||
int ret;
|
||||
|
||||
ret = dma_get_slave_caps(chan, &dma_caps);
|
||||
if (ret != 0)
|
||||
return true;
|
||||
|
||||
if (dma_caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
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)
|
||||
max_buffer_size);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
/*
|
||||
* This will only return false if we know for sure that at least
|
||||
* one channel does not support residue reporting. If the DMA
|
||||
* driver does not implement the slave_caps API we rely having
|
||||
* the NO_RESIDUE flag set manually in case residue reporting is
|
||||
* not supported.
|
||||
*/
|
||||
if (!dmaengine_pcm_can_report_residue(pcm->chan[i]))
|
||||
pcm->flags |= SND_DMAENGINE_PCM_FLAG_NO_RESIDUE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user