Subject: kern/16373: auich outputs data too fast
To: None <gnats-bugs@gnats.netbsd.org>
From: Johan Danielsson <joda@pdc.kth.se>
List: netbsd-bugs
Date: 04/16/2002 22:58:29
>Number:         16373
>Category:       kern
>Synopsis:       auich outputs data too fast
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 16 13:59:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Johan Danielsson
>Release:        NetBSD 1.5ZC
>Organization:
>Environment:
	<The following information is extracted from your kernel. Please>
	<append output of "ldd", "ident" where relevant (multiple lines).>
System: NetBSD shoal.pdc.kth.se 1.5ZC NetBSD 1.5ZC (SHOAL) #19: Tue Apr 16 22:31:53 CEST 2002     joda@shoal.pdc.kth.se:/usr/misc/src/netbsd/src/sys/arch/i386/compile/SHOAL i386
Architecture: i386
Machine: i386
>Description:

The auich driver outputs data about 17% too fast, and no, this is not
a simple issue of it not beeing able to do VRA, 48kHz audio shows the
same behaviour.

auich0 at pci0 dev 31 function 5: i82801BA (ICH2) AC-97 Audio
auich0: interrupting at irq 10
auich0: ADS96 codec; headphone, Analog Devices Phat Stereo
audio0 at auich0: full duplex, mmap, independent

>How-To-Repeat:
>Fix:

This (non-serious) fix works for me.

--- auich.c	2002/04/11 10:54:23	1.17
+++ auich.c	2002/04/16 20:40:57
@@ -588,12 +588,14 @@
 auich_set_rate(struct auich_softc *sc, int mode, uint srate)
 {
 	u_int16_t val, rate, inout;
+	uint srate2 = srate;
 
 	inout = mode == AUMODE_PLAY ? ICH_PM_PCMO : ICH_PM_PCMI;
 
 	auich_read_codec(sc, AC97_REG_POWER, &val);
 	auich_write_codec(sc, AC97_REG_POWER, val | inout);
 	
+	srate = srate * 10000 / 11693;	
 	if (mode == AUMODE_PLAY) {
 		auich_write_codec(sc, AC97_REG_PCM_FRONT_DAC_RATE, srate);
 		auich_read_codec(sc, AC97_REG_PCM_FRONT_DAC_RATE, &rate);
@@ -601,6 +603,10 @@
 		auich_write_codec(sc, AC97_REG_PCM_LR_ADC_RATE, srate);
 		auich_read_codec(sc, AC97_REG_PCM_LR_ADC_RATE, &rate);
 	}
+	if(rate == srate)
+	    rate = srate2;
+	else
+	    rate = rate * 11693 / 10000;
 	
 	auich_write_codec(sc, AC97_REG_POWER, val);
 

>Release-Note:
>Audit-Trail:
>Unformatted: