[alsa-devel] [PATCH 1/3] ASoC: davinci-pcm: latch EDMA errors
Ben Gardiner
bengardiner at nanometrics.ca
Fri Sep 30 23:23:01 CEST 2011
The davinci-pcm driver currently ignores all EDMA completion callbacks that
could be indicating an error.
Latch any edma error-status callbacks and report them as SNDDRV_PCM_POS_XRUN
like is done in fsl_dma.c.
Signed-off-by: Ben Gardiner <bengardiner at nanometrics.ca>
---
In testing when an error occured early-on in playback the stream did not halt,
but several underruns were reported until eventually the stream halted.
Is there a better way to report HW errors up the stack?
---
sound/soc/davinci/davinci-pcm.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index d5fe08c..41a3b5b 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -155,6 +155,7 @@ struct davinci_runtime_data {
int ram_link2;
struct edmacc_param asp_params;
struct edmacc_param ram_params;
+ unsigned error:1;
};
static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream)
@@ -245,8 +246,12 @@ static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
print_buf_info(prtd->ram_channel, "i ram_channel");
pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status);
- if (unlikely(ch_status != DMA_COMPLETE))
+ if (unlikely(ch_status != DMA_COMPLETE)) {
+ spin_lock(&prtd->lock);
+ prtd->error = 1;
+ spin_unlock(&prtd->lock);
return;
+ }
if (snd_pcm_running(substream)) {
spin_lock(&prtd->lock);
@@ -635,7 +640,7 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct davinci_runtime_data *prtd = runtime->private_data;
unsigned int offset;
- int asp_count;
+ int asp_count, error;
unsigned int period_size = snd_pcm_lib_period_bytes(substream);
/*
@@ -647,8 +652,12 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)
*/
spin_lock(&prtd->lock);
asp_count = prtd->period - 2;
+ error = prtd->error;
spin_unlock(&prtd->lock);
+ if (error)
+ return SNDRV_PCM_POS_XRUN;
+
if (asp_count < 0)
asp_count += runtime->periods;
asp_count *= period_size;
--
1.7.4.1
More information about the Alsa-devel
mailing list