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.c318
1 files changed, 245 insertions, 73 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7f81cc2274f..aa376b59c00 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -95,6 +95,7 @@ enum {
95 STAC_92HD83XXX_PWR_REF, 95 STAC_92HD83XXX_PWR_REF,
96 STAC_DELL_S14, 96 STAC_DELL_S14,
97 STAC_92HD83XXX_HP, 97 STAC_92HD83XXX_HP,
98 STAC_92HD83XXX_HP_cNB11_INTQUAD,
98 STAC_HP_DV7_4000, 99 STAC_HP_DV7_4000,
99 STAC_92HD83XXX_MODELS 100 STAC_92HD83XXX_MODELS
100}; 101};
@@ -212,6 +213,7 @@ struct sigmatel_spec {
212 unsigned int gpio_mute; 213 unsigned int gpio_mute;
213 unsigned int gpio_led; 214 unsigned int gpio_led;
214 unsigned int gpio_led_polarity; 215 unsigned int gpio_led_polarity;
216 unsigned int vref_led;
215 217
216 /* stream */ 218 /* stream */
217 unsigned int stream_delay; 219 unsigned int stream_delay;
@@ -671,6 +673,30 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
671 return 0; 673 return 0;
672} 674}
673 675
676static int stac_vrefout_set(struct hda_codec *codec,
677 hda_nid_t nid, unsigned int new_vref)
678{
679 int error, pinctl;
680
681 snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
682 pinctl = snd_hda_codec_read(codec, nid, 0,
683 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
684
685 if (pinctl < 0)
686 return pinctl;
687
688 pinctl &= 0xff;
689 pinctl &= ~AC_PINCTL_VREFEN;
690 pinctl |= (new_vref & AC_PINCTL_VREFEN);
691
692 error = snd_hda_codec_write_cache(codec, nid, 0,
693 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
694 if (error < 0)
695 return error;
696
697 return 1;
698}
699
674static unsigned int stac92xx_vref_set(struct hda_codec *codec, 700static unsigned int stac92xx_vref_set(struct hda_codec *codec,
675 hda_nid_t nid, unsigned int new_vref) 701 hda_nid_t nid, unsigned int new_vref)
676{ 702{
@@ -1112,7 +1138,9 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1112 } 1138 }
1113 1139
1114 if (spec->multiout.dig_out_nid) { 1140 if (spec->multiout.dig_out_nid) {
1115 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 1141 err = snd_hda_create_spdif_out_ctls(codec,
1142 spec->multiout.dig_out_nid,
1143 spec->multiout.dig_out_nid);
1116 if (err < 0) 1144 if (err < 0)
1117 return err; 1145 return err;
1118 err = snd_hda_create_spdif_share_sw(codec, 1146 err = snd_hda_create_spdif_share_sw(codec,
@@ -1634,10 +1662,17 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = {
1634 0x40f000f0, 0x40f000f0, 1662 0x40f000f0, 0x40f000f0,
1635}; 1663};
1636 1664
1665static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
1666 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
1667 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
1668 0x40f000f0, 0x40f000f0,
1669};
1670
1637static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { 1671static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1638 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, 1672 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1639 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, 1673 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
1640 [STAC_DELL_S14] = dell_s14_pin_configs, 1674 [STAC_DELL_S14] = dell_s14_pin_configs,
1675 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
1641 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1676 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1642}; 1677};
1643 1678
@@ -1647,6 +1682,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1647 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1682 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
1648 [STAC_DELL_S14] = "dell-s14", 1683 [STAC_DELL_S14] = "dell-s14",
1649 [STAC_92HD83XXX_HP] = "hp", 1684 [STAC_92HD83XXX_HP] = "hp",
1685 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1650 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1686 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1651}; 1687};
1652 1688
@@ -1659,7 +1695,47 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1659 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, 1695 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
1660 "unknown Dell", STAC_DELL_S14), 1696 "unknown Dell", STAC_DELL_S14),
1661 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, 1697 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
1662 "HP", STAC_92HD83XXX_HP), 1698 "HP", STAC_92HD83XXX_HP),
1699 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
1700 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1701 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
1702 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1703 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
1704 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1705 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
1706 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1707 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
1708 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1709 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
1710 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1711 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
1712 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1713 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
1714 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1715 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
1716 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1717 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
1718 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1719 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
1720 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1721 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
1722 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1723 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
1724 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
1726 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1727 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
1728 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1729 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
1730 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1731 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
1732 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1733 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
1734 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1735 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
1736 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1737 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
1738 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1663 {} /* terminator */ 1739 {} /* terminator */
1664}; 1740};
1665 1741
@@ -3406,30 +3482,9 @@ static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
3406 return 0; 3482 return 0;
3407} 3483}
3408 3484
3409static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3485/* look for NID recursively */
3410 hda_nid_t nid) 3486#define get_connection_index(codec, mux, nid) \
3411{ 3487 snd_hda_get_conn_index(codec, mux, nid, 1)
3412 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3413 int i, nums;
3414
3415 if (!(get_wcaps(codec, mux) & AC_WCAP_CONN_LIST))
3416 return -1;
3417
3418 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3419 for (i = 0; i < nums; i++)
3420 if (conn[i] == nid)
3421 return i;
3422
3423 for (i = 0; i < nums; i++) {
3424 unsigned int wid_caps = get_wcaps(codec, conn[i]);
3425 unsigned int wid_type = get_wcaps_type(wid_caps);
3426
3427 if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX)
3428 if (get_connection_index(codec, conn[i], nid) >= 0)
3429 return i;
3430 }
3431 return -1;
3432}
3433 3488
3434/* create a volume assigned to the given pin (only if supported) */ 3489/* create a volume assigned to the given pin (only if supported) */
3435/* return 1 if the volume control is created */ 3490/* return 1 if the volume control is created */
@@ -4039,6 +4094,8 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4039{ 4094{
4040 unsigned int gpiostate, gpiomask, gpiodir; 4095 unsigned int gpiostate, gpiomask, gpiodir;
4041 4096
4097 snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
4098
4042 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 4099 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
4043 AC_VERB_GET_GPIO_DATA, 0); 4100 AC_VERB_GET_GPIO_DATA, 0);
4044 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); 4101 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
@@ -4228,10 +4285,12 @@ static void stac_store_hints(struct hda_codec *codec)
4228 spec->eapd_switch = val; 4285 spec->eapd_switch = val;
4229 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); 4286 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4230 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { 4287 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4231 spec->gpio_mask |= spec->gpio_led; 4288 if (spec->gpio_led <= 8) {
4232 spec->gpio_dir |= spec->gpio_led; 4289 spec->gpio_mask |= spec->gpio_led;
4233 if (spec->gpio_led_polarity) 4290 spec->gpio_dir |= spec->gpio_led;
4234 spec->gpio_data |= spec->gpio_led; 4291 if (spec->gpio_led_polarity)
4292 spec->gpio_data |= spec->gpio_led;
4293 }
4235 } 4294 }
4236} 4295}
4237 4296
@@ -4401,11 +4460,26 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
4401 snd_array_free(&spec->kctls); 4460 snd_array_free(&spec->kctls);
4402} 4461}
4403 4462
4463static void stac92xx_shutup_pins(struct hda_codec *codec)
4464{
4465 unsigned int i, def_conf;
4466
4467 if (codec->bus->shutdown)
4468 return;
4469 for (i = 0; i < codec->init_pins.used; i++) {
4470 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
4471 def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
4472 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
4473 snd_hda_codec_write(codec, pin->nid, 0,
4474 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4475 }
4476}
4477
4404static void stac92xx_shutup(struct hda_codec *codec) 4478static void stac92xx_shutup(struct hda_codec *codec)
4405{ 4479{
4406 struct sigmatel_spec *spec = codec->spec; 4480 struct sigmatel_spec *spec = codec->spec;
4407 4481
4408 snd_hda_shutup_pins(codec); 4482 stac92xx_shutup_pins(codec);
4409 4483
4410 if (spec->eapd_mask) 4484 if (spec->eapd_mask)
4411 stac_gpio_set(codec, spec->gpio_mask, 4485 stac_gpio_set(codec, spec->gpio_mask,
@@ -4803,10 +4877,11 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4803 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { 4877 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
4804 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, 4878 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
4805 NULL, dev))) { 4879 NULL, dev))) {
4806 if (sscanf(dev->name, "HP_Mute_LED_%d_%d", 4880 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
4807 &spec->gpio_led_polarity, 4881 &spec->gpio_led_polarity,
4808 &spec->gpio_led) == 2) { 4882 &spec->gpio_led) == 2) {
4809 spec->gpio_led = 1 << spec->gpio_led; 4883 if (spec->gpio_led < 4)
4884 spec->gpio_led = 1 << spec->gpio_led;
4810 return 1; 4885 return 1;
4811 } 4886 }
4812 if (sscanf(dev->name, "HP_Mute_LED_%d", 4887 if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -4904,7 +4979,7 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4904#define stac927x_proc_hook NULL 4979#define stac927x_proc_hook NULL
4905#endif 4980#endif
4906 4981
4907#ifdef SND_HDA_NEEDS_RESUME 4982#ifdef CONFIG_PM
4908static int stac92xx_resume(struct hda_codec *codec) 4983static int stac92xx_resume(struct hda_codec *codec)
4909{ 4984{
4910 struct sigmatel_spec *spec = codec->spec; 4985 struct sigmatel_spec *spec = codec->spec;
@@ -4920,29 +4995,81 @@ static int stac92xx_resume(struct hda_codec *codec)
4920 stac_issue_unsol_event(codec, 4995 stac_issue_unsol_event(codec,
4921 spec->autocfg.line_out_pins[0]); 4996 spec->autocfg.line_out_pins[0]);
4922 } 4997 }
4998 return 0;
4999}
5000
5001static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
5002{
5003 stac92xx_shutup(codec);
5004 return 0;
5005}
5006
5007#ifdef CONFIG_SND_HDA_POWER_SAVE
5008static int stac92xx_pre_resume(struct hda_codec *codec)
5009{
5010 struct sigmatel_spec *spec = codec->spec;
5011
4923 /* sync mute LED */ 5012 /* sync mute LED */
4924 if (spec->gpio_led) 5013 if (spec->gpio_led) {
4925 hda_call_check_power_status(codec, 0x01); 5014 if (spec->gpio_led <= 8) {
5015 stac_gpio_set(codec, spec->gpio_mask,
5016 spec->gpio_dir, spec->gpio_data);
5017 } else {
5018 stac_vrefout_set(codec,
5019 spec->gpio_led, spec->vref_led);
5020 }
5021 }
5022 return 0;
5023}
5024
5025static int stac92xx_post_suspend(struct hda_codec *codec)
5026{
5027 struct sigmatel_spec *spec = codec->spec;
5028 if (spec->gpio_led > 8) {
5029 /* with vref-out pin used for mute led control
5030 * codec AFG is prevented from D3 state, but on
5031 * system suspend it can (and should) be used
5032 */
5033 snd_hda_codec_read(codec, codec->afg, 0,
5034 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5035 }
4926 return 0; 5036 return 0;
4927} 5037}
4928 5038
5039static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5040 unsigned int power_state)
5041{
5042 unsigned int afg_power_state = power_state;
5043 struct sigmatel_spec *spec = codec->spec;
5044
5045 if (power_state == AC_PWRST_D3) {
5046 if (spec->gpio_led > 8) {
5047 /* with vref-out pin used for mute led control
5048 * codec AFG is prevented from D3 state
5049 */
5050 afg_power_state = AC_PWRST_D1;
5051 }
5052 /* this delay seems necessary to avoid click noise at power-down */
5053 msleep(100);
5054 }
5055 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
5056 afg_power_state);
5057 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
5058}
5059
4929/* 5060/*
4930 * using power check for controlling mute led of HP notebooks 5061 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed
4931 * check for mute state only on Speakers (nid = 0x10) 5062 * as mute LED state is updated in check_power_status hook
4932 *
4933 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise
4934 * the LED is NOT working properly !
4935 *
4936 * Changed name to reflect that it now works for any designated
4937 * model, not just HP HDX.
4938 */ 5063 */
4939 5064static int stac92xx_update_led_status(struct hda_codec *codec)
4940#ifdef CONFIG_SND_HDA_POWER_SAVE
4941static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4942 hda_nid_t nid)
4943{ 5065{
4944 struct sigmatel_spec *spec = codec->spec; 5066 struct sigmatel_spec *spec = codec->spec;
4945 int i, muted = 1; 5067 int i, num_ext_dacs, muted = 1;
5068 unsigned int muted_lvl, notmtd_lvl;
5069 hda_nid_t nid;
5070
5071 if (!spec->gpio_led)
5072 return 0;
4946 5073
4947 for (i = 0; i < spec->multiout.num_dacs; i++) { 5074 for (i = 0; i < spec->multiout.num_dacs; i++) {
4948 nid = spec->multiout.dac_nids[i]; 5075 nid = spec->multiout.dac_nids[i];
@@ -4952,27 +5079,58 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4952 break; 5079 break;
4953 } 5080 }
4954 } 5081 }
4955 if (muted) 5082 if (muted && spec->multiout.hp_nid)
4956 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5083 if (!(snd_hda_codec_amp_read(codec,
4957 else 5084 spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
4958 spec->gpio_data |= spec->gpio_led; /* white */ 5085 HDA_AMP_MUTE)) {
4959 5086 muted = 0; /* HP is not muted */
4960 if (!spec->gpio_led_polarity) { 5087 }
4961 /* LED state is inverted on these systems */ 5088 num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
4962 spec->gpio_data ^= spec->gpio_led; 5089 for (i = 0; muted && i < num_ext_dacs; i++) {
5090 nid = spec->multiout.extra_out_nid[i];
5091 if (nid == 0)
5092 break;
5093 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5094 HDA_AMP_MUTE)) {
5095 muted = 0; /* extra output is not muted */
5096 }
4963 } 5097 }
5098 /*polarity defines *not* muted state level*/
5099 if (spec->gpio_led <= 8) {
5100 if (muted)
5101 spec->gpio_data &= ~spec->gpio_led; /* orange */
5102 else
5103 spec->gpio_data |= spec->gpio_led; /* white */
4964 5104
4965 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 5105 if (!spec->gpio_led_polarity) {
5106 /* LED state is inverted on these systems */
5107 spec->gpio_data ^= spec->gpio_led;
5108 }
5109 stac_gpio_set(codec, spec->gpio_mask,
5110 spec->gpio_dir, spec->gpio_data);
5111 } else {
5112 notmtd_lvl = spec->gpio_led_polarity ?
5113 AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD;
5114 muted_lvl = spec->gpio_led_polarity ?
5115 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5116 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5117 stac_vrefout_set(codec, spec->gpio_led, spec->vref_led);
5118 }
4966 return 0; 5119 return 0;
4967} 5120}
4968#endif
4969 5121
4970static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 5122/*
5123 * use power check for controlling mute led of HP notebooks
5124 */
5125static int stac92xx_check_power_status(struct hda_codec *codec,
5126 hda_nid_t nid)
4971{ 5127{
4972 stac92xx_shutup(codec); 5128 stac92xx_update_led_status(codec);
5129
4973 return 0; 5130 return 0;
4974} 5131}
4975#endif 5132#endif /* CONFIG_SND_HDA_POWER_SAVE */
5133#endif /* CONFIG_PM */
4976 5134
4977static const struct hda_codec_ops stac92xx_patch_ops = { 5135static const struct hda_codec_ops stac92xx_patch_ops = {
4978 .build_controls = stac92xx_build_controls, 5136 .build_controls = stac92xx_build_controls,
@@ -4980,7 +5138,7 @@ static const struct hda_codec_ops stac92xx_patch_ops = {
4980 .init = stac92xx_init, 5138 .init = stac92xx_init,
4981 .free = stac92xx_free, 5139 .free = stac92xx_free,
4982 .unsol_event = stac92xx_unsol_event, 5140 .unsol_event = stac92xx_unsol_event,
4983#ifdef SND_HDA_NEEDS_RESUME 5141#ifdef CONFIG_PM
4984 .suspend = stac92xx_suspend, 5142 .suspend = stac92xx_suspend,
4985 .resume = stac92xx_resume, 5143 .resume = stac92xx_resume,
4986#endif 5144#endif
@@ -5496,12 +5654,19 @@ again:
5496 5654
5497#ifdef CONFIG_SND_HDA_POWER_SAVE 5655#ifdef CONFIG_SND_HDA_POWER_SAVE
5498 if (spec->gpio_led) { 5656 if (spec->gpio_led) {
5499 spec->gpio_mask |= spec->gpio_led; 5657 if (spec->gpio_led <= 8) {
5500 spec->gpio_dir |= spec->gpio_led; 5658 spec->gpio_mask |= spec->gpio_led;
5501 spec->gpio_data |= spec->gpio_led; 5659 spec->gpio_dir |= spec->gpio_led;
5502 /* register check_power_status callback. */ 5660 spec->gpio_data |= spec->gpio_led;
5661 } else {
5662 codec->patch_ops.set_power_state =
5663 stac92xx_set_power_state;
5664 codec->patch_ops.post_suspend =
5665 stac92xx_post_suspend;
5666 }
5667 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5503 codec->patch_ops.check_power_status = 5668 codec->patch_ops.check_power_status =
5504 stac92xx_hp_check_power_status; 5669 stac92xx_check_power_status;
5505 } 5670 }
5506#endif 5671#endif
5507 5672
@@ -5824,12 +5989,19 @@ again:
5824 5989
5825#ifdef CONFIG_SND_HDA_POWER_SAVE 5990#ifdef CONFIG_SND_HDA_POWER_SAVE
5826 if (spec->gpio_led) { 5991 if (spec->gpio_led) {
5827 spec->gpio_mask |= spec->gpio_led; 5992 if (spec->gpio_led <= 8) {
5828 spec->gpio_dir |= spec->gpio_led; 5993 spec->gpio_mask |= spec->gpio_led;
5829 spec->gpio_data |= spec->gpio_led; 5994 spec->gpio_dir |= spec->gpio_led;
5830 /* register check_power_status callback. */ 5995 spec->gpio_data |= spec->gpio_led;
5996 } else {
5997 codec->patch_ops.set_power_state =
5998 stac92xx_set_power_state;
5999 codec->patch_ops.post_suspend =
6000 stac92xx_post_suspend;
6001 }
6002 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5831 codec->patch_ops.check_power_status = 6003 codec->patch_ops.check_power_status =
5832 stac92xx_hp_check_power_status; 6004 stac92xx_check_power_status;
5833 } 6005 }
5834#endif 6006#endif
5835 6007