aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaliy Kulikov <Vitaliy.Kulikov@idt.com>2009-12-11 01:51:54 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-11 01:51:54 -0500
commitc357aab02ee8de1f833579861ebd1e5683d2e806 (patch)
tree00f55160e3501b7efff4e4fb47d9be0b99a95c14
parent7aee67466536bbf8bb44a95712c848a61c5a0acd (diff)
ALSA: hda - Fix LED GPIO setup for HP laptops with IDT codecs
This patch fixes an error in processing of the HP BIOS configuration to enable GPIO based mute LED indicator control. That error causes driver to enable such control on all HP systems with the 92HD75 IDT codecs and results in unnecessary toggling of the GPIO on mute control manipulation. It also adds support of the future HP BIOS configuration extension for the named control. New configuration string has a format HP_Mute_LED_P_G where P can be 0 or 1 and defines mute LED GPIO control state (low/high) that corresponds to the NOT muted state of the master volume and G is the index of the GPIO to use (0..9) Lastly, it adds more systems to the support of the audio implementation as found on HP B-series systems Signed-off-by: Vitaliy Kulikov <Vitaliy.Kulikov@idt.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/patch_sigmatel.c95
1 files changed, 68 insertions, 27 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6b0bc040c3b1..e66672317e57 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;
@@ -4724,13 +4725,61 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4724 } 4725 }
4725} 4726}
4726 4727
4727static int hp_bseries_system(u32 subsystem_id) 4728/*
4729 * This method searches for the mute LED GPIO configuration
4730 * provided as OEM string in SMBIOS. The format of that string
4731 * is HP_Mute_LED_P_G or HP_Mute_LED_P
4732 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
4733 * that corresponds to the NOT muted state of the master volume
4734 * and G is the index of the GPIO to use as the mute LED control (0..9)
4735 * If _G portion is missing it is assigned based on the codec ID
4736 *
4737 * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
4738 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
4739 */
4740static int find_mute_led_gpio(struct hda_codec *codec)
4741{
4742 struct sigmatel_spec *spec = codec->spec;
4743 const struct dmi_device *dev = NULL;
4744
4745 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
4746 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
4747 NULL, dev))) {
4748 if (sscanf(dev->name, "HP_Mute_LED_%d_%d",
4749 &spec->gpio_led_polarity,
4750 &spec->gpio_led) == 2) {
4751 spec->gpio_led = 1 << spec->gpio_led;
4752 return 1;
4753 }
4754 if (sscanf(dev->name, "HP_Mute_LED_%d",
4755 &spec->gpio_led_polarity) == 1) {
4756 switch (codec->vendor_id) {
4757 case 0x111d7608:
4758 /* GPIO 0 */
4759 spec->gpio_led = 0x01;
4760 return 1;
4761 case 0x111d7600:
4762 case 0x111d7601:
4763 case 0x111d7602:
4764 case 0x111d7603:
4765 /* GPIO 3 */
4766 spec->gpio_led = 0x08;
4767 return 1;
4768 }
4769 }
4770 }
4771 }
4772 return 0;
4773}
4774
4775static int hp_blike_system(u32 subsystem_id)
4728{ 4776{
4729 switch (subsystem_id) { 4777 switch (subsystem_id) {
4730 case 0x103c307e: 4778 case 0x103c1520:
4731 case 0x103c307f: 4779 case 0x103c1521:
4732 case 0x103c3080: 4780 case 0x103c1523:
4733 case 0x103c3081: 4781 case 0x103c1524:
4782 case 0x103c1525:
4734 case 0x103c1722: 4783 case 0x103c1722:
4735 case 0x103c1723: 4784 case 0x103c1723:
4736 case 0x103c1724: 4785 case 0x103c1724:
@@ -4739,6 +4788,14 @@ static int hp_bseries_system(u32 subsystem_id)
4739 case 0x103c1727: 4788 case 0x103c1727:
4740 case 0x103c1728: 4789 case 0x103c1728:
4741 case 0x103c1729: 4790 case 0x103c1729:
4791 case 0x103c172a:
4792 case 0x103c172b:
4793 case 0x103c307e:
4794 case 0x103c307f:
4795 case 0x103c3080:
4796 case 0x103c3081:
4797 case 0x103c7007:
4798 case 0x103c7008:
4742 return 1; 4799 return 1;
4743 } 4800 }
4744 return 0; 4801 return 0;
@@ -4833,7 +4890,7 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4833 else 4890 else
4834 spec->gpio_data |= spec->gpio_led; /* white */ 4891 spec->gpio_data |= spec->gpio_led; /* white */
4835 4892
4836 if (hp_bseries_system(codec->subsystem_id)) { 4893 if (!spec->gpio_led_polarity) {
4837 /* LED state is inverted on these systems */ 4894 /* LED state is inverted on these systems */
4838 spec->gpio_data ^= spec->gpio_led; 4895 spec->gpio_data ^= spec->gpio_led;
4839 } 4896 }
@@ -5526,7 +5583,7 @@ again:
5526 break; 5583 break;
5527 } 5584 }
5528 5585
5529 if (hp_bseries_system(codec->subsystem_id)) { 5586 if (hp_blike_system(codec->subsystem_id)) {
5530 pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); 5587 pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
5531 if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || 5588 if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
5532 get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || 5589 get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER ||
@@ -5544,26 +5601,10 @@ again:
5544 } 5601 }
5545 } 5602 }
5546 5603
5547 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { 5604 if (find_mute_led_gpio(codec))
5548 const struct dmi_device *dev = NULL; 5605 snd_printd("mute LED gpio %d polarity %d\n",
5549 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, 5606 spec->gpio_led,
5550 NULL, dev))) { 5607 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 5608
5568#ifdef CONFIG_SND_HDA_POWER_SAVE 5609#ifdef CONFIG_SND_HDA_POWER_SAVE
5569 if (spec->gpio_led) { 5610 if (spec->gpio_led) {