Re: i810 audio patch

Nathan Bryant
2001-12-06T02:55:00Z

as evidenced by,

/* if we are currently stopped, then our CIV is actually set to our
* *last* sg segment and we are ready to wrap to the next. However,
* if we set our LVI to the last sg segment, then it won't wrap to
* the next sg segment, it won't even get a start. So, instead,
when
* we are stopped, we set both the LVI value and also we increment
* the CIV value to the next sg segment to be played so that when
* we call start_{dac,adc}, things will operate properly
*/
if (!dmabuf->enable) {
#ifdef DEBUG_MMAP
printk("fnord? %d\n", inb(port+OFF_CIV));
#endif
/* maybe we have to increment LVI to make room before
incrementing CIV,
(databook says CELV isn't cleared until new val written
to LVI.)
we'll set LVI where we really want it down below. */
//outb((inb(port+OFF_LVI)+1)&31, port+OFF_LVI);
newciv = (inb(port+OFF_CIV)+1)&31;
outb(newciv, port+OFF_CIV);
for (x = 0; inb(port+OFF_CIV) != newciv && x< 5000000; x++);
if (x==5000000) printk("foo! civ != %d\n", newciv);
}

and

Dec 5 21:34:32 lasn-001 kernel: foo! civ != 1

CIV doesn't seem to respond to writes on my chipset, at least not in
this situation. you'll note that nowhere in the driver are we
initializing CIV to anything other than 0 anyway.

two alternatives I can think of:

first fix:
set LVI to desired value minus one SG
start_dac (which should have side effect of incrementing CIV by one)
increment LVI to desired value

2nd fix:
back off and perform DMA reset.

3rd fix (really fix 1a ;)
just don't allow use of the last SG when restarting