···212212 /* i/o switches */213213 unsigned int io_switch[2];214214 unsigned int clfe_swap;215215- unsigned int hp_switch;215215+ unsigned int hp_switch; /* NID of HP as line-out */216216 unsigned int aloopback;217217218218 struct hda_pcm pcm_rec[2]; /* PCM information */···24432443 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);24442444 struct sigmatel_spec *spec = codec->spec;2445244524462446- ucontrol->value.integer.value[0] = spec->hp_switch;24462446+ ucontrol->value.integer.value[0] = !!spec->hp_switch;24472447 return 0;24482448}24492449···24522452{24532453 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);24542454 struct sigmatel_spec *spec = codec->spec;24552455-24562456- spec->hp_switch = ucontrol->value.integer.value[0];24552455+ int nid = kcontrol->private_value;24562456+24572457+ spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;2457245824582459 /* check to be sure that the ports are upto date with24592460 * switch changes···28632862 if (cfg->hp_outs > 1) {28642863 err = stac92xx_add_control(spec,28652864 STAC_CTL_WIDGET_HP_SWITCH,28662866- "Headphone as Line Out Switch", 0);28652865+ "Headphone as Line Out Switch",28662866+ cfg->hp_pins[cfg->hp_outs - 1]);28672867 if (err < 0)28682868 return err;28692869 }···35323530 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)35333531 return err;3534353235333533+ if (spec->num_muxes > 0) {35343534+ err = stac92xx_auto_create_mux_input_ctls(codec);35353535+ if (err < 0)35363536+ return err;35373537+ }35383538+35353539 if (spec->autocfg.dig_out_pin)35363540 spec->multiout.dig_out_nid = 0x05;35373541 if (spec->autocfg.dig_in_pin)···36553647 for (i = 0; i < AUTO_PIN_LAST; i++) {36563648 hda_nid_t nid = cfg->input_pins[i];36573649 if (nid) {36583658- unsigned int pinctl = snd_hda_codec_read(codec, nid,36593659- 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);36603660- /* if PINCTL already set then skip */36613661- if (pinctl & AC_PINCAP_IN)36623662- continue;36633663- pinctl = AC_PINCTL_IN_EN;36643664- if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)36653665- pinctl |= stac92xx_get_vref(codec, nid);36503650+ unsigned int pinctl;36513651+ if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {36523652+ /* for mic pins, force to initialize */36533653+ pinctl = stac92xx_get_vref(codec, nid);36543654+ } else {36553655+ pinctl = snd_hda_codec_read(codec, nid, 0,36563656+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0);36573657+ /* if PINCTL already set then skip */36583658+ if (pinctl & AC_PINCTL_IN_EN)36593659+ continue;36603660+ }36613661+ pinctl |= AC_PINCTL_IN_EN;36663662 stac92xx_auto_set_pinctl(codec, nid, pinctl);36673663 }36683664 }···37883776 return 0;37893777}3790377837793779+/* return non-zero if the hp-pin of the given array index isn't37803780+ * a jack-detection target37813781+ */37823782+static int no_hp_sensing(struct sigmatel_spec *spec, int i)37833783+{37843784+ struct auto_pin_cfg *cfg = &spec->autocfg;37853785+37863786+ /* ignore sensing of shared line and mic jacks */37873787+ if (spec->line_switch &&37883788+ cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])37893789+ return 1;37903790+ if (spec->mic_switch &&37913791+ cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])37923792+ return 1;37933793+ /* ignore if the pin is set as line-out */37943794+ if (cfg->hp_pins[i] == spec->hp_switch)37953795+ return 1;37963796+ return 0;37973797+}37983798+37913799static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)37923800{37933801 struct sigmatel_spec *spec = codec->spec;37943802 struct auto_pin_cfg *cfg = &spec->autocfg;37953795- int nid = cfg->hp_pins[cfg->hp_outs - 1];37963803 int i, presence;3797380437983805 presence = 0;···38223791 for (i = 0; i < cfg->hp_outs; i++) {38233792 if (presence)38243793 break;38253825- if (spec->hp_switch && cfg->hp_pins[i] == nid)38263826- break;37943794+ if (no_hp_sensing(spec, i))37953795+ continue;38273796 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);38283797 }3829379838303799 if (presence) {38313831- /* disable lineouts, enable hp */38003800+ /* disable lineouts */38323801 if (spec->hp_switch)38333833- stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN);38023802+ stac92xx_reset_pinctl(codec, spec->hp_switch,38033803+ AC_PINCTL_OUT_EN);38343804 for (i = 0; i < cfg->line_outs; i++)38353805 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],38363806 AC_PINCTL_OUT_EN);···38433811 spec->gpio_dir, spec->gpio_data &38443812 ~spec->eapd_mask);38453813 } else {38463846- /* enable lineouts, disable hp */38143814+ /* enable lineouts */38473815 if (spec->hp_switch)38483848- stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);38163816+ stac92xx_set_pinctl(codec, spec->hp_switch,38173817+ AC_PINCTL_OUT_EN);38493818 for (i = 0; i < cfg->line_outs; i++)38503819 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],38513820 AC_PINCTL_OUT_EN);···38583825 spec->gpio_dir, spec->gpio_data |38593826 spec->eapd_mask);38603827 }38613861- if (!spec->hp_switch && cfg->hp_outs > 1 && presence)38623862- stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);38283828+ /* toggle hp outs */38293829+ for (i = 0; i < cfg->hp_outs; i++) {38303830+ unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;38313831+ if (no_hp_sensing(spec, i))38323832+ continue;38333833+ if (presence)38343834+ stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);38353835+ else38363836+ stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);38373837+ }38633838} 3864383938653840static void stac92xx_pin_sense(struct hda_codec *codec, int idx)