Messages in this thread | | | Date | Wed, 05 Dec 2001 22:39:17 -0500 | From | Doug Ledford <> | Subject | Re: i810 audio patch |
| |
Nathan Bryant wrote:
> 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 >
Try this out: /* 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) { outb((inb(port+OFF_CIV)+1)&31, port+OFF_LVI); if(rec) { __start_adc(state); while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) barrier(); } else { __start_dac(state); while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) barrier(); } }
--
Doug Ledford <dledford@redhat.com> http://people.redhat.com/dledford Please check my web site for aic7xxx updates/answers before e-mailing me about problems
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |