this patch makes ALSA treat the hammerfall the exact same way that ASIO does, which makes sense to do given RME's claims about the card.
the hw pointer is reduced to essentially a 1 bit value - its either at the start of the first period or at the start of the second. there are no values between these two locations, as befits "ASIO poured in hardware". AFAIK, no other solution will work until or unless RME corrects their h/w design; even then, it wouldn't work correctly on older hammerfalls. as i've noted several times, neither abramo's code nor my own has ever worked correctly; this new code is simpler and will work always. the only possible criticism is that it prevents using the card with the RTC as the poll timer - fair point, buts that because the h/w hasn't been designed to be used like that, so denying that chance is in keeping with ALSA philosophy, IMHO. There is one additional patch in here that displays the value of the control register in /proc/asound/foo/rme9652. --p Index: card-rme9652.c =================================================================== RCS file: /cvsroot/alsa/alsa-driver/cards/card-rme9652.c,v retrieving revision 1.126 diff -c -u -r1.126 card-rme9652.c --- card-rme9652.c 2001/06/24 23:12:43 1.126 +++ card-rme9652.c 2001/11/16 18:32:38 @@ -213,10 +213,6 @@ char *card_name; /* hammerfall or hammerfall light names */ - size_t hw_offsetmask; /* &-with status register to get real hw_offset */ - size_t prev_hw_offset; /* previous hw offset */ - size_t max_jitter; /* maximum jitter in frames for - hw pointer */ size_t period_bytes; /* guess what this is */ unsigned char ds_channels; @@ -346,54 +342,14 @@ i = rme9652->control_register & RME9652_latency; rme9652->period_bytes = 1 << ((rme9652_decode_latency(i) + 8)); - rme9652->hw_offsetmask = - (rme9652->period_bytes * 2 - 1) & RME9652_buf_pos; - rme9652->max_jitter = 16 + (rme9652->period_bytes <= 1024 ? 32 : 64); } static inline snd_pcm_uframes_t rme9652_hw_pointer(rme9652_t *rme9652) { - int status; - int offset, frag; - snd_pcm_uframes_t period_size = rme9652->period_bytes / 4; - snd_pcm_sframes_t delta; - - status = rme9652_read(rme9652, RME9652_status_register); - offset = status & RME9652_buf_pos; - - /* The hardware may give a backward movement for up to 80 frames - Martin Kirst <[EMAIL PROTECTED]> knows the details. - */ - - delta = rme9652->prev_hw_offset - offset; - delta &= 0xffff; - if (delta <= rme9652->max_jitter * 4) - offset = rme9652->prev_hw_offset; - else - rme9652->prev_hw_offset = offset; - offset &= rme9652->hw_offsetmask; - offset /= 4; - frag = status & RME9652_buffer_id; - - if (offset < period_size) { - if (offset > rme9652->max_jitter) { - if (frag) - printk("Unexpected hw_pointer position (bufid == 0): status: %x offset: %d\n", status, offset); - } else if (!frag) - return 0; - offset -= rme9652->max_jitter; - if (offset < 0) - offset += period_size * 2; - } else { - if (offset > period_size + rme9652->max_jitter) { - if (!frag) - printk("Unexpected hw_pointer position (bufid == 1): status: %x offset: %d\n", status, offset); - } else if (frag) - return period_size; - offset -= rme9652->max_jitter; - } - - return offset; + if (rme9652_read(rme9652, RME9652_status_register) & RME9652_buffer_id) + return rme9652->period_bytes/4; + else + return 0; } static inline void rme9652_reset_hw_pointer(rme9652_t *rme9652) @@ -410,7 +366,6 @@ rme9652_write(rme9652, i * 4, 0); udelay(10); } - rme9652->prev_hw_offset = 0; } static inline void rme9652_start(rme9652_t *s) @@ -1617,6 +1572,7 @@ rme9652->capture_buffer, rme9652->playback_buffer); snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", rme9652->irq, rme9652->port, rme9652->iobase); + snd_iprintf(buffer, "Control register: %x\n", rme9652->control_register); snd_iprintf(buffer, "\n"); _______________________________________________ Alsa-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-devel