]>
Commit | Line | Data |
---|---|---|
82094b55 AF |
1 | From 5bdaaada16363d64e10ae081755d1a8d392429f2 Mon Sep 17 00:00:00 2001 |
2 | From: Vitaliy Kulikov <Vitaliy.Kulikov@idt.com> | |
3 | Date: Wed, 4 Nov 2009 07:57:45 +0100 | |
4 | Subject: ALSA: hda - Enable GPIO control for mute LED on HP systems | |
5 | Patch-mainline: 2.6.32-rc6 | |
6 | References: bnc#547357,bnc#523487 | |
7 | ||
8 | This patch enables GPIO to control mute LED indicator on the HP systems | |
9 | with the special string in BIOS and applies it with the correct polarity on | |
10 | HP B-series systems. | |
11 | ||
12 | It also restores configuration of the pin intended as the second Headphone | |
13 | on HP B-series systems but configured as something else in the BIOS to | |
14 | pass MS DTM. | |
15 | ||
16 | Signed-off-by: Vitaliy Kulikov <Vitaliy.Kulikov@idt.com> | |
17 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
18 | ||
19 | --- | |
20 | sound/pci/hda/patch_sigmatel.c | 68 +++++++++++++++++++++++++++++++++++++++++ | |
21 | 1 file changed, 68 insertions(+) | |
22 | ||
23 | --- a/sound/pci/hda/patch_sigmatel.c | |
24 | +++ b/sound/pci/hda/patch_sigmatel.c | |
25 | @@ -28,6 +28,7 @@ | |
26 | #include <linux/delay.h> | |
27 | #include <linux/slab.h> | |
28 | #include <linux/pci.h> | |
29 | +#include <linux/dmi.h> | |
30 | #include <sound/core.h> | |
31 | #include <sound/asoundef.h> | |
32 | #include "hda_codec.h" | |
33 | @@ -1506,6 +1507,8 @@ | |
34 | "DFI LanParty", STAC_92HD71BXX_REF), | |
35 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb, | |
36 | "HP dv4-1222nr", STAC_HP_DV4_1222NR), | |
37 | + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720, | |
38 | + "HP", STAC_HP_DV5), | |
39 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, | |
40 | "HP", STAC_HP_DV5), | |
41 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, | |
42 | @@ -4439,6 +4442,26 @@ | |
43 | return 0; | |
44 | } | |
45 | ||
46 | +static int hp_bseries_system(u32 subsystem_id) | |
47 | +{ | |
48 | + switch (subsystem_id) { | |
49 | + case 0x103c307e: | |
50 | + case 0x103c307f: | |
51 | + case 0x103c3080: | |
52 | + case 0x103c3081: | |
53 | + case 0x103c1722: | |
54 | + case 0x103c1723: | |
55 | + case 0x103c1724: | |
56 | + case 0x103c1725: | |
57 | + case 0x103c1726: | |
58 | + case 0x103c1727: | |
59 | + case 0x103c1728: | |
60 | + case 0x103c1729: | |
61 | + return 1; | |
62 | + } | |
63 | + return 0; | |
64 | +} | |
65 | + | |
66 | /* | |
67 | * using power check for controlling mute led of HP notebooks | |
68 | * check for mute state only on Speakers (nid = 0x10) | |
69 | @@ -4463,6 +4486,11 @@ | |
70 | else | |
71 | spec->gpio_data |= spec->gpio_led; /* white */ | |
72 | ||
73 | + if (hp_bseries_system(codec->subsystem_id)) { | |
74 | + /* LED state is inverted on these systems */ | |
75 | + spec->gpio_data ^= spec->gpio_led; | |
76 | + } | |
77 | + | |
78 | stac_gpio_set(codec, spec->gpio_mask, | |
79 | spec->gpio_dir, | |
80 | spec->gpio_data); | |
81 | @@ -4944,6 +4972,7 @@ | |
82 | { | |
83 | struct sigmatel_spec *spec; | |
84 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; | |
85 | + unsigned int pin_cfg; | |
86 | int err = 0; | |
87 | ||
88 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | |
89 | @@ -5130,6 +5159,45 @@ | |
90 | break; | |
91 | } | |
92 | ||
93 | + if (hp_bseries_system(codec->subsystem_id)) { | |
94 | + pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); | |
95 | + if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || | |
96 | + get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || | |
97 | + get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) { | |
98 | + /* It was changed in the BIOS to just satisfy MS DTM. | |
99 | + * Lets turn it back into slaved HP | |
100 | + */ | |
101 | + pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) | |
102 | + | (AC_JACK_HP_OUT << | |
103 | + AC_DEFCFG_DEVICE_SHIFT); | |
104 | + pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | |
105 | + | AC_DEFCFG_SEQUENCE))) | |
106 | + | 0x1f; | |
107 | + snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg); | |
108 | + } | |
109 | + } | |
110 | + | |
111 | + if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { | |
112 | + const struct dmi_device *dev = NULL; | |
113 | + while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, | |
114 | + NULL, dev))) { | |
115 | + if (strcmp(dev->name, "HP_Mute_LED_1")) { | |
116 | + switch (codec->vendor_id) { | |
117 | + case 0x111d7608: | |
118 | + spec->gpio_led = 0x01; | |
119 | + break; | |
120 | + case 0x111d7600: | |
121 | + case 0x111d7601: | |
122 | + case 0x111d7602: | |
123 | + case 0x111d7603: | |
124 | + spec->gpio_led = 0x08; | |
125 | + break; | |
126 | + } | |
127 | + break; | |
128 | + } | |
129 | + } | |
130 | + } | |
131 | + | |
132 | #ifdef CONFIG_SND_HDA_POWER_SAVE | |
133 | if (spec->gpio_led) { | |
134 | spec->gpio_mask |= spec->gpio_led; |