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.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index b56ca4019392..abe9493f0a2c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -534,6 +534,22 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
534 return 0; 534 return 0;
535} 535}
536 536
537static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
538{
539 unsigned int pincap = snd_hda_param_read(codec, nid,
540 AC_PAR_PIN_CAP);
541 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
542 if (pincap & AC_PINCAP_VREF_100)
543 return AC_PINCTL_VREF_100;
544 if (pincap & AC_PINCAP_VREF_80)
545 return AC_PINCTL_VREF_80;
546 if (pincap & AC_PINCAP_VREF_50)
547 return AC_PINCTL_VREF_50;
548 if (pincap & AC_PINCAP_VREF_GRD)
549 return AC_PINCTL_VREF_GRD;
550 return 0;
551}
552
537static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) 553static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
538 554
539{ 555{
@@ -571,9 +587,12 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
571 587
572 if (val) 588 if (val)
573 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); 589 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
574 else 590 else {
575 stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_IN_EN); 591 unsigned int pinctl = AC_PINCTL_IN_EN;
576 592 if (io_idx) /* set VREF for mic */
593 pinctl |= stac92xx_get_vref(codec, nid);
594 stac92xx_auto_set_pinctl(codec, nid, pinctl);
595 }
577 return 1; 596 return 1;
578} 597}
579 598
@@ -767,13 +786,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin
767 return 0; 786 return 0;
768 787
769 wid_caps = get_wcaps(codec, pin); 788 wid_caps = get_wcaps(codec, pin);
770 if (wid_caps & AC_WCAP_UNSOL_CAP) { 789 if (wid_caps & AC_WCAP_UNSOL_CAP)
771 /* Enable unsolicited responses on the HP widget */
772 snd_hda_codec_write(codec, pin, 0,
773 AC_VERB_SET_UNSOLICITED_ENABLE,
774 STAC_UNSOL_ENABLE);
775 spec->hp_detect = 1; 790 spec->hp_detect = 1;
776 }
777 791
778 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 792 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
779 for (i = 0; i < cfg->line_outs; i++) { 793 for (i = 0; i < cfg->line_outs; i++) {
@@ -896,13 +910,8 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
896 return 0; 910 return 0;
897 911
898 wid_caps = get_wcaps(codec, pin); 912 wid_caps = get_wcaps(codec, pin);
899 if (wid_caps & AC_WCAP_UNSOL_CAP) { 913 if (wid_caps & AC_WCAP_UNSOL_CAP)
900 /* Enable unsolicited responses on the HP widget */
901 snd_hda_codec_write(codec, pin, 0,
902 AC_VERB_SET_UNSOLICITED_ENABLE,
903 STAC_UNSOL_ENABLE);
904 spec->hp_detect = 1; 914 spec->hp_detect = 1;
905 }
906 915
907 return 0; 916 return 0;
908} 917}
@@ -944,6 +953,10 @@ static int stac92xx_init(struct hda_codec *codec)
944 953
945 /* set up pins */ 954 /* set up pins */
946 if (spec->hp_detect) { 955 if (spec->hp_detect) {
956 /* Enable unsolicited responses on the HP widget */
957 snd_hda_codec_write(codec, cfg->hp_pin, 0,
958 AC_VERB_SET_UNSOLICITED_ENABLE,
959 STAC_UNSOL_ENABLE);
947 /* fake event to set up pins */ 960 /* fake event to set up pins */
948 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 961 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
949 } else { 962 } else {
@@ -951,9 +964,13 @@ static int stac92xx_init(struct hda_codec *codec)
951 stac92xx_auto_init_hp_out(codec); 964 stac92xx_auto_init_hp_out(codec);
952 } 965 }
953 for (i = 0; i < AUTO_PIN_LAST; i++) { 966 for (i = 0; i < AUTO_PIN_LAST; i++) {
954 if (cfg->input_pins[i]) 967 hda_nid_t nid = cfg->input_pins[i];
955 stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], 968 if (nid) {
956 AC_PINCTL_IN_EN); 969 unsigned int pinctl = AC_PINCTL_IN_EN;
970 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
971 pinctl |= stac92xx_get_vref(codec, nid);
972 stac92xx_auto_set_pinctl(codec, nid, pinctl);
973 }
957 } 974 }
958 if (cfg->dig_out_pin) 975 if (cfg->dig_out_pin)
959 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, 976 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,