diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_codec.h | 5 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 7 | ||||
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 114 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 103 |
5 files changed, 175 insertions, 57 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 2d627613aea3..1d541b7f5547 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -255,9 +255,13 @@ enum { | |||
255 | * in HD-audio specification | 255 | * in HD-audio specification |
256 | */ | 256 | */ |
257 | #define AC_PINCAP_HDMI (1<<7) /* HDMI pin */ | 257 | #define AC_PINCAP_HDMI (1<<7) /* HDMI pin */ |
258 | #define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can | ||
259 | * coexist with AC_PINCAP_HDMI | ||
260 | */ | ||
258 | #define AC_PINCAP_VREF (0x37<<8) | 261 | #define AC_PINCAP_VREF (0x37<<8) |
259 | #define AC_PINCAP_VREF_SHIFT 8 | 262 | #define AC_PINCAP_VREF_SHIFT 8 |
260 | #define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ | 263 | #define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ |
264 | #define AC_PINCAP_HBR (1<<27) /* High Bit Rate */ | ||
261 | /* Vref status (used in pin cap) */ | 265 | /* Vref status (used in pin cap) */ |
262 | #define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */ | 266 | #define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */ |
263 | #define AC_PINCAP_VREF_50 (1<<1) /* 50% */ | 267 | #define AC_PINCAP_VREF_50 (1<<1) /* 50% */ |
@@ -635,6 +639,7 @@ struct hda_bus { | |||
635 | unsigned int rirb_error:1; /* error in codec communication */ | 639 | unsigned int rirb_error:1; /* error in codec communication */ |
636 | unsigned int response_reset:1; /* controller was reset */ | 640 | unsigned int response_reset:1; /* controller was reset */ |
637 | unsigned int in_reset:1; /* during reset operation */ | 641 | unsigned int in_reset:1; /* during reset operation */ |
642 | unsigned int power_keep_link_on:1; /* don't power off HDA link */ | ||
638 | }; | 643 | }; |
639 | 644 | ||
640 | /* | 645 | /* |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index efcc4f7c57f2..e54420e691ae 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2082,7 +2082,8 @@ static void azx_power_notify(struct hda_bus *bus) | |||
2082 | } | 2082 | } |
2083 | if (power_on) | 2083 | if (power_on) |
2084 | azx_init_chip(chip); | 2084 | azx_init_chip(chip); |
2085 | else if (chip->running && power_save_controller) | 2085 | else if (chip->running && power_save_controller && |
2086 | !bus->power_keep_link_on) | ||
2086 | azx_stop_chip(chip); | 2087 | azx_stop_chip(chip); |
2087 | } | 2088 | } |
2088 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | 2089 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 09476fc1ab64..c9afc04adac8 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -240,9 +240,14 @@ static void print_pin_caps(struct snd_info_buffer *buffer, | |||
240 | /* Realtek uses this bit as a different meaning */ | 240 | /* Realtek uses this bit as a different meaning */ |
241 | if ((codec->vendor_id >> 16) == 0x10ec) | 241 | if ((codec->vendor_id >> 16) == 0x10ec) |
242 | snd_iprintf(buffer, " R/L"); | 242 | snd_iprintf(buffer, " R/L"); |
243 | else | 243 | else { |
244 | if (caps & AC_PINCAP_HBR) | ||
245 | snd_iprintf(buffer, " HBR"); | ||
244 | snd_iprintf(buffer, " HDMI"); | 246 | snd_iprintf(buffer, " HDMI"); |
247 | } | ||
245 | } | 248 | } |
249 | if (caps & AC_PINCAP_DP) | ||
250 | snd_iprintf(buffer, " DP"); | ||
246 | if (caps & AC_PINCAP_TRIG_REQ) | 251 | if (caps & AC_PINCAP_TRIG_REQ) |
247 | snd_iprintf(buffer, " Trigger"); | 252 | snd_iprintf(buffer, " Trigger"); |
248 | if (caps & AC_PINCAP_IMP_SENSE) | 253 | if (caps & AC_PINCAP_IMP_SENSE) |
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index 928df59be5d8..918f40378d52 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -146,38 +146,78 @@ struct cea_channel_speaker_allocation { | |||
146 | }; | 146 | }; |
147 | 147 | ||
148 | /* | 148 | /* |
149 | * ALSA sequence is: | ||
150 | * | ||
151 | * surround40 surround41 surround50 surround51 surround71 | ||
152 | * ch0 front left = = = = | ||
153 | * ch1 front right = = = = | ||
154 | * ch2 rear left = = = = | ||
155 | * ch3 rear right = = = = | ||
156 | * ch4 LFE center center center | ||
157 | * ch5 LFE LFE | ||
158 | * ch6 side left | ||
159 | * ch7 side right | ||
160 | * | ||
161 | * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR} | ||
162 | */ | ||
163 | static int hdmi_channel_mapping[0x32][8] = { | ||
164 | /* stereo */ | ||
165 | [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }, | ||
166 | /* 2.1 */ | ||
167 | [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }, | ||
168 | /* Dolby Surround */ | ||
169 | [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 }, | ||
170 | /* surround40 */ | ||
171 | [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 }, | ||
172 | /* 4ch */ | ||
173 | [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 }, | ||
174 | /* surround41 */ | ||
175 | [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 }, | ||
176 | /* surround50 */ | ||
177 | [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 }, | ||
178 | /* surround51 */ | ||
179 | [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 }, | ||
180 | /* 7.1 */ | ||
181 | [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 }, | ||
182 | }; | ||
183 | |||
184 | /* | ||
149 | * This is an ordered list! | 185 | * This is an ordered list! |
150 | * | 186 | * |
151 | * The preceding ones have better chances to be selected by | 187 | * The preceding ones have better chances to be selected by |
152 | * hdmi_setup_channel_allocation(). | 188 | * hdmi_setup_channel_allocation(). |
153 | */ | 189 | */ |
154 | static struct cea_channel_speaker_allocation channel_allocations[] = { | 190 | static struct cea_channel_speaker_allocation channel_allocations[] = { |
155 | /* channel: 8 7 6 5 4 3 2 1 */ | 191 | /* channel: 7 6 5 4 3 2 1 0 */ |
156 | { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, | 192 | { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, |
157 | /* 2.1 */ | 193 | /* 2.1 */ |
158 | { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, | 194 | { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, |
159 | /* Dolby Surround */ | 195 | /* Dolby Surround */ |
160 | { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, | 196 | { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, |
197 | /* surround40 */ | ||
198 | { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, | ||
199 | /* surround41 */ | ||
200 | { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, | ||
201 | /* surround50 */ | ||
202 | { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, | ||
203 | /* surround51 */ | ||
204 | { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, | ||
205 | /* 6.1 */ | ||
206 | { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, | ||
207 | /* surround71 */ | ||
208 | { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, | ||
209 | |||
161 | { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, | 210 | { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, |
162 | { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, | 211 | { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, |
163 | { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, | 212 | { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, |
164 | { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, | 213 | { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, |
165 | { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, | 214 | { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, |
166 | { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, | ||
167 | { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, | ||
168 | { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, | ||
169 | /* 5.1 */ | ||
170 | { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, | ||
171 | { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, | 215 | { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, |
172 | { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, | 216 | { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, |
173 | { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, | 217 | { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, |
174 | /* 6.1 */ | ||
175 | { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, | ||
176 | { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, | 218 | { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, |
177 | { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, | 219 | { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, |
178 | { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, | 220 | { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, |
179 | /* 7.1 */ | ||
180 | { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, | ||
181 | { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, | 221 | { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, |
182 | { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, | 222 | { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, |
183 | { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, | 223 | { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, |
@@ -210,7 +250,6 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { | |||
210 | { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, | 250 | { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, |
211 | }; | 251 | }; |
212 | 252 | ||
213 | |||
214 | /* | 253 | /* |
215 | * HDA/HDMI auto parsing | 254 | * HDA/HDMI auto parsing |
216 | */ | 255 | */ |
@@ -344,7 +383,7 @@ static int intel_hdmi_parse_codec(struct hda_codec *codec) | |||
344 | break; | 383 | break; |
345 | case AC_WID_PIN: | 384 | case AC_WID_PIN: |
346 | caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | 385 | caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); |
347 | if (!(caps & AC_PINCAP_HDMI)) | 386 | if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) |
348 | continue; | 387 | continue; |
349 | if (intel_hdmi_add_pin(codec, nid) < 0) | 388 | if (intel_hdmi_add_pin(codec, nid) < 0) |
350 | return -EINVAL; | 389 | return -EINVAL; |
@@ -352,6 +391,17 @@ static int intel_hdmi_parse_codec(struct hda_codec *codec) | |||
352 | } | 391 | } |
353 | } | 392 | } |
354 | 393 | ||
394 | /* | ||
395 | * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event | ||
396 | * can be lost and presence sense verb will become inaccurate if the | ||
397 | * HDA link is powered off at hot plug or hw initialization time. | ||
398 | */ | ||
399 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
400 | if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) & | ||
401 | AC_PWRST_EPSS)) | ||
402 | codec->bus->power_keep_link_on = 1; | ||
403 | #endif | ||
404 | |||
355 | return 0; | 405 | return 0; |
356 | } | 406 | } |
357 | 407 | ||
@@ -436,14 +486,15 @@ static void hdmi_set_channel_count(struct hda_codec *codec, | |||
436 | AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); | 486 | AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); |
437 | } | 487 | } |
438 | 488 | ||
439 | static void hdmi_debug_channel_mapping(struct hda_codec *codec, hda_nid_t nid) | 489 | static void hdmi_debug_channel_mapping(struct hda_codec *codec, |
490 | hda_nid_t pin_nid) | ||
440 | { | 491 | { |
441 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 492 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
442 | int i; | 493 | int i; |
443 | int slot; | 494 | int slot; |
444 | 495 | ||
445 | for (i = 0; i < 8; i++) { | 496 | for (i = 0; i < 8; i++) { |
446 | slot = snd_hda_codec_read(codec, nid, 0, | 497 | slot = snd_hda_codec_read(codec, pin_nid, 0, |
447 | AC_VERB_GET_HDMI_CHAN_SLOT, i); | 498 | AC_VERB_GET_HDMI_CHAN_SLOT, i); |
448 | printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", | 499 | printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", |
449 | slot >> 4, slot & 0xf); | 500 | slot >> 4, slot & 0xf); |
@@ -619,25 +670,32 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid, | |||
619 | return ai->CA; | 670 | return ai->CA; |
620 | } | 671 | } |
621 | 672 | ||
622 | static void hdmi_setup_channel_mapping(struct hda_codec *codec, hda_nid_t nid, | 673 | static void hdmi_setup_channel_mapping(struct hda_codec *codec, |
674 | hda_nid_t pin_nid, | ||
623 | struct hdmi_audio_infoframe *ai) | 675 | struct hdmi_audio_infoframe *ai) |
624 | { | 676 | { |
625 | int i; | 677 | int i; |
678 | int ca = ai->CA; | ||
679 | int err; | ||
626 | 680 | ||
627 | if (!ai->CA) | 681 | if (hdmi_channel_mapping[ca][1] == 0) { |
628 | return; | 682 | for (i = 0; i < channel_allocations[ca].channels; i++) |
629 | 683 | hdmi_channel_mapping[ca][i] = i | (i << 4); | |
630 | /* | 684 | for (; i < 8; i++) |
631 | * TODO: adjust channel mapping if necessary | 685 | hdmi_channel_mapping[ca][i] = 0xf | (i << 4); |
632 | * ALSA sequence is front/surr/clfe/side? | 686 | } |
633 | */ | ||
634 | 687 | ||
635 | for (i = 0; i < 8; i++) | 688 | for (i = 0; i < 8; i++) { |
636 | snd_hda_codec_write(codec, nid, 0, | 689 | err = snd_hda_codec_write(codec, pin_nid, 0, |
637 | AC_VERB_SET_HDMI_CHAN_SLOT, | 690 | AC_VERB_SET_HDMI_CHAN_SLOT, |
638 | (i << 4) | i); | 691 | hdmi_channel_mapping[ca][i]); |
692 | if (err) { | ||
693 | snd_printdd(KERN_INFO "HDMI: channel mapping failed\n"); | ||
694 | break; | ||
695 | } | ||
696 | } | ||
639 | 697 | ||
640 | hdmi_debug_channel_mapping(codec, nid); | 698 | hdmi_debug_channel_mapping(codec, pin_nid); |
641 | } | 699 | } |
642 | 700 | ||
643 | static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, | 701 | static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, |
@@ -676,7 +734,6 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
676 | }; | 734 | }; |
677 | 735 | ||
678 | hdmi_setup_channel_allocation(codec, nid, &ai); | 736 | hdmi_setup_channel_allocation(codec, nid, &ai); |
679 | hdmi_setup_channel_mapping(codec, nid, &ai); | ||
680 | 737 | ||
681 | for (i = 0; i < spec->num_pins; i++) { | 738 | for (i = 0; i < spec->num_pins; i++) { |
682 | if (spec->pin_cvt[i] != nid) | 739 | if (spec->pin_cvt[i] != nid) |
@@ -686,6 +743,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
686 | 743 | ||
687 | pin_nid = spec->pin[i]; | 744 | pin_nid = spec->pin[i]; |
688 | if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) { | 745 | if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) { |
746 | hdmi_setup_channel_mapping(codec, pin_nid, &ai); | ||
689 | hdmi_stop_infoframe_trans(codec, pin_nid); | 747 | hdmi_stop_infoframe_trans(codec, pin_nid); |
690 | hdmi_fill_audio_infoframe(codec, pin_nid, &ai); | 748 | hdmi_fill_audio_infoframe(codec, pin_nid, &ai); |
691 | hdmi_start_infoframe_trans(codec, pin_nid); | 749 | hdmi_start_infoframe_trans(codec, pin_nid); |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6b0bc040c3b1..3d59f8325848 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -209,6 +209,7 @@ struct sigmatel_spec { | |||
209 | unsigned int gpio_data; | 209 | unsigned int gpio_data; |
210 | unsigned int gpio_mute; | 210 | unsigned int gpio_mute; |
211 | unsigned int gpio_led; | 211 | unsigned int gpio_led; |
212 | unsigned int gpio_led_polarity; | ||
212 | 213 | ||
213 | /* stream */ | 214 | /* stream */ |
214 | unsigned int stream_delay; | 215 | unsigned int stream_delay; |
@@ -1538,6 +1539,13 @@ static unsigned int alienware_m17x_pin_configs[13] = { | |||
1538 | 0x904601b0, | 1539 | 0x904601b0, |
1539 | }; | 1540 | }; |
1540 | 1541 | ||
1542 | static unsigned int intel_dg45id_pin_configs[14] = { | ||
1543 | 0x02214230, 0x02A19240, 0x01013214, 0x01014210, | ||
1544 | 0x01A19250, 0x01011212, 0x01016211, 0x40f000f0, | ||
1545 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x014510A0, | ||
1546 | 0x074510B0, 0x40f000f0 | ||
1547 | }; | ||
1548 | |||
1541 | static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { | 1549 | static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { |
1542 | [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, | 1550 | [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, |
1543 | [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, | 1551 | [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, |
@@ -1545,6 +1553,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { | |||
1545 | [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, | 1553 | [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, |
1546 | [STAC_DELL_EQ] = dell_m6_pin_configs, | 1554 | [STAC_DELL_EQ] = dell_m6_pin_configs, |
1547 | [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs, | 1555 | [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs, |
1556 | [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs, | ||
1548 | }; | 1557 | }; |
1549 | 1558 | ||
1550 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { | 1559 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { |
@@ -4724,13 +4733,61 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
4724 | } | 4733 | } |
4725 | } | 4734 | } |
4726 | 4735 | ||
4727 | static int hp_bseries_system(u32 subsystem_id) | 4736 | /* |
4737 | * This method searches for the mute LED GPIO configuration | ||
4738 | * provided as OEM string in SMBIOS. The format of that string | ||
4739 | * is HP_Mute_LED_P_G or HP_Mute_LED_P | ||
4740 | * where P can be 0 or 1 and defines mute LED GPIO control state (low/high) | ||
4741 | * that corresponds to the NOT muted state of the master volume | ||
4742 | * and G is the index of the GPIO to use as the mute LED control (0..9) | ||
4743 | * If _G portion is missing it is assigned based on the codec ID | ||
4744 | * | ||
4745 | * So, HP B-series like systems may have HP_Mute_LED_0 (current models) | ||
4746 | * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings | ||
4747 | */ | ||
4748 | static int find_mute_led_gpio(struct hda_codec *codec) | ||
4749 | { | ||
4750 | struct sigmatel_spec *spec = codec->spec; | ||
4751 | const struct dmi_device *dev = NULL; | ||
4752 | |||
4753 | if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { | ||
4754 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, | ||
4755 | NULL, dev))) { | ||
4756 | if (sscanf(dev->name, "HP_Mute_LED_%d_%d", | ||
4757 | &spec->gpio_led_polarity, | ||
4758 | &spec->gpio_led) == 2) { | ||
4759 | spec->gpio_led = 1 << spec->gpio_led; | ||
4760 | return 1; | ||
4761 | } | ||
4762 | if (sscanf(dev->name, "HP_Mute_LED_%d", | ||
4763 | &spec->gpio_led_polarity) == 1) { | ||
4764 | switch (codec->vendor_id) { | ||
4765 | case 0x111d7608: | ||
4766 | /* GPIO 0 */ | ||
4767 | spec->gpio_led = 0x01; | ||
4768 | return 1; | ||
4769 | case 0x111d7600: | ||
4770 | case 0x111d7601: | ||
4771 | case 0x111d7602: | ||
4772 | case 0x111d7603: | ||
4773 | /* GPIO 3 */ | ||
4774 | spec->gpio_led = 0x08; | ||
4775 | return 1; | ||
4776 | } | ||
4777 | } | ||
4778 | } | ||
4779 | } | ||
4780 | return 0; | ||
4781 | } | ||
4782 | |||
4783 | static int hp_blike_system(u32 subsystem_id) | ||
4728 | { | 4784 | { |
4729 | switch (subsystem_id) { | 4785 | switch (subsystem_id) { |
4730 | case 0x103c307e: | 4786 | case 0x103c1520: |
4731 | case 0x103c307f: | 4787 | case 0x103c1521: |
4732 | case 0x103c3080: | 4788 | case 0x103c1523: |
4733 | case 0x103c3081: | 4789 | case 0x103c1524: |
4790 | case 0x103c1525: | ||
4734 | case 0x103c1722: | 4791 | case 0x103c1722: |
4735 | case 0x103c1723: | 4792 | case 0x103c1723: |
4736 | case 0x103c1724: | 4793 | case 0x103c1724: |
@@ -4739,6 +4796,14 @@ static int hp_bseries_system(u32 subsystem_id) | |||
4739 | case 0x103c1727: | 4796 | case 0x103c1727: |
4740 | case 0x103c1728: | 4797 | case 0x103c1728: |
4741 | case 0x103c1729: | 4798 | case 0x103c1729: |
4799 | case 0x103c172a: | ||
4800 | case 0x103c172b: | ||
4801 | case 0x103c307e: | ||
4802 | case 0x103c307f: | ||
4803 | case 0x103c3080: | ||
4804 | case 0x103c3081: | ||
4805 | case 0x103c7007: | ||
4806 | case 0x103c7008: | ||
4742 | return 1; | 4807 | return 1; |
4743 | } | 4808 | } |
4744 | return 0; | 4809 | return 0; |
@@ -4833,7 +4898,7 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, | |||
4833 | else | 4898 | else |
4834 | spec->gpio_data |= spec->gpio_led; /* white */ | 4899 | spec->gpio_data |= spec->gpio_led; /* white */ |
4835 | 4900 | ||
4836 | if (hp_bseries_system(codec->subsystem_id)) { | 4901 | if (!spec->gpio_led_polarity) { |
4837 | /* LED state is inverted on these systems */ | 4902 | /* LED state is inverted on these systems */ |
4838 | spec->gpio_data ^= spec->gpio_led; | 4903 | spec->gpio_data ^= spec->gpio_led; |
4839 | } | 4904 | } |
@@ -5526,7 +5591,7 @@ again: | |||
5526 | break; | 5591 | break; |
5527 | } | 5592 | } |
5528 | 5593 | ||
5529 | if (hp_bseries_system(codec->subsystem_id)) { | 5594 | if (hp_blike_system(codec->subsystem_id)) { |
5530 | pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); | 5595 | pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); |
5531 | if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || | 5596 | if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || |
5532 | get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || | 5597 | get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || |
@@ -5544,26 +5609,10 @@ again: | |||
5544 | } | 5609 | } |
5545 | } | 5610 | } |
5546 | 5611 | ||
5547 | if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { | 5612 | if (find_mute_led_gpio(codec)) |
5548 | const struct dmi_device *dev = NULL; | 5613 | snd_printd("mute LED gpio %d polarity %d\n", |
5549 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, | 5614 | spec->gpio_led, |
5550 | NULL, dev))) { | 5615 | spec->gpio_led_polarity); |
5551 | if (strcmp(dev->name, "HP_Mute_LED_1")) { | ||
5552 | switch (codec->vendor_id) { | ||
5553 | case 0x111d7608: | ||
5554 | spec->gpio_led = 0x01; | ||
5555 | break; | ||
5556 | case 0x111d7600: | ||
5557 | case 0x111d7601: | ||
5558 | case 0x111d7602: | ||
5559 | case 0x111d7603: | ||
5560 | spec->gpio_led = 0x08; | ||
5561 | break; | ||
5562 | } | ||
5563 | break; | ||
5564 | } | ||
5565 | } | ||
5566 | } | ||
5567 | 5616 | ||
5568 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5617 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5569 | if (spec->gpio_led) { | 5618 | if (spec->gpio_led) { |