mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 00:21:59 +00:00
ALSA: hda - Introduce snd_hda_set_pin_ctl*() helper functions
For setting the pin-control values more safely to match with the actual pin capability bits, a copule of new helper functions, snd_hda_set_pin_ctl() and snd_hda_set_pin_ctl_cache(), are introduced. These are simple replacement of the codec verb write with AC_VERB_SET_PIN_WIDGET but do more sanity checks and filter out superfluous pin-control bits if they don't fit with the corresponding pin capabilities. Some codecs are screwed up or ignore the command when such a wrong bit is set. These helpers will avoid such secret errors. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
d398011057
commit
cdd03cedc5
@ -4795,6 +4795,32 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
|
||||
|
||||
int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
|
||||
unsigned int val, bool cached)
|
||||
{
|
||||
if (val) {
|
||||
unsigned int cap = snd_hda_query_pin_caps(codec, pin);
|
||||
if (val & AC_PINCTL_OUT_EN) {
|
||||
if (!(cap & AC_PINCAP_OUT))
|
||||
val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
|
||||
else if ((val & AC_PINCTL_HP_EN) &&
|
||||
!(cap & AC_PINCAP_HP_DRV))
|
||||
val &= ~AC_PINCTL_HP_EN;
|
||||
}
|
||||
if (val & AC_PINCTL_IN_EN) {
|
||||
if (!(cap & AC_PINCAP_IN))
|
||||
val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN);
|
||||
}
|
||||
}
|
||||
if (cached)
|
||||
return snd_hda_codec_update_cache(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
||||
else
|
||||
return snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(_snd_hda_set_pin_ctl);
|
||||
|
||||
/*
|
||||
* Helper for automatic pin configuration
|
||||
*/
|
||||
|
@ -502,6 +502,44 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
|
||||
#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
|
||||
#define PIN_HP_AMP (AC_PINCTL_HP_EN)
|
||||
|
||||
int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
|
||||
unsigned int val, bool cached);
|
||||
|
||||
/**
|
||||
* _snd_hda_set_pin_ctl - Set a pin-control value safely
|
||||
* @codec: the codec instance
|
||||
* @pin: the pin NID to set the control
|
||||
* @val: the pin-control value (AC_PINCTL_* bits)
|
||||
*
|
||||
* This function sets the pin-control value to the given pin, but
|
||||
* filters out the invalid pin-control bits when the pin has no such
|
||||
* capabilities. For example, when PIN_HP is passed but the pin has no
|
||||
* HP-drive capability, the HP bit is omitted.
|
||||
*
|
||||
* The function doesn't check the input VREF capability bits, though.
|
||||
* Also, this function is only for analog pins, not for HDMI pins.
|
||||
*/
|
||||
static inline int
|
||||
snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, unsigned int val)
|
||||
{
|
||||
return _snd_hda_set_pin_ctl(codec, pin, val, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_set_pin_ctl_cache - Set a pin-control value safely
|
||||
* @codec: the codec instance
|
||||
* @pin: the pin NID to set the control
|
||||
* @val: the pin-control value (AC_PINCTL_* bits)
|
||||
*
|
||||
* Just like snd_hda_set_pin_ctl() but write to cache as well.
|
||||
*/
|
||||
static inline int
|
||||
snd_hda_set_pin_ctl_cache(struct hda_codec *codec, hda_nid_t pin,
|
||||
unsigned int val)
|
||||
{
|
||||
return _snd_hda_set_pin_ctl(codec, pin, val, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* get widget capabilities
|
||||
*/
|
||||
|
@ -1742,9 +1742,7 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
|
||||
if (! ad198x_eapd_put(kcontrol, ucontrol))
|
||||
return 0;
|
||||
/* change speaker pin appropriately */
|
||||
snd_hda_codec_write(codec, 0x05, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
spec->cur_eapd ? PIN_OUT : 0);
|
||||
snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0);
|
||||
/* toggle HP mute appropriately */
|
||||
snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
|
||||
HDA_AMP_MUTE,
|
||||
@ -3103,7 +3101,7 @@ static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
|
||||
int dac_idx)
|
||||
{
|
||||
/* set as output */
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
|
||||
snd_hda_set_pin_ctl(codec, nid, pin_type);
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
|
||||
switch (nid) {
|
||||
case 0x11: /* port-A - DAC 03 */
|
||||
@ -3165,7 +3163,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
|
||||
snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
|
||||
break;
|
||||
}
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
snd_hda_set_pin_ctl(codec, nid,
|
||||
type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN);
|
||||
if (nid != AD1988_PIN_CD_NID)
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
|
@ -341,8 +341,7 @@ static int ca0110_build_pcms(struct hda_codec *codec)
|
||||
static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
|
||||
{
|
||||
if (pin) {
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
|
||||
snd_hda_set_pin_ctl(codec, pin, PIN_HP);
|
||||
if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
@ -356,8 +355,7 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
|
||||
static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
|
||||
{
|
||||
if (pin) {
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80);
|
||||
snd_hda_set_pin_ctl(codec, pin, PIN_VREF80);
|
||||
if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
|
@ -239,8 +239,7 @@ enum get_set {
|
||||
static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
|
||||
{
|
||||
if (pin) {
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
|
||||
snd_hda_set_pin_ctl(codec, pin, PIN_HP);
|
||||
if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
@ -254,9 +253,7 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
|
||||
static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
|
||||
{
|
||||
if (pin) {
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
PIN_VREF80);
|
||||
snd_hda_set_pin_ctl(codec, pin, PIN_VREF80);
|
||||
if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
|
@ -933,8 +933,7 @@ static void cs_automute(struct hda_codec *codec)
|
||||
pin_ctl = 0;
|
||||
|
||||
nid = cfg->speaker_pins[i];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl);
|
||||
snd_hda_set_pin_ctl(codec, nid, pin_ctl);
|
||||
}
|
||||
if (spec->gpio_eapd_hp) {
|
||||
unsigned int gpio = hp_present ?
|
||||
@ -948,16 +947,14 @@ static void cs_automute(struct hda_codec *codec)
|
||||
/* mute HPs if spdif jack (SENSE_B) is present */
|
||||
for (i = 0; i < cfg->hp_outs; i++) {
|
||||
nid = cfg->hp_pins[i];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
snd_hda_set_pin_ctl(codec, nid,
|
||||
(spdif_present && spec->sense_b) ? 0 : PIN_HP);
|
||||
}
|
||||
|
||||
/* SPDIF TX on/off */
|
||||
if (cfg->dig_outs) {
|
||||
nid = cfg->dig_out_pins[0];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
snd_hda_set_pin_ctl(codec, nid,
|
||||
spdif_present ? PIN_OUT : 0);
|
||||
|
||||
}
|
||||
@ -1024,13 +1021,11 @@ static void init_output(struct hda_codec *codec)
|
||||
|
||||
/* set appropriate pin controls */
|
||||
for (i = 0; i < cfg->line_outs; i++)
|
||||
snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
snd_hda_set_pin_ctl(codec, cfg->line_out_pins[i], PIN_OUT);
|
||||
/* HP */
|
||||
for (i = 0; i < cfg->hp_outs; i++) {
|
||||
hda_nid_t nid = cfg->hp_pins[i];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
|
||||
snd_hda_set_pin_ctl(codec, nid, PIN_HP);
|
||||
if (!cfg->speaker_outs)
|
||||
continue;
|
||||
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
|
||||
@ -1041,8 +1036,7 @@ static void init_output(struct hda_codec *codec)
|
||||
|
||||
/* Speaker */
|
||||
for (i = 0; i < cfg->speaker_outs; i++)
|
||||
snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
snd_hda_set_pin_ctl(codec, cfg->speaker_pins[i], PIN_OUT);
|
||||
|
||||
/* SPDIF is enabled on presence detect for CS421x */
|
||||
if (spec->hp_detect || spec->spdif_detect)
|
||||
@ -1069,8 +1063,7 @@ static void init_input(struct hda_codec *codec)
|
||||
if (caps & AC_PINCAP_VREF_80)
|
||||
ctl = PIN_VREF80;
|
||||
}
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
|
||||
snd_hda_set_pin_ctl(codec, pin, ctl);
|
||||
snd_hda_codec_write(codec, spec->adc_nid[i], 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AMP_IN_MUTE(spec->adc_idx[i]));
|
||||
|
@ -1602,17 +1602,13 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
|
||||
unsigned int pinctl;
|
||||
/* headphone pin */
|
||||
pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
|
||||
snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pinctl);
|
||||
snd_hda_set_pin_ctl(codec, 0x16, pinctl);
|
||||
/* speaker pin */
|
||||
pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
|
||||
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pinctl);
|
||||
snd_hda_set_pin_ctl(codec, 0x1a, pinctl);
|
||||
/* on ideapad there is an additional speaker (subwoofer) to mute */
|
||||
if (spec->ideapad)
|
||||
snd_hda_codec_write(codec, 0x1b, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pinctl);
|
||||
snd_hda_set_pin_ctl(codec, 0x1b, pinctl);
|
||||
}
|
||||
|
||||
/* turn on/off EAPD (+ mute HP) as a master switch */
|
||||
@ -1997,8 +1993,7 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
|
||||
|
||||
/* Port A (HP) */
|
||||
pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
|
||||
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pinctl);
|
||||
snd_hda_set_pin_ctl(codec, 0x19, pinctl);
|
||||
|
||||
/* Port D (HP/LO) */
|
||||
pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
|
||||
@ -2011,13 +2006,11 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
|
||||
if (!hp_port_d_present(spec))
|
||||
pinctl = 0;
|
||||
}
|
||||
snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pinctl);
|
||||
snd_hda_set_pin_ctl(codec, 0x1c, pinctl);
|
||||
|
||||
/* CLASS_D AMP */
|
||||
pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
|
||||
snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pinctl);
|
||||
snd_hda_set_pin_ctl(codec, 0x1f, pinctl);
|
||||
}
|
||||
|
||||
/* turn on/off EAPD (+ mute HP) as a master switch */
|
||||
@ -2048,8 +2041,7 @@ static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
|
||||
/* Even though port F is the DC input, the bias is controlled on port B.
|
||||
* we also leave that port as an active input (but unselected) in DC mode
|
||||
* just in case that is necessary to make the bias setting take effect. */
|
||||
return snd_hda_codec_write_cache(codec, 0x1a, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
return snd_hda_set_pin_ctl_cache(codec, 0x1a,
|
||||
cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
|
||||
}
|
||||
|
||||
@ -2082,14 +2074,14 @@ static void cxt5066_olpc_select_mic(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
/* disable DC (port F) */
|
||||
snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_set_pin_ctl(codec, 0x1e, 0);
|
||||
|
||||
/* external mic, port B */
|
||||
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
snd_hda_set_pin_ctl(codec, 0x1a,
|
||||
spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
|
||||
|
||||
/* internal mic, port C */
|
||||
snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
snd_hda_set_pin_ctl(codec, 0x1b,
|
||||
spec->ext_mic_present ? 0 : PIN_VREF80);
|
||||
}
|
||||
|
||||
@ -3358,9 +3350,7 @@ static void do_automute(struct hda_codec *codec, int num_pins,
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
int i;
|
||||
for (i = 0; i < num_pins; i++)
|
||||
snd_hda_codec_write(codec, pins[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
on ? PIN_OUT : 0);
|
||||
snd_hda_set_pin_ctl(codec, pins[i], on ? PIN_OUT : 0);
|
||||
if (spec->pin_eapd_ctrls)
|
||||
cx_auto_turn_eapd(codec, num_pins, pins, on);
|
||||
}
|
||||
@ -3977,8 +3967,7 @@ static void cx_auto_init_output(struct hda_codec *codec)
|
||||
if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) &
|
||||
AC_PINCAP_HP_DRV)
|
||||
val |= AC_PINCTL_HP_EN;
|
||||
snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
||||
snd_hda_set_pin_ctl(codec, cfg->hp_pins[i], val);
|
||||
}
|
||||
mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
|
||||
mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
|
||||
@ -4036,8 +4025,7 @@ static void cx_auto_init_input(struct hda_codec *codec)
|
||||
type = PIN_VREF80;
|
||||
else
|
||||
type = PIN_IN;
|
||||
snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, type);
|
||||
snd_hda_set_pin_ctl(codec, cfg->inputs[i].pin, type);
|
||||
}
|
||||
|
||||
if (spec->auto_mic) {
|
||||
@ -4064,11 +4052,9 @@ static void cx_auto_init_digital(struct hda_codec *codec)
|
||||
struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||
|
||||
if (spec->multiout.dig_out_nid)
|
||||
snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
snd_hda_set_pin_ctl(codec, cfg->dig_out_pins[0], PIN_OUT);
|
||||
if (spec->dig_in_nid)
|
||||
snd_hda_codec_write(codec, cfg->dig_in_pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
|
||||
snd_hda_set_pin_ctl(codec, cfg->dig_in_pin, PIN_IN);
|
||||
}
|
||||
|
||||
static int cx_auto_init(struct hda_codec *codec)
|
||||
|
@ -319,13 +319,16 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
|
||||
|
||||
/* for shared I/O, change the pin-control accordingly */
|
||||
if (spec->shared_mic_hp) {
|
||||
unsigned int val;
|
||||
hda_nid_t pin = spec->autocfg.inputs[1].pin;
|
||||
/* NOTE: this assumes that there are only two inputs, the
|
||||
* first is the real internal mic and the second is HP jack.
|
||||
*/
|
||||
snd_hda_codec_write(codec, spec->autocfg.inputs[1].pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
spec->cur_mux[adc_idx] ?
|
||||
PIN_VREF80 : PIN_HP);
|
||||
if (spec->cur_mux[adc_idx])
|
||||
val = PIN_VREF80;
|
||||
else
|
||||
val = PIN_HP;
|
||||
snd_hda_set_pin_ctl(codec, pin, val);
|
||||
spec->automute_speaker = !spec->cur_mux[adc_idx];
|
||||
call_update_outputs(codec);
|
||||
}
|
||||
@ -394,7 +397,7 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
|
||||
else if (pincap & AC_PINCAP_VREF_GRD)
|
||||
val = PIN_VREFGRD;
|
||||
}
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
||||
snd_hda_set_pin_ctl(codec, nid, val);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -517,9 +520,7 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
|
||||
} else
|
||||
val = 0;
|
||||
val |= pin_bits;
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
val);
|
||||
snd_hda_set_pin_ctl(codec, nid, val);
|
||||
break;
|
||||
case ALC_AUTOMUTE_AMP:
|
||||
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
|
||||
@ -1621,8 +1622,7 @@ static void alc_auto_init_digital(struct hda_codec *codec)
|
||||
pin = spec->autocfg.dig_out_pins[i];
|
||||
if (!pin)
|
||||
continue;
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
snd_hda_set_pin_ctl(codec, pin, PIN_OUT);
|
||||
if (!i)
|
||||
dac = spec->multiout.dig_out_nid;
|
||||
else
|
||||
@ -1635,9 +1635,7 @@ static void alc_auto_init_digital(struct hda_codec *codec)
|
||||
}
|
||||
pin = spec->autocfg.dig_in_pin;
|
||||
if (pin)
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
PIN_IN);
|
||||
snd_hda_set_pin_ctl(codec, pin, PIN_IN);
|
||||
}
|
||||
|
||||
/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
|
||||
@ -2856,8 +2854,7 @@ static int alc_auto_create_shared_input(struct hda_codec *codec)
|
||||
static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int pin_type)
|
||||
{
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pin_type);
|
||||
snd_hda_set_pin_ctl(codec, nid, pin_type);
|
||||
/* unmute pin */
|
||||
if (nid_has_mute(codec, nid, HDA_OUTPUT))
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
@ -3998,9 +3995,7 @@ static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
|
||||
snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
if (output) {
|
||||
snd_hda_codec_update_cache(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
PIN_OUT);
|
||||
snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT);
|
||||
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
|
||||
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
|
||||
HDA_AMP_MUTE, 0);
|
||||
@ -4009,9 +4004,8 @@ static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
|
||||
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
|
||||
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
|
||||
HDA_AMP_MUTE, HDA_AMP_MUTE);
|
||||
snd_hda_codec_update_cache(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
spec->multi_io[idx].ctl_in);
|
||||
snd_hda_set_pin_ctl_cache(codec, nid,
|
||||
spec->multi_io[idx].ctl_in);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -5171,8 +5165,7 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec,
|
||||
val = snd_hda_codec_read(codec, nids[i], 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
val |= AC_PINCTL_VREF_80;
|
||||
snd_hda_codec_write(codec, nids[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
||||
snd_hda_set_pin_ctl(codec, nids[i], val);
|
||||
spec->keep_vref_in_automute = 1;
|
||||
break;
|
||||
}
|
||||
@ -5193,8 +5186,7 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec,
|
||||
val = snd_hda_codec_read(codec, nids[i], 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
val |= AC_PINCTL_VREF_50;
|
||||
snd_hda_codec_write(codec, nids[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
||||
snd_hda_set_pin_ctl(codec, nids[i], val);
|
||||
}
|
||||
spec->keep_vref_in_automute = 1;
|
||||
}
|
||||
@ -5943,9 +5935,7 @@ static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
|
||||
{
|
||||
struct hda_codec *codec = private_data;
|
||||
unsigned int pinval = enabled ? 0x20 : 0x24;
|
||||
snd_hda_codec_update_cache(codec, 0x19, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pinval);
|
||||
snd_hda_set_pin_ctl_cache(codec, 0x19, pinval);
|
||||
}
|
||||
|
||||
static void alc269_fixup_mic2_mute(struct hda_codec *codec,
|
||||
@ -6342,8 +6332,7 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
|
||||
if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
|
||||
val |= AC_PINCTL_IN_EN;
|
||||
val |= AC_PINCTL_VREF_50;
|
||||
snd_hda_codec_write(codec, 0x0f, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
||||
snd_hda_set_pin_ctl(codec, 0x0f, val);
|
||||
spec->keep_vref_in_automute = 1;
|
||||
}
|
||||
|
||||
|
@ -681,8 +681,7 @@ static int stac_vrefout_set(struct hda_codec *codec,
|
||||
pinctl &= ~AC_PINCTL_VREFEN;
|
||||
pinctl |= (new_vref & AC_PINCTL_VREFEN);
|
||||
|
||||
error = snd_hda_codec_write_cache(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
|
||||
error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
@ -706,8 +705,7 @@ static unsigned int stac92xx_vref_set(struct hda_codec *codec,
|
||||
else
|
||||
pincfg |= AC_PINCTL_IN_EN;
|
||||
|
||||
error = snd_hda_codec_write_cache(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, pincfg);
|
||||
error = snd_hda_set_pin_ctl_cache(codec, nid, pincfg);
|
||||
if (error < 0)
|
||||
return error;
|
||||
else
|
||||
@ -2524,8 +2522,7 @@ static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
|
||||
static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
|
||||
|
||||
{
|
||||
snd_hda_codec_write_cache(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
|
||||
snd_hda_set_pin_ctl_cache(codec, nid, pin_type);
|
||||
}
|
||||
|
||||
#define stac92xx_hp_switch_info snd_ctl_boolean_mono_info
|
||||
@ -4460,8 +4457,7 @@ static void stac92xx_shutup_pins(struct hda_codec *codec)
|
||||
struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
|
||||
def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
|
||||
if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
|
||||
snd_hda_codec_write(codec, pin->nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_set_pin_ctl(codec, pin->nid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4517,9 +4513,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
|
||||
pin_ctl |= flag;
|
||||
if (old_ctl != pin_ctl)
|
||||
snd_hda_codec_write_cache(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pin_ctl);
|
||||
snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl);
|
||||
}
|
||||
|
||||
static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
@ -4528,9 +4522,7 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
|
||||
0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
|
||||
if (pin_ctl & flag)
|
||||
snd_hda_codec_write_cache(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pin_ctl & ~flag);
|
||||
snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl & ~flag);
|
||||
}
|
||||
|
||||
static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
|
||||
|
@ -532,8 +532,7 @@ static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
|
||||
{
|
||||
if (!pin)
|
||||
return;
|
||||
snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pin_type);
|
||||
snd_hda_set_pin_ctl(codec, pin, pin_type);
|
||||
if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, 0x02);
|
||||
@ -666,8 +665,7 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
|
||||
ctl = PIN_VREF50;
|
||||
else
|
||||
ctl = PIN_IN;
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
|
||||
snd_hda_set_pin_ctl(codec, nid, ctl);
|
||||
}
|
||||
|
||||
/* init input-src */
|
||||
@ -1006,9 +1004,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
|
||||
parm |= out_in;
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
parm);
|
||||
snd_hda_set_pin_ctl(codec, nid, parm);
|
||||
if (out_in == AC_PINCTL_OUT_EN) {
|
||||
mute_aa_path(codec, 1);
|
||||
notify_aa_path_ctls(codec);
|
||||
@ -1647,8 +1643,7 @@ static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
|
||||
parm &= ~AC_PINCTL_OUT_EN;
|
||||
else
|
||||
parm |= AC_PINCTL_OUT_EN;
|
||||
snd_hda_codec_write(codec, pins[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, parm);
|
||||
snd_hda_set_pin_ctl(codec, pins[i], parm);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1709,8 +1704,7 @@ static void via_gpio_control(struct hda_codec *codec)
|
||||
|
||||
if (gpio_data == 0x02) {
|
||||
/* unmute line out */
|
||||
snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0],
|
||||
PIN_OUT);
|
||||
if (vol_counter & 0x20) {
|
||||
/* decrease volume */
|
||||
@ -1728,9 +1722,7 @@ static void via_gpio_control(struct hda_codec *codec)
|
||||
}
|
||||
} else if (!(gpio_data & 0x02)) {
|
||||
/* mute line out */
|
||||
snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
0);
|
||||
snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0], 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2757,8 +2749,7 @@ static void via_auto_init_dig_in(struct hda_codec *codec)
|
||||
struct via_spec *spec = codec->spec;
|
||||
if (!spec->dig_in_nid)
|
||||
return;
|
||||
snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
|
||||
snd_hda_set_pin_ctl(codec, spec->autocfg.dig_in_pin, PIN_IN);
|
||||
}
|
||||
|
||||
/* initialize the unsolicited events */
|
||||
|
Loading…
Reference in New Issue
Block a user