ALSA: au88x0 - Modify pointer callback to give accurate playback position
authorRaymond Yau <superquad.vortex2@gmail.com>
Sun, 13 Feb 2011 23:33:24 +0000 (07:33 +0800)
committerTakashi Iwai <tiwai@suse.de>
Mon, 14 Feb 2011 16:13:20 +0000 (17:13 +0100)
Signed-off-by: Raymond Yau <superquad.vortex2@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/au88x0/au88x0_core.c

index 23f49f356e0f0375a784de99c05b832c2bc66ad4..16c0bdfbb16481148acfeb4845cbfcc020e5b6ab 100644 (file)
@@ -1252,11 +1252,19 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
 static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
 {
        stream_t *dma = &vortex->dma_adb[adbdma];
-       int temp;
+       int temp, page, delta;
 
        temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
-       temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
-       return temp;
+       page = (temp & ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
+       if (dma->nr_periods >= 4)
+               delta = (page - dma->period_real) & 3;
+       else {
+               delta = (page - dma->period_real);
+               if (delta < 0)
+                       delta += dma->nr_periods;
+       }
+       return (dma->period_virt + delta) * dma->period_bytes
+               + (temp & (dma->period_bytes - 1));
 }
 
 static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)