On Tue, 11 Aug 2009 01:07:10 +0200 Janusz Krzysztofik <jkrzyszt@xxxxxxxxxxxx> wrote: > Enhance period index accuracy, particularly just before buffer rewind, by > making use of DMA interrupt status flags in addition to simply counting up > interrupts. > > Corrections since v1: > 1. Fix buggy DMA interrupt handling in case of multiple status flags set in > parallel. > 2. Enable OMAP_DMA_LAST_IRQ only for playback on OMAP1510. > > This patch applies on top of patch 2 from this series: > [RFC][PATCH 2/3] ASoC: OMAP: Make use of DMA channel self linking on OMAP1510 > > Created against linux-2.6.31-rc5. > > Tested on Amstrad Delta. > > Signed-off-by: Janusz Krzysztofik <jkrzyszt@xxxxxxxxxxxx> > > --- > --- linux-2.6.31-rc5/sound/soc/omap/omap-pcm.c.orig 2009-08-10 22:41:25.000000000 +0200 > +++ linux-2.6.31-rc5/sound/soc/omap/omap-pcm.c 2009-08-10 23:15:46.000000000 +0200 > @@ -68,13 +68,27 @@ static void omap_pcm_dma_irq(int ch, u16 > * that can be used by omap_pcm_pointer() instead. > */ > spin_lock_irqsave(&prtd->lock, flags); > + if ((stat == OMAP_DMA_LAST_IRQ) && > + (prtd->period_index == runtime->periods - 1)) { > + /* we are in sync, do nothing */ > + spin_unlock_irqrestore(&prtd->lock, flags); > + return; > + } > if (prtd->period_index >= 0) { > - if (++prtd->period_index == runtime->periods) { > + if (stat & OMAP_DMA_BLOCK_IRQ) { > + /* end of buffer reached, loop back */ > + prtd->period_index = 0; > + } else if (stat & OMAP_DMA_LAST_IRQ) { > + /* update the counter for the last period */ > + prtd->period_index = runtime->periods - 1; > + } else if (++prtd->period_index >= runtime->periods) { > + /* end of buffer missed? loop back */ > prtd->period_index = 0; > } > } > spin_unlock_irqrestore(&prtd->lock, flags); > - } > + } else if (stat == OMAP_DMA_LAST_IRQ) > + return; > Is this test needed? This interrupt is set only for playback on omap1510 so this looks null-op. > snd_pcm_period_elapsed(substream); > } > @@ -175,7 +189,12 @@ static int omap_pcm_prepare(struct snd_p > dma_params.frame_count = runtime->periods; > omap_set_dma_params(prtd->dma_ch, &dma_params); > > - omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); > + if ((cpu_is_omap1510()) && > + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) > + omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | > + OMAP_DMA_LAST_IRQ); Indent OMAP_DMA_LAST_IRQ with tab(s) and spaces to the same column than OMAP_DMA_FRAME_IRQ. Looks nicer then. Should the OMAP_DMA_BLOCK_IRQ to be set since it is handled in omap_pcm_dma_irq? -- Jarkko -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html