ALSA: hda - Introduce snd_hda_set_pin_ctl*() helper functions
authorTakashi Iwai <tiwai@suse.de>
Fri, 20 Apr 2012 10:34:50 +0000 (12:34 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 20 Apr 2012 10:38:48 +0000 (12:38 +0200)
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>
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_ca0110.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c

index 7a8fcc4c15f84acf5baab4ec9301f35f84a75049..2d9716e7a116aae3ced1523d4375d9928da5ec83 100644 (file)
@@ -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
  */
index 0ec9248165bca9c7f7f7d47aaffe4abc863b600c..17d425775c99cbafb90e600de17bd9a169021cf8 100644 (file)
@@ -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
  */
index 7143393927da34ddeac2c86ce6538c669e85d16a..38163abeea92f8168bf64f5eea9b5fc33bd92291 100644 (file)
@@ -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,
index 09ccfabb4a17c38a608d04d05b4a5979e6dc7ed7..646dc976f4bdd314cb8b2677c6a5fd099daa0610 100644 (file)
@@ -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,
index 21d91d580da8b9e29091dca8ad5d91440b38797a..ea63333f41fecea3a9301774fb74c9e2e808a212 100644 (file)
@@ -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,
index c83ccdba1e5afc1dca9715a870eedf68a8961ee8..778e4b9dd88c999ef9d9761c5beaa0441b1f7427 100644 (file)
@@ -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]));
index 6e04c2bf06de47b1b1a267d773cebec8be6a59c6..afa510f0b99367fe337e5bf0ada528b2a8ebe322 100644 (file)
@@ -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)
index e65e3543305568a9ab910057502ba583f656e724..9560b8e1e85c1a2e4eca7131fc3ce78eb181f7fa 100644 (file)
@@ -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;
 }
 
index 4742cac26aa9b4058a58220897e45c2e826dc47d..21de62b7c991ddf25b9499b77ff7dec9b82cf7b8 100644 (file)
@@ -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)
index 06214fdc9486d2c5d1d6c59eca22325330c5c3f3..8ee531aeda6e6c3cfe123eb9f95775d1e8cc2f99 100644 (file)
@@ -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 */