On VIA VT1812/VT2002P, the "Master Front Playback Switch" doesn't mute first line-out. This is an issue, for example I saw a laptop with VT1812 and only one line-out (main speaker) that doesn't mute main speaker, because the master switch doesn't act on first line-out, and first line-out nid in array is assigned to speaker as expected by autoconfig code.
But there is one more issue also: main switches and automute code deal with mute on same Amp-Outs, which can cause conflicts, thus if you mute "Master Front Playback Switch" and remove headphone for example, it will not respect the mixer setting. To solve it, we can change the pin type instead of muting Amp-Out, which is done here.
Signed-off-by: Herton Ronaldo Krzesinski herton@mandriva.com.br --- sound/pci/hda/patch_via.c | 23 +++++++++-------------- 1 files changed, 9 insertions(+), 14 deletions(-)
Hi, I'm attaching the codec file of the laptop with the issue, this is kernel log relevant info: autoconfig: line_outs=1 (0x24/0x0/0x0/0x0/0x0) speaker_outs=0 (0x0/0x0/0x0/0x0/0x0) hp_outs=1 (0x33/0x0/0x0/0x0/0x0) mono: mono_out=0x0 inputs: mic=0x29, fmic=0x2b, line=0x0, fline=0x0, cd=0x0, aux=0x0
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 9ddc373..d6e6f40 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -295,8 +295,6 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol, .put = analog_input_switch_put, \ .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
-static void via_hp_bind_automute(struct hda_codec *codec); - static int bind_pin_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -343,13 +341,10 @@ static int bind_pin_switch_put(struct snd_kcontrol *kcontrol, snd_hda_codec_amp_stereo( codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); - /* unmute */ - via_hp_bind_automute(codec); - } else { if (lmute) { /* Mute all left channels */ - for (i = 1; i < spec->autocfg.line_outs; i++) + for (i = 0; i < spec->autocfg.line_outs; i++) snd_hda_codec_amp_update( codec, spec->autocfg.line_out_pins[i], @@ -364,7 +359,7 @@ static int bind_pin_switch_put(struct snd_kcontrol *kcontrol, } if (rmute) { /* mute all right channels */ - for (i = 1; i < spec->autocfg.line_outs; i++) + for (i = 0; i < spec->autocfg.line_outs; i++) snd_hda_codec_amp_update( codec, spec->autocfg.line_out_pins[i], @@ -2129,18 +2124,18 @@ static void via_hp_bind_automute(struct hda_codec *codec) if (!spec->hp_independent_mode) { /* Mute Line-Outs */ for (i = 0; i < spec->autocfg.line_outs; i++) - snd_hda_codec_amp_stereo( - codec, spec->autocfg.line_out_pins[i], - HDA_OUTPUT, 0, - HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0); + snd_hda_codec_write(codec, + spec->autocfg.line_out_pins[i], + 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + hp_present ? 0 : PIN_OUT); if (hp_present) present = hp_present; } /* Speakers */ for (i = 0; i < spec->autocfg.speaker_outs; i++) - snd_hda_codec_amp_stereo( - codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0, - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + snd_hda_codec_write(codec, spec->autocfg.speaker_pins[i], 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + present ? 0 : PIN_OUT); }