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.c354
1 files changed, 261 insertions, 93 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index e6085915d86d..5dd3e89f620a 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -36,9 +36,11 @@
36#include "hda_beep.h" 36#include "hda_beep.h"
37 37
38#define NUM_CONTROL_ALLOC 32 38#define NUM_CONTROL_ALLOC 32
39
40#define STAC_VREF_EVENT 0x00
41#define STAC_INSERT_EVENT 0x10
39#define STAC_PWR_EVENT 0x20 42#define STAC_PWR_EVENT 0x20
40#define STAC_HP_EVENT 0x30 43#define STAC_HP_EVENT 0x30
41#define STAC_VREF_EVENT 0x40
42 44
43enum { 45enum {
44 STAC_REF, 46 STAC_REF,
@@ -68,7 +70,9 @@ enum {
68 70
69enum { 71enum {
70 STAC_92HD73XX_REF, 72 STAC_92HD73XX_REF,
71 STAC_DELL_M6, 73 STAC_DELL_M6_AMIC,
74 STAC_DELL_M6_DMIC,
75 STAC_DELL_M6_BOTH,
72 STAC_DELL_EQ, 76 STAC_DELL_EQ,
73 STAC_92HD73XX_MODELS 77 STAC_92HD73XX_MODELS
74}; 78};
@@ -82,6 +86,7 @@ enum {
82 STAC_92HD71BXX_REF, 86 STAC_92HD71BXX_REF,
83 STAC_DELL_M4_1, 87 STAC_DELL_M4_1,
84 STAC_DELL_M4_2, 88 STAC_DELL_M4_2,
89 STAC_DELL_M4_3,
85 STAC_HP_M4, 90 STAC_HP_M4,
86 STAC_92HD71BXX_MODELS 91 STAC_92HD71BXX_MODELS
87}; 92};
@@ -135,6 +140,7 @@ struct sigmatel_spec {
135 unsigned int num_mixers; 140 unsigned int num_mixers;
136 141
137 int board_config; 142 int board_config;
143 unsigned int eapd_switch: 1;
138 unsigned int surr_switch: 1; 144 unsigned int surr_switch: 1;
139 unsigned int line_switch: 1; 145 unsigned int line_switch: 1;
140 unsigned int mic_switch: 1; 146 unsigned int mic_switch: 1;
@@ -212,7 +218,7 @@ struct sigmatel_spec {
212 /* i/o switches */ 218 /* i/o switches */
213 unsigned int io_switch[2]; 219 unsigned int io_switch[2];
214 unsigned int clfe_swap; 220 unsigned int clfe_swap;
215 unsigned int hp_switch; 221 unsigned int hp_switch; /* NID of HP as line-out */
216 unsigned int aloopback; 222 unsigned int aloopback;
217 223
218 struct hda_pcm pcm_rec[2]; /* PCM information */ 224 struct hda_pcm pcm_rec[2]; /* PCM information */
@@ -1598,13 +1604,17 @@ static unsigned int dell_m6_pin_configs[13] = {
1598 1604
1599static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { 1605static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1600 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, 1606 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1601 [STAC_DELL_M6] = dell_m6_pin_configs, 1607 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs,
1608 [STAC_DELL_M6_DMIC] = dell_m6_pin_configs,
1609 [STAC_DELL_M6_BOTH] = dell_m6_pin_configs,
1602 [STAC_DELL_EQ] = dell_m6_pin_configs, 1610 [STAC_DELL_EQ] = dell_m6_pin_configs,
1603}; 1611};
1604 1612
1605static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { 1613static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1606 [STAC_92HD73XX_REF] = "ref", 1614 [STAC_92HD73XX_REF] = "ref",
1607 [STAC_DELL_M6] = "dell-m6", 1615 [STAC_DELL_M6_AMIC] = "dell-m6-amic",
1616 [STAC_DELL_M6_DMIC] = "dell-m6-dmic",
1617 [STAC_DELL_M6_BOTH] = "dell-m6",
1608 [STAC_DELL_EQ] = "dell-eq", 1618 [STAC_DELL_EQ] = "dell-eq",
1609}; 1619};
1610 1620
@@ -1613,19 +1623,23 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1613 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1623 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1614 "DFI LanParty", STAC_92HD73XX_REF), 1624 "DFI LanParty", STAC_92HD73XX_REF),
1615 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, 1625 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
1616 "unknown Dell", STAC_DELL_M6), 1626 "Dell Studio 1535", STAC_DELL_M6_DMIC),
1617 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, 1627 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
1618 "unknown Dell", STAC_DELL_M6), 1628 "unknown Dell", STAC_DELL_M6_DMIC),
1619 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256, 1629 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
1620 "unknown Dell", STAC_DELL_M6), 1630 "unknown Dell", STAC_DELL_M6_BOTH),
1621 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257, 1631 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
1622 "unknown Dell", STAC_DELL_M6), 1632 "unknown Dell", STAC_DELL_M6_BOTH),
1623 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e, 1633 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
1624 "unknown Dell", STAC_DELL_M6), 1634 "unknown Dell", STAC_DELL_M6_AMIC),
1625 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f, 1635 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
1626 "unknown Dell", STAC_DELL_M6), 1636 "unknown Dell", STAC_DELL_M6_AMIC),
1627 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271, 1637 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
1628 "unknown Dell", STAC_DELL_M6), 1638 "unknown Dell", STAC_DELL_M6_DMIC),
1639 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
1640 "unknown Dell", STAC_DELL_M6_DMIC),
1641 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1642 "Dell Studio 1537", STAC_DELL_M6_DMIC),
1629 {} /* terminator */ 1643 {} /* terminator */
1630}; 1644};
1631 1645
@@ -1668,10 +1682,17 @@ static unsigned int dell_m4_2_pin_configs[11] = {
1668 0x40f000f0, 0x044413b0, 0x044413b0, 1682 0x40f000f0, 0x044413b0, 0x044413b0,
1669}; 1683};
1670 1684
1685static unsigned int dell_m4_3_pin_configs[11] = {
1686 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
1687 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0,
1688 0x40f000f0, 0x044413b0, 0x044413b0,
1689};
1690
1671static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { 1691static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1672 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, 1692 [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
1673 [STAC_DELL_M4_1] = dell_m4_1_pin_configs, 1693 [STAC_DELL_M4_1] = dell_m4_1_pin_configs,
1674 [STAC_DELL_M4_2] = dell_m4_2_pin_configs, 1694 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
1695 [STAC_DELL_M4_3] = dell_m4_3_pin_configs,
1675 [STAC_HP_M4] = NULL, 1696 [STAC_HP_M4] = NULL,
1676}; 1697};
1677 1698
@@ -1679,6 +1700,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1679 [STAC_92HD71BXX_REF] = "ref", 1700 [STAC_92HD71BXX_REF] = "ref",
1680 [STAC_DELL_M4_1] = "dell-m4-1", 1701 [STAC_DELL_M4_1] = "dell-m4-1",
1681 [STAC_DELL_M4_2] = "dell-m4-2", 1702 [STAC_DELL_M4_2] = "dell-m4-2",
1703 [STAC_DELL_M4_3] = "dell-m4-3",
1682 [STAC_HP_M4] = "hp-m4", 1704 [STAC_HP_M4] = "hp-m4",
1683}; 1705};
1684 1706
@@ -1686,6 +1708,10 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1686 /* SigmaTel reference board */ 1708 /* SigmaTel reference board */
1687 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1709 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1688 "DFI LanParty", STAC_92HD71BXX_REF), 1710 "DFI LanParty", STAC_92HD71BXX_REF),
1711 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2,
1712 "HP dv5", STAC_HP_M4),
1713 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
1714 "HP dv7", STAC_HP_M4),
1689 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, 1715 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
1690 "unknown HP", STAC_HP_M4), 1716 "unknown HP", STAC_HP_M4),
1691 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1717 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -1710,6 +1736,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1710 "unknown Dell", STAC_DELL_M4_2), 1736 "unknown Dell", STAC_DELL_M4_2),
1711 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264, 1737 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
1712 "unknown Dell", STAC_DELL_M4_2), 1738 "unknown Dell", STAC_DELL_M4_2),
1739 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
1740 "unknown Dell", STAC_DELL_M4_3),
1713 {} /* terminator */ 1741 {} /* terminator */
1714}; 1742};
1715 1743
@@ -2443,7 +2471,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
2443 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2444 struct sigmatel_spec *spec = codec->spec; 2472 struct sigmatel_spec *spec = codec->spec;
2445 2473
2446 ucontrol->value.integer.value[0] = spec->hp_switch; 2474 ucontrol->value.integer.value[0] = !!spec->hp_switch;
2447 return 0; 2475 return 0;
2448} 2476}
2449 2477
@@ -2452,8 +2480,9 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2452{ 2480{
2453 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2481 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2454 struct sigmatel_spec *spec = codec->spec; 2482 struct sigmatel_spec *spec = codec->spec;
2455 2483 int nid = kcontrol->private_value;
2456 spec->hp_switch = ucontrol->value.integer.value[0]; 2484
2485 spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
2457 2486
2458 /* check to be sure that the ports are upto date with 2487 /* check to be sure that the ports are upto date with
2459 * switch changes 2488 * switch changes
@@ -2586,8 +2615,10 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
2586}; 2615};
2587 2616
2588/* add dynamic controls */ 2617/* add dynamic controls */
2589static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, 2618static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2590 int idx, const char *name, unsigned long val) 2619 struct snd_kcontrol_new *ktemp,
2620 int idx, const char *name,
2621 unsigned long val)
2591{ 2622{
2592 struct snd_kcontrol_new *knew; 2623 struct snd_kcontrol_new *knew;
2593 2624
@@ -2606,20 +2637,29 @@ static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
2606 } 2637 }
2607 2638
2608 knew = &spec->kctl_alloc[spec->num_kctl_used]; 2639 knew = &spec->kctl_alloc[spec->num_kctl_used];
2609 *knew = stac92xx_control_templates[type]; 2640 *knew = *ktemp;
2610 knew->index = idx; 2641 knew->index = idx;
2611 knew->name = kstrdup(name, GFP_KERNEL); 2642 knew->name = kstrdup(name, GFP_KERNEL);
2612 if (! knew->name) 2643 if (!knew->name)
2613 return -ENOMEM; 2644 return -ENOMEM;
2614 knew->private_value = val; 2645 knew->private_value = val;
2615 spec->num_kctl_used++; 2646 spec->num_kctl_used++;
2616 return 0; 2647 return 0;
2617} 2648}
2618 2649
2650static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
2651 int type, int idx, const char *name,
2652 unsigned long val)
2653{
2654 return stac92xx_add_control_temp(spec,
2655 &stac92xx_control_templates[type],
2656 idx, name, val);
2657}
2658
2619 2659
2620/* add dynamic controls */ 2660/* add dynamic controls */
2621static int stac92xx_add_control(struct sigmatel_spec *spec, int type, 2661static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2622 const char *name, unsigned long val) 2662 const char *name, unsigned long val)
2623{ 2663{
2624 return stac92xx_add_control_idx(spec, type, 0, name, val); 2664 return stac92xx_add_control_idx(spec, type, 0, name, val);
2625} 2665}
@@ -2859,10 +2899,11 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2859 cfg->hp_outs && !spec->multiout.hp_nid) 2899 cfg->hp_outs && !spec->multiout.hp_nid)
2860 spec->multiout.hp_nid = nid; 2900 spec->multiout.hp_nid = nid;
2861 2901
2862 if (cfg->hp_outs > 1) { 2902 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
2863 err = stac92xx_add_control(spec, 2903 err = stac92xx_add_control(spec,
2864 STAC_CTL_WIDGET_HP_SWITCH, 2904 STAC_CTL_WIDGET_HP_SWITCH,
2865 "Headphone as Line Out Switch", 0); 2905 "Headphone as Line Out Switch",
2906 cfg->hp_pins[cfg->hp_outs - 1]);
2866 if (err < 0) 2907 if (err < 0)
2867 return err; 2908 return err;
2868 } 2909 }
@@ -3060,6 +3101,43 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
3060 return 0; 3101 return 0;
3061} 3102}
3062 3103
3104#ifdef CONFIG_SND_HDA_INPUT_BEEP
3105#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info
3106
3107static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
3108 struct snd_ctl_elem_value *ucontrol)
3109{
3110 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3111 ucontrol->value.integer.value[0] = codec->beep->enabled;
3112 return 0;
3113}
3114
3115static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
3116 struct snd_ctl_elem_value *ucontrol)
3117{
3118 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3119 int enabled = !!ucontrol->value.integer.value[0];
3120 if (codec->beep->enabled != enabled) {
3121 codec->beep->enabled = enabled;
3122 return 1;
3123 }
3124 return 0;
3125}
3126
3127static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
3128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3129 .info = stac92xx_dig_beep_switch_info,
3130 .get = stac92xx_dig_beep_switch_get,
3131 .put = stac92xx_dig_beep_switch_put,
3132};
3133
3134static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
3135{
3136 return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
3137 0, "PC Beep Playback Switch", 0);
3138}
3139#endif
3140
3063static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) 3141static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
3064{ 3142{
3065 struct sigmatel_spec *spec = codec->spec; 3143 struct sigmatel_spec *spec = codec->spec;
@@ -3366,6 +3444,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3366#ifdef CONFIG_SND_HDA_INPUT_BEEP 3444#ifdef CONFIG_SND_HDA_INPUT_BEEP
3367 if (spec->digbeep_nid > 0) { 3445 if (spec->digbeep_nid > 0) {
3368 hda_nid_t nid = spec->digbeep_nid; 3446 hda_nid_t nid = spec->digbeep_nid;
3447 unsigned int caps;
3369 3448
3370 err = stac92xx_auto_create_beep_ctls(codec, nid); 3449 err = stac92xx_auto_create_beep_ctls(codec, nid);
3371 if (err < 0) 3450 if (err < 0)
@@ -3373,6 +3452,14 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3373 err = snd_hda_attach_beep_device(codec, nid); 3452 err = snd_hda_attach_beep_device(codec, nid);
3374 if (err < 0) 3453 if (err < 0)
3375 return err; 3454 return err;
3455 /* if no beep switch is available, make its own one */
3456 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3457 if (codec->beep &&
3458 !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) {
3459 err = stac92xx_beep_switch_ctl(codec);
3460 if (err < 0)
3461 return err;
3462 }
3376 } 3463 }
3377#endif 3464#endif
3378 3465
@@ -3530,6 +3617,12 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
3530 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0) 3617 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
3531 return err; 3618 return err;
3532 3619
3620 if (spec->num_muxes > 0) {
3621 err = stac92xx_auto_create_mux_input_ctls(codec);
3622 if (err < 0)
3623 return err;
3624 }
3625
3533 if (spec->autocfg.dig_out_pin) 3626 if (spec->autocfg.dig_out_pin)
3534 spec->multiout.dig_out_nid = 0x05; 3627 spec->multiout.dig_out_nid = 0x05;
3535 if (spec->autocfg.dig_in_pin) 3628 if (spec->autocfg.dig_in_pin)
@@ -3612,10 +3705,14 @@ static void stac92xx_power_down(struct hda_codec *codec)
3612 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3705 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3613} 3706}
3614 3707
3708static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
3709 int enable);
3710
3615static int stac92xx_init(struct hda_codec *codec) 3711static int stac92xx_init(struct hda_codec *codec)
3616{ 3712{
3617 struct sigmatel_spec *spec = codec->spec; 3713 struct sigmatel_spec *spec = codec->spec;
3618 struct auto_pin_cfg *cfg = &spec->autocfg; 3714 struct auto_pin_cfg *cfg = &spec->autocfg;
3715 unsigned int gpio;
3619 int i; 3716 int i;
3620 3717
3621 snd_hda_sequence_write(codec, spec->init); 3718 snd_hda_sequence_write(codec, spec->init);
@@ -3626,6 +3723,16 @@ static int stac92xx_init(struct hda_codec *codec)
3626 snd_hda_codec_write_cache(codec, 3723 snd_hda_codec_write_cache(codec,
3627 spec->adc_nids[i], 0, 3724 spec->adc_nids[i], 0,
3628 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3725 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3726
3727 /* set up GPIO */
3728 gpio = spec->gpio_data;
3729 /* turn on EAPD statically when spec->eapd_switch isn't set.
3730 * otherwise, unsol event will turn it on/off dynamically
3731 */
3732 if (!spec->eapd_switch)
3733 gpio |= spec->eapd_mask;
3734 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio);
3735
3629 /* set up pins */ 3736 /* set up pins */
3630 if (spec->hp_detect) { 3737 if (spec->hp_detect) {
3631 /* Enable unsolicited responses on the HP widget */ 3738 /* Enable unsolicited responses on the HP widget */
@@ -3647,53 +3754,61 @@ static int stac92xx_init(struct hda_codec *codec)
3647 for (i = 0; i < AUTO_PIN_LAST; i++) { 3754 for (i = 0; i < AUTO_PIN_LAST; i++) {
3648 hda_nid_t nid = cfg->input_pins[i]; 3755 hda_nid_t nid = cfg->input_pins[i];
3649 if (nid) { 3756 if (nid) {
3650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 3757 unsigned int pinctl;
3651 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3758 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
3652 /* if PINCTL already set then skip */ 3759 /* for mic pins, force to initialize */
3653 if (pinctl & AC_PINCAP_IN) 3760 pinctl = stac92xx_get_vref(codec, nid);
3654 continue; 3761 } else {
3655 pinctl = AC_PINCTL_IN_EN; 3762 pinctl = snd_hda_codec_read(codec, nid, 0,
3656 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) 3763 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3657 pinctl |= stac92xx_get_vref(codec, nid); 3764 /* if PINCTL already set then skip */
3765 if (pinctl & AC_PINCTL_IN_EN)
3766 continue;
3767 }
3768 pinctl |= AC_PINCTL_IN_EN;
3658 stac92xx_auto_set_pinctl(codec, nid, pinctl); 3769 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3659 } 3770 }
3660 } 3771 }
3661 for (i = 0; i < spec->num_dmics; i++) 3772 for (i = 0; i < spec->num_dmics; i++)
3662 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], 3773 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
3663 AC_PINCTL_IN_EN); 3774 AC_PINCTL_IN_EN);
3775 if (cfg->dig_out_pin)
3776 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
3777 AC_PINCTL_OUT_EN);
3778 if (cfg->dig_in_pin)
3779 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
3780 AC_PINCTL_IN_EN);
3664 for (i = 0; i < spec->num_pwrs; i++) { 3781 for (i = 0; i < spec->num_pwrs; i++) {
3665 int event = is_nid_hp_pin(cfg, spec->pwr_nids[i]) 3782 hda_nid_t nid = spec->pwr_nids[i];
3666 ? STAC_HP_EVENT : STAC_PWR_EVENT; 3783 int pinctl, def_conf;
3667 int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i], 3784 int event = STAC_PWR_EVENT;
3668 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3785
3669 int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], 3786 if (is_nid_hp_pin(cfg, nid) && spec->hp_detect)
3670 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 3787 continue; /* already has an unsol event */
3671 def_conf = get_defcfg_connect(def_conf); 3788
3789 pinctl = snd_hda_codec_read(codec, nid, 0,
3790 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3672 /* outputs are only ports capable of power management 3791 /* outputs are only ports capable of power management
3673 * any attempts on powering down a input port cause the 3792 * any attempts on powering down a input port cause the
3674 * referenced VREF to act quirky. 3793 * referenced VREF to act quirky.
3675 */ 3794 */
3676 if (pinctl & AC_PINCTL_IN_EN) 3795 if (pinctl & AC_PINCTL_IN_EN)
3677 continue; 3796 continue;
3797 def_conf = snd_hda_codec_read(codec, nid, 0,
3798 AC_VERB_GET_CONFIG_DEFAULT, 0);
3799 def_conf = get_defcfg_connect(def_conf);
3678 /* skip any ports that don't have jacks since presence 3800 /* skip any ports that don't have jacks since presence
3679 * detection is useless */ 3801 * detection is useless */
3680 if (def_conf && def_conf != AC_JACK_PORT_FIXED) 3802 if (def_conf != AC_JACK_PORT_COMPLEX) {
3803 if (def_conf != AC_JACK_PORT_NONE)
3804 stac_toggle_power_map(codec, nid, 1);
3681 continue; 3805 continue;
3806 }
3682 enable_pin_detect(codec, spec->pwr_nids[i], event | i); 3807 enable_pin_detect(codec, spec->pwr_nids[i], event | i);
3683 codec->patch_ops.unsol_event(codec, (event | i) << 26); 3808 codec->patch_ops.unsol_event(codec, (event | i) << 26);
3684 } 3809 }
3685 if (spec->dac_list) 3810 if (spec->dac_list)
3686 stac92xx_power_down(codec); 3811 stac92xx_power_down(codec);
3687 if (cfg->dig_out_pin)
3688 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
3689 AC_PINCTL_OUT_EN);
3690 if (cfg->dig_in_pin)
3691 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
3692 AC_PINCTL_IN_EN);
3693
3694 stac_gpio_set(codec, spec->gpio_mask,
3695 spec->gpio_dir, spec->gpio_data);
3696
3697 return 0; 3812 return 0;
3698} 3813}
3699 3814
@@ -3776,11 +3891,30 @@ static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
3776 return 0; 3891 return 0;
3777} 3892}
3778 3893
3894/* return non-zero if the hp-pin of the given array index isn't
3895 * a jack-detection target
3896 */
3897static int no_hp_sensing(struct sigmatel_spec *spec, int i)
3898{
3899 struct auto_pin_cfg *cfg = &spec->autocfg;
3900
3901 /* ignore sensing of shared line and mic jacks */
3902 if (spec->line_switch &&
3903 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
3904 return 1;
3905 if (spec->mic_switch &&
3906 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
3907 return 1;
3908 /* ignore if the pin is set as line-out */
3909 if (cfg->hp_pins[i] == spec->hp_switch)
3910 return 1;
3911 return 0;
3912}
3913
3779static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) 3914static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
3780{ 3915{
3781 struct sigmatel_spec *spec = codec->spec; 3916 struct sigmatel_spec *spec = codec->spec;
3782 struct auto_pin_cfg *cfg = &spec->autocfg; 3917 struct auto_pin_cfg *cfg = &spec->autocfg;
3783 int nid = cfg->hp_pins[cfg->hp_outs - 1];
3784 int i, presence; 3918 int i, presence;
3785 3919
3786 presence = 0; 3920 presence = 0;
@@ -3791,52 +3925,66 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
3791 for (i = 0; i < cfg->hp_outs; i++) { 3925 for (i = 0; i < cfg->hp_outs; i++) {
3792 if (presence) 3926 if (presence)
3793 break; 3927 break;
3794 if (spec->hp_switch && cfg->hp_pins[i] == nid) 3928 if (no_hp_sensing(spec, i))
3795 break; 3929 continue;
3796 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); 3930 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
3797 } 3931 }
3798 3932
3799 if (presence) { 3933 if (presence) {
3800 /* disable lineouts, enable hp */ 3934 /* disable lineouts */
3801 if (spec->hp_switch) 3935 if (spec->hp_switch)
3802 stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN); 3936 stac92xx_reset_pinctl(codec, spec->hp_switch,
3937 AC_PINCTL_OUT_EN);
3803 for (i = 0; i < cfg->line_outs; i++) 3938 for (i = 0; i < cfg->line_outs; i++)
3804 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], 3939 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
3805 AC_PINCTL_OUT_EN); 3940 AC_PINCTL_OUT_EN);
3806 for (i = 0; i < cfg->speaker_outs; i++) 3941 for (i = 0; i < cfg->speaker_outs; i++)
3807 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], 3942 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
3808 AC_PINCTL_OUT_EN); 3943 AC_PINCTL_OUT_EN);
3809 if (spec->eapd_mask) 3944 if (spec->eapd_mask && spec->eapd_switch)
3810 stac_gpio_set(codec, spec->gpio_mask, 3945 stac_gpio_set(codec, spec->gpio_mask,
3811 spec->gpio_dir, spec->gpio_data & 3946 spec->gpio_dir, spec->gpio_data &
3812 ~spec->eapd_mask); 3947 ~spec->eapd_mask);
3813 } else { 3948 } else {
3814 /* enable lineouts, disable hp */ 3949 /* enable lineouts */
3815 if (spec->hp_switch) 3950 if (spec->hp_switch)
3816 stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); 3951 stac92xx_set_pinctl(codec, spec->hp_switch,
3952 AC_PINCTL_OUT_EN);
3817 for (i = 0; i < cfg->line_outs; i++) 3953 for (i = 0; i < cfg->line_outs; i++)
3818 stac92xx_set_pinctl(codec, cfg->line_out_pins[i], 3954 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
3819 AC_PINCTL_OUT_EN); 3955 AC_PINCTL_OUT_EN);
3820 for (i = 0; i < cfg->speaker_outs; i++) 3956 for (i = 0; i < cfg->speaker_outs; i++)
3821 stac92xx_set_pinctl(codec, cfg->speaker_pins[i], 3957 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
3822 AC_PINCTL_OUT_EN); 3958 AC_PINCTL_OUT_EN);
3823 if (spec->eapd_mask) 3959 if (spec->eapd_mask && spec->eapd_switch)
3824 stac_gpio_set(codec, spec->gpio_mask, 3960 stac_gpio_set(codec, spec->gpio_mask,
3825 spec->gpio_dir, spec->gpio_data | 3961 spec->gpio_dir, spec->gpio_data |
3826 spec->eapd_mask); 3962 spec->eapd_mask);
3827 } 3963 }
3828 if (!spec->hp_switch && cfg->hp_outs > 1 && presence) 3964 /* toggle hp outs */
3829 stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); 3965 for (i = 0; i < cfg->hp_outs; i++) {
3966 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
3967 if (no_hp_sensing(spec, i))
3968 continue;
3969 if (presence)
3970 stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
3971 else
3972 stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
3973 }
3830} 3974}
3831 3975
3832static void stac92xx_pin_sense(struct hda_codec *codec, int idx) 3976static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
3977 int enable)
3833{ 3978{
3834 struct sigmatel_spec *spec = codec->spec; 3979 struct sigmatel_spec *spec = codec->spec;
3835 hda_nid_t nid = spec->pwr_nids[idx]; 3980 unsigned int idx, val;
3836 int presence, val; 3981
3837 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) 3982 for (idx = 0; idx < spec->num_pwrs; idx++) {
3838 & 0x000000ff; 3983 if (spec->pwr_nids[idx] == nid)
3839 presence = get_hp_pin_presence(codec, nid); 3984 break;
3985 }
3986 if (idx >= spec->num_pwrs)
3987 return;
3840 3988
3841 /* several codecs have two power down bits */ 3989 /* several codecs have two power down bits */
3842 if (spec->pwr_mapping) 3990 if (spec->pwr_mapping)
@@ -3844,14 +3992,20 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
3844 else 3992 else
3845 idx = 1 << idx; 3993 idx = 1 << idx;
3846 3994
3847 if (presence) 3995 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff;
3996 if (enable)
3848 val &= ~idx; 3997 val &= ~idx;
3849 else 3998 else
3850 val |= idx; 3999 val |= idx;
3851 4000
3852 /* power down unused output ports */ 4001 /* power down unused output ports */
3853 snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val); 4002 snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val);
3854}; 4003}
4004
4005static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
4006{
4007 stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid));
4008}
3855 4009
3856static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) 4010static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
3857{ 4011{
@@ -4135,31 +4289,29 @@ again:
4135 case STAC_DELL_EQ: 4289 case STAC_DELL_EQ:
4136 spec->init = dell_eq_core_init; 4290 spec->init = dell_eq_core_init;
4137 /* fallthru */ 4291 /* fallthru */
4138 case STAC_DELL_M6: 4292 case STAC_DELL_M6_AMIC:
4293 case STAC_DELL_M6_DMIC:
4294 case STAC_DELL_M6_BOTH:
4139 spec->num_smuxes = 0; 4295 spec->num_smuxes = 0;
4140 spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; 4296 spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER];
4141 spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; 4297 spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
4298 spec->eapd_switch = 0;
4142 spec->num_amps = 1; 4299 spec->num_amps = 1;
4143 4300
4144 if (!spec->init) 4301 if (!spec->init)
4145 spec->init = dell_m6_core_init; 4302 spec->init = dell_m6_core_init;
4146 switch (codec->subsystem_id) { 4303 switch (spec->board_config) {
4147 case 0x1028025e: /* Analog Mics */ 4304 case STAC_DELL_M6_AMIC: /* Analog Mics */
4148 case 0x1028025f:
4149 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); 4305 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
4150 spec->num_dmics = 0; 4306 spec->num_dmics = 0;
4151 spec->private_dimux.num_items = 1; 4307 spec->private_dimux.num_items = 1;
4152 break; 4308 break;
4153 case 0x10280271: /* Digital Mics */ 4309 case STAC_DELL_M6_DMIC: /* Digital Mics */
4154 case 0x10280272:
4155 case 0x10280254:
4156 case 0x10280255:
4157 stac92xx_set_config_reg(codec, 0x13, 0x90A60160); 4310 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
4158 spec->num_dmics = 1; 4311 spec->num_dmics = 1;
4159 spec->private_dimux.num_items = 2; 4312 spec->private_dimux.num_items = 2;
4160 break; 4313 break;
4161 case 0x10280256: /* Both */ 4314 case STAC_DELL_M6_BOTH: /* Both */
4162 case 0x10280057:
4163 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); 4315 stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
4164 stac92xx_set_config_reg(codec, 0x13, 0x90A60160); 4316 stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
4165 spec->num_dmics = 1; 4317 spec->num_dmics = 1;
@@ -4170,6 +4322,7 @@ again:
4170 default: 4322 default:
4171 spec->num_dmics = STAC92HD73XX_NUM_DMICS; 4323 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
4172 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); 4324 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
4325 spec->eapd_switch = 1;
4173 } 4326 }
4174 if (spec->board_config > STAC_92HD73XX_REF) { 4327 if (spec->board_config > STAC_92HD73XX_REF) {
4175 /* GPIO0 High = Enable EAPD */ 4328 /* GPIO0 High = Enable EAPD */
@@ -4315,7 +4468,13 @@ static int stac92hd71xx_resume(struct hda_codec *codec)
4315 4468
4316static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state) 4469static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
4317{ 4470{
4471 struct sigmatel_spec *spec = codec->spec;
4472
4318 stac92hd71xx_set_power_state(codec, AC_PWRST_D3); 4473 stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
4474 if (spec->eapd_mask)
4475 stac_gpio_set(codec, spec->gpio_mask,
4476 spec->gpio_dir, spec->gpio_data &
4477 ~spec->eapd_mask);
4319 return 0; 4478 return 0;
4320}; 4479};
4321 4480
@@ -4378,6 +4537,13 @@ again:
4378 stac92xx_set_config_regs(codec); 4537 stac92xx_set_config_regs(codec);
4379 } 4538 }
4380 4539
4540 if (spec->board_config > STAC_92HD71BXX_REF) {
4541 /* GPIO0 = EAPD */
4542 spec->gpio_mask = 0x01;
4543 spec->gpio_dir = 0x01;
4544 spec->gpio_data = 0x01;
4545 }
4546
4381 switch (codec->vendor_id) { 4547 switch (codec->vendor_id) {
4382 case 0x111d76b6: /* 4 Port without Analog Mixer */ 4548 case 0x111d76b6: /* 4 Port without Analog Mixer */
4383 case 0x111d76b7: 4549 case 0x111d76b7:
@@ -4388,10 +4554,10 @@ again:
4388 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 4554 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
4389 break; 4555 break;
4390 case 0x111d7608: /* 5 Port with Analog Mixer */ 4556 case 0x111d7608: /* 5 Port with Analog Mixer */
4391 switch (codec->subsystem_id) { 4557 switch (spec->board_config) {
4392 case 0x103c361a: 4558 case STAC_HP_M4:
4393 /* Enable VREF power saving on GPIO1 detect */ 4559 /* Enable VREF power saving on GPIO1 detect */
4394 snd_hda_codec_write(codec, codec->afg, 0, 4560 snd_hda_codec_write_cache(codec, codec->afg, 0,
4395 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); 4561 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
4396 snd_hda_codec_write_cache(codec, codec->afg, 0, 4562 snd_hda_codec_write_cache(codec, codec->afg, 0,
4397 AC_VERB_SET_UNSOLICITED_ENABLE, 4563 AC_VERB_SET_UNSOLICITED_ENABLE,
@@ -4437,13 +4603,6 @@ again:
4437 spec->aloopback_mask = 0x50; 4603 spec->aloopback_mask = 0x50;
4438 spec->aloopback_shift = 0; 4604 spec->aloopback_shift = 0;
4439 4605
4440 if (spec->board_config > STAC_92HD71BXX_REF) {
4441 /* GPIO0 = EAPD */
4442 spec->gpio_mask = 0x01;
4443 spec->gpio_dir = 0x01;
4444 spec->gpio_data = 0x01;
4445 }
4446
4447 spec->powerdown_adcs = 1; 4606 spec->powerdown_adcs = 1;
4448 spec->digbeep_nid = 0x26; 4607 spec->digbeep_nid = 0x26;
4449 spec->mux_nids = stac92hd71bxx_mux_nids; 4608 spec->mux_nids = stac92hd71bxx_mux_nids;
@@ -4458,14 +4617,21 @@ again:
4458 4617
4459 switch (spec->board_config) { 4618 switch (spec->board_config) {
4460 case STAC_HP_M4: 4619 case STAC_HP_M4:
4461 spec->num_dmics = 0;
4462 spec->num_smuxes = 0;
4463 spec->num_dmuxes = 0;
4464
4465 /* enable internal microphone */ 4620 /* enable internal microphone */
4466 stac92xx_set_config_reg(codec, 0x0e, 0x01813040); 4621 stac92xx_set_config_reg(codec, 0x0e, 0x01813040);
4467 stac92xx_auto_set_pinctl(codec, 0x0e, 4622 stac92xx_auto_set_pinctl(codec, 0x0e,
4468 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); 4623 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
4624 /* fallthru */
4625 case STAC_DELL_M4_2:
4626 spec->num_dmics = 0;
4627 spec->num_smuxes = 0;
4628 spec->num_dmuxes = 0;
4629 break;
4630 case STAC_DELL_M4_1:
4631 case STAC_DELL_M4_3:
4632 spec->num_dmics = 1;
4633 spec->num_smuxes = 0;
4634 spec->num_dmuxes = 0;
4469 break; 4635 break;
4470 default: 4636 default:
4471 spec->num_dmics = STAC92HD71BXX_NUM_DMICS; 4637 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
@@ -4702,6 +4868,7 @@ static int patch_stac927x(struct hda_codec *codec)
4702 spec->num_pwrs = 0; 4868 spec->num_pwrs = 0;
4703 spec->aloopback_mask = 0x40; 4869 spec->aloopback_mask = 0x40;
4704 spec->aloopback_shift = 0; 4870 spec->aloopback_shift = 0;
4871 spec->eapd_switch = 1;
4705 4872
4706 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); 4873 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
4707 if (!err) { 4874 if (!err) {
@@ -4782,6 +4949,7 @@ static int patch_stac9205(struct hda_codec *codec)
4782 4949
4783 spec->aloopback_mask = 0x40; 4950 spec->aloopback_mask = 0x40;
4784 spec->aloopback_shift = 0; 4951 spec->aloopback_shift = 0;
4952 spec->eapd_switch = 1;
4785 spec->multiout.dac_nids = spec->dac_nids; 4953 spec->multiout.dac_nids = spec->dac_nids;
4786 4954
4787 switch (spec->board_config){ 4955 switch (spec->board_config){
@@ -4791,7 +4959,7 @@ static int patch_stac9205(struct hda_codec *codec)
4791 stac92xx_set_config_reg(codec, 0x20, 0x1c410030); 4959 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
4792 4960
4793 /* Enable unsol response for GPIO4/Dock HP connection */ 4961 /* Enable unsol response for GPIO4/Dock HP connection */
4794 snd_hda_codec_write(codec, codec->afg, 0, 4962 snd_hda_codec_write_cache(codec, codec->afg, 0,
4795 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); 4963 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
4796 snd_hda_codec_write_cache(codec, codec->afg, 0, 4964 snd_hda_codec_write_cache(codec, codec->afg, 0,
4797 AC_VERB_SET_UNSOLICITED_ENABLE, 4965 AC_VERB_SET_UNSOLICITED_ENABLE,