}
 EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
 
+/**
+ * snd_hda_get_default_vref - Get the default (mic) VREF pin bits
+ *
+ * Guess the suitable VREF pin bits to be set as the pin-control value.
+ * Note: the function doesn't set the AC_PINCTL_IN_EN bit.
+ */
+unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin)
+{
+       unsigned int pincap;
+       unsigned int oldval;
+       oldval = snd_hda_codec_read(codec, pin, 0,
+                                   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+       pincap = snd_hda_query_pin_caps(codec, pin);
+       pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
+       /* Exception: if the default pin setup is vref50, we give it priority */
+       if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
+               return AC_PINCTL_VREF_80;
+       else if (pincap & AC_PINCAP_VREF_50)
+               return AC_PINCTL_VREF_50;
+       else if (pincap & AC_PINCAP_VREF_100)
+               return AC_PINCTL_VREF_100;
+       else if (pincap & AC_PINCAP_VREF_GRD)
+               return AC_PINCTL_VREF_GRD;
+       return AC_PINCTL_VREF_HIZ;
+}
+EXPORT_SYMBOL_HDA(snd_hda_get_default_vref);
+
 int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
                         unsigned int val, bool cached)
 {
 
 #define PIN_HP                 (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
 #define PIN_HP_AMP             (AC_PINCTL_HP_EN)
 
+unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin);
 int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
                         unsigned int val, bool cached);
 
  * HP-drive capability, the HP bit is omitted.
  *
  * The function doesn't check the input VREF capability bits, though.
+ * Use snd_hda_get_default_vref() to guess the right value.
  * Also, this function is only for analog pins, not for HDMI pins.
  */
 static inline int
 
        for (i = 0; i < cfg->num_inputs; i++) {
                hda_nid_t nid = cfg->inputs[i].pin;
                int type = cfg->inputs[i].type;
+               int val;
                switch (nid) {
                case 0x15: /* port-C */
                        snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
                        snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
                        break;
                }
-               snd_hda_set_pin_ctl(codec, nid,
-                                   type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN);
+               val = PIN_IN;
+               if (type == AUTO_PIN_MIC)
+                       val |= snd_hda_get_default_vref(codec, nid);
+               snd_hda_set_pin_ctl(codec, nid, val);
                if (nid != AD1988_PIN_CD_NID)
                        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
                                            AMP_OUT_MUTE);
 
 static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
 {
        if (pin) {
-               snd_hda_set_pin_ctl(codec, pin, PIN_VREF80);
+               snd_hda_set_pin_ctl(codec, pin, PIN_IN |
+                                   snd_hda_get_default_vref(codec, pin));
                if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
                        snd_hda_codec_write(codec, pin, 0,
                                            AC_VERB_SET_AMP_GAIN_MUTE,
 
 static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
 {
        if (pin) {
-               snd_hda_set_pin_ctl(codec, pin, PIN_VREF80);
+               snd_hda_set_pin_ctl(codec, pin, PIN_IN |
+                                   snd_hda_get_default_vref(codec, pin));
                if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
                        snd_hda_codec_write(codec, pin, 0,
                                            AC_VERB_SET_AMP_GAIN_MUTE,
 
                        continue;
                /* set appropriate pin control and mute first */
                ctl = PIN_IN;
-               if (cfg->inputs[i].type == AUTO_PIN_MIC) {
-                       unsigned int caps = snd_hda_query_pin_caps(codec, pin);
-                       caps >>= AC_PINCAP_VREF_SHIFT;
-                       if (caps & AC_PINCAP_VREF_80)
-                               ctl = PIN_VREF80;
-               }
+               if (cfg->inputs[i].type == AUTO_PIN_MIC)
+                       ctl |= snd_hda_get_default_vref(codec, pin);
                snd_hda_set_pin_ctl(codec, pin, ctl);
                snd_hda_codec_write(codec, spec->adc_nid[i], 0,
                                    AC_VERB_SET_AMP_GAIN_MUTE,
 
        }
 
        for (i = 0; i < cfg->num_inputs; i++) {
-               unsigned int type;
+               hda_nid_t pin = cfg->inputs[i].pin;
+               unsigned int type = PIN_IN;
                if (cfg->inputs[i].type == AUTO_PIN_MIC)
-                       type = PIN_VREF80;
-               else
-                       type = PIN_IN;
-               snd_hda_set_pin_ctl(codec, cfg->inputs[i].pin, type);
+                       type |= snd_hda_get_default_vref(codec, pin);
+               snd_hda_set_pin_ctl(codec, pin, type);
        }
 
        if (spec->auto_mic) {
 
                 * first is the real internal mic and the second is HP jack.
                 */
                if (spec->cur_mux[adc_idx])
-                       val = PIN_VREF80;
+                       val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
                else
                        val = PIN_HP;
                snd_hda_set_pin_ctl(codec, pin, val);
                              int auto_pin_type)
 {
        unsigned int val = PIN_IN;
-
-       if (auto_pin_type == AUTO_PIN_MIC) {
-               unsigned int pincap;
-               unsigned int oldval;
-               oldval = snd_hda_codec_read(codec, nid, 0,
-                                           AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-               pincap = snd_hda_query_pin_caps(codec, nid);
-               pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
-               /* if the default pin setup is vref50, we give it priority */
-               if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
-                       val = PIN_VREF80;
-               else if (pincap & AC_PINCAP_VREF_50)
-                       val = PIN_VREF50;
-               else if (pincap & AC_PINCAP_VREF_100)
-                       val = PIN_VREF100;
-               else if (pincap & AC_PINCAP_VREF_GRD)
-                       val = PIN_VREFGRD;
-       }
+       if (auto_pin_type == AUTO_PIN_MIC)
+               val |= snd_hda_get_default_vref(codec, nid);
        snd_hda_set_pin_ctl(codec, nid, val);
 }
 
 
        return 0;
 }
 
-static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
-                                       hda_nid_t nid)
-{
-       unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
-       pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
-       if (pincap & AC_PINCAP_VREF_100)
-               return AC_PINCTL_VREF_100;
-       if (pincap & AC_PINCAP_VREF_80)
-               return AC_PINCTL_VREF_80;
-       if (pincap & AC_PINCAP_VREF_50)
-               return AC_PINCTL_VREF_50;
-       if (pincap & AC_PINCAP_VREF_GRD)
-               return AC_PINCTL_VREF_GRD;
-       return 0;
-}
-
 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
 
 {
        hda_nid_t nid = kcontrol->private_value;
        unsigned int vref = stac92xx_vref_get(codec, nid);
 
-       if (vref == stac92xx_get_default_vref(codec, nid))
+       if (vref == snd_hda_get_default_vref(codec, nid))
                ucontrol->value.enumerated.item[0] = 0;
        else if (vref == AC_PINCTL_VREF_GRD)
                ucontrol->value.enumerated.item[0] = 1;
        hda_nid_t nid = kcontrol->private_value;
 
        if (ucontrol->value.enumerated.item[0] == 0)
-               new_vref = stac92xx_get_default_vref(codec, nid);
+               new_vref = snd_hda_get_default_vref(codec, nid);
        else if (ucontrol->value.enumerated.item[0] == 1)
                new_vref = AC_PINCTL_VREF_GRD;
        else if (ucontrol->value.enumerated.item[0] == 2)
        else {
                unsigned int pinctl = AC_PINCTL_IN_EN;
                if (io_idx) /* set VREF for mic */
-                       pinctl |= stac92xx_get_default_vref(codec, nid);
+                       pinctl |= snd_hda_get_default_vref(codec, nid);
                stac92xx_auto_set_pinctl(codec, nid, pinctl);
        }
 
        char name[22];
 
        if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
-               if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
+               if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
                        && nid == spec->line_switch)
                        control = STAC_CTL_WIDGET_IO_SWITCH;
                else if (snd_hda_query_pin_caps(codec, nid)
                unsigned int pinctl, conf;
                if (type == AUTO_PIN_MIC) {
                        /* for mic pins, force to initialize */
-                       pinctl = stac92xx_get_default_vref(codec, nid);
+                       pinctl = snd_hda_get_default_vref(codec, nid);
                        pinctl |= AC_PINCTL_IN_EN;
                        stac92xx_auto_set_pinctl(codec, nid, pinctl);
                } else {
 
                hda_nid_t nid = cfg->inputs[i].pin;
                if (spec->smart51_enabled && is_smart51_pins(codec, nid))
                        ctl = PIN_OUT;
-               else if (cfg->inputs[i].type == AUTO_PIN_MIC)
-                       ctl = PIN_VREF50;
-               else
+               else {
                        ctl = PIN_IN;
+                       if (cfg->inputs[i].type == AUTO_PIN_MIC)
+                               ctl |= snd_hda_get_default_vref(codec, nid);
+               }
                snd_hda_set_pin_ctl(codec, nid, ctl);
        }