aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c53
-rw-r--r--sound/pci/hda/hda_local.h40
-rw-r--r--sound/pci/hda/patch_analog.c13
-rw-r--r--sound/pci/hda/patch_ca0110.c7
-rw-r--r--sound/pci/hda/patch_ca0132.c8
-rw-r--r--sound/pci/hda/patch_cirrus.c29
-rw-r--r--sound/pci/hda/patch_conexant.c145
-rw-r--r--sound/pci/hda/patch_realtek.c69
-rw-r--r--sound/pci/hda/patch_sigmatel.c46
-rw-r--r--sound/pci/hda/patch_via.c30
10 files changed, 255 insertions, 185 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 841475cc13b6..393a3043a46e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4795,6 +4795,59 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
4795} 4795}
4796EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); 4796EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
4797 4797
4798/**
4799 * snd_hda_get_default_vref - Get the default (mic) VREF pin bits
4800 *
4801 * Guess the suitable VREF pin bits to be set as the pin-control value.
4802 * Note: the function doesn't set the AC_PINCTL_IN_EN bit.
4803 */
4804unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin)
4805{
4806 unsigned int pincap;
4807 unsigned int oldval;
4808 oldval = snd_hda_codec_read(codec, pin, 0,
4809 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4810 pincap = snd_hda_query_pin_caps(codec, pin);
4811 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
4812 /* Exception: if the default pin setup is vref50, we give it priority */
4813 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
4814 return AC_PINCTL_VREF_80;
4815 else if (pincap & AC_PINCAP_VREF_50)
4816 return AC_PINCTL_VREF_50;
4817 else if (pincap & AC_PINCAP_VREF_100)
4818 return AC_PINCTL_VREF_100;
4819 else if (pincap & AC_PINCAP_VREF_GRD)
4820 return AC_PINCTL_VREF_GRD;
4821 return AC_PINCTL_VREF_HIZ;
4822}
4823EXPORT_SYMBOL_HDA(snd_hda_get_default_vref);
4824
4825int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
4826 unsigned int val, bool cached)
4827{
4828 if (val) {
4829 unsigned int cap = snd_hda_query_pin_caps(codec, pin);
4830 if (cap && (val & AC_PINCTL_OUT_EN)) {
4831 if (!(cap & AC_PINCAP_OUT))
4832 val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
4833 else if ((val & AC_PINCTL_HP_EN) &&
4834 !(cap & AC_PINCAP_HP_DRV))
4835 val &= ~AC_PINCTL_HP_EN;
4836 }
4837 if (cap && (val & AC_PINCTL_IN_EN)) {
4838 if (!(cap & AC_PINCAP_IN))
4839 val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN);
4840 }
4841 }
4842 if (cached)
4843 return snd_hda_codec_update_cache(codec, pin, 0,
4844 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
4845 else
4846 return snd_hda_codec_write(codec, pin, 0,
4847 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
4848}
4849EXPORT_SYMBOL_HDA(_snd_hda_set_pin_ctl);
4850
4798/* 4851/*
4799 * Helper for automatic pin configuration 4852 * Helper for automatic pin configuration
4800 */ 4853 */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 0ec9248165bc..a5cee952547d 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -502,6 +502,46 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
502#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN) 502#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
503#define PIN_HP_AMP (AC_PINCTL_HP_EN) 503#define PIN_HP_AMP (AC_PINCTL_HP_EN)
504 504
505unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin);
506int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
507 unsigned int val, bool cached);
508
509/**
510 * _snd_hda_set_pin_ctl - Set a pin-control value safely
511 * @codec: the codec instance
512 * @pin: the pin NID to set the control
513 * @val: the pin-control value (AC_PINCTL_* bits)
514 *
515 * This function sets the pin-control value to the given pin, but
516 * filters out the invalid pin-control bits when the pin has no such
517 * capabilities. For example, when PIN_HP is passed but the pin has no
518 * HP-drive capability, the HP bit is omitted.
519 *
520 * The function doesn't check the input VREF capability bits, though.
521 * Use snd_hda_get_default_vref() to guess the right value.
522 * Also, this function is only for analog pins, not for HDMI pins.
523 */
524static inline int
525snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, unsigned int val)
526{
527 return _snd_hda_set_pin_ctl(codec, pin, val, false);
528}
529
530/**
531 * snd_hda_set_pin_ctl_cache - Set a pin-control value safely
532 * @codec: the codec instance
533 * @pin: the pin NID to set the control
534 * @val: the pin-control value (AC_PINCTL_* bits)
535 *
536 * Just like snd_hda_set_pin_ctl() but write to cache as well.
537 */
538static inline int
539snd_hda_set_pin_ctl_cache(struct hda_codec *codec, hda_nid_t pin,
540 unsigned int val)
541{
542 return _snd_hda_set_pin_ctl(codec, pin, val, true);
543}
544
505/* 545/*
506 * get widget capabilities 546 * get widget capabilities
507 */ 547 */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 7143393927da..723bb9cb5f09 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,
1742 if (! ad198x_eapd_put(kcontrol, ucontrol)) 1742 if (! ad198x_eapd_put(kcontrol, ucontrol))
1743 return 0; 1743 return 0;
1744 /* change speaker pin appropriately */ 1744 /* change speaker pin appropriately */
1745 snd_hda_codec_write(codec, 0x05, 0, 1745 snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0);
1746 AC_VERB_SET_PIN_WIDGET_CONTROL,
1747 spec->cur_eapd ? PIN_OUT : 0);
1748 /* toggle HP mute appropriately */ 1746 /* toggle HP mute appropriately */
1749 snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0, 1747 snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1750 HDA_AMP_MUTE, 1748 HDA_AMP_MUTE,
@@ -3103,7 +3101,7 @@ static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
3103 int dac_idx) 3101 int dac_idx)
3104{ 3102{
3105 /* set as output */ 3103 /* set as output */
3106 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 3104 snd_hda_set_pin_ctl(codec, nid, pin_type);
3107 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 3105 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
3108 switch (nid) { 3106 switch (nid) {
3109 case 0x11: /* port-A - DAC 03 */ 3107 case 0x11: /* port-A - DAC 03 */
@@ -3157,6 +3155,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3157 for (i = 0; i < cfg->num_inputs; i++) { 3155 for (i = 0; i < cfg->num_inputs; i++) {
3158 hda_nid_t nid = cfg->inputs[i].pin; 3156 hda_nid_t nid = cfg->inputs[i].pin;
3159 int type = cfg->inputs[i].type; 3157 int type = cfg->inputs[i].type;
3158 int val;
3160 switch (nid) { 3159 switch (nid) {
3161 case 0x15: /* port-C */ 3160 case 0x15: /* port-C */
3162 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 3161 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
@@ -3165,8 +3164,10 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3165 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 3164 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3166 break; 3165 break;
3167 } 3166 }
3168 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3167 val = PIN_IN;
3169 type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); 3168 if (type == AUTO_PIN_MIC)
3169 val |= snd_hda_get_default_vref(codec, nid);
3170 snd_hda_set_pin_ctl(codec, nid, val);
3170 if (nid != AD1988_PIN_CD_NID) 3171 if (nid != AD1988_PIN_CD_NID)
3171 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3172 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3172 AMP_OUT_MUTE); 3173 AMP_OUT_MUTE);
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 09ccfabb4a17..a3b70a8f6df8 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)
341static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) 341static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
342{ 342{
343 if (pin) { 343 if (pin) {
344 snd_hda_codec_write(codec, pin, 0, 344 snd_hda_set_pin_ctl(codec, pin, PIN_HP);
345 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
346 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) 345 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
347 snd_hda_codec_write(codec, pin, 0, 346 snd_hda_codec_write(codec, pin, 0,
348 AC_VERB_SET_AMP_GAIN_MUTE, 347 AC_VERB_SET_AMP_GAIN_MUTE,
@@ -356,8 +355,8 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
356static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) 355static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
357{ 356{
358 if (pin) { 357 if (pin) {
359 snd_hda_codec_write(codec, pin, 0, 358 snd_hda_set_pin_ctl(codec, pin, PIN_IN |
360 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80); 359 snd_hda_get_default_vref(codec, pin));
361 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) 360 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
362 snd_hda_codec_write(codec, pin, 0, 361 snd_hda_codec_write(codec, pin, 0,
363 AC_VERB_SET_AMP_GAIN_MUTE, 362 AC_VERB_SET_AMP_GAIN_MUTE,
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 21d91d580da8..d290a8ff0108 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -239,8 +239,7 @@ enum get_set {
239static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) 239static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
240{ 240{
241 if (pin) { 241 if (pin) {
242 snd_hda_codec_write(codec, pin, 0, 242 snd_hda_set_pin_ctl(codec, pin, PIN_HP);
243 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
244 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) 243 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
245 snd_hda_codec_write(codec, pin, 0, 244 snd_hda_codec_write(codec, pin, 0,
246 AC_VERB_SET_AMP_GAIN_MUTE, 245 AC_VERB_SET_AMP_GAIN_MUTE,
@@ -254,9 +253,8 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
254static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) 253static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
255{ 254{
256 if (pin) { 255 if (pin) {
257 snd_hda_codec_write(codec, pin, 0, 256 snd_hda_set_pin_ctl(codec, pin, PIN_IN |
258 AC_VERB_SET_PIN_WIDGET_CONTROL, 257 snd_hda_get_default_vref(codec, pin));
259 PIN_VREF80);
260 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) 258 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
261 snd_hda_codec_write(codec, pin, 0, 259 snd_hda_codec_write(codec, pin, 0,
262 AC_VERB_SET_AMP_GAIN_MUTE, 260 AC_VERB_SET_AMP_GAIN_MUTE,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index c83ccdba1e5a..48c6d8186e90 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)
933 pin_ctl = 0; 933 pin_ctl = 0;
934 934
935 nid = cfg->speaker_pins[i]; 935 nid = cfg->speaker_pins[i];
936 snd_hda_codec_write(codec, nid, 0, 936 snd_hda_set_pin_ctl(codec, nid, pin_ctl);
937 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl);
938 } 937 }
939 if (spec->gpio_eapd_hp) { 938 if (spec->gpio_eapd_hp) {
940 unsigned int gpio = hp_present ? 939 unsigned int gpio = hp_present ?
@@ -948,16 +947,14 @@ static void cs_automute(struct hda_codec *codec)
948 /* mute HPs if spdif jack (SENSE_B) is present */ 947 /* mute HPs if spdif jack (SENSE_B) is present */
949 for (i = 0; i < cfg->hp_outs; i++) { 948 for (i = 0; i < cfg->hp_outs; i++) {
950 nid = cfg->hp_pins[i]; 949 nid = cfg->hp_pins[i];
951 snd_hda_codec_write(codec, nid, 0, 950 snd_hda_set_pin_ctl(codec, nid,
952 AC_VERB_SET_PIN_WIDGET_CONTROL,
953 (spdif_present && spec->sense_b) ? 0 : PIN_HP); 951 (spdif_present && spec->sense_b) ? 0 : PIN_HP);
954 } 952 }
955 953
956 /* SPDIF TX on/off */ 954 /* SPDIF TX on/off */
957 if (cfg->dig_outs) { 955 if (cfg->dig_outs) {
958 nid = cfg->dig_out_pins[0]; 956 nid = cfg->dig_out_pins[0];
959 snd_hda_codec_write(codec, nid, 0, 957 snd_hda_set_pin_ctl(codec, nid,
960 AC_VERB_SET_PIN_WIDGET_CONTROL,
961 spdif_present ? PIN_OUT : 0); 958 spdif_present ? PIN_OUT : 0);
962 959
963 } 960 }
@@ -1024,13 +1021,11 @@ static void init_output(struct hda_codec *codec)
1024 1021
1025 /* set appropriate pin controls */ 1022 /* set appropriate pin controls */
1026 for (i = 0; i < cfg->line_outs; i++) 1023 for (i = 0; i < cfg->line_outs; i++)
1027 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, 1024 snd_hda_set_pin_ctl(codec, cfg->line_out_pins[i], PIN_OUT);
1028 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1029 /* HP */ 1025 /* HP */
1030 for (i = 0; i < cfg->hp_outs; i++) { 1026 for (i = 0; i < cfg->hp_outs; i++) {
1031 hda_nid_t nid = cfg->hp_pins[i]; 1027 hda_nid_t nid = cfg->hp_pins[i];
1032 snd_hda_codec_write(codec, nid, 0, 1028 snd_hda_set_pin_ctl(codec, nid, PIN_HP);
1033 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
1034 if (!cfg->speaker_outs) 1029 if (!cfg->speaker_outs)
1035 continue; 1030 continue;
1036 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { 1031 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
@@ -1041,8 +1036,7 @@ static void init_output(struct hda_codec *codec)
1041 1036
1042 /* Speaker */ 1037 /* Speaker */
1043 for (i = 0; i < cfg->speaker_outs; i++) 1038 for (i = 0; i < cfg->speaker_outs; i++)
1044 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, 1039 snd_hda_set_pin_ctl(codec, cfg->speaker_pins[i], PIN_OUT);
1045 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1046 1040
1047 /* SPDIF is enabled on presence detect for CS421x */ 1041 /* SPDIF is enabled on presence detect for CS421x */
1048 if (spec->hp_detect || spec->spdif_detect) 1042 if (spec->hp_detect || spec->spdif_detect)
@@ -1063,14 +1057,9 @@ static void init_input(struct hda_codec *codec)
1063 continue; 1057 continue;
1064 /* set appropriate pin control and mute first */ 1058 /* set appropriate pin control and mute first */
1065 ctl = PIN_IN; 1059 ctl = PIN_IN;
1066 if (cfg->inputs[i].type == AUTO_PIN_MIC) { 1060 if (cfg->inputs[i].type == AUTO_PIN_MIC)
1067 unsigned int caps = snd_hda_query_pin_caps(codec, pin); 1061 ctl |= snd_hda_get_default_vref(codec, pin);
1068 caps >>= AC_PINCAP_VREF_SHIFT; 1062 snd_hda_set_pin_ctl(codec, pin, ctl);
1069 if (caps & AC_PINCAP_VREF_80)
1070 ctl = PIN_VREF80;
1071 }
1072 snd_hda_codec_write(codec, pin, 0,
1073 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
1074 snd_hda_codec_write(codec, spec->adc_nid[i], 0, 1063 snd_hda_codec_write(codec, spec->adc_nid[i], 0,
1075 AC_VERB_SET_AMP_GAIN_MUTE, 1064 AC_VERB_SET_AMP_GAIN_MUTE,
1076 AMP_IN_MUTE(spec->adc_idx[i])); 1065 AMP_IN_MUTE(spec->adc_idx[i]));
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index d906c5b74cf0..aabdb9e9a484 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -141,6 +141,7 @@ struct conexant_spec {
141 unsigned int hp_laptop:1; 141 unsigned int hp_laptop:1;
142 unsigned int asus:1; 142 unsigned int asus:1;
143 unsigned int pin_eapd_ctrls:1; 143 unsigned int pin_eapd_ctrls:1;
144 unsigned int fixup_stereo_dmic:1;
144 145
145 unsigned int adc_switching:1; 146 unsigned int adc_switching:1;
146 147
@@ -1601,17 +1602,13 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1601 unsigned int pinctl; 1602 unsigned int pinctl;
1602 /* headphone pin */ 1603 /* headphone pin */
1603 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0; 1604 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1604 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1605 snd_hda_set_pin_ctl(codec, 0x16, pinctl);
1605 pinctl);
1606 /* speaker pin */ 1606 /* speaker pin */
1607 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1607 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1608 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1608 snd_hda_set_pin_ctl(codec, 0x1a, pinctl);
1609 pinctl);
1610 /* on ideapad there is an additional speaker (subwoofer) to mute */ 1609 /* on ideapad there is an additional speaker (subwoofer) to mute */
1611 if (spec->ideapad) 1610 if (spec->ideapad)
1612 snd_hda_codec_write(codec, 0x1b, 0, 1611 snd_hda_set_pin_ctl(codec, 0x1b, pinctl);
1613 AC_VERB_SET_PIN_WIDGET_CONTROL,
1614 pinctl);
1615} 1612}
1616 1613
1617/* turn on/off EAPD (+ mute HP) as a master switch */ 1614/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -1996,8 +1993,7 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
1996 1993
1997 /* Port A (HP) */ 1994 /* Port A (HP) */
1998 pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0; 1995 pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
1999 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1996 snd_hda_set_pin_ctl(codec, 0x19, pinctl);
2000 pinctl);
2001 1997
2002 /* Port D (HP/LO) */ 1998 /* Port D (HP/LO) */
2003 pinctl = spec->cur_eapd ? spec->port_d_mode : 0; 1999 pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
@@ -2010,13 +2006,11 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
2010 if (!hp_port_d_present(spec)) 2006 if (!hp_port_d_present(spec))
2011 pinctl = 0; 2007 pinctl = 0;
2012 } 2008 }
2013 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2009 snd_hda_set_pin_ctl(codec, 0x1c, pinctl);
2014 pinctl);
2015 2010
2016 /* CLASS_D AMP */ 2011 /* CLASS_D AMP */
2017 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 2012 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
2018 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2013 snd_hda_set_pin_ctl(codec, 0x1f, pinctl);
2019 pinctl);
2020} 2014}
2021 2015
2022/* turn on/off EAPD (+ mute HP) as a master switch */ 2016/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -2047,8 +2041,7 @@ static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2047 /* Even though port F is the DC input, the bias is controlled on port B. 2041 /* Even though port F is the DC input, the bias is controlled on port B.
2048 * we also leave that port as an active input (but unselected) in DC mode 2042 * we also leave that port as an active input (but unselected) in DC mode
2049 * just in case that is necessary to make the bias setting take effect. */ 2043 * just in case that is necessary to make the bias setting take effect. */
2050 return snd_hda_codec_write_cache(codec, 0x1a, 0, 2044 return snd_hda_set_pin_ctl_cache(codec, 0x1a,
2051 AC_VERB_SET_PIN_WIDGET_CONTROL,
2052 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index); 2045 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2053} 2046}
2054 2047
@@ -2081,14 +2074,14 @@ static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2081 } 2074 }
2082 2075
2083 /* disable DC (port F) */ 2076 /* disable DC (port F) */
2084 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 2077 snd_hda_set_pin_ctl(codec, 0x1e, 0);
2085 2078
2086 /* external mic, port B */ 2079 /* external mic, port B */
2087 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2080 snd_hda_set_pin_ctl(codec, 0x1a,
2088 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0); 2081 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2089 2082
2090 /* internal mic, port C */ 2083 /* internal mic, port C */
2091 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2084 snd_hda_set_pin_ctl(codec, 0x1b,
2092 spec->ext_mic_present ? 0 : PIN_VREF80); 2085 spec->ext_mic_present ? 0 : PIN_VREF80);
2093} 2086}
2094 2087
@@ -3357,9 +3350,7 @@ static void do_automute(struct hda_codec *codec, int num_pins,
3357 struct conexant_spec *spec = codec->spec; 3350 struct conexant_spec *spec = codec->spec;
3358 int i; 3351 int i;
3359 for (i = 0; i < num_pins; i++) 3352 for (i = 0; i < num_pins; i++)
3360 snd_hda_codec_write(codec, pins[i], 0, 3353 snd_hda_set_pin_ctl(codec, pins[i], on ? PIN_OUT : 0);
3361 AC_VERB_SET_PIN_WIDGET_CONTROL,
3362 on ? PIN_OUT : 0);
3363 if (spec->pin_eapd_ctrls) 3354 if (spec->pin_eapd_ctrls)
3364 cx_auto_turn_eapd(codec, num_pins, pins, on); 3355 cx_auto_turn_eapd(codec, num_pins, pins, on);
3365} 3356}
@@ -3976,8 +3967,7 @@ static void cx_auto_init_output(struct hda_codec *codec)
3976 if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & 3967 if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) &
3977 AC_PINCAP_HP_DRV) 3968 AC_PINCAP_HP_DRV)
3978 val |= AC_PINCTL_HP_EN; 3969 val |= AC_PINCTL_HP_EN;
3979 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 3970 snd_hda_set_pin_ctl(codec, cfg->hp_pins[i], val);
3980 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
3981 } 3971 }
3982 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); 3972 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
3983 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); 3973 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
@@ -4030,13 +4020,11 @@ static void cx_auto_init_input(struct hda_codec *codec)
4030 } 4020 }
4031 4021
4032 for (i = 0; i < cfg->num_inputs; i++) { 4022 for (i = 0; i < cfg->num_inputs; i++) {
4033 unsigned int type; 4023 hda_nid_t pin = cfg->inputs[i].pin;
4024 unsigned int type = PIN_IN;
4034 if (cfg->inputs[i].type == AUTO_PIN_MIC) 4025 if (cfg->inputs[i].type == AUTO_PIN_MIC)
4035 type = PIN_VREF80; 4026 type |= snd_hda_get_default_vref(codec, pin);
4036 else 4027 snd_hda_set_pin_ctl(codec, pin, type);
4037 type = PIN_IN;
4038 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
4039 AC_VERB_SET_PIN_WIDGET_CONTROL, type);
4040 } 4028 }
4041 4029
4042 if (spec->auto_mic) { 4030 if (spec->auto_mic) {
@@ -4063,11 +4051,9 @@ static void cx_auto_init_digital(struct hda_codec *codec)
4063 struct auto_pin_cfg *cfg = &spec->autocfg; 4051 struct auto_pin_cfg *cfg = &spec->autocfg;
4064 4052
4065 if (spec->multiout.dig_out_nid) 4053 if (spec->multiout.dig_out_nid)
4066 snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0, 4054 snd_hda_set_pin_ctl(codec, cfg->dig_out_pins[0], PIN_OUT);
4067 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4068 if (spec->dig_in_nid) 4055 if (spec->dig_in_nid)
4069 snd_hda_codec_write(codec, cfg->dig_in_pin, 0, 4056 snd_hda_set_pin_ctl(codec, cfg->dig_in_pin, PIN_IN);
4070 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
4071} 4057}
4072 4058
4073static int cx_auto_init(struct hda_codec *codec) 4059static int cx_auto_init(struct hda_codec *codec)
@@ -4084,9 +4070,9 @@ static int cx_auto_init(struct hda_codec *codec)
4084 4070
4085static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, 4071static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
4086 const char *dir, int cidx, 4072 const char *dir, int cidx,
4087 hda_nid_t nid, int hda_dir, int amp_idx) 4073 hda_nid_t nid, int hda_dir, int amp_idx, int chs)
4088{ 4074{
4089 static char name[32]; 4075 static char name[44];
4090 static struct snd_kcontrol_new knew[] = { 4076 static struct snd_kcontrol_new knew[] = {
4091 HDA_CODEC_VOLUME(name, 0, 0, 0), 4077 HDA_CODEC_VOLUME(name, 0, 0, 0),
4092 HDA_CODEC_MUTE(name, 0, 0, 0), 4078 HDA_CODEC_MUTE(name, 0, 0, 0),
@@ -4096,7 +4082,7 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
4096 4082
4097 for (i = 0; i < 2; i++) { 4083 for (i = 0; i < 2; i++) {
4098 struct snd_kcontrol *kctl; 4084 struct snd_kcontrol *kctl;
4099 knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx, 4085 knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, chs, amp_idx,
4100 hda_dir); 4086 hda_dir);
4101 knew[i].subdevice = HDA_SUBDEV_AMP_FLAG; 4087 knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
4102 knew[i].index = cidx; 4088 knew[i].index = cidx;
@@ -4115,7 +4101,7 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
4115} 4101}
4116 4102
4117#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \ 4103#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \
4118 cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0) 4104 cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0, 3)
4119 4105
4120#define cx_auto_add_pb_volume(codec, nid, str, idx) \ 4106#define cx_auto_add_pb_volume(codec, nid, str, idx) \
4121 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) 4107 cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
@@ -4185,6 +4171,36 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
4185 return 0; 4171 return 0;
4186} 4172}
4187 4173
4174/* Returns zero if this is a normal stereo channel, and non-zero if it should
4175 be split in two independent channels.
4176 dest_label must be at least 44 characters. */
4177static int cx_auto_get_rightch_label(struct hda_codec *codec, const char *label,
4178 char *dest_label, int nid)
4179{
4180 struct conexant_spec *spec = codec->spec;
4181 int i;
4182
4183 if (!spec->fixup_stereo_dmic)
4184 return 0;
4185
4186 for (i = 0; i < AUTO_CFG_MAX_INS; i++) {
4187 int def_conf;
4188 if (spec->autocfg.inputs[i].pin != nid)
4189 continue;
4190
4191 if (spec->autocfg.inputs[i].type != AUTO_PIN_MIC)
4192 return 0;
4193 def_conf = snd_hda_codec_get_pincfg(codec, nid);
4194 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT)
4195 return 0;
4196
4197 /* Finally found the inverted internal mic! */
4198 snprintf(dest_label, 44, "Inverted %s", label);
4199 return 1;
4200 }
4201 return 0;
4202}
4203
4188static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, 4204static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4189 const char *label, const char *pfx, 4205 const char *label, const char *pfx,
4190 int cidx) 4206 int cidx)
@@ -4193,14 +4209,25 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4193 int i; 4209 int i;
4194 4210
4195 for (i = 0; i < spec->num_adc_nids; i++) { 4211 for (i = 0; i < spec->num_adc_nids; i++) {
4212 char rightch_label[44];
4196 hda_nid_t adc_nid = spec->adc_nids[i]; 4213 hda_nid_t adc_nid = spec->adc_nids[i];
4197 int idx = get_input_connection(codec, adc_nid, nid); 4214 int idx = get_input_connection(codec, adc_nid, nid);
4198 if (idx < 0) 4215 if (idx < 0)
4199 continue; 4216 continue;
4200 if (codec->single_adc_amp) 4217 if (codec->single_adc_amp)
4201 idx = 0; 4218 idx = 0;
4219
4220 if (cx_auto_get_rightch_label(codec, label, rightch_label, nid)) {
4221 /* Make two independent kcontrols for left and right */
4222 int err = cx_auto_add_volume_idx(codec, label, pfx,
4223 cidx, adc_nid, HDA_INPUT, idx, 1);
4224 if (err < 0)
4225 return err;
4226 return cx_auto_add_volume_idx(codec, rightch_label, pfx,
4227 cidx, adc_nid, HDA_INPUT, idx, 2);
4228 }
4202 return cx_auto_add_volume_idx(codec, label, pfx, 4229 return cx_auto_add_volume_idx(codec, label, pfx,
4203 cidx, adc_nid, HDA_INPUT, idx); 4230 cidx, adc_nid, HDA_INPUT, idx, 3);
4204 } 4231 }
4205 return 0; 4232 return 0;
4206} 4233}
@@ -4213,9 +4240,19 @@ static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx,
4213 int i, con; 4240 int i, con;
4214 4241
4215 nid = spec->imux_info[idx].pin; 4242 nid = spec->imux_info[idx].pin;
4216 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 4243 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
4244 char rightch_label[44];
4245 if (cx_auto_get_rightch_label(codec, label, rightch_label, nid)) {
4246 int err = cx_auto_add_volume_idx(codec, label, " Boost",
4247 cidx, nid, HDA_INPUT, 0, 1);
4248 if (err < 0)
4249 return err;
4250 return cx_auto_add_volume_idx(codec, rightch_label, " Boost",
4251 cidx, nid, HDA_INPUT, 0, 2);
4252 }
4217 return cx_auto_add_volume(codec, label, " Boost", cidx, 4253 return cx_auto_add_volume(codec, label, " Boost", cidx,
4218 nid, HDA_INPUT); 4254 nid, HDA_INPUT);
4255 }
4219 con = __select_input_connection(codec, spec->imux_info[idx].adc, nid, 4256 con = __select_input_connection(codec, spec->imux_info[idx].adc, nid,
4220 &mux, false, 0); 4257 &mux, false, 0);
4221 if (con < 0) 4258 if (con < 0)
@@ -4382,23 +4419,33 @@ static void apply_pincfg(struct hda_codec *codec, const struct cxt_pincfg *cfg)
4382 4419
4383} 4420}
4384 4421
4385static void apply_pin_fixup(struct hda_codec *codec, 4422enum {
4423 CXT_PINCFG_LENOVO_X200,
4424 CXT_PINCFG_LENOVO_TP410,
4425 CXT_FIXUP_STEREO_DMIC,
4426};
4427
4428static void apply_fixup(struct hda_codec *codec,
4386 const struct snd_pci_quirk *quirk, 4429 const struct snd_pci_quirk *quirk,
4387 const struct cxt_pincfg **table) 4430 const struct cxt_pincfg **table)
4388{ 4431{
4432 struct conexant_spec *spec = codec->spec;
4433
4389 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 4434 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
4390 if (quirk) { 4435 if (!quirk)
4436 return;
4437 if (table[quirk->value]) {
4391 snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n", 4438 snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n",
4392 quirk->name); 4439 quirk->name);
4393 apply_pincfg(codec, table[quirk->value]); 4440 apply_pincfg(codec, table[quirk->value]);
4394 } 4441 }
4442 if (quirk->value == CXT_FIXUP_STEREO_DMIC) {
4443 snd_printdd(KERN_INFO "hda_codec: applying internal mic workaround for %s\n",
4444 quirk->name);
4445 spec->fixup_stereo_dmic = 1;
4446 }
4395} 4447}
4396 4448
4397enum {
4398 CXT_PINCFG_LENOVO_X200,
4399 CXT_PINCFG_LENOVO_TP410,
4400};
4401
4402/* ThinkPad X200 & co with cxt5051 */ 4449/* ThinkPad X200 & co with cxt5051 */
4403static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { 4450static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
4404 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ 4451 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
@@ -4419,6 +4466,7 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = {
4419static const struct cxt_pincfg *cxt_pincfg_tbl[] = { 4466static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
4420 [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, 4467 [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
4421 [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410, 4468 [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,
4469 [CXT_FIXUP_STEREO_DMIC] = NULL,
4422}; 4470};
4423 4471
4424static const struct snd_pci_quirk cxt5051_fixups[] = { 4472static const struct snd_pci_quirk cxt5051_fixups[] = {
@@ -4432,6 +4480,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
4432 SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), 4480 SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
4433 SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), 4481 SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
4434 SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), 4482 SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
4483 SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
4435 {} 4484 {}
4436}; 4485};
4437 4486
@@ -4471,11 +4520,11 @@ static int patch_conexant_auto(struct hda_codec *codec)
4471 case 0x14f15051: 4520 case 0x14f15051:
4472 add_cx5051_fake_mutes(codec); 4521 add_cx5051_fake_mutes(codec);
4473 codec->pin_amp_workaround = 1; 4522 codec->pin_amp_workaround = 1;
4474 apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl); 4523 apply_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
4475 break; 4524 break;
4476 default: 4525 default:
4477 codec->pin_amp_workaround = 1; 4526 codec->pin_amp_workaround = 1;
4478 apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl); 4527 apply_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
4479 } 4528 }
4480 4529
4481 /* Show mute-led control only on HP laptops 4530 /* Show mute-led control only on HP laptops
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7810913d07a0..6dd1b74e9f68 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,
319 319
320 /* for shared I/O, change the pin-control accordingly */ 320 /* for shared I/O, change the pin-control accordingly */
321 if (spec->shared_mic_hp) { 321 if (spec->shared_mic_hp) {
322 unsigned int val;
323 hda_nid_t pin = spec->autocfg.inputs[1].pin;
322 /* NOTE: this assumes that there are only two inputs, the 324 /* NOTE: this assumes that there are only two inputs, the
323 * first is the real internal mic and the second is HP jack. 325 * first is the real internal mic and the second is HP jack.
324 */ 326 */
325 snd_hda_codec_write(codec, spec->autocfg.inputs[1].pin, 0, 327 if (spec->cur_mux[adc_idx])
326 AC_VERB_SET_PIN_WIDGET_CONTROL, 328 val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
327 spec->cur_mux[adc_idx] ? 329 else
328 PIN_VREF80 : PIN_HP); 330 val = PIN_HP;
331 snd_hda_set_pin_ctl(codec, pin, val);
329 spec->automute_speaker = !spec->cur_mux[adc_idx]; 332 spec->automute_speaker = !spec->cur_mux[adc_idx];
330 call_update_outputs(codec); 333 call_update_outputs(codec);
331 } 334 }
@@ -376,25 +379,9 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
376 int auto_pin_type) 379 int auto_pin_type)
377{ 380{
378 unsigned int val = PIN_IN; 381 unsigned int val = PIN_IN;
379 382 if (auto_pin_type == AUTO_PIN_MIC)
380 if (auto_pin_type == AUTO_PIN_MIC) { 383 val |= snd_hda_get_default_vref(codec, nid);
381 unsigned int pincap; 384 snd_hda_set_pin_ctl(codec, nid, val);
382 unsigned int oldval;
383 oldval = snd_hda_codec_read(codec, nid, 0,
384 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
385 pincap = snd_hda_query_pin_caps(codec, nid);
386 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
387 /* if the default pin setup is vref50, we give it priority */
388 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
389 val = PIN_VREF80;
390 else if (pincap & AC_PINCAP_VREF_50)
391 val = PIN_VREF50;
392 else if (pincap & AC_PINCAP_VREF_100)
393 val = PIN_VREF100;
394 else if (pincap & AC_PINCAP_VREF_GRD)
395 val = PIN_VREFGRD;
396 }
397 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
398} 385}
399 386
400/* 387/*
@@ -517,9 +504,7 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
517 } else 504 } else
518 val = 0; 505 val = 0;
519 val |= pin_bits; 506 val |= pin_bits;
520 snd_hda_codec_write(codec, nid, 0, 507 snd_hda_set_pin_ctl(codec, nid, val);
521 AC_VERB_SET_PIN_WIDGET_CONTROL,
522 val);
523 break; 508 break;
524 case ALC_AUTOMUTE_AMP: 509 case ALC_AUTOMUTE_AMP:
525 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 510 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
@@ -1621,8 +1606,7 @@ static void alc_auto_init_digital(struct hda_codec *codec)
1621 pin = spec->autocfg.dig_out_pins[i]; 1606 pin = spec->autocfg.dig_out_pins[i];
1622 if (!pin) 1607 if (!pin)
1623 continue; 1608 continue;
1624 snd_hda_codec_write(codec, pin, 0, 1609 snd_hda_set_pin_ctl(codec, pin, PIN_OUT);
1625 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1626 if (!i) 1610 if (!i)
1627 dac = spec->multiout.dig_out_nid; 1611 dac = spec->multiout.dig_out_nid;
1628 else 1612 else
@@ -1635,9 +1619,7 @@ static void alc_auto_init_digital(struct hda_codec *codec)
1635 } 1619 }
1636 pin = spec->autocfg.dig_in_pin; 1620 pin = spec->autocfg.dig_in_pin;
1637 if (pin) 1621 if (pin)
1638 snd_hda_codec_write(codec, pin, 0, 1622 snd_hda_set_pin_ctl(codec, pin, PIN_IN);
1639 AC_VERB_SET_PIN_WIDGET_CONTROL,
1640 PIN_IN);
1641} 1623}
1642 1624
1643/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ 1625/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
@@ -2856,8 +2838,7 @@ static int alc_auto_create_shared_input(struct hda_codec *codec)
2856static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 2838static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
2857 unsigned int pin_type) 2839 unsigned int pin_type)
2858{ 2840{
2859 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2841 snd_hda_set_pin_ctl(codec, nid, pin_type);
2860 pin_type);
2861 /* unmute pin */ 2842 /* unmute pin */
2862 if (nid_has_mute(codec, nid, HDA_OUTPUT)) 2843 if (nid_has_mute(codec, nid, HDA_OUTPUT))
2863 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 2844 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
@@ -3998,9 +3979,7 @@ static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
3998 snd_hda_codec_read(codec, nid, 0, 3979 snd_hda_codec_read(codec, nid, 0,
3999 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3980 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4000 if (output) { 3981 if (output) {
4001 snd_hda_codec_update_cache(codec, nid, 0, 3982 snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT);
4002 AC_VERB_SET_PIN_WIDGET_CONTROL,
4003 PIN_OUT);
4004 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 3983 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
4005 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 3984 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4006 HDA_AMP_MUTE, 0); 3985 HDA_AMP_MUTE, 0);
@@ -4009,9 +3988,8 @@ static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
4009 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 3988 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
4010 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 3989 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4011 HDA_AMP_MUTE, HDA_AMP_MUTE); 3990 HDA_AMP_MUTE, HDA_AMP_MUTE);
4012 snd_hda_codec_update_cache(codec, nid, 0, 3991 snd_hda_set_pin_ctl_cache(codec, nid,
4013 AC_VERB_SET_PIN_WIDGET_CONTROL, 3992 spec->multi_io[idx].ctl_in);
4014 spec->multi_io[idx].ctl_in);
4015 } 3993 }
4016 return 0; 3994 return 0;
4017} 3995}
@@ -5171,8 +5149,7 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec,
5171 val = snd_hda_codec_read(codec, nids[i], 0, 5149 val = snd_hda_codec_read(codec, nids[i], 0,
5172 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 5150 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5173 val |= AC_PINCTL_VREF_80; 5151 val |= AC_PINCTL_VREF_80;
5174 snd_hda_codec_write(codec, nids[i], 0, 5152 snd_hda_set_pin_ctl(codec, nids[i], val);
5175 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5176 spec->keep_vref_in_automute = 1; 5153 spec->keep_vref_in_automute = 1;
5177 break; 5154 break;
5178 } 5155 }
@@ -5193,8 +5170,7 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec,
5193 val = snd_hda_codec_read(codec, nids[i], 0, 5170 val = snd_hda_codec_read(codec, nids[i], 0,
5194 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 5171 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5195 val |= AC_PINCTL_VREF_50; 5172 val |= AC_PINCTL_VREF_50;
5196 snd_hda_codec_write(codec, nids[i], 0, 5173 snd_hda_set_pin_ctl(codec, nids[i], val);
5197 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5198 } 5174 }
5199 spec->keep_vref_in_automute = 1; 5175 spec->keep_vref_in_automute = 1;
5200} 5176}
@@ -5946,9 +5922,7 @@ static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
5946{ 5922{
5947 struct hda_codec *codec = private_data; 5923 struct hda_codec *codec = private_data;
5948 unsigned int pinval = enabled ? 0x20 : 0x24; 5924 unsigned int pinval = enabled ? 0x20 : 0x24;
5949 snd_hda_codec_update_cache(codec, 0x19, 0, 5925 snd_hda_set_pin_ctl_cache(codec, 0x19, pinval);
5950 AC_VERB_SET_PIN_WIDGET_CONTROL,
5951 pinval);
5952} 5926}
5953 5927
5954static void alc269_fixup_mic2_mute(struct hda_codec *codec, 5928static void alc269_fixup_mic2_mute(struct hda_codec *codec,
@@ -6346,8 +6320,7 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
6346 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) 6320 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
6347 val |= AC_PINCTL_IN_EN; 6321 val |= AC_PINCTL_IN_EN;
6348 val |= AC_PINCTL_VREF_50; 6322 val |= AC_PINCTL_VREF_50;
6349 snd_hda_codec_write(codec, 0x0f, 0, 6323 snd_hda_set_pin_ctl(codec, 0x0f, val);
6350 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
6351 spec->keep_vref_in_automute = 1; 6324 spec->keep_vref_in_automute = 1;
6352} 6325}
6353 6326
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 4742cac26aa9..884f8ad351fd 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,
681 pinctl &= ~AC_PINCTL_VREFEN; 681 pinctl &= ~AC_PINCTL_VREFEN;
682 pinctl |= (new_vref & AC_PINCTL_VREFEN); 682 pinctl |= (new_vref & AC_PINCTL_VREFEN);
683 683
684 error = snd_hda_codec_write_cache(codec, nid, 0, 684 error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
685 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
686 if (error < 0) 685 if (error < 0)
687 return error; 686 return error;
688 687
@@ -706,8 +705,7 @@ static unsigned int stac92xx_vref_set(struct hda_codec *codec,
706 else 705 else
707 pincfg |= AC_PINCTL_IN_EN; 706 pincfg |= AC_PINCTL_IN_EN;
708 707
709 error = snd_hda_codec_write_cache(codec, nid, 0, 708 error = snd_hda_set_pin_ctl_cache(codec, nid, pincfg);
710 AC_VERB_SET_PIN_WIDGET_CONTROL, pincfg);
711 if (error < 0) 709 if (error < 0)
712 return error; 710 return error;
713 else 711 else
@@ -2505,27 +2503,10 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
2505 return 0; 2503 return 0;
2506} 2504}
2507 2505
2508static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
2509 hda_nid_t nid)
2510{
2511 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2512 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
2513 if (pincap & AC_PINCAP_VREF_100)
2514 return AC_PINCTL_VREF_100;
2515 if (pincap & AC_PINCAP_VREF_80)
2516 return AC_PINCTL_VREF_80;
2517 if (pincap & AC_PINCAP_VREF_50)
2518 return AC_PINCTL_VREF_50;
2519 if (pincap & AC_PINCAP_VREF_GRD)
2520 return AC_PINCTL_VREF_GRD;
2521 return 0;
2522}
2523
2524static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) 2506static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
2525 2507
2526{ 2508{
2527 snd_hda_codec_write_cache(codec, nid, 0, 2509 snd_hda_set_pin_ctl_cache(codec, nid, pin_type);
2528 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2529} 2510}
2530 2511
2531#define stac92xx_hp_switch_info snd_ctl_boolean_mono_info 2512#define stac92xx_hp_switch_info snd_ctl_boolean_mono_info
@@ -2594,7 +2575,7 @@ static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
2594 hda_nid_t nid = kcontrol->private_value; 2575 hda_nid_t nid = kcontrol->private_value;
2595 unsigned int vref = stac92xx_vref_get(codec, nid); 2576 unsigned int vref = stac92xx_vref_get(codec, nid);
2596 2577
2597 if (vref == stac92xx_get_default_vref(codec, nid)) 2578 if (vref == snd_hda_get_default_vref(codec, nid))
2598 ucontrol->value.enumerated.item[0] = 0; 2579 ucontrol->value.enumerated.item[0] = 0;
2599 else if (vref == AC_PINCTL_VREF_GRD) 2580 else if (vref == AC_PINCTL_VREF_GRD)
2600 ucontrol->value.enumerated.item[0] = 1; 2581 ucontrol->value.enumerated.item[0] = 1;
@@ -2613,7 +2594,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
2613 hda_nid_t nid = kcontrol->private_value; 2594 hda_nid_t nid = kcontrol->private_value;
2614 2595
2615 if (ucontrol->value.enumerated.item[0] == 0) 2596 if (ucontrol->value.enumerated.item[0] == 0)
2616 new_vref = stac92xx_get_default_vref(codec, nid); 2597 new_vref = snd_hda_get_default_vref(codec, nid);
2617 else if (ucontrol->value.enumerated.item[0] == 1) 2598 else if (ucontrol->value.enumerated.item[0] == 1)
2618 new_vref = AC_PINCTL_VREF_GRD; 2599 new_vref = AC_PINCTL_VREF_GRD;
2619 else if (ucontrol->value.enumerated.item[0] == 2) 2600 else if (ucontrol->value.enumerated.item[0] == 2)
@@ -2679,7 +2660,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2679 else { 2660 else {
2680 unsigned int pinctl = AC_PINCTL_IN_EN; 2661 unsigned int pinctl = AC_PINCTL_IN_EN;
2681 if (io_idx) /* set VREF for mic */ 2662 if (io_idx) /* set VREF for mic */
2682 pinctl |= stac92xx_get_default_vref(codec, nid); 2663 pinctl |= snd_hda_get_default_vref(codec, nid);
2683 stac92xx_auto_set_pinctl(codec, nid, pinctl); 2664 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2684 } 2665 }
2685 2666
@@ -2847,7 +2828,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
2847 char name[22]; 2828 char name[22];
2848 2829
2849 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) { 2830 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
2850 if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD 2831 if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
2851 && nid == spec->line_switch) 2832 && nid == spec->line_switch)
2852 control = STAC_CTL_WIDGET_IO_SWITCH; 2833 control = STAC_CTL_WIDGET_IO_SWITCH;
2853 else if (snd_hda_query_pin_caps(codec, nid) 2834 else if (snd_hda_query_pin_caps(codec, nid)
@@ -4354,7 +4335,7 @@ static int stac92xx_init(struct hda_codec *codec)
4354 unsigned int pinctl, conf; 4335 unsigned int pinctl, conf;
4355 if (type == AUTO_PIN_MIC) { 4336 if (type == AUTO_PIN_MIC) {
4356 /* for mic pins, force to initialize */ 4337 /* for mic pins, force to initialize */
4357 pinctl = stac92xx_get_default_vref(codec, nid); 4338 pinctl = snd_hda_get_default_vref(codec, nid);
4358 pinctl |= AC_PINCTL_IN_EN; 4339 pinctl |= AC_PINCTL_IN_EN;
4359 stac92xx_auto_set_pinctl(codec, nid, pinctl); 4340 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4360 } else { 4341 } else {
@@ -4460,8 +4441,7 @@ static void stac92xx_shutup_pins(struct hda_codec *codec)
4460 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); 4441 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
4461 def_conf = snd_hda_codec_get_pincfg(codec, pin->nid); 4442 def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
4462 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) 4443 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
4463 snd_hda_codec_write(codec, pin->nid, 0, 4444 snd_hda_set_pin_ctl(codec, pin->nid, 0);
4464 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4465 } 4445 }
4466} 4446}
4467 4447
@@ -4517,9 +4497,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
4517 4497
4518 pin_ctl |= flag; 4498 pin_ctl |= flag;
4519 if (old_ctl != pin_ctl) 4499 if (old_ctl != pin_ctl)
4520 snd_hda_codec_write_cache(codec, nid, 0, 4500 snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl);
4521 AC_VERB_SET_PIN_WIDGET_CONTROL,
4522 pin_ctl);
4523} 4501}
4524 4502
4525static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, 4503static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
@@ -4528,9 +4506,7 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
4528 unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 4506 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
4529 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); 4507 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
4530 if (pin_ctl & flag) 4508 if (pin_ctl & flag)
4531 snd_hda_codec_write_cache(codec, nid, 0, 4509 snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl & ~flag);
4532 AC_VERB_SET_PIN_WIDGET_CONTROL,
4533 pin_ctl & ~flag);
4534} 4510}
4535 4511
4536static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) 4512static 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..92e11672b91c 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,
532{ 532{
533 if (!pin) 533 if (!pin)
534 return; 534 return;
535 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 535 snd_hda_set_pin_ctl(codec, pin, pin_type);
536 pin_type);
537 if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD) 536 if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
538 snd_hda_codec_write(codec, pin, 0, 537 snd_hda_codec_write(codec, pin, 0,
539 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 538 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
@@ -662,12 +661,12 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
662 hda_nid_t nid = cfg->inputs[i].pin; 661 hda_nid_t nid = cfg->inputs[i].pin;
663 if (spec->smart51_enabled && is_smart51_pins(codec, nid)) 662 if (spec->smart51_enabled && is_smart51_pins(codec, nid))
664 ctl = PIN_OUT; 663 ctl = PIN_OUT;
665 else if (cfg->inputs[i].type == AUTO_PIN_MIC) 664 else {
666 ctl = PIN_VREF50;
667 else
668 ctl = PIN_IN; 665 ctl = PIN_IN;
669 snd_hda_codec_write(codec, nid, 0, 666 if (cfg->inputs[i].type == AUTO_PIN_MIC)
670 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl); 667 ctl |= snd_hda_get_default_vref(codec, nid);
668 }
669 snd_hda_set_pin_ctl(codec, nid, ctl);
671 } 670 }
672 671
673 /* init input-src */ 672 /* init input-src */
@@ -1006,9 +1005,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1006 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 1005 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1007 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); 1006 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1008 parm |= out_in; 1007 parm |= out_in;
1009 snd_hda_codec_write(codec, nid, 0, 1008 snd_hda_set_pin_ctl(codec, nid, parm);
1010 AC_VERB_SET_PIN_WIDGET_CONTROL,
1011 parm);
1012 if (out_in == AC_PINCTL_OUT_EN) { 1009 if (out_in == AC_PINCTL_OUT_EN) {
1013 mute_aa_path(codec, 1); 1010 mute_aa_path(codec, 1);
1014 notify_aa_path_ctls(codec); 1011 notify_aa_path_ctls(codec);
@@ -1647,8 +1644,7 @@ static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
1647 parm &= ~AC_PINCTL_OUT_EN; 1644 parm &= ~AC_PINCTL_OUT_EN;
1648 else 1645 else
1649 parm |= AC_PINCTL_OUT_EN; 1646 parm |= AC_PINCTL_OUT_EN;
1650 snd_hda_codec_write(codec, pins[i], 0, 1647 snd_hda_set_pin_ctl(codec, pins[i], parm);
1651 AC_VERB_SET_PIN_WIDGET_CONTROL, parm);
1652 } 1648 }
1653} 1649}
1654 1650
@@ -1709,8 +1705,7 @@ static void via_gpio_control(struct hda_codec *codec)
1709 1705
1710 if (gpio_data == 0x02) { 1706 if (gpio_data == 0x02) {
1711 /* unmute line out */ 1707 /* unmute line out */
1712 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0, 1708 snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0],
1713 AC_VERB_SET_PIN_WIDGET_CONTROL,
1714 PIN_OUT); 1709 PIN_OUT);
1715 if (vol_counter & 0x20) { 1710 if (vol_counter & 0x20) {
1716 /* decrease volume */ 1711 /* decrease volume */
@@ -1728,9 +1723,7 @@ static void via_gpio_control(struct hda_codec *codec)
1728 } 1723 }
1729 } else if (!(gpio_data & 0x02)) { 1724 } else if (!(gpio_data & 0x02)) {
1730 /* mute line out */ 1725 /* mute line out */
1731 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0, 1726 snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0], 0);
1732 AC_VERB_SET_PIN_WIDGET_CONTROL,
1733 0);
1734 } 1727 }
1735} 1728}
1736 1729
@@ -2757,8 +2750,7 @@ static void via_auto_init_dig_in(struct hda_codec *codec)
2757 struct via_spec *spec = codec->spec; 2750 struct via_spec *spec = codec->spec;
2758 if (!spec->dig_in_nid) 2751 if (!spec->dig_in_nid)
2759 return; 2752 return;
2760 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, 2753 snd_hda_set_pin_ctl(codec, spec->autocfg.dig_in_pin, PIN_IN);
2761 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2762} 2754}
2763 2755
2764/* initialize the unsolicited events */ 2756/* initialize the unsolicited events */