diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 103 |
1 files changed, 76 insertions, 27 deletions
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) { |