aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/patch_sigmatel.c80
1 files changed, 54 insertions, 26 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 2b52a4056a9b..5a29699c6fdb 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -3697,10 +3697,14 @@ static void stac92xx_power_down(struct hda_codec *codec)
3697 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3697 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3698} 3698}
3699 3699
3700static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
3701 int enable);
3702
3700static int stac92xx_init(struct hda_codec *codec) 3703static int stac92xx_init(struct hda_codec *codec)
3701{ 3704{
3702 struct sigmatel_spec *spec = codec->spec; 3705 struct sigmatel_spec *spec = codec->spec;
3703 struct auto_pin_cfg *cfg = &spec->autocfg; 3706 struct auto_pin_cfg *cfg = &spec->autocfg;
3707 unsigned int gpio;
3704 int i; 3708 int i;
3705 3709
3706 snd_hda_sequence_write(codec, spec->init); 3710 snd_hda_sequence_write(codec, spec->init);
@@ -3711,6 +3715,16 @@ static int stac92xx_init(struct hda_codec *codec)
3711 snd_hda_codec_write_cache(codec, 3715 snd_hda_codec_write_cache(codec,
3712 spec->adc_nids[i], 0, 3716 spec->adc_nids[i], 0,
3713 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3717 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3718
3719 /* set up GPIO */
3720 gpio = spec->gpio_data;
3721 /* turn on EAPD statically when spec->eapd_switch isn't set.
3722 * otherwise, unsol event will turn it on/off dynamically
3723 */
3724 if (!spec->eapd_switch)
3725 gpio |= spec->eapd_mask;
3726 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio);
3727
3714 /* set up pins */ 3728 /* set up pins */
3715 if (spec->hp_detect) { 3729 if (spec->hp_detect) {
3716 /* Enable unsolicited responses on the HP widget */ 3730 /* Enable unsolicited responses on the HP widget */
@@ -3750,39 +3764,43 @@ static int stac92xx_init(struct hda_codec *codec)
3750 for (i = 0; i < spec->num_dmics; i++) 3764 for (i = 0; i < spec->num_dmics; i++)
3751 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], 3765 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
3752 AC_PINCTL_IN_EN); 3766 AC_PINCTL_IN_EN);
3767 if (cfg->dig_out_pin)
3768 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
3769 AC_PINCTL_OUT_EN);
3770 if (cfg->dig_in_pin)
3771 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
3772 AC_PINCTL_IN_EN);
3753 for (i = 0; i < spec->num_pwrs; i++) { 3773 for (i = 0; i < spec->num_pwrs; i++) {
3754 int event = is_nid_hp_pin(cfg, spec->pwr_nids[i]) 3774 hda_nid_t nid = spec->pwr_nids[i];
3755 ? STAC_HP_EVENT : STAC_PWR_EVENT; 3775 int pinctl, def_conf;
3756 int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i], 3776 int event = STAC_PWR_EVENT;
3757 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3777
3758 int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], 3778 if (is_nid_hp_pin(cfg, nid) && spec->hp_detect)
3759 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 3779 continue; /* already has an unsol event */
3760 def_conf = get_defcfg_connect(def_conf); 3780
3781 pinctl = snd_hda_codec_read(codec, nid, 0,
3782 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3761 /* outputs are only ports capable of power management 3783 /* outputs are only ports capable of power management
3762 * any attempts on powering down a input port cause the 3784 * any attempts on powering down a input port cause the
3763 * referenced VREF to act quirky. 3785 * referenced VREF to act quirky.
3764 */ 3786 */
3765 if (pinctl & AC_PINCTL_IN_EN) 3787 if (pinctl & AC_PINCTL_IN_EN)
3766 continue; 3788 continue;
3789 def_conf = snd_hda_codec_read(codec, nid, 0,
3790 AC_VERB_GET_CONFIG_DEFAULT, 0);
3791 def_conf = get_defcfg_connect(def_conf);
3767 /* skip any ports that don't have jacks since presence 3792 /* skip any ports that don't have jacks since presence
3768 * detection is useless */ 3793 * detection is useless */
3769 if (def_conf && def_conf != AC_JACK_PORT_FIXED) 3794 if (def_conf != AC_JACK_PORT_COMPLEX) {
3795 if (def_conf != AC_JACK_PORT_NONE)
3796 stac_toggle_power_map(codec, nid, 1);
3770 continue; 3797 continue;
3798 }
3771 enable_pin_detect(codec, spec->pwr_nids[i], event | i); 3799 enable_pin_detect(codec, spec->pwr_nids[i], event | i);
3772 codec->patch_ops.unsol_event(codec, (event | i) << 26); 3800 codec->patch_ops.unsol_event(codec, (event | i) << 26);
3773 } 3801 }
3774 if (spec->dac_list) 3802 if (spec->dac_list)
3775 stac92xx_power_down(codec); 3803 stac92xx_power_down(codec);
3776 if (cfg->dig_out_pin)
3777 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
3778 AC_PINCTL_OUT_EN);
3779 if (cfg->dig_in_pin)
3780 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
3781 AC_PINCTL_IN_EN);
3782
3783 stac_gpio_set(codec, spec->gpio_mask,
3784 spec->gpio_dir, spec->gpio_data);
3785
3786 return 0; 3804 return 0;
3787} 3805}
3788 3806
@@ -3947,14 +3965,18 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
3947 } 3965 }
3948} 3966}
3949 3967
3950static void stac92xx_pin_sense(struct hda_codec *codec, int idx) 3968static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
3969 int enable)
3951{ 3970{
3952 struct sigmatel_spec *spec = codec->spec; 3971 struct sigmatel_spec *spec = codec->spec;
3953 hda_nid_t nid = spec->pwr_nids[idx]; 3972 unsigned int idx, val;
3954 int presence, val; 3973
3955 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) 3974 for (idx = 0; idx < spec->num_pwrs; idx++) {
3956 & 0x000000ff; 3975 if (spec->pwr_nids[idx] == nid)
3957 presence = get_hp_pin_presence(codec, nid); 3976 break;
3977 }
3978 if (idx >= spec->num_pwrs)
3979 return;
3958 3980
3959 /* several codecs have two power down bits */ 3981 /* several codecs have two power down bits */
3960 if (spec->pwr_mapping) 3982 if (spec->pwr_mapping)
@@ -3962,14 +3984,20 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
3962 else 3984 else
3963 idx = 1 << idx; 3985 idx = 1 << idx;
3964 3986
3965 if (presence) 3987 val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff;
3988 if (enable)
3966 val &= ~idx; 3989 val &= ~idx;
3967 else 3990 else
3968 val |= idx; 3991 val |= idx;
3969 3992
3970 /* power down unused output ports */ 3993 /* power down unused output ports */
3971 snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val); 3994 snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val);
3972}; 3995}
3996
3997static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
3998{
3999 stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid));
4000}
3973 4001
3974static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) 4002static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
3975{ 4003{