Merge branch 'topic/fix/hda' into for-linus
This commit is contained in:
commit
24924f884c
|
@ -212,7 +212,7 @@ struct sigmatel_spec {
|
||||||
/* i/o switches */
|
/* i/o switches */
|
||||||
unsigned int io_switch[2];
|
unsigned int io_switch[2];
|
||||||
unsigned int clfe_swap;
|
unsigned int clfe_swap;
|
||||||
unsigned int hp_switch;
|
unsigned int hp_switch; /* NID of HP as line-out */
|
||||||
unsigned int aloopback;
|
unsigned int aloopback;
|
||||||
|
|
||||||
struct hda_pcm pcm_rec[2]; /* PCM information */
|
struct hda_pcm pcm_rec[2]; /* PCM information */
|
||||||
|
@ -2443,7 +2443,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
|
||||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||||
struct sigmatel_spec *spec = codec->spec;
|
struct sigmatel_spec *spec = codec->spec;
|
||||||
|
|
||||||
ucontrol->value.integer.value[0] = spec->hp_switch;
|
ucontrol->value.integer.value[0] = !!spec->hp_switch;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2452,8 +2452,9 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
|
||||||
{
|
{
|
||||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||||
struct sigmatel_spec *spec = codec->spec;
|
struct sigmatel_spec *spec = codec->spec;
|
||||||
|
int nid = kcontrol->private_value;
|
||||||
spec->hp_switch = ucontrol->value.integer.value[0];
|
|
||||||
|
spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
|
||||||
|
|
||||||
/* check to be sure that the ports are upto date with
|
/* check to be sure that the ports are upto date with
|
||||||
* switch changes
|
* switch changes
|
||||||
|
@ -2862,7 +2863,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
|
||||||
if (cfg->hp_outs > 1) {
|
if (cfg->hp_outs > 1) {
|
||||||
err = stac92xx_add_control(spec,
|
err = stac92xx_add_control(spec,
|
||||||
STAC_CTL_WIDGET_HP_SWITCH,
|
STAC_CTL_WIDGET_HP_SWITCH,
|
||||||
"Headphone as Line Out Switch", 0);
|
"Headphone as Line Out Switch",
|
||||||
|
cfg->hp_pins[cfg->hp_outs - 1]);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -3530,6 +3532,12 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
|
||||||
if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
|
if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
if (spec->num_muxes > 0) {
|
||||||
|
err = stac92xx_auto_create_mux_input_ctls(codec);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (spec->autocfg.dig_out_pin)
|
if (spec->autocfg.dig_out_pin)
|
||||||
spec->multiout.dig_out_nid = 0x05;
|
spec->multiout.dig_out_nid = 0x05;
|
||||||
if (spec->autocfg.dig_in_pin)
|
if (spec->autocfg.dig_in_pin)
|
||||||
|
@ -3647,14 +3655,18 @@ static int stac92xx_init(struct hda_codec *codec)
|
||||||
for (i = 0; i < AUTO_PIN_LAST; i++) {
|
for (i = 0; i < AUTO_PIN_LAST; i++) {
|
||||||
hda_nid_t nid = cfg->input_pins[i];
|
hda_nid_t nid = cfg->input_pins[i];
|
||||||
if (nid) {
|
if (nid) {
|
||||||
unsigned int pinctl = snd_hda_codec_read(codec, nid,
|
unsigned int pinctl;
|
||||||
0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
|
||||||
/* if PINCTL already set then skip */
|
/* for mic pins, force to initialize */
|
||||||
if (pinctl & AC_PINCAP_IN)
|
pinctl = stac92xx_get_vref(codec, nid);
|
||||||
continue;
|
} else {
|
||||||
pinctl = AC_PINCTL_IN_EN;
|
pinctl = snd_hda_codec_read(codec, nid, 0,
|
||||||
if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
|
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||||
pinctl |= stac92xx_get_vref(codec, nid);
|
/* if PINCTL already set then skip */
|
||||||
|
if (pinctl & AC_PINCTL_IN_EN)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pinctl |= AC_PINCTL_IN_EN;
|
||||||
stac92xx_auto_set_pinctl(codec, nid, pinctl);
|
stac92xx_auto_set_pinctl(codec, nid, pinctl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3776,11 +3788,30 @@ static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return non-zero if the hp-pin of the given array index isn't
|
||||||
|
* a jack-detection target
|
||||||
|
*/
|
||||||
|
static int no_hp_sensing(struct sigmatel_spec *spec, int i)
|
||||||
|
{
|
||||||
|
struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
|
|
||||||
|
/* ignore sensing of shared line and mic jacks */
|
||||||
|
if (spec->line_switch &&
|
||||||
|
cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
|
||||||
|
return 1;
|
||||||
|
if (spec->mic_switch &&
|
||||||
|
cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
|
||||||
|
return 1;
|
||||||
|
/* ignore if the pin is set as line-out */
|
||||||
|
if (cfg->hp_pins[i] == spec->hp_switch)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
|
static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
|
||||||
{
|
{
|
||||||
struct sigmatel_spec *spec = codec->spec;
|
struct sigmatel_spec *spec = codec->spec;
|
||||||
struct auto_pin_cfg *cfg = &spec->autocfg;
|
struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
int nid = cfg->hp_pins[cfg->hp_outs - 1];
|
|
||||||
int i, presence;
|
int i, presence;
|
||||||
|
|
||||||
presence = 0;
|
presence = 0;
|
||||||
|
@ -3791,15 +3822,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
|
||||||
for (i = 0; i < cfg->hp_outs; i++) {
|
for (i = 0; i < cfg->hp_outs; i++) {
|
||||||
if (presence)
|
if (presence)
|
||||||
break;
|
break;
|
||||||
if (spec->hp_switch && cfg->hp_pins[i] == nid)
|
if (no_hp_sensing(spec, i))
|
||||||
break;
|
continue;
|
||||||
presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
|
presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presence) {
|
if (presence) {
|
||||||
/* disable lineouts, enable hp */
|
/* disable lineouts */
|
||||||
if (spec->hp_switch)
|
if (spec->hp_switch)
|
||||||
stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN);
|
stac92xx_reset_pinctl(codec, spec->hp_switch,
|
||||||
|
AC_PINCTL_OUT_EN);
|
||||||
for (i = 0; i < cfg->line_outs; i++)
|
for (i = 0; i < cfg->line_outs; i++)
|
||||||
stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
|
stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
|
||||||
AC_PINCTL_OUT_EN);
|
AC_PINCTL_OUT_EN);
|
||||||
|
@ -3811,9 +3843,10 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
|
||||||
spec->gpio_dir, spec->gpio_data &
|
spec->gpio_dir, spec->gpio_data &
|
||||||
~spec->eapd_mask);
|
~spec->eapd_mask);
|
||||||
} else {
|
} else {
|
||||||
/* enable lineouts, disable hp */
|
/* enable lineouts */
|
||||||
if (spec->hp_switch)
|
if (spec->hp_switch)
|
||||||
stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
|
stac92xx_set_pinctl(codec, spec->hp_switch,
|
||||||
|
AC_PINCTL_OUT_EN);
|
||||||
for (i = 0; i < cfg->line_outs; i++)
|
for (i = 0; i < cfg->line_outs; i++)
|
||||||
stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
|
stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
|
||||||
AC_PINCTL_OUT_EN);
|
AC_PINCTL_OUT_EN);
|
||||||
|
@ -3825,8 +3858,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
|
||||||
spec->gpio_dir, spec->gpio_data |
|
spec->gpio_dir, spec->gpio_data |
|
||||||
spec->eapd_mask);
|
spec->eapd_mask);
|
||||||
}
|
}
|
||||||
if (!spec->hp_switch && cfg->hp_outs > 1 && presence)
|
/* toggle hp outs */
|
||||||
stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
|
for (i = 0; i < cfg->hp_outs; i++) {
|
||||||
|
unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
|
||||||
|
if (no_hp_sensing(spec, i))
|
||||||
|
continue;
|
||||||
|
if (presence)
|
||||||
|
stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
|
||||||
|
else
|
||||||
|
stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
|
static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
|
||||||
|
|
Loading…
Reference in a new issue