From cdd03cedc5b55da017fcdeff7d47cac2639cded8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 20 Apr 2012 12:34:50 +0200 Subject: [PATCH] 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 --- sound/pci/hda/hda_codec.c | 26 ++++++++++++++++++ sound/pci/hda/hda_local.h | 38 ++++++++++++++++++++++++++ sound/pci/hda/patch_analog.c | 8 +++--- sound/pci/hda/patch_ca0110.c | 6 ++--- sound/pci/hda/patch_ca0132.c | 7 ++--- sound/pci/hda/patch_cirrus.c | 21 +++++---------- sound/pci/hda/patch_conexant.c | 44 +++++++++++------------------- sound/pci/hda/patch_realtek.c | 49 +++++++++++++--------------------- sound/pci/hda/patch_sigmatel.c | 20 +++++--------- sound/pci/hda/patch_via.c | 23 +++++----------- 10 files changed, 125 insertions(+), 117 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7a8fcc4c15f8..2d9716e7a116 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -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 */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 0ec9248165bc..17d425775c99 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -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 */ diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 7143393927da..38163abeea92 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -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, diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 09ccfabb4a17..646dc976f4bd 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c @@ -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, diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 21d91d580da8..ea63333f41fe 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -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, diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index c83ccdba1e5a..778e4b9dd88c 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -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])); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 6e04c2bf06de..afa510f0b993 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -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) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e65e35433055..9560b8e1e85c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -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; } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4742cac26aa9..21de62b7c991 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -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) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 06214fdc9486..8ee531aeda6e 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -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 */ -- 2.39.5