diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 53 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 40 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 13 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0110.c | 7 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 8 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 29 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 145 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 69 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 46 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 30 |
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 | } |
4796 | EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); | 4796 | EXPORT_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 | */ | ||
4804 | unsigned 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 | } | ||
4823 | EXPORT_SYMBOL_HDA(snd_hda_get_default_vref); | ||
4824 | |||
4825 | int _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 | } | ||
4849 | EXPORT_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 | ||
505 | unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin); | ||
506 | int _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 | */ | ||
524 | static inline int | ||
525 | snd_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 | */ | ||
538 | static inline int | ||
539 | snd_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) | |||
341 | static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | 341 | static 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) | |||
356 | static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | 355 | static 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 { | |||
239 | static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | 239 | static 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) | |||
254 | static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | 253 | static 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 | ||
4073 | static int cx_auto_init(struct hda_codec *codec) | 4059 | static int cx_auto_init(struct hda_codec *codec) |
@@ -4084,9 +4070,9 @@ static int cx_auto_init(struct hda_codec *codec) | |||
4084 | 4070 | ||
4085 | static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, | 4071 | static 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. */ | ||
4177 | static 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 | |||
4188 | static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, | 4204 | static 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 | ||
4385 | static void apply_pin_fixup(struct hda_codec *codec, | 4422 | enum { |
4423 | CXT_PINCFG_LENOVO_X200, | ||
4424 | CXT_PINCFG_LENOVO_TP410, | ||
4425 | CXT_FIXUP_STEREO_DMIC, | ||
4426 | }; | ||
4427 | |||
4428 | static 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 | ||
4397 | enum { | ||
4398 | CXT_PINCFG_LENOVO_X200, | ||
4399 | CXT_PINCFG_LENOVO_TP410, | ||
4400 | }; | ||
4401 | |||
4402 | /* ThinkPad X200 & co with cxt5051 */ | 4449 | /* ThinkPad X200 & co with cxt5051 */ |
4403 | static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { | 4450 | static 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[] = { | |||
4419 | static const struct cxt_pincfg *cxt_pincfg_tbl[] = { | 4466 | static 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 | ||
4424 | static const struct snd_pci_quirk cxt5051_fixups[] = { | 4472 | static 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) | |||
2856 | static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, | 2838 | static 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 | ||
5954 | static void alc269_fixup_mic2_mute(struct hda_codec *codec, | 5928 | static 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 | ||
2508 | static 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 | |||
2524 | static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) | 2506 | static 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 | ||
4525 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | 4503 | static 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 | ||
4536 | static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | 4512 | 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..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 */ |