···212 /* i/o switches */213 unsigned int io_switch[2];214 unsigned int clfe_swap;215- unsigned int hp_switch;216 unsigned int aloopback;217218 struct hda_pcm pcm_rec[2]; /* PCM information */···2443 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);2444 struct sigmatel_spec *spec = codec->spec;24452446- ucontrol->value.integer.value[0] = spec->hp_switch;2447 return 0;2448}2449···2452{2453 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);2454 struct sigmatel_spec *spec = codec->spec;2455-2456- spec->hp_switch = ucontrol->value.integer.value[0];024572458 /* check to be sure that the ports are upto date with2459 * switch changes···2863 if (cfg->hp_outs > 1) {2864 err = stac92xx_add_control(spec,2865 STAC_CTL_WIDGET_HP_SWITCH,2866- "Headphone as Line Out Switch", 0);02867 if (err < 0)2868 return err;2869 }···3532 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)3533 return err;35340000003535 if (spec->autocfg.dig_out_pin)3536 spec->multiout.dig_out_nid = 0x05;3537 if (spec->autocfg.dig_in_pin)···3655 for (i = 0; i < AUTO_PIN_LAST; i++) {3656 hda_nid_t nid = cfg->input_pins[i];3657 if (nid) {3658- unsigned int pinctl = snd_hda_codec_read(codec, nid,3659- 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);3660- /* if PINCTL already set then skip */3661- if (pinctl & AC_PINCAP_IN)3662- continue;3663- pinctl = AC_PINCTL_IN_EN;3664- if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)3665- pinctl |= stac92xx_get_vref(codec, nid);00003666 stac92xx_auto_set_pinctl(codec, nid, pinctl);3667 }3668 }···3788 return 0;3789}3790000000000000000000003791static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)3792{3793 struct sigmatel_spec *spec = codec->spec;3794 struct auto_pin_cfg *cfg = &spec->autocfg;3795- int nid = cfg->hp_pins[cfg->hp_outs - 1];3796 int i, presence;37973798 presence = 0;···3822 for (i = 0; i < cfg->hp_outs; i++) {3823 if (presence)3824 break;3825- if (spec->hp_switch && cfg->hp_pins[i] == nid)3826- break;3827 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);3828 }38293830 if (presence) {3831- /* disable lineouts, enable hp */3832 if (spec->hp_switch)3833- stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN);03834 for (i = 0; i < cfg->line_outs; i++)3835 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],3836 AC_PINCTL_OUT_EN);···3843 spec->gpio_dir, spec->gpio_data &3844 ~spec->eapd_mask);3845 } else {3846- /* enable lineouts, disable hp */3847 if (spec->hp_switch)3848- stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);03849 for (i = 0; i < cfg->line_outs; i++)3850 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],3851 AC_PINCTL_OUT_EN);···3858 spec->gpio_dir, spec->gpio_data |3859 spec->eapd_mask);3860 }3861- if (!spec->hp_switch && cfg->hp_outs > 1 && presence)3862- stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);000000003863} 38643865static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
···212 /* i/o switches */213 unsigned int io_switch[2];214 unsigned int clfe_swap;215+ unsigned int hp_switch; /* NID of HP as line-out */216 unsigned int aloopback;217218 struct hda_pcm pcm_rec[2]; /* PCM information */···2443 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);2444 struct sigmatel_spec *spec = codec->spec;24452446+ ucontrol->value.integer.value[0] = !!spec->hp_switch;2447 return 0;2448}2449···2452{2453 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);2454 struct sigmatel_spec *spec = codec->spec;2455+ int nid = kcontrol->private_value;2456+2457+ spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;24582459 /* check to be sure that the ports are upto date with2460 * switch changes···2862 if (cfg->hp_outs > 1) {2863 err = stac92xx_add_control(spec,2864 STAC_CTL_WIDGET_HP_SWITCH,2865+ "Headphone as Line Out Switch",2866+ cfg->hp_pins[cfg->hp_outs - 1]);2867 if (err < 0)2868 return err;2869 }···3530 if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)3531 return err;35323533+ if (spec->num_muxes > 0) {3534+ err = stac92xx_auto_create_mux_input_ctls(codec);3535+ if (err < 0)3536+ return err;3537+ }3538+3539 if (spec->autocfg.dig_out_pin)3540 spec->multiout.dig_out_nid = 0x05;3541 if (spec->autocfg.dig_in_pin)···3647 for (i = 0; i < AUTO_PIN_LAST; i++) {3648 hda_nid_t nid = cfg->input_pins[i];3649 if (nid) {3650+ unsigned int pinctl;3651+ if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {3652+ /* for mic pins, force to initialize */3653+ pinctl = stac92xx_get_vref(codec, nid);3654+ } else {3655+ pinctl = snd_hda_codec_read(codec, nid, 0,3656+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0);3657+ /* if PINCTL already set then skip */3658+ if (pinctl & AC_PINCTL_IN_EN)3659+ continue;3660+ }3661+ pinctl |= AC_PINCTL_IN_EN;3662 stac92xx_auto_set_pinctl(codec, nid, pinctl);3663 }3664 }···3776 return 0;3777}37783779+/* return non-zero if the hp-pin of the given array index isn't3780+ * a jack-detection target3781+ */3782+static int no_hp_sensing(struct sigmatel_spec *spec, int i)3783+{3784+ struct auto_pin_cfg *cfg = &spec->autocfg;3785+3786+ /* ignore sensing of shared line and mic jacks */3787+ if (spec->line_switch &&3788+ cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])3789+ return 1;3790+ if (spec->mic_switch &&3791+ cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])3792+ return 1;3793+ /* ignore if the pin is set as line-out */3794+ if (cfg->hp_pins[i] == spec->hp_switch)3795+ return 1;3796+ return 0;3797+}3798+3799static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)3800{3801 struct sigmatel_spec *spec = codec->spec;3802 struct auto_pin_cfg *cfg = &spec->autocfg;03803 int i, presence;38043805 presence = 0;···3791 for (i = 0; i < cfg->hp_outs; i++) {3792 if (presence)3793 break;3794+ if (no_hp_sensing(spec, i))3795+ continue;3796 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);3797 }37983799 if (presence) {3800+ /* disable lineouts */3801 if (spec->hp_switch)3802+ stac92xx_reset_pinctl(codec, spec->hp_switch,3803+ AC_PINCTL_OUT_EN);3804 for (i = 0; i < cfg->line_outs; i++)3805 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],3806 AC_PINCTL_OUT_EN);···3811 spec->gpio_dir, spec->gpio_data &3812 ~spec->eapd_mask);3813 } else {3814+ /* enable lineouts */3815 if (spec->hp_switch)3816+ stac92xx_set_pinctl(codec, spec->hp_switch,3817+ AC_PINCTL_OUT_EN);3818 for (i = 0; i < cfg->line_outs; i++)3819 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],3820 AC_PINCTL_OUT_EN);···3825 spec->gpio_dir, spec->gpio_data |3826 spec->eapd_mask);3827 }3828+ /* toggle hp outs */3829+ for (i = 0; i < cfg->hp_outs; i++) {3830+ unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;3831+ if (no_hp_sensing(spec, i))3832+ continue;3833+ if (presence)3834+ stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);3835+ else3836+ stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);3837+ }3838} 38393840static void stac92xx_pin_sense(struct hda_codec *codec, int idx)