ALSA: hda - Add GPIO1 control at muting with HP laptops

HP laptops with AD1984A codecs (at least mobile models) need to set
GPIO1 appropriately to indicate the mute state. The BIOS checks this
bit to judge whether the mute on or off is sent via F8 key.
Without changing this bit, the BIOS can be confused and may toggle
the mute wrongly.

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

Signed-off-by: Takashi Iwai <tiwai@suse.de>

+26 -1
+26 -1
sound/pci/hda/patch_analog.c
··· 3734 { } /* end */ 3735 }; 3736 3737 static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { 3738 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3739 - HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 3740 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 3741 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 3742 HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), ··· 3878 /* unsolicited event for pin-sense */ 3879 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 3880 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 3881 { } /* end */ 3882 }; 3883
··· 3734 { } /* end */ 3735 }; 3736 3737 + static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol, 3738 + struct snd_ctl_elem_value *ucontrol) 3739 + { 3740 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3741 + int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 3742 + int mute = (!ucontrol->value.integer.value[0] && 3743 + !ucontrol->value.integer.value[1]); 3744 + /* toggle GPIO1 according to the mute state */ 3745 + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 3746 + mute ? 0x02 : 0x0); 3747 + return ret; 3748 + } 3749 + 3750 static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { 3751 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3752 + /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 3753 + { 3754 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3755 + .name = "Master Playback Switch", 3756 + .info = snd_hda_mixer_amp_switch_info, 3757 + .get = snd_hda_mixer_amp_switch_get, 3758 + .put = ad1884a_mobile_master_sw_put, 3759 + .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 3760 + }, 3761 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 3762 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 3763 HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), ··· 3857 /* unsolicited event for pin-sense */ 3858 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 3859 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 3860 + /* allow to touch GPIO1 (for mute control) */ 3861 + {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 3862 + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 3863 + {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */ 3864 { } /* end */ 3865 }; 3866