aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c103
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
1542static 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
1541static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { 1549static 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
1550static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { 1559static 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
4727static 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 */
4748static 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
4783static 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) {