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 3734 { } /* end */ 3735 3735 }; 3736 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 + 3737 3750 static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { 3738 3751 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3739 - HDA_CODEC_MUTE("Master Playback Switch", 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 + }, 3740 3761 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 3741 3762 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 3742 3763 HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), ··· 3878 3857 /* unsolicited event for pin-sense */ 3879 3858 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 3880 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 */ 3881 3864 { } /* end */ 3882 3865 }; 3883 3866