Subject: kern/12878: swapped channels in AC97
To: None <gnats-bugs@gnats.netbsd.org, rh@netbsd.org>
From: None <salvet@ics.muni.cz>
List: netbsd-bugs
Date: 05/09/2001 12:10:38
>Number:         12878
>Category:       kern
>Synopsis:       swapped channels in AC97
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed May 09 03:10:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Zdenek Salvet
>Release:        1.5.1_BETA
>Organization:
Masaryk University, Brno, Czech Republic
>Environment:
System: NetBSD horn.ics.muni.cz 1.5.1_BETA NetBSD 1.5.1_BETA (HORN_151A_SB128) #2: Wed May 9 09:22:30 MEST 2001 salvet@horn.ics.muni.cz:/amd/eru/scratch2/salvet/root15/usr/src/sys/arch/i386/compile/HORN_151A_SB128 i386


>Description:
When using stereo output with
eap0 at pci0 dev 16 function 0: Ensoniq CT5880 CT5880C (rev. 0x02)
eap0: interrupting at irq 9
eap0: SigmaTel STAC9721/23 codec; 18 bit DAC, 18 bit ADC, Rockwell 3D

left and right audio channels are swapped. According to AC97 specification,
left channel is controlled by MSB half of volume registers, our code
does the opposite.

After fix, use of AC97_HOST_SWAPPED_CHANNELS in pci/esm.c should
be revised/retested.

BTW, AC97_REG_RECORD_GAIN is inverted.

>How-To-Repeat:
>Fix:
--- sys/dev/ic/ac97.c.orig      Wed May  9 11:20:31 2001
+++ sys/dev/ic/ac97.c   Wed May  9 11:47:04 2001
@@ -216,7 +216,7 @@
        /* Record Gain */
        { AudioCrecord,      AudioNvolume,        NULL,    AUDIO_MIXER_VALUE,
          WRAP(ac97_volume_stereo),
-         AC97_REG_RECORD_GAIN, 0x8000, 4, 0, 1, 
+         AC97_REG_RECORD_GAIN, 0x8000, 4, 0, 1, 1,
        },
        /* Record Gain mic */
        { AudioCrecord,  AudioNmicrophone,        NULL,    AUDIO_MIXER_VALUE,
@@ -750,7 +750,7 @@
 
                newval = ((l & mask) << si->ofs);
                if (value->num_channels == 2) {
-                       newval |= ((r & mask) << (si->ofs + 8));
+                       newval = (newval << 8 ) | ((r & mask) << si->ofs );
                        mask |= (mask << 8);
                }
 

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