At Sun, 26 Apr 2009 12:45:32 -0400, Jon Smirl wrote:
On Sun, Apr 26, 2009 at 12:31 PM, Jaroslav Kysela perex@perex.cz wrote:
On Sun, 26 Apr 2009, Jon Smirl wrote:
On Sun, Apr 26, 2009 at 4:12 AM, Jaroslav Kysela perex@perex.cz wrote:
On Sat, 25 Apr 2009, Jon Smirl wrote:
This appears to be a bug in this code...
if (delta < 0) { delta += runtime->period_size * runtime->periods;
it was adding, buffer_size. But buffer_size is not correct when the periods don't evenly fit into the buffer
Could you show real values what you're getting here with your driver?
psc_dma_pcm_pointer pos 0 hw_ptr_interrupt 22052 new_hw_ptr 0
pos should be >2 here for buffer_size = 22050 and period_size = 5513.. Your driver code is broken - the routine must be called when period_size is processed - not before and .pointer callback must return correct value at this point..
So pos at interrupt time should be equal or slightly greater than:
5513, 11026, 16540, 22054 % 22050 = 4, 5517 etc..
pos is position from range 0 .. (buffer_size - 1) not from range 0 .. (periods * period_size).
So the DMA hardware needs to be able to wrap that last packet in the buffer? I will need to turn that into two DMA operations which will cause two interrupts, is that ok?
This code was originally written with the assumption that an integral number of periods would fit into the DMA buffer.
It's assured only when you set up the proper hw_params constraints. Namely, call snd_pcm_hw_constraint_integer() with SNDRV_PCM_HW_PARAM_PERIODS parameter.
Takashi