diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e7b59d3eaba8..1bd2d49194e7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -85,6 +85,8 @@ struct alc_spec { | |||
85 | int mute_led_polarity; | 85 | int mute_led_polarity; |
86 | hda_nid_t mute_led_nid; | 86 | hda_nid_t mute_led_nid; |
87 | 87 | ||
88 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ | ||
89 | |||
88 | /* hooks */ | 90 | /* hooks */ |
89 | void (*init_hook)(struct hda_codec *codec); | 91 | void (*init_hook)(struct hda_codec *codec); |
90 | #ifdef CONFIG_PM | 92 | #ifdef CONFIG_PM |
@@ -2741,6 +2743,60 @@ static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, | |||
2741 | } | 2743 | } |
2742 | } | 2744 | } |
2743 | 2745 | ||
2746 | /* turn on/off mute LED per vmaster hook */ | ||
2747 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) | ||
2748 | { | ||
2749 | struct hda_codec *codec = private_data; | ||
2750 | struct alc_spec *spec = codec->spec; | ||
2751 | unsigned int oldval = spec->gpio_led; | ||
2752 | |||
2753 | if (enabled) | ||
2754 | spec->gpio_led &= ~0x08; | ||
2755 | else | ||
2756 | spec->gpio_led |= 0x08; | ||
2757 | if (spec->gpio_led != oldval) | ||
2758 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
2759 | spec->gpio_led); | ||
2760 | } | ||
2761 | |||
2762 | /* turn on/off mic-mute LED per capture hook */ | ||
2763 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, | ||
2764 | struct snd_ctl_elem_value *ucontrol) | ||
2765 | { | ||
2766 | struct alc_spec *spec = codec->spec; | ||
2767 | unsigned int oldval = spec->gpio_led; | ||
2768 | |||
2769 | if (!ucontrol) | ||
2770 | return; | ||
2771 | |||
2772 | if (ucontrol->value.integer.value[0] || | ||
2773 | ucontrol->value.integer.value[1]) | ||
2774 | spec->gpio_led &= ~0x10; | ||
2775 | else | ||
2776 | spec->gpio_led |= 0x10; | ||
2777 | if (spec->gpio_led != oldval) | ||
2778 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
2779 | spec->gpio_led); | ||
2780 | } | ||
2781 | |||
2782 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | ||
2783 | const struct hda_fixup *fix, int action) | ||
2784 | { | ||
2785 | struct alc_spec *spec = codec->spec; | ||
2786 | static const struct hda_verb gpio_init[] = { | ||
2787 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, | ||
2788 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, | ||
2789 | {} | ||
2790 | }; | ||
2791 | |||
2792 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2793 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | ||
2794 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; | ||
2795 | spec->gpio_led = 0; | ||
2796 | snd_hda_add_verbs(codec, gpio_init); | ||
2797 | } | ||
2798 | } | ||
2799 | |||
2744 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | 2800 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, |
2745 | const struct hda_fixup *fix, | 2801 | const struct hda_fixup *fix, |
2746 | int action) | 2802 | int action) |
@@ -2776,6 +2832,7 @@ enum { | |||
2776 | ALC269_FIXUP_HP_MUTE_LED, | 2832 | ALC269_FIXUP_HP_MUTE_LED, |
2777 | ALC269_FIXUP_HP_MUTE_LED_MIC1, | 2833 | ALC269_FIXUP_HP_MUTE_LED_MIC1, |
2778 | ALC269_FIXUP_HP_MUTE_LED_MIC2, | 2834 | ALC269_FIXUP_HP_MUTE_LED_MIC2, |
2835 | ALC269_FIXUP_HP_GPIO_LED, | ||
2779 | ALC269_FIXUP_INV_DMIC, | 2836 | ALC269_FIXUP_INV_DMIC, |
2780 | ALC269_FIXUP_LENOVO_DOCK, | 2837 | ALC269_FIXUP_LENOVO_DOCK, |
2781 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, | 2838 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
@@ -2915,6 +2972,10 @@ static const struct hda_fixup alc269_fixups[] = { | |||
2915 | .type = HDA_FIXUP_FUNC, | 2972 | .type = HDA_FIXUP_FUNC, |
2916 | .v.func = alc269_fixup_hp_mute_led_mic2, | 2973 | .v.func = alc269_fixup_hp_mute_led_mic2, |
2917 | }, | 2974 | }, |
2975 | [ALC269_FIXUP_HP_GPIO_LED] = { | ||
2976 | .type = HDA_FIXUP_FUNC, | ||
2977 | .v.func = alc269_fixup_hp_gpio_led, | ||
2978 | }, | ||
2918 | [ALC269_FIXUP_INV_DMIC] = { | 2979 | [ALC269_FIXUP_INV_DMIC] = { |
2919 | .type = HDA_FIXUP_FUNC, | 2980 | .type = HDA_FIXUP_FUNC, |
2920 | .v.func = alc_fixup_inv_dmic_0x12, | 2981 | .v.func = alc_fixup_inv_dmic_0x12, |
@@ -2955,6 +3016,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
2955 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | 3016 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), |
2956 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | 3017 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), |
2957 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 3018 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
3019 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | ||
2958 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 3020 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
2959 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 3021 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
2960 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), | 3022 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), |
@@ -3047,6 +3109,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { | |||
3047 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, | 3109 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, |
3048 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 3110 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
3049 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, | 3111 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, |
3112 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, | ||
3050 | {} | 3113 | {} |
3051 | }; | 3114 | }; |
3052 | 3115 | ||