diff options
author | Jerónimo Borque <jeronimo@borque.com.ar> | 2017-04-19 11:09:50 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-04-19 12:00:56 -0400 |
commit | 5cd5b1bdfb0137d0e814a51ff203d72c76b9f375 (patch) | |
tree | 6e2f778ed3f99eab352191cf39de0206882173a5 | |
parent | a5f8661df0190f206ec73bd42b756d889c16150d (diff) |
ALSA: hda - Add HP ZBook 15u G3 Conexant CX20724 GPIO mute leds
The HP ZBook 15u G3 has a Conexant CX20724 with mute led on GPIO1 and
mic mute led on GPIO2.
Adding CXT_FIXUP_MUTE_LED_GPIO inspired on patch_realtek's one.
Signed-off-by: Jerónimo Borque <jeronimo@borque.com.ar>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 69266b8ea2ad..e8253737c47a 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -52,6 +52,12 @@ struct conexant_spec { | |||
52 | bool dc_enable; | 52 | bool dc_enable; |
53 | unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */ | 53 | unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */ |
54 | struct nid_path *dc_mode_path; | 54 | struct nid_path *dc_mode_path; |
55 | |||
56 | int mute_led_polarity; | ||
57 | unsigned int gpio_led; | ||
58 | unsigned int gpio_mute_led_mask; | ||
59 | unsigned int gpio_mic_led_mask; | ||
60 | |||
55 | }; | 61 | }; |
56 | 62 | ||
57 | 63 | ||
@@ -264,6 +270,7 @@ enum { | |||
264 | CXT_FIXUP_HP_DOCK, | 270 | CXT_FIXUP_HP_DOCK, |
265 | CXT_FIXUP_HP_SPECTRE, | 271 | CXT_FIXUP_HP_SPECTRE, |
266 | CXT_FIXUP_HP_GATE_MIC, | 272 | CXT_FIXUP_HP_GATE_MIC, |
273 | CXT_FIXUP_MUTE_LED_GPIO, | ||
267 | }; | 274 | }; |
268 | 275 | ||
269 | /* for hda_fixup_thinkpad_acpi() */ | 276 | /* for hda_fixup_thinkpad_acpi() */ |
@@ -646,6 +653,74 @@ static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec, | |||
646 | snd_hda_jack_set_gating_jack(codec, 0x19, 0x16); | 653 | snd_hda_jack_set_gating_jack(codec, 0x19, 0x16); |
647 | } | 654 | } |
648 | 655 | ||
656 | /* update LED status via GPIO */ | ||
657 | static void cxt_update_gpio_led(struct hda_codec *codec, unsigned int mask, | ||
658 | bool enabled) | ||
659 | { | ||
660 | struct conexant_spec *spec = codec->spec; | ||
661 | unsigned int oldval = spec->gpio_led; | ||
662 | |||
663 | if (spec->mute_led_polarity) | ||
664 | enabled = !enabled; | ||
665 | |||
666 | if (enabled) | ||
667 | spec->gpio_led &= ~mask; | ||
668 | else | ||
669 | spec->gpio_led |= mask; | ||
670 | if (spec->gpio_led != oldval) | ||
671 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
672 | spec->gpio_led); | ||
673 | } | ||
674 | |||
675 | /* turn on/off mute LED via GPIO per vmaster hook */ | ||
676 | static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled) | ||
677 | { | ||
678 | struct hda_codec *codec = private_data; | ||
679 | struct conexant_spec *spec = codec->spec; | ||
680 | |||
681 | cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled); | ||
682 | } | ||
683 | |||
684 | /* turn on/off mic-mute LED via GPIO per capture hook */ | ||
685 | static void cxt_fixup_gpio_mic_mute_hook(struct hda_codec *codec, | ||
686 | struct snd_kcontrol *kcontrol, | ||
687 | struct snd_ctl_elem_value *ucontrol) | ||
688 | { | ||
689 | struct conexant_spec *spec = codec->spec; | ||
690 | |||
691 | if (ucontrol) | ||
692 | cxt_update_gpio_led(codec, spec->gpio_mic_led_mask, | ||
693 | ucontrol->value.integer.value[0] || | ||
694 | ucontrol->value.integer.value[1]); | ||
695 | } | ||
696 | |||
697 | |||
698 | static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, | ||
699 | const struct hda_fixup *fix, int action) | ||
700 | { | ||
701 | struct conexant_spec *spec = codec->spec; | ||
702 | static const struct hda_verb gpio_init[] = { | ||
703 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x03 }, | ||
704 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 }, | ||
705 | {} | ||
706 | }; | ||
707 | codec_info(codec, "action: %d gpio_led: %d\n", action, spec->gpio_led); | ||
708 | |||
709 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
710 | spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook; | ||
711 | spec->gen.cap_sync_hook = cxt_fixup_gpio_mic_mute_hook; | ||
712 | spec->gpio_led = 0; | ||
713 | spec->mute_led_polarity = 0; | ||
714 | spec->gpio_mute_led_mask = 0x01; | ||
715 | spec->gpio_mic_led_mask = 0x02; | ||
716 | } | ||
717 | snd_hda_add_verbs(codec, gpio_init); | ||
718 | if (spec->gpio_led) | ||
719 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
720 | spec->gpio_led); | ||
721 | } | ||
722 | |||
723 | |||
649 | /* ThinkPad X200 & co with cxt5051 */ | 724 | /* ThinkPad X200 & co with cxt5051 */ |
650 | static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { | 725 | static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { |
651 | { 0x16, 0x042140ff }, /* HP (seq# overridden) */ | 726 | { 0x16, 0x042140ff }, /* HP (seq# overridden) */ |
@@ -799,6 +874,10 @@ static const struct hda_fixup cxt_fixups[] = { | |||
799 | .type = HDA_FIXUP_FUNC, | 874 | .type = HDA_FIXUP_FUNC, |
800 | .v.func = cxt_fixup_hp_gate_mic_jack, | 875 | .v.func = cxt_fixup_hp_gate_mic_jack, |
801 | }, | 876 | }, |
877 | [CXT_FIXUP_MUTE_LED_GPIO] = { | ||
878 | .type = HDA_FIXUP_FUNC, | ||
879 | .v.func = cxt_fixup_mute_led_gpio, | ||
880 | }, | ||
802 | }; | 881 | }; |
803 | 882 | ||
804 | static const struct snd_pci_quirk cxt5045_fixups[] = { | 883 | static const struct snd_pci_quirk cxt5045_fixups[] = { |
@@ -851,6 +930,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { | |||
851 | SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), | 930 | SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), |
852 | SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), | 931 | SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), |
853 | SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), | 932 | SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), |
933 | SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), | ||
854 | SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), | 934 | SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), |
855 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), | 935 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), |
856 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), | 936 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), |
@@ -882,6 +962,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { | |||
882 | { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, | 962 | { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, |
883 | { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, | 963 | { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, |
884 | { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, | 964 | { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, |
965 | { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" }, | ||
885 | {} | 966 | {} |
886 | }; | 967 | }; |
887 | 968 | ||