ALSA: hda - Fix mute control with some ALC262 models
authorTakashi Iwai <tiwai@suse.de>
Fri, 24 Jul 2009 14:51:47 +0000 (16:51 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 24 Jul 2009 14:54:31 +0000 (16:54 +0200)
The master mute switch is wrongly implemented as checking the pointer
instead of its value, thus it can be never muted.  This patch fixes
the issue.

Reference: Novell bnc#404873
https://bugzilla.novell.com/show_bug.cgi?id=404873

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Cc: <stable@kernel.org>
sound/pci/hda/patch_realtek.c

index 7e99763ca527209ad3243e3b0f75228aeb440fce..8c8b273116fbcc71bbe241bd6f9b63c69fbcd2ef 100644 (file)
@@ -10631,6 +10631,18 @@ static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
        alc262_lenovo_3000_automute(codec, 1);
 }
 
+static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
+                                 int dir, int idx, long *valp)
+{
+       int i, change = 0;
+
+       for (i = 0; i < 2; i++, valp++)
+               change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
+                                                  HDA_AMP_MUTE,
+                                                  *valp ? 0 : HDA_AMP_MUTE);
+       return change;
+}
+
 /* bind hp and internal speaker mute (with plug check) */
 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
                                         struct snd_ctl_elem_value *ucontrol)
@@ -10639,13 +10651,8 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
        long *valp = ucontrol->value.integer.value;
        int change;
 
-       change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
-                                                HDA_AMP_MUTE,
-                                                valp ? 0 : HDA_AMP_MUTE);
-       change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
-                                                HDA_AMP_MUTE,
-                                                valp ? 0 : HDA_AMP_MUTE);
-
+       change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
+       change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
        if (change)
                alc262_fujitsu_automute(codec, 0);
        return change;
@@ -10680,10 +10687,7 @@ static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
        long *valp = ucontrol->value.integer.value;
        int change;
 
-       change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
-                                                HDA_AMP_MUTE,
-                                                valp ? 0 : HDA_AMP_MUTE);
-
+       change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
        if (change)
                alc262_lenovo_3000_automute(codec, 0);
        return change;
@@ -11854,12 +11858,7 @@ static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
        long *valp = ucontrol->value.integer.value;
        int change;
 
-       change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
-                                         HDA_AMP_MUTE,
-                                         valp[0] ? 0 : HDA_AMP_MUTE);
-       change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
-                                          HDA_AMP_MUTE,
-                                          valp[1] ? 0 : HDA_AMP_MUTE);
+       change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
        if (change)
                alc268_acer_automute(codec, 0);
        return change;