[alsa-devel] DMA buffer gets played only once

Markus Franke markus.franke at s2002.tu-chemnitz.de
Wed Sep 5 08:20:33 CEST 2007


Dear Alsa Developers/Users,

I am working on a SoC Alsa driver for the WM8973. Currently I am facing 
the problem that after playing once the whole preallocated DMA buffer 
the playback stops and Alsa returns with

---snip---
ALSA sound/core/pcm_native.c:1526: playback drain error (DMA or IRQ 
trouble?)
---snap---


As far as I understood the callflow is like this:

pcm_prepare() --> pcm_trigger(TRIGGER_START) --> 
snd_pcm_period_elapsed() from interrupt handler or DMA callback --> 
pcm_pointer() --> pcm_trigger(TRIGGER_STOP) --> pcm_prepare() --> .....

With each call of pcm_trigger(TRIGGER_START) I am transfering one period 
of sounddata. For some reason the playback stops once the DMA buffer (in 
my 8 example it holds 8 periods of data) is finished and the pointer 
should wrap around to the beginning through pcm_pointer() callback. I 
checked return values of pcm_pointer() and tried to trace it back 
through Alsa/SoC stack without success. It seems like that after the 8th 
period is transferred pcm_trigger(TRIGGER_STOP) isn't getting called. 
Instead of this I get a lot of calls to pcm_pointer() which result 
finally in the above mentioned Alsa error message. I checked 
pcm_pointer() return values but everything seems to be fine I think.

Below you can find some verbose printk's I added to the source code:

---snip---
vi1888-i2s: vi1888_i2s_startup()-->
vi1888-pcm: vi1888_pcm_open()-->
vi1888-i2s: vi1888_i2s_set_dai_fmt()-->
vi1888-i2s: vi1888_i2s_set_dai_sysclk()-->
vi1888-i2s: vi1888_i2s_hw_params()-->
vi1888-pcm: vi1888_pcm_hw_params()-->
hw_params: DMA for I2S PCM Stereo out initialized (dma_bytes=32768, 
period_size=4096)
vi1888-i2s: vi1888_i2s_set_dai_fmt()-->
vi1888-i2s: vi1888_i2s_set_dai_sysclk()-->
vi1888-pcm: vi1888_pcm_hw_params()-->
hw_params: DMA for I2S PCM Stereo out initialized (dma_bytes=32768, 
period_size=4096)
vi1888-pcm: vi1888_pcm_prepare()-->
vi1888-i2s: vi1888_i2s_prepare()-->
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_dma_userCallback()-->
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 1024
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_prepare()-->
vi1888-i2s: vi1888_i2s_prepare()-->
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_dma_userCallback()-->
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 2048
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_prepare()-->
vi1888-i2s: vi1888_i2s_prepare()-->
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_dma_userCallback()-->
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 3072
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_prepare()-->
vi1888-i2s: vi1888_i2s_prepare()-->
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_dma_userCallback()-->
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 4096
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_prepare()-->
vi1888-i2s: vi1888_i2s_prepare()-->
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_dma_userCallback()-->
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 5120
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_prepare()-->
vi1888-i2s: vi1888_i2s_prepare()-->
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_dma_userCallback()-->
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 6144
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_prepare()-->
vi1888-i2s: vi1888_i2s_prepare()-->
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_dma_userCallback()-->
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 7168
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_prepare()-->
vi1888-i2s: vi1888_i2s_prepare()-->
vi1888-pcm: vi1888_pcm_trigger()-->
vi1888-pcm: vi1888_pcm_dma_userCallback()-->
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 0
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 1024
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 2048
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 3072
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 4096
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 5120
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 6144
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 7168
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 0
vi1888-pcm: vi1888_pcm_pointer()-->
pcm_pointer returns 1024

.
.
.
.
.
.
.

ALSA sound/core/pcm_native.c:1526: playback drain error (DMA or IRQ 
trouble?)
---snap---

I get this output when trying to play a 16-bit stereo WAV file.

Thanks for any help on this,

Regards,
Markus Franke


More information about the Alsa-devel mailing list