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.c113
1 files changed, 49 insertions, 64 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 4e715fefebef..eeb25d529e30 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -95,6 +95,7 @@ enum {
95 STAC_92HD83XXX_REF, 95 STAC_92HD83XXX_REF,
96 STAC_92HD83XXX_PWR_REF, 96 STAC_92HD83XXX_PWR_REF,
97 STAC_DELL_S14, 97 STAC_DELL_S14,
98 STAC_DELL_VOSTRO_3500,
98 STAC_92HD83XXX_HP, 99 STAC_92HD83XXX_HP,
99 STAC_92HD83XXX_HP_cNB11_INTQUAD, 100 STAC_92HD83XXX_HP_cNB11_INTQUAD,
100 STAC_HP_DV7_4000, 101 STAC_HP_DV7_4000,
@@ -214,6 +215,7 @@ struct sigmatel_spec {
214 unsigned int gpio_mute; 215 unsigned int gpio_mute;
215 unsigned int gpio_led; 216 unsigned int gpio_led;
216 unsigned int gpio_led_polarity; 217 unsigned int gpio_led_polarity;
218 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
217 unsigned int vref_led; 219 unsigned int vref_led;
218 220
219 /* stream */ 221 /* stream */
@@ -226,7 +228,6 @@ struct sigmatel_spec {
226 228
227 /* power management */ 229 /* power management */
228 unsigned int num_pwrs; 230 unsigned int num_pwrs;
229 const unsigned int *pwr_mapping;
230 const hda_nid_t *pwr_nids; 231 const hda_nid_t *pwr_nids;
231 const hda_nid_t *dac_list; 232 const hda_nid_t *dac_list;
232 233
@@ -373,18 +374,15 @@ static const unsigned long stac92hd73xx_capvols[] = {
373 374
374#define STAC92HD83_DAC_COUNT 3 375#define STAC92HD83_DAC_COUNT 3
375 376
376static const hda_nid_t stac92hd83xxx_pwr_nids[4] = { 377static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
377 0xa, 0xb, 0xd, 0xe, 378 0x0a, 0x0b, 0x0c, 0xd, 0x0e,
379 0x0f, 0x10
378}; 380};
379 381
380static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { 382static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
381 0x1e, 0, 383 0x1e, 0,
382}; 384};
383 385
384static const unsigned int stac92hd83xxx_pwr_mapping[4] = {
385 0x03, 0x0c, 0x20, 0x40,
386};
387
388static const hda_nid_t stac92hd83xxx_dmic_nids[] = { 386static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
389 0x11, 0x20, 387 0x11, 0x20,
390}; 388};
@@ -1644,6 +1642,8 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
1644 "Alienware M17x", STAC_ALIENWARE_M17X), 1642 "Alienware M17x", STAC_ALIENWARE_M17X),
1645 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, 1643 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
1646 "Alienware M17x", STAC_ALIENWARE_M17X), 1644 "Alienware M17x", STAC_ALIENWARE_M17X),
1645 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
1646 "Alienware M17x", STAC_ALIENWARE_M17X),
1647 {} /* terminator */ 1647 {} /* terminator */
1648}; 1648};
1649 1649
@@ -1659,6 +1659,12 @@ static const unsigned int dell_s14_pin_configs[10] = {
1659 0x40f000f0, 0x40f000f0, 1659 0x40f000f0, 0x40f000f0,
1660}; 1660};
1661 1661
1662static const unsigned int dell_vostro_3500_pin_configs[10] = {
1663 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110,
1664 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160,
1665 0x400000f4, 0x400000f5,
1666};
1667
1662static const unsigned int hp_dv7_4000_pin_configs[10] = { 1668static const unsigned int hp_dv7_4000_pin_configs[10] = {
1663 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 1669 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
1664 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, 1670 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
@@ -1675,6 +1681,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1675 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, 1681 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1676 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, 1682 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
1677 [STAC_DELL_S14] = dell_s14_pin_configs, 1683 [STAC_DELL_S14] = dell_s14_pin_configs,
1684 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
1678 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, 1685 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
1679 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1686 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1680}; 1687};
@@ -1684,6 +1691,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1684 [STAC_92HD83XXX_REF] = "ref", 1691 [STAC_92HD83XXX_REF] = "ref",
1685 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1692 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
1686 [STAC_DELL_S14] = "dell-s14", 1693 [STAC_DELL_S14] = "dell-s14",
1694 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
1687 [STAC_92HD83XXX_HP] = "hp", 1695 [STAC_92HD83XXX_HP] = "hp",
1688 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", 1696 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1689 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1697 [STAC_HP_DV7_4000] = "hp-dv7-4000",
@@ -1697,6 +1705,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1697 "DFI LanParty", STAC_92HD83XXX_REF), 1705 "DFI LanParty", STAC_92HD83XXX_REF),
1698 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, 1706 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
1699 "unknown Dell", STAC_DELL_S14), 1707 "unknown Dell", STAC_DELL_S14),
1708 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
1709 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
1700 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, 1710 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
1701 "HP", STAC_92HD83XXX_HP), 1711 "HP", STAC_92HD83XXX_HP),
1702 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, 1712 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
@@ -4309,12 +4319,10 @@ static void stac_store_hints(struct hda_codec *codec)
4309 spec->eapd_switch = val; 4319 spec->eapd_switch = val;
4310 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); 4320 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4311 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { 4321 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4312 if (spec->gpio_led <= 8) { 4322 spec->gpio_mask |= spec->gpio_led;
4313 spec->gpio_mask |= spec->gpio_led; 4323 spec->gpio_dir |= spec->gpio_led;
4314 spec->gpio_dir |= spec->gpio_led; 4324 if (spec->gpio_led_polarity)
4315 if (spec->gpio_led_polarity) 4325 spec->gpio_data |= spec->gpio_led;
4316 spec->gpio_data |= spec->gpio_led;
4317 }
4318 } 4326 }
4319} 4327}
4320 4328
@@ -4432,7 +4440,9 @@ static int stac92xx_init(struct hda_codec *codec)
4432 int pinctl, def_conf; 4440 int pinctl, def_conf;
4433 4441
4434 /* power on when no jack detection is available */ 4442 /* power on when no jack detection is available */
4435 if (!spec->hp_detect) { 4443 /* or when the VREF is used for controlling LED */
4444 if (!spec->hp_detect ||
4445 spec->vref_mute_led_nid == nid) {
4436 stac_toggle_power_map(codec, nid, 1); 4446 stac_toggle_power_map(codec, nid, 1);
4437 continue; 4447 continue;
4438 } 4448 }
@@ -4459,8 +4469,12 @@ static int stac92xx_init(struct hda_codec *codec)
4459 stac_toggle_power_map(codec, nid, 1); 4469 stac_toggle_power_map(codec, nid, 1);
4460 continue; 4470 continue;
4461 } 4471 }
4462 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) 4472 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
4463 stac_issue_unsol_event(codec, nid); 4473 stac_issue_unsol_event(codec, nid);
4474 continue;
4475 }
4476 /* none of the above, turn the port OFF */
4477 stac_toggle_power_map(codec, nid, 0);
4464 } 4478 }
4465 4479
4466 /* sync mute LED */ 4480 /* sync mute LED */
@@ -4716,11 +4730,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4716 if (idx >= spec->num_pwrs) 4730 if (idx >= spec->num_pwrs)
4717 return; 4731 return;
4718 4732
4719 /* several codecs have two power down bits */ 4733 idx = 1 << idx;
4720 if (spec->pwr_mapping)
4721 idx = spec->pwr_mapping[idx];
4722 else
4723 idx = 1 << idx;
4724 4734
4725 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; 4735 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff;
4726 if (enable) 4736 if (enable)
@@ -4904,8 +4914,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4904 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", 4914 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
4905 &spec->gpio_led_polarity, 4915 &spec->gpio_led_polarity,
4906 &spec->gpio_led) == 2) { 4916 &spec->gpio_led) == 2) {
4907 if (spec->gpio_led < 4) 4917 unsigned int max_gpio;
4918 max_gpio = snd_hda_param_read(codec, codec->afg,
4919 AC_PAR_GPIO_CAP);
4920 max_gpio &= AC_GPIO_IO_COUNT;
4921 if (spec->gpio_led < max_gpio)
4908 spec->gpio_led = 1 << spec->gpio_led; 4922 spec->gpio_led = 1 << spec->gpio_led;
4923 else
4924 spec->vref_mute_led_nid = spec->gpio_led;
4909 return 1; 4925 return 1;
4910 } 4926 }
4911 if (sscanf(dev->name, "HP_Mute_LED_%d", 4927 if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -5034,29 +5050,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec)
5034 struct sigmatel_spec *spec = codec->spec; 5050 struct sigmatel_spec *spec = codec->spec;
5035 5051
5036 /* sync mute LED */ 5052 /* sync mute LED */
5037 if (spec->gpio_led) { 5053 if (spec->vref_mute_led_nid)
5038 if (spec->gpio_led <= 8) { 5054 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5039 stac_gpio_set(codec, spec->gpio_mask, 5055 spec->vref_led);
5040 spec->gpio_dir, spec->gpio_data); 5056 else if (spec->gpio_led)
5041 } else { 5057 stac_gpio_set(codec, spec->gpio_mask,
5042 stac_vrefout_set(codec, 5058 spec->gpio_dir, spec->gpio_data);
5043 spec->gpio_led, spec->vref_led);
5044 }
5045 }
5046 return 0;
5047}
5048
5049static int stac92xx_post_suspend(struct hda_codec *codec)
5050{
5051 struct sigmatel_spec *spec = codec->spec;
5052 if (spec->gpio_led > 8) {
5053 /* with vref-out pin used for mute led control
5054 * codec AFG is prevented from D3 state, but on
5055 * system suspend it can (and should) be used
5056 */
5057 snd_hda_codec_read(codec, codec->afg, 0,
5058 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5059 }
5060 return 0; 5059 return 0;
5061} 5060}
5062 5061
@@ -5067,7 +5066,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5067 struct sigmatel_spec *spec = codec->spec; 5066 struct sigmatel_spec *spec = codec->spec;
5068 5067
5069 if (power_state == AC_PWRST_D3) { 5068 if (power_state == AC_PWRST_D3) {
5070 if (spec->gpio_led > 8) { 5069 if (spec->vref_mute_led_nid) {
5071 /* with vref-out pin used for mute led control 5070 /* with vref-out pin used for mute led control
5072 * codec AFG is prevented from D3 state 5071 * codec AFG is prevented from D3 state
5073 */ 5072 */
@@ -5120,7 +5119,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5120 } 5119 }
5121 } 5120 }
5122 /*polarity defines *not* muted state level*/ 5121 /*polarity defines *not* muted state level*/
5123 if (spec->gpio_led <= 8) { 5122 if (!spec->vref_mute_led_nid) {
5124 if (muted) 5123 if (muted)
5125 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5124 spec->gpio_data &= ~spec->gpio_led; /* orange */
5126 else 5125 else
@@ -5138,7 +5137,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5138 muted_lvl = spec->gpio_led_polarity ? 5137 muted_lvl = spec->gpio_led_polarity ?
5139 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; 5138 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5140 spec->vref_led = muted ? muted_lvl : notmtd_lvl; 5139 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5141 stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); 5140 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5141 spec->vref_led);
5142 } 5142 }
5143 return 0; 5143 return 0;
5144} 5144}
@@ -5618,9 +5618,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5618 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); 5618 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
5619 } 5619 }
5620 5620
5621 /* reset pin power-down; Windows may leave these bits after reboot */
5622 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0);
5623 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
5624 codec->no_trigger_sense = 1; 5621 codec->no_trigger_sense = 1;
5625 codec->spec = spec; 5622 codec->spec = spec;
5626 5623
@@ -5630,7 +5627,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5630 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5627 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5631 spec->digbeep_nid = 0x21; 5628 spec->digbeep_nid = 0x21;
5632 spec->pwr_nids = stac92hd83xxx_pwr_nids; 5629 spec->pwr_nids = stac92hd83xxx_pwr_nids;
5633 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
5634 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 5630 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
5635 spec->multiout.dac_nids = spec->dac_nids; 5631 spec->multiout.dac_nids = spec->dac_nids;
5636 spec->init = stac92hd83xxx_core_init; 5632 spec->init = stac92hd83xxx_core_init;
@@ -5647,9 +5643,6 @@ again:
5647 stac92xx_set_config_regs(codec, 5643 stac92xx_set_config_regs(codec,
5648 stac92hd83xxx_brd_tbl[spec->board_config]); 5644 stac92hd83xxx_brd_tbl[spec->board_config]);
5649 5645
5650 if (spec->board_config != STAC_92HD83XXX_PWR_REF)
5651 spec->num_pwrs = 0;
5652
5653 codec->patch_ops = stac92xx_patch_ops; 5646 codec->patch_ops = stac92xx_patch_ops;
5654 5647
5655 if (find_mute_led_gpio(codec, 0)) 5648 if (find_mute_led_gpio(codec, 0))
@@ -5659,15 +5652,13 @@ again:
5659 5652
5660#ifdef CONFIG_SND_HDA_POWER_SAVE 5653#ifdef CONFIG_SND_HDA_POWER_SAVE
5661 if (spec->gpio_led) { 5654 if (spec->gpio_led) {
5662 if (spec->gpio_led <= 8) { 5655 if (!spec->vref_mute_led_nid) {
5663 spec->gpio_mask |= spec->gpio_led; 5656 spec->gpio_mask |= spec->gpio_led;
5664 spec->gpio_dir |= spec->gpio_led; 5657 spec->gpio_dir |= spec->gpio_led;
5665 spec->gpio_data |= spec->gpio_led; 5658 spec->gpio_data |= spec->gpio_led;
5666 } else { 5659 } else {
5667 codec->patch_ops.set_power_state = 5660 codec->patch_ops.set_power_state =
5668 stac92xx_set_power_state; 5661 stac92xx_set_power_state;
5669 codec->patch_ops.post_suspend =
5670 stac92xx_post_suspend;
5671 } 5662 }
5672 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5663 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5673 codec->patch_ops.check_power_status = 5664 codec->patch_ops.check_power_status =
@@ -5858,8 +5849,6 @@ again:
5858 (codec->revision_id & 0xf) == 1) 5849 (codec->revision_id & 0xf) == 1)
5859 spec->stream_delay = 40; /* 40 milliseconds */ 5850 spec->stream_delay = 40; /* 40 milliseconds */
5860 5851
5861 /* no output amps */
5862 spec->num_pwrs = 0;
5863 /* disable VSW */ 5852 /* disable VSW */
5864 spec->init = stac92hd71bxx_core_init; 5853 spec->init = stac92hd71bxx_core_init;
5865 unmute_init++; 5854 unmute_init++;
@@ -5874,8 +5863,6 @@ again:
5874 if ((codec->revision_id & 0xf) == 1) 5863 if ((codec->revision_id & 0xf) == 1)
5875 spec->stream_delay = 40; /* 40 milliseconds */ 5864 spec->stream_delay = 40; /* 40 milliseconds */
5876 5865
5877 /* no output amps */
5878 spec->num_pwrs = 0;
5879 /* fallthru */ 5866 /* fallthru */
5880 default: 5867 default:
5881 spec->init = stac92hd71bxx_core_init; 5868 spec->init = stac92hd71bxx_core_init;
@@ -5978,15 +5965,13 @@ again:
5978 5965
5979#ifdef CONFIG_SND_HDA_POWER_SAVE 5966#ifdef CONFIG_SND_HDA_POWER_SAVE
5980 if (spec->gpio_led) { 5967 if (spec->gpio_led) {
5981 if (spec->gpio_led <= 8) { 5968 if (!spec->vref_mute_led_nid) {
5982 spec->gpio_mask |= spec->gpio_led; 5969 spec->gpio_mask |= spec->gpio_led;
5983 spec->gpio_dir |= spec->gpio_led; 5970 spec->gpio_dir |= spec->gpio_led;
5984 spec->gpio_data |= spec->gpio_led; 5971 spec->gpio_data |= spec->gpio_led;
5985 } else { 5972 } else {
5986 codec->patch_ops.set_power_state = 5973 codec->patch_ops.set_power_state =
5987 stac92xx_set_power_state; 5974 stac92xx_set_power_state;
5988 codec->patch_ops.post_suspend =
5989 stac92xx_post_suspend;
5990 } 5975 }
5991 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5976 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5992 codec->patch_ops.check_power_status = 5977 codec->patch_ops.check_power_status =