aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-03-18 09:15:58 -0400
committerTakashi Iwai <tiwai@suse.de>2013-03-18 09:15:58 -0400
commit9f5c6faf72d5ecc1c16e6a8737b21ba7d5e3c87d (patch)
tree6110ac65dc2eefa621b0d5b85bd5d34aaa85739b /sound/pci/hda/patch_realtek.c
parent8bc0a8469c514016bc04de55eda3bf597a9340e2 (diff)
ALSA: hda - Add GPIO-based LED support on HP desktop machines
The new HP desktop machines have Realtek codecs and their LEDs are controlled via GPIO as for many laptop models. Add similar hooks as well as in patch_sigmatel.c for controlling LEDs. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c63
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 */
2747static 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 */
2763static 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
2782static 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
2744static void alc271_hp_gate_mic_jack(struct hda_codec *codec, 2800static 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