]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
[PATCH] Fix stereo mutes on Surround volume control
authordsd@gentoo.org <dsd@gentoo.org>
Sat, 19 Mar 2005 05:32:08 +0000 (21:32 -0800)
committerGreg KH <gregkh@suse.de>
Thu, 12 May 2005 17:00:12 +0000 (10:00 -0700)
As of 2.6.11, I have no output out of the rear right speaker of my 4.1
surround sound setup. I am using snd-intel8x0 based on a Realtek ALC650F chip
on an nvidia motherboard.

A gentoo user with completely different hardware also ran into this:
http://bugs.gentoo.org/84276

2.6.11-mm3 fixes this problem and I've identified the specific fix, which is
already in the ALSA development tree. An ALSA developer asked me to submit the
fix for 2.6.11.x when I'd found it, so here it is :)

--
AC97 Codec
Fix stereo mutes on Surround volume control.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
sound/pci/ac97/ac97_codec.c

index 171bf668a3ff97c9069ff7ffeda605517a625648..188dc958184658c2e0cf642b8158d1f570feed58 100644 (file)
@@ -1185,7 +1185,7 @@ snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97
 /*
  * create mute switch(es) for normal stereo controls
  */
-static int snd_ac97_cmute_new(snd_card_t *card, char *name, int reg, ac97_t *ac97)
+static int snd_ac97_cmute_new_stereo(snd_card_t *card, char *name, int reg, int check_stereo, ac97_t *ac97)
 {
        snd_kcontrol_t *kctl;
        int err;
@@ -1196,7 +1196,7 @@ static int snd_ac97_cmute_new(snd_card_t *card, char *name, int reg, ac97_t *ac9
 
        mute_mask = 0x8000;
        val = snd_ac97_read(ac97, reg);
-       if (ac97->flags & AC97_STEREO_MUTES) {
+       if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) {
                /* check whether both mute bits work */
                val1 = val | 0x8080;
                snd_ac97_write(ac97, reg, val1);
@@ -1254,7 +1254,7 @@ static int snd_ac97_cvol_new(snd_card_t *card, char *name, int reg, unsigned int
 /*
  * create a mute-switch and a volume for normal stereo/mono controls
  */
-static int snd_ac97_cmix_new(snd_card_t *card, const char *pfx, int reg, ac97_t *ac97)
+static int snd_ac97_cmix_new_stereo(snd_card_t *card, const char *pfx, int reg, int check_stereo, ac97_t *ac97)
 {
        int err;
        char name[44];
@@ -1265,7 +1265,7 @@ static int snd_ac97_cmix_new(snd_card_t *card, const char *pfx, int reg, ac97_t
 
        if (snd_ac97_try_bit(ac97, reg, 15)) {
                sprintf(name, "%s Switch", pfx);
-               if ((err = snd_ac97_cmute_new(card, name, reg, ac97)) < 0)
+               if ((err = snd_ac97_cmute_new_stereo(card, name, reg, check_stereo, ac97)) < 0)
                        return err;
        }
        check_volume_resolution(ac97, reg, &lo_max, &hi_max);
@@ -1277,6 +1277,8 @@ static int snd_ac97_cmix_new(snd_card_t *card, const char *pfx, int reg, ac97_t
        return 0;
 }
 
+#define snd_ac97_cmix_new(card, pfx, reg, ac97)        snd_ac97_cmix_new_stereo(card, pfx, reg, 0, ac97)
+#define snd_ac97_cmute_new(card, name, reg, ac97)      snd_ac97_cmute_new_stereo(card, name, reg, 0, ac97)
 
 static unsigned int snd_ac97_determine_spdif_rates(ac97_t *ac97);
 
@@ -1327,7 +1329,8 @@ static int snd_ac97_mixer_build(ac97_t * ac97)
 
        /* build surround controls */
        if (snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER)) {
-               if ((err = snd_ac97_cmix_new(card, "Surround Playback", AC97_SURROUND_MASTER, ac97)) < 0)
+               /* Surround Master (0x38) is with stereo mutes */
+               if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", AC97_SURROUND_MASTER, 1, ac97)) < 0)
                        return err;
        }