diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 1211 |
1 files changed, 815 insertions, 396 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ea4c88fe05c4..f35e58a2d921 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include "hda_codec.h" | 31 | #include "hda_codec.h" |
32 | #include "hda_local.h" | 32 | #include "hda_local.h" |
33 | #include "hda_beep.h" | ||
33 | 34 | ||
34 | #define ALC880_FRONT_EVENT 0x01 | 35 | #define ALC880_FRONT_EVENT 0x01 |
35 | #define ALC880_DCVOL_EVENT 0x02 | 36 | #define ALC880_DCVOL_EVENT 0x02 |
@@ -77,6 +78,7 @@ enum { | |||
77 | ALC260_ACER, | 78 | ALC260_ACER, |
78 | ALC260_WILL, | 79 | ALC260_WILL, |
79 | ALC260_REPLACER_672V, | 80 | ALC260_REPLACER_672V, |
81 | ALC260_FAVORIT100, | ||
80 | #ifdef CONFIG_SND_DEBUG | 82 | #ifdef CONFIG_SND_DEBUG |
81 | ALC260_TEST, | 83 | ALC260_TEST, |
82 | #endif | 84 | #endif |
@@ -103,6 +105,7 @@ enum { | |||
103 | ALC262_NEC, | 105 | ALC262_NEC, |
104 | ALC262_TOSHIBA_S06, | 106 | ALC262_TOSHIBA_S06, |
105 | ALC262_TOSHIBA_RX1, | 107 | ALC262_TOSHIBA_RX1, |
108 | ALC262_TYAN, | ||
106 | ALC262_AUTO, | 109 | ALC262_AUTO, |
107 | ALC262_MODEL_LAST /* last tag */ | 110 | ALC262_MODEL_LAST /* last tag */ |
108 | }; | 111 | }; |
@@ -238,6 +241,13 @@ enum { | |||
238 | ALC883_MODEL_LAST, | 241 | ALC883_MODEL_LAST, |
239 | }; | 242 | }; |
240 | 243 | ||
244 | /* styles of capture selection */ | ||
245 | enum { | ||
246 | CAPT_MUX = 0, /* only mux based */ | ||
247 | CAPT_MIX, /* only mixer based */ | ||
248 | CAPT_1MUX_MIX, /* first mux and other mixers */ | ||
249 | }; | ||
250 | |||
241 | /* for GPIO Poll */ | 251 | /* for GPIO Poll */ |
242 | #define GPIO_MASK 0x03 | 252 | #define GPIO_MASK 0x03 |
243 | 253 | ||
@@ -246,6 +256,7 @@ struct alc_spec { | |||
246 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 256 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
247 | unsigned int num_mixers; | 257 | unsigned int num_mixers; |
248 | struct snd_kcontrol_new *cap_mixer; /* capture mixer */ | 258 | struct snd_kcontrol_new *cap_mixer; /* capture mixer */ |
259 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | ||
249 | 260 | ||
250 | const struct hda_verb *init_verbs[5]; /* initialization verbs | 261 | const struct hda_verb *init_verbs[5]; /* initialization verbs |
251 | * don't forget NULL | 262 | * don't forget NULL |
@@ -269,13 +280,15 @@ struct alc_spec { | |||
269 | * dig_out_nid and hp_nid are optional | 280 | * dig_out_nid and hp_nid are optional |
270 | */ | 281 | */ |
271 | hda_nid_t alt_dac_nid; | 282 | hda_nid_t alt_dac_nid; |
283 | hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ | ||
284 | int dig_out_type; | ||
272 | 285 | ||
273 | /* capture */ | 286 | /* capture */ |
274 | unsigned int num_adc_nids; | 287 | unsigned int num_adc_nids; |
275 | hda_nid_t *adc_nids; | 288 | hda_nid_t *adc_nids; |
276 | hda_nid_t *capsrc_nids; | 289 | hda_nid_t *capsrc_nids; |
277 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 290 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
278 | unsigned char is_mix_capture; /* matrix-style capture (non-mux) */ | 291 | int capture_style; /* capture style (CAPT_*) */ |
279 | 292 | ||
280 | /* capture source */ | 293 | /* capture source */ |
281 | unsigned int num_mux_defs; | 294 | unsigned int num_mux_defs; |
@@ -293,7 +306,7 @@ struct alc_spec { | |||
293 | /* dynamic controls, init_verbs and input_mux */ | 306 | /* dynamic controls, init_verbs and input_mux */ |
294 | struct auto_pin_cfg autocfg; | 307 | struct auto_pin_cfg autocfg; |
295 | struct snd_array kctls; | 308 | struct snd_array kctls; |
296 | struct hda_input_mux private_imux; | 309 | struct hda_input_mux private_imux[3]; |
297 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 310 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
298 | 311 | ||
299 | /* hooks */ | 312 | /* hooks */ |
@@ -305,6 +318,9 @@ struct alc_spec { | |||
305 | unsigned int jack_present: 1; | 318 | unsigned int jack_present: 1; |
306 | unsigned int master_sw: 1; | 319 | unsigned int master_sw: 1; |
307 | 320 | ||
321 | /* other flags */ | ||
322 | unsigned int no_analog :1; /* digital I/O only */ | ||
323 | |||
308 | /* for virtual master */ | 324 | /* for virtual master */ |
309 | hda_nid_t vmaster_nid; | 325 | hda_nid_t vmaster_nid; |
310 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 326 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -314,13 +330,6 @@ struct alc_spec { | |||
314 | /* for PLL fix */ | 330 | /* for PLL fix */ |
315 | hda_nid_t pll_nid; | 331 | hda_nid_t pll_nid; |
316 | unsigned int pll_coef_idx, pll_coef_bit; | 332 | unsigned int pll_coef_idx, pll_coef_bit; |
317 | |||
318 | #ifdef SND_HDA_NEEDS_RESUME | ||
319 | #define ALC_MAX_PINS 16 | ||
320 | unsigned int num_pins; | ||
321 | hda_nid_t pin_nids[ALC_MAX_PINS]; | ||
322 | unsigned int pin_cfgs[ALC_MAX_PINS]; | ||
323 | #endif | ||
324 | }; | 333 | }; |
325 | 334 | ||
326 | /* | 335 | /* |
@@ -336,6 +345,7 @@ struct alc_config_preset { | |||
336 | hda_nid_t *dac_nids; | 345 | hda_nid_t *dac_nids; |
337 | hda_nid_t dig_out_nid; /* optional */ | 346 | hda_nid_t dig_out_nid; /* optional */ |
338 | hda_nid_t hp_nid; /* optional */ | 347 | hda_nid_t hp_nid; /* optional */ |
348 | hda_nid_t *slave_dig_outs; | ||
339 | unsigned int num_adc_nids; | 349 | unsigned int num_adc_nids; |
340 | hda_nid_t *adc_nids; | 350 | hda_nid_t *adc_nids; |
341 | hda_nid_t *capsrc_nids; | 351 | hda_nid_t *capsrc_nids; |
@@ -392,7 +402,8 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
392 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 402 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
393 | imux = &spec->input_mux[mux_idx]; | 403 | imux = &spec->input_mux[mux_idx]; |
394 | 404 | ||
395 | if (spec->is_mix_capture) { | 405 | if (spec->capture_style && |
406 | !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) { | ||
396 | /* Matrix-mixer style (e.g. ALC882) */ | 407 | /* Matrix-mixer style (e.g. ALC882) */ |
397 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | 408 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; |
398 | unsigned int i, idx; | 409 | unsigned int i, idx; |
@@ -750,6 +761,24 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, | |||
750 | #endif /* CONFIG_SND_DEBUG */ | 761 | #endif /* CONFIG_SND_DEBUG */ |
751 | 762 | ||
752 | /* | 763 | /* |
764 | * set up the input pin config (depending on the given auto-pin type) | ||
765 | */ | ||
766 | static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, | ||
767 | int auto_pin_type) | ||
768 | { | ||
769 | unsigned int val = PIN_IN; | ||
770 | |||
771 | if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { | ||
772 | unsigned int pincap; | ||
773 | pincap = snd_hda_query_pin_caps(codec, nid); | ||
774 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; | ||
775 | if (pincap & AC_PINCAP_VREF_80) | ||
776 | val = PIN_VREF80; | ||
777 | } | ||
778 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); | ||
779 | } | ||
780 | |||
781 | /* | ||
753 | */ | 782 | */ |
754 | static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) | 783 | static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) |
755 | { | 784 | { |
@@ -810,6 +839,7 @@ static void setup_preset(struct alc_spec *spec, | |||
810 | spec->multiout.num_dacs = preset->num_dacs; | 839 | spec->multiout.num_dacs = preset->num_dacs; |
811 | spec->multiout.dac_nids = preset->dac_nids; | 840 | spec->multiout.dac_nids = preset->dac_nids; |
812 | spec->multiout.dig_out_nid = preset->dig_out_nid; | 841 | spec->multiout.dig_out_nid = preset->dig_out_nid; |
842 | spec->multiout.slave_dig_outs = preset->slave_dig_outs; | ||
813 | spec->multiout.hp_nid = preset->hp_nid; | 843 | spec->multiout.hp_nid = preset->hp_nid; |
814 | 844 | ||
815 | spec->num_mux_defs = preset->num_mux_defs; | 845 | spec->num_mux_defs = preset->num_mux_defs; |
@@ -921,7 +951,7 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
921 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 951 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
922 | } | 952 | } |
923 | #else | 953 | #else |
924 | #define alc_mic_automute(codec) /* NOP */ | 954 | #define alc_mic_automute(codec) do {} while(0) /* NOP */ |
925 | #endif /* disabled */ | 955 | #endif /* disabled */ |
926 | 956 | ||
927 | /* unsolicited event for HP jack sensing */ | 957 | /* unsolicited event for HP jack sensing */ |
@@ -952,7 +982,7 @@ static void alc888_coef_init(struct hda_codec *codec) | |||
952 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); | 982 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); |
953 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | 983 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); |
954 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | 984 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); |
955 | if ((tmp & 0xf0) == 2) | 985 | if ((tmp & 0xf0) == 0x20) |
956 | /* alc888S-VC */ | 986 | /* alc888S-VC */ |
957 | snd_hda_codec_read(codec, 0x20, 0, | 987 | snd_hda_codec_read(codec, 0x20, 0, |
958 | AC_VERB_SET_PROC_COEF, 0x830); | 988 | AC_VERB_SET_PROC_COEF, 0x830); |
@@ -991,8 +1021,7 @@ static void alc_subsystem_id(struct hda_codec *codec, | |||
991 | nid = 0x1d; | 1021 | nid = 0x1d; |
992 | if (codec->vendor_id == 0x10ec0260) | 1022 | if (codec->vendor_id == 0x10ec0260) |
993 | nid = 0x17; | 1023 | nid = 0x17; |
994 | ass = snd_hda_codec_read(codec, nid, 0, | 1024 | ass = snd_hda_codec_get_pincfg(codec, nid); |
995 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
996 | if (!(ass & 1) && !(ass & 0x100000)) | 1025 | if (!(ass & 1) && !(ass & 0x100000)) |
997 | return; | 1026 | return; |
998 | if ((ass >> 30) != 1) /* no physical connection */ | 1027 | if ((ass >> 30) != 1) /* no physical connection */ |
@@ -1037,6 +1066,7 @@ do_sku: | |||
1037 | case 0x10ec0267: | 1066 | case 0x10ec0267: |
1038 | case 0x10ec0268: | 1067 | case 0x10ec0268: |
1039 | case 0x10ec0269: | 1068 | case 0x10ec0269: |
1069 | case 0x10ec0272: | ||
1040 | case 0x10ec0660: | 1070 | case 0x10ec0660: |
1041 | case 0x10ec0662: | 1071 | case 0x10ec0662: |
1042 | case 0x10ec0663: | 1072 | case 0x10ec0663: |
@@ -1065,6 +1095,7 @@ do_sku: | |||
1065 | case 0x10ec0882: | 1095 | case 0x10ec0882: |
1066 | case 0x10ec0883: | 1096 | case 0x10ec0883: |
1067 | case 0x10ec0885: | 1097 | case 0x10ec0885: |
1098 | case 0x10ec0887: | ||
1068 | case 0x10ec0889: | 1099 | case 0x10ec0889: |
1069 | snd_hda_codec_write(codec, 0x20, 0, | 1100 | snd_hda_codec_write(codec, 0x20, 0, |
1070 | AC_VERB_SET_COEF_INDEX, 7); | 1101 | AC_VERB_SET_COEF_INDEX, 7); |
@@ -1164,16 +1195,8 @@ static void alc_fix_pincfg(struct hda_codec *codec, | |||
1164 | return; | 1195 | return; |
1165 | 1196 | ||
1166 | cfg = pinfix[quirk->value]; | 1197 | cfg = pinfix[quirk->value]; |
1167 | for (; cfg->nid; cfg++) { | 1198 | for (; cfg->nid; cfg++) |
1168 | int i; | 1199 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); |
1169 | u32 val = cfg->val; | ||
1170 | for (i = 0; i < 4; i++) { | ||
1171 | snd_hda_codec_write(codec, cfg->nid, 0, | ||
1172 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, | ||
1173 | val & 0xff); | ||
1174 | val >>= 8; | ||
1175 | } | ||
1176 | } | ||
1177 | } | 1200 | } |
1178 | 1201 | ||
1179 | /* | 1202 | /* |
@@ -1373,8 +1396,6 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { | |||
1373 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 1396 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
1374 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 1397 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
1375 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 1398 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
1376 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
1377 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
1378 | { } /* end */ | 1399 | { } /* end */ |
1379 | }; | 1400 | }; |
1380 | 1401 | ||
@@ -1481,8 +1502,6 @@ static struct snd_kcontrol_new alc880_three_stack_mixer[] = { | |||
1481 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 1502 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
1482 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), | 1503 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), |
1483 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), | 1504 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), |
1484 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
1485 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
1486 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), | 1505 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), |
1487 | { | 1506 | { |
1488 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1507 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -1576,8 +1595,7 @@ static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, | |||
1576 | snd_hda_mixer_amp_switch_put); | 1595 | snd_hda_mixer_amp_switch_put); |
1577 | } | 1596 | } |
1578 | 1597 | ||
1579 | #define DEFINE_CAPMIX(num) \ | 1598 | #define _DEFINE_CAPMIX(num) \ |
1580 | static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ | ||
1581 | { \ | 1599 | { \ |
1582 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 1600 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1583 | .name = "Capture Switch", \ | 1601 | .name = "Capture Switch", \ |
@@ -1598,7 +1616,9 @@ static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ | |||
1598 | .get = alc_cap_vol_get, \ | 1616 | .get = alc_cap_vol_get, \ |
1599 | .put = alc_cap_vol_put, \ | 1617 | .put = alc_cap_vol_put, \ |
1600 | .tlv = { .c = alc_cap_vol_tlv }, \ | 1618 | .tlv = { .c = alc_cap_vol_tlv }, \ |
1601 | }, \ | 1619 | } |
1620 | |||
1621 | #define _DEFINE_CAPSRC(num) \ | ||
1602 | { \ | 1622 | { \ |
1603 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 1623 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
1604 | /* .name = "Capture Source", */ \ | 1624 | /* .name = "Capture Source", */ \ |
@@ -1607,15 +1627,28 @@ static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ | |||
1607 | .info = alc_mux_enum_info, \ | 1627 | .info = alc_mux_enum_info, \ |
1608 | .get = alc_mux_enum_get, \ | 1628 | .get = alc_mux_enum_get, \ |
1609 | .put = alc_mux_enum_put, \ | 1629 | .put = alc_mux_enum_put, \ |
1610 | }, \ | 1630 | } |
1611 | { } /* end */ \ | 1631 | |
1632 | #define DEFINE_CAPMIX(num) \ | ||
1633 | static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ | ||
1634 | _DEFINE_CAPMIX(num), \ | ||
1635 | _DEFINE_CAPSRC(num), \ | ||
1636 | { } /* end */ \ | ||
1637 | } | ||
1638 | |||
1639 | #define DEFINE_CAPMIX_NOSRC(num) \ | ||
1640 | static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ | ||
1641 | _DEFINE_CAPMIX(num), \ | ||
1642 | { } /* end */ \ | ||
1612 | } | 1643 | } |
1613 | 1644 | ||
1614 | /* up to three ADCs */ | 1645 | /* up to three ADCs */ |
1615 | DEFINE_CAPMIX(1); | 1646 | DEFINE_CAPMIX(1); |
1616 | DEFINE_CAPMIX(2); | 1647 | DEFINE_CAPMIX(2); |
1617 | DEFINE_CAPMIX(3); | 1648 | DEFINE_CAPMIX(3); |
1618 | 1649 | DEFINE_CAPMIX_NOSRC(1); | |
1650 | DEFINE_CAPMIX_NOSRC(2); | ||
1651 | DEFINE_CAPMIX_NOSRC(3); | ||
1619 | 1652 | ||
1620 | /* | 1653 | /* |
1621 | * ALC880 5-stack model | 1654 | * ALC880 5-stack model |
@@ -1704,8 +1737,6 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = { | |||
1704 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 1737 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
1705 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 1738 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
1706 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 1739 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
1707 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
1708 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
1709 | { | 1740 | { |
1710 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1741 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1711 | .name = "Channel Mode", | 1742 | .name = "Channel Mode", |
@@ -1882,13 +1913,6 @@ static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { | |||
1882 | { } /* end */ | 1913 | { } /* end */ |
1883 | }; | 1914 | }; |
1884 | 1915 | ||
1885 | /* additional mixers to alc880_asus_mixer */ | ||
1886 | static struct snd_kcontrol_new alc880_pcbeep_mixer[] = { | ||
1887 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
1888 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
1889 | { } /* end */ | ||
1890 | }; | ||
1891 | |||
1892 | /* TCL S700 */ | 1916 | /* TCL S700 */ |
1893 | static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { | 1917 | static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { |
1894 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 1918 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
@@ -1921,8 +1945,6 @@ static struct snd_kcontrol_new alc880_uniwill_mixer[] = { | |||
1921 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 1945 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
1922 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 1946 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
1923 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 1947 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
1924 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
1925 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
1926 | { | 1948 | { |
1927 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1949 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1928 | .name = "Channel Mode", | 1950 | .name = "Channel Mode", |
@@ -1997,6 +2019,13 @@ static const char *alc_slave_sws[] = { | |||
1997 | 2019 | ||
1998 | static void alc_free_kctls(struct hda_codec *codec); | 2020 | static void alc_free_kctls(struct hda_codec *codec); |
1999 | 2021 | ||
2022 | /* additional beep mixers; the actual parameters are overwritten at build */ | ||
2023 | static struct snd_kcontrol_new alc_beep_mixer[] = { | ||
2024 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), | ||
2025 | HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT), | ||
2026 | { } /* end */ | ||
2027 | }; | ||
2028 | |||
2000 | static int alc_build_controls(struct hda_codec *codec) | 2029 | static int alc_build_controls(struct hda_codec *codec) |
2001 | { | 2030 | { |
2002 | struct alc_spec *spec = codec->spec; | 2031 | struct alc_spec *spec = codec->spec; |
@@ -2018,11 +2047,13 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2018 | spec->multiout.dig_out_nid); | 2047 | spec->multiout.dig_out_nid); |
2019 | if (err < 0) | 2048 | if (err < 0) |
2020 | return err; | 2049 | return err; |
2021 | err = snd_hda_create_spdif_share_sw(codec, | 2050 | if (!spec->no_analog) { |
2022 | &spec->multiout); | 2051 | err = snd_hda_create_spdif_share_sw(codec, |
2023 | if (err < 0) | 2052 | &spec->multiout); |
2024 | return err; | 2053 | if (err < 0) |
2025 | spec->multiout.share_spdif = 1; | 2054 | return err; |
2055 | spec->multiout.share_spdif = 1; | ||
2056 | } | ||
2026 | } | 2057 | } |
2027 | if (spec->dig_in_nid) { | 2058 | if (spec->dig_in_nid) { |
2028 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | 2059 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); |
@@ -2030,8 +2061,24 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2030 | return err; | 2061 | return err; |
2031 | } | 2062 | } |
2032 | 2063 | ||
2064 | /* create beep controls if needed */ | ||
2065 | if (spec->beep_amp) { | ||
2066 | struct snd_kcontrol_new *knew; | ||
2067 | for (knew = alc_beep_mixer; knew->name; knew++) { | ||
2068 | struct snd_kcontrol *kctl; | ||
2069 | kctl = snd_ctl_new1(knew, codec); | ||
2070 | if (!kctl) | ||
2071 | return -ENOMEM; | ||
2072 | kctl->private_value = spec->beep_amp; | ||
2073 | err = snd_hda_ctl_add(codec, kctl); | ||
2074 | if (err < 0) | ||
2075 | return err; | ||
2076 | } | ||
2077 | } | ||
2078 | |||
2033 | /* if we have no master control, let's create it */ | 2079 | /* if we have no master control, let's create it */ |
2034 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | 2080 | if (!spec->no_analog && |
2081 | !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | ||
2035 | unsigned int vmaster_tlv[4]; | 2082 | unsigned int vmaster_tlv[4]; |
2036 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | 2083 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, |
2037 | HDA_OUTPUT, vmaster_tlv); | 2084 | HDA_OUTPUT, vmaster_tlv); |
@@ -2040,7 +2087,8 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2040 | if (err < 0) | 2087 | if (err < 0) |
2041 | return err; | 2088 | return err; |
2042 | } | 2089 | } |
2043 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 2090 | if (!spec->no_analog && |
2091 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | ||
2044 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 2092 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
2045 | NULL, alc_slave_sws); | 2093 | NULL, alc_slave_sws); |
2046 | if (err < 0) | 2094 | if (err < 0) |
@@ -2949,6 +2997,14 @@ static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2949 | stream_tag, format, substream); | 2997 | stream_tag, format, substream); |
2950 | } | 2998 | } |
2951 | 2999 | ||
3000 | static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
3001 | struct hda_codec *codec, | ||
3002 | struct snd_pcm_substream *substream) | ||
3003 | { | ||
3004 | struct alc_spec *spec = codec->spec; | ||
3005 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
3006 | } | ||
3007 | |||
2952 | static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | 3008 | static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, |
2953 | struct hda_codec *codec, | 3009 | struct hda_codec *codec, |
2954 | struct snd_pcm_substream *substream) | 3010 | struct snd_pcm_substream *substream) |
@@ -3032,7 +3088,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { | |||
3032 | .ops = { | 3088 | .ops = { |
3033 | .open = alc880_dig_playback_pcm_open, | 3089 | .open = alc880_dig_playback_pcm_open, |
3034 | .close = alc880_dig_playback_pcm_close, | 3090 | .close = alc880_dig_playback_pcm_close, |
3035 | .prepare = alc880_dig_playback_pcm_prepare | 3091 | .prepare = alc880_dig_playback_pcm_prepare, |
3092 | .cleanup = alc880_dig_playback_pcm_cleanup | ||
3036 | }, | 3093 | }, |
3037 | }; | 3094 | }; |
3038 | 3095 | ||
@@ -3059,6 +3116,9 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3059 | codec->num_pcms = 1; | 3116 | codec->num_pcms = 1; |
3060 | codec->pcm_info = info; | 3117 | codec->pcm_info = info; |
3061 | 3118 | ||
3119 | if (spec->no_analog) | ||
3120 | goto skip_analog; | ||
3121 | |||
3062 | info->name = spec->stream_name_analog; | 3122 | info->name = spec->stream_name_analog; |
3063 | if (spec->stream_analog_playback) { | 3123 | if (spec->stream_analog_playback) { |
3064 | if (snd_BUG_ON(!spec->multiout.dac_nids)) | 3124 | if (snd_BUG_ON(!spec->multiout.dac_nids)) |
@@ -3082,12 +3142,17 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3082 | } | 3142 | } |
3083 | } | 3143 | } |
3084 | 3144 | ||
3145 | skip_analog: | ||
3085 | /* SPDIF for stream index #1 */ | 3146 | /* SPDIF for stream index #1 */ |
3086 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | 3147 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { |
3087 | codec->num_pcms = 2; | 3148 | codec->num_pcms = 2; |
3149 | codec->slave_dig_outs = spec->multiout.slave_dig_outs; | ||
3088 | info = spec->pcm_rec + 1; | 3150 | info = spec->pcm_rec + 1; |
3089 | info->name = spec->stream_name_digital; | 3151 | info->name = spec->stream_name_digital; |
3090 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | 3152 | if (spec->dig_out_type) |
3153 | info->pcm_type = spec->dig_out_type; | ||
3154 | else | ||
3155 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
3091 | if (spec->multiout.dig_out_nid && | 3156 | if (spec->multiout.dig_out_nid && |
3092 | spec->stream_digital_playback) { | 3157 | spec->stream_digital_playback) { |
3093 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); | 3158 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); |
@@ -3102,6 +3167,9 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
3102 | codec->spdif_status_reset = 1; | 3167 | codec->spdif_status_reset = 1; |
3103 | } | 3168 | } |
3104 | 3169 | ||
3170 | if (spec->no_analog) | ||
3171 | return 0; | ||
3172 | |||
3105 | /* If the use of more than one ADC is requested for the current | 3173 | /* If the use of more than one ADC is requested for the current |
3106 | * model, configure a second analog capture-only PCM. | 3174 | * model, configure a second analog capture-only PCM. |
3107 | */ | 3175 | */ |
@@ -3160,65 +3228,17 @@ static void alc_free(struct hda_codec *codec) | |||
3160 | 3228 | ||
3161 | alc_free_kctls(codec); | 3229 | alc_free_kctls(codec); |
3162 | kfree(spec); | 3230 | kfree(spec); |
3163 | codec->spec = NULL; /* to be sure */ | 3231 | snd_hda_detach_beep_device(codec); |
3164 | } | 3232 | } |
3165 | 3233 | ||
3166 | #ifdef SND_HDA_NEEDS_RESUME | 3234 | #ifdef SND_HDA_NEEDS_RESUME |
3167 | static void store_pin_configs(struct hda_codec *codec) | ||
3168 | { | ||
3169 | struct alc_spec *spec = codec->spec; | ||
3170 | hda_nid_t nid, end_nid; | ||
3171 | |||
3172 | end_nid = codec->start_nid + codec->num_nodes; | ||
3173 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
3174 | unsigned int wid_caps = get_wcaps(codec, nid); | ||
3175 | unsigned int wid_type = | ||
3176 | (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
3177 | if (wid_type != AC_WID_PIN) | ||
3178 | continue; | ||
3179 | if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids)) | ||
3180 | break; | ||
3181 | spec->pin_nids[spec->num_pins] = nid; | ||
3182 | spec->pin_cfgs[spec->num_pins] = | ||
3183 | snd_hda_codec_read(codec, nid, 0, | ||
3184 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
3185 | spec->num_pins++; | ||
3186 | } | ||
3187 | } | ||
3188 | |||
3189 | static void resume_pin_configs(struct hda_codec *codec) | ||
3190 | { | ||
3191 | struct alc_spec *spec = codec->spec; | ||
3192 | int i; | ||
3193 | |||
3194 | for (i = 0; i < spec->num_pins; i++) { | ||
3195 | hda_nid_t pin_nid = spec->pin_nids[i]; | ||
3196 | unsigned int pin_config = spec->pin_cfgs[i]; | ||
3197 | snd_hda_codec_write(codec, pin_nid, 0, | ||
3198 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | ||
3199 | pin_config & 0x000000ff); | ||
3200 | snd_hda_codec_write(codec, pin_nid, 0, | ||
3201 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | ||
3202 | (pin_config & 0x0000ff00) >> 8); | ||
3203 | snd_hda_codec_write(codec, pin_nid, 0, | ||
3204 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | ||
3205 | (pin_config & 0x00ff0000) >> 16); | ||
3206 | snd_hda_codec_write(codec, pin_nid, 0, | ||
3207 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | ||
3208 | pin_config >> 24); | ||
3209 | } | ||
3210 | } | ||
3211 | |||
3212 | static int alc_resume(struct hda_codec *codec) | 3235 | static int alc_resume(struct hda_codec *codec) |
3213 | { | 3236 | { |
3214 | resume_pin_configs(codec); | ||
3215 | codec->patch_ops.init(codec); | 3237 | codec->patch_ops.init(codec); |
3216 | snd_hda_codec_resume_amp(codec); | 3238 | snd_hda_codec_resume_amp(codec); |
3217 | snd_hda_codec_resume_cache(codec); | 3239 | snd_hda_codec_resume_cache(codec); |
3218 | return 0; | 3240 | return 0; |
3219 | } | 3241 | } |
3220 | #else | ||
3221 | #define store_pin_configs(codec) | ||
3222 | #endif | 3242 | #endif |
3223 | 3243 | ||
3224 | /* | 3244 | /* |
@@ -3557,7 +3577,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
3557 | SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), | 3577 | SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), |
3558 | SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), | 3578 | SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), |
3559 | SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), | 3579 | SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), |
3560 | SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */ | 3580 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ |
3561 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), | 3581 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), |
3562 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), | 3582 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), |
3563 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), | 3583 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), |
@@ -3600,7 +3620,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
3600 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), | 3620 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), |
3601 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), | 3621 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), |
3602 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), | 3622 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), |
3603 | SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */ | 3623 | /* default Intel */ |
3624 | SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), | ||
3604 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), | 3625 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), |
3605 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), | 3626 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), |
3606 | {} | 3627 | {} |
@@ -3780,7 +3801,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3780 | .input_mux = &alc880_capture_source, | 3801 | .input_mux = &alc880_capture_source, |
3781 | }, | 3802 | }, |
3782 | [ALC880_UNIWILL_DIG] = { | 3803 | [ALC880_UNIWILL_DIG] = { |
3783 | .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, | 3804 | .mixers = { alc880_asus_mixer }, |
3784 | .init_verbs = { alc880_volume_init_verbs, | 3805 | .init_verbs = { alc880_volume_init_verbs, |
3785 | alc880_pin_asus_init_verbs }, | 3806 | alc880_pin_asus_init_verbs }, |
3786 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 3807 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
@@ -3818,8 +3839,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
3818 | .init_hook = alc880_uniwill_p53_hp_automute, | 3839 | .init_hook = alc880_uniwill_p53_hp_automute, |
3819 | }, | 3840 | }, |
3820 | [ALC880_FUJITSU] = { | 3841 | [ALC880_FUJITSU] = { |
3821 | .mixers = { alc880_fujitsu_mixer, | 3842 | .mixers = { alc880_fujitsu_mixer }, |
3822 | alc880_pcbeep_mixer, }, | ||
3823 | .init_verbs = { alc880_volume_init_verbs, | 3843 | .init_verbs = { alc880_volume_init_verbs, |
3824 | alc880_uniwill_p53_init_verbs, | 3844 | alc880_uniwill_p53_init_verbs, |
3825 | alc880_beep_init_verbs }, | 3845 | alc880_beep_init_verbs }, |
@@ -4112,7 +4132,7 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, | |||
4112 | static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, | 4132 | static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, |
4113 | const struct auto_pin_cfg *cfg) | 4133 | const struct auto_pin_cfg *cfg) |
4114 | { | 4134 | { |
4115 | struct hda_input_mux *imux = &spec->private_imux; | 4135 | struct hda_input_mux *imux = &spec->private_imux[0]; |
4116 | int i, err, idx; | 4136 | int i, err, idx; |
4117 | 4137 | ||
4118 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 4138 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
@@ -4200,11 +4220,9 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) | |||
4200 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 4220 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
4201 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 4221 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
4202 | if (alc880_is_input_pin(nid)) { | 4222 | if (alc880_is_input_pin(nid)) { |
4203 | snd_hda_codec_write(codec, nid, 0, | 4223 | alc_set_input_pin(codec, nid, i); |
4204 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 4224 | if (nid != ALC880_PIN_CD_NID && |
4205 | i <= AUTO_PIN_FRONT_MIC ? | 4225 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
4206 | PIN_VREF80 : PIN_IN); | ||
4207 | if (nid != ALC880_PIN_CD_NID) | ||
4208 | snd_hda_codec_write(codec, nid, 0, | 4226 | snd_hda_codec_write(codec, nid, 0, |
4209 | AC_VERB_SET_AMP_GAIN_MUTE, | 4227 | AC_VERB_SET_AMP_GAIN_MUTE, |
4210 | AMP_OUT_MUTE); | 4228 | AMP_OUT_MUTE); |
@@ -4219,7 +4237,7 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) | |||
4219 | static int alc880_parse_auto_config(struct hda_codec *codec) | 4237 | static int alc880_parse_auto_config(struct hda_codec *codec) |
4220 | { | 4238 | { |
4221 | struct alc_spec *spec = codec->spec; | 4239 | struct alc_spec *spec = codec->spec; |
4222 | int err; | 4240 | int i, err; |
4223 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 4241 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
4224 | 4242 | ||
4225 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 4243 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
@@ -4250,8 +4268,23 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4250 | 4268 | ||
4251 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 4269 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
4252 | 4270 | ||
4253 | if (spec->autocfg.dig_out_pin) | 4271 | /* check multiple SPDIF-out (for recent codecs) */ |
4254 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | 4272 | for (i = 0; i < spec->autocfg.dig_outs; i++) { |
4273 | hda_nid_t dig_nid; | ||
4274 | err = snd_hda_get_connections(codec, | ||
4275 | spec->autocfg.dig_out_pins[i], | ||
4276 | &dig_nid, 1); | ||
4277 | if (err < 0) | ||
4278 | continue; | ||
4279 | if (!i) | ||
4280 | spec->multiout.dig_out_nid = dig_nid; | ||
4281 | else { | ||
4282 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
4283 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
4284 | if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
4285 | break; | ||
4286 | } | ||
4287 | } | ||
4255 | if (spec->autocfg.dig_in_pin) | 4288 | if (spec->autocfg.dig_in_pin) |
4256 | spec->dig_in_nid = ALC880_DIGIN_NID; | 4289 | spec->dig_in_nid = ALC880_DIGIN_NID; |
4257 | 4290 | ||
@@ -4261,9 +4294,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4261 | add_verb(spec, alc880_volume_init_verbs); | 4294 | add_verb(spec, alc880_volume_init_verbs); |
4262 | 4295 | ||
4263 | spec->num_mux_defs = 1; | 4296 | spec->num_mux_defs = 1; |
4264 | spec->input_mux = &spec->private_imux; | 4297 | spec->input_mux = &spec->private_imux[0]; |
4265 | 4298 | ||
4266 | store_pin_configs(codec); | ||
4267 | return 1; | 4299 | return 1; |
4268 | } | 4300 | } |
4269 | 4301 | ||
@@ -4278,21 +4310,33 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
4278 | alc_inithook(codec); | 4310 | alc_inithook(codec); |
4279 | } | 4311 | } |
4280 | 4312 | ||
4281 | /* | ||
4282 | * OK, here we have finally the patch for ALC880 | ||
4283 | */ | ||
4284 | |||
4285 | static void set_capture_mixer(struct alc_spec *spec) | 4313 | static void set_capture_mixer(struct alc_spec *spec) |
4286 | { | 4314 | { |
4287 | static struct snd_kcontrol_new *caps[3] = { | 4315 | static struct snd_kcontrol_new *caps[2][3] = { |
4288 | alc_capture_mixer1, | 4316 | { alc_capture_mixer_nosrc1, |
4289 | alc_capture_mixer2, | 4317 | alc_capture_mixer_nosrc2, |
4290 | alc_capture_mixer3, | 4318 | alc_capture_mixer_nosrc3 }, |
4319 | { alc_capture_mixer1, | ||
4320 | alc_capture_mixer2, | ||
4321 | alc_capture_mixer3 }, | ||
4291 | }; | 4322 | }; |
4292 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) | 4323 | if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { |
4293 | spec->cap_mixer = caps[spec->num_adc_nids - 1]; | 4324 | int mux; |
4325 | if (spec->input_mux && spec->input_mux->num_items > 1) | ||
4326 | mux = 1; | ||
4327 | else | ||
4328 | mux = 0; | ||
4329 | spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; | ||
4330 | } | ||
4294 | } | 4331 | } |
4295 | 4332 | ||
4333 | #define set_beep_amp(spec, nid, idx, dir) \ | ||
4334 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | ||
4335 | |||
4336 | /* | ||
4337 | * OK, here we have finally the patch for ALC880 | ||
4338 | */ | ||
4339 | |||
4296 | static int patch_alc880(struct hda_codec *codec) | 4340 | static int patch_alc880(struct hda_codec *codec) |
4297 | { | 4341 | { |
4298 | struct alc_spec *spec; | 4342 | struct alc_spec *spec; |
@@ -4328,6 +4372,12 @@ static int patch_alc880(struct hda_codec *codec) | |||
4328 | } | 4372 | } |
4329 | } | 4373 | } |
4330 | 4374 | ||
4375 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
4376 | if (err < 0) { | ||
4377 | alc_free(codec); | ||
4378 | return err; | ||
4379 | } | ||
4380 | |||
4331 | if (board_config != ALC880_AUTO) | 4381 | if (board_config != ALC880_AUTO) |
4332 | setup_preset(spec, &alc880_presets[board_config]); | 4382 | setup_preset(spec, &alc880_presets[board_config]); |
4333 | 4383 | ||
@@ -4354,6 +4404,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
4354 | } | 4404 | } |
4355 | } | 4405 | } |
4356 | set_capture_mixer(spec); | 4406 | set_capture_mixer(spec); |
4407 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | ||
4357 | 4408 | ||
4358 | spec->vmaster_nid = 0x0c; | 4409 | spec->vmaster_nid = 0x0c; |
4359 | 4410 | ||
@@ -4461,6 +4512,26 @@ static struct hda_input_mux alc260_acer_capture_sources[2] = { | |||
4461 | }, | 4512 | }, |
4462 | }, | 4513 | }, |
4463 | }; | 4514 | }; |
4515 | |||
4516 | /* Maxdata Favorit 100XS */ | ||
4517 | static struct hda_input_mux alc260_favorit100_capture_sources[2] = { | ||
4518 | { | ||
4519 | .num_items = 2, | ||
4520 | .items = { | ||
4521 | { "Line/Mic", 0x0 }, | ||
4522 | { "CD", 0x4 }, | ||
4523 | }, | ||
4524 | }, | ||
4525 | { | ||
4526 | .num_items = 3, | ||
4527 | .items = { | ||
4528 | { "Line/Mic", 0x0 }, | ||
4529 | { "CD", 0x4 }, | ||
4530 | { "Mixer", 0x5 }, | ||
4531 | }, | ||
4532 | }, | ||
4533 | }; | ||
4534 | |||
4464 | /* | 4535 | /* |
4465 | * This is just place-holder, so there's something for alc_build_pcms to look | 4536 | * This is just place-holder, so there's something for alc_build_pcms to look |
4466 | * at when it calculates the maximum number of channels. ALC260 has no mixer | 4537 | * at when it calculates the maximum number of channels. ALC260 has no mixer |
@@ -4503,12 +4574,6 @@ static struct snd_kcontrol_new alc260_input_mixer[] = { | |||
4503 | { } /* end */ | 4574 | { } /* end */ |
4504 | }; | 4575 | }; |
4505 | 4576 | ||
4506 | static struct snd_kcontrol_new alc260_pc_beep_mixer[] = { | ||
4507 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
4508 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
4509 | { } /* end */ | ||
4510 | }; | ||
4511 | |||
4512 | /* update HP, line and mono out pins according to the master switch */ | 4577 | /* update HP, line and mono out pins according to the master switch */ |
4513 | static void alc260_hp_master_update(struct hda_codec *codec, | 4578 | static void alc260_hp_master_update(struct hda_codec *codec, |
4514 | hda_nid_t hp, hda_nid_t line, | 4579 | hda_nid_t hp, hda_nid_t line, |
@@ -4700,8 +4765,6 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { | |||
4700 | HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), | 4765 | HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), |
4701 | HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), | 4766 | HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), |
4702 | ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), | 4767 | ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), |
4703 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
4704 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
4705 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 4768 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
4706 | HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), | 4769 | HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), |
4707 | { } /* end */ | 4770 | { } /* end */ |
@@ -4746,8 +4809,18 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { | |||
4746 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | 4809 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), |
4747 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | 4810 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), |
4748 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | 4811 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), |
4749 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | 4812 | { } /* end */ |
4750 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | 4813 | }; |
4814 | |||
4815 | /* Maxdata Favorit 100XS: one output and one input (0x12) jack | ||
4816 | */ | ||
4817 | static struct snd_kcontrol_new alc260_favorit100_mixer[] = { | ||
4818 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
4819 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | ||
4820 | ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
4821 | HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
4822 | HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
4823 | ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
4751 | { } /* end */ | 4824 | { } /* end */ |
4752 | }; | 4825 | }; |
4753 | 4826 | ||
@@ -4765,8 +4838,6 @@ static struct snd_kcontrol_new alc260_will_mixer[] = { | |||
4765 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | 4838 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), |
4766 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 4839 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
4767 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 4840 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
4768 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
4769 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
4770 | { } /* end */ | 4841 | { } /* end */ |
4771 | }; | 4842 | }; |
4772 | 4843 | ||
@@ -5124,6 +5195,89 @@ static struct hda_verb alc260_acer_init_verbs[] = { | |||
5124 | { } | 5195 | { } |
5125 | }; | 5196 | }; |
5126 | 5197 | ||
5198 | /* Initialisation sequence for Maxdata Favorit 100XS | ||
5199 | * (adapted from Acer init verbs). | ||
5200 | */ | ||
5201 | static struct hda_verb alc260_favorit100_init_verbs[] = { | ||
5202 | /* GPIO 0 enables the output jack. | ||
5203 | * Turn this on and rely on the standard mute | ||
5204 | * methods whenever the user wants to turn these outputs off. | ||
5205 | */ | ||
5206 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
5207 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
5208 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
5209 | /* Line/Mic input jack is connected to Mic1 pin */ | ||
5210 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
5211 | /* Ensure all other unused pins are disabled and muted. */ | ||
5212 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
5213 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5214 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
5215 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5216 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
5217 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5218 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
5219 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5220 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
5221 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5222 | /* Disable digital (SPDIF) pins */ | ||
5223 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
5224 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
5225 | |||
5226 | /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum | ||
5227 | * bus when acting as outputs. | ||
5228 | */ | ||
5229 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5230 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5231 | |||
5232 | /* Start with output sum widgets muted and their output gains at min */ | ||
5233 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5234 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
5235 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5236 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5237 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
5238 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5239 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5240 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
5241 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5242 | |||
5243 | /* Unmute Line-out pin widget amp left and right | ||
5244 | * (no equiv mixer ctrl) | ||
5245 | */ | ||
5246 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
5247 | /* Unmute Mic1 and Line1 pin widget input buffers since they start as | ||
5248 | * inputs. If the pin mode is changed by the user the pin mode control | ||
5249 | * will take care of enabling the pin's input/output buffers as needed. | ||
5250 | * Therefore there's no need to enable the input buffer at this | ||
5251 | * stage. | ||
5252 | */ | ||
5253 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5254 | |||
5255 | /* Mute capture amp left and right */ | ||
5256 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5257 | /* Set ADC connection select to match default mixer setting - mic | ||
5258 | * (on mic1 pin) | ||
5259 | */ | ||
5260 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5261 | |||
5262 | /* Do similar with the second ADC: mute capture input amp and | ||
5263 | * set ADC connection to mic to match ALSA's default state. | ||
5264 | */ | ||
5265 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5266 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5267 | |||
5268 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
5269 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
5270 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
5271 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
5272 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
5273 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
5274 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
5275 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
5276 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
5277 | |||
5278 | { } | ||
5279 | }; | ||
5280 | |||
5127 | static struct hda_verb alc260_will_verbs[] = { | 5281 | static struct hda_verb alc260_will_verbs[] = { |
5128 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 5282 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
5129 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, | 5283 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -5270,8 +5424,6 @@ static struct snd_kcontrol_new alc260_test_mixer[] = { | |||
5270 | HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), | 5424 | HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), |
5271 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 5425 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
5272 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 5426 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
5273 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
5274 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
5275 | HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), | 5427 | HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), |
5276 | HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), | 5428 | HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), |
5277 | HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), | 5429 | HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), |
@@ -5469,7 +5621,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
5469 | static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, | 5621 | static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, |
5470 | const struct auto_pin_cfg *cfg) | 5622 | const struct auto_pin_cfg *cfg) |
5471 | { | 5623 | { |
5472 | struct hda_input_mux *imux = &spec->private_imux; | 5624 | struct hda_input_mux *imux = &spec->private_imux[0]; |
5473 | int i, err, idx; | 5625 | int i, err, idx; |
5474 | 5626 | ||
5475 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5627 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
@@ -5544,11 +5696,9 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) | |||
5544 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 5696 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
5545 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 5697 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
5546 | if (nid >= 0x12) { | 5698 | if (nid >= 0x12) { |
5547 | snd_hda_codec_write(codec, nid, 0, | 5699 | alc_set_input_pin(codec, nid, i); |
5548 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 5700 | if (nid != ALC260_PIN_CD_NID && |
5549 | i <= AUTO_PIN_FRONT_MIC ? | 5701 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
5550 | PIN_VREF80 : PIN_IN); | ||
5551 | if (nid != ALC260_PIN_CD_NID) | ||
5552 | snd_hda_codec_write(codec, nid, 0, | 5702 | snd_hda_codec_write(codec, nid, 0, |
5553 | AC_VERB_SET_AMP_GAIN_MUTE, | 5703 | AC_VERB_SET_AMP_GAIN_MUTE, |
5554 | AMP_OUT_MUTE); | 5704 | AMP_OUT_MUTE); |
@@ -5621,7 +5771,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
5621 | 5771 | ||
5622 | spec->multiout.max_channels = 2; | 5772 | spec->multiout.max_channels = 2; |
5623 | 5773 | ||
5624 | if (spec->autocfg.dig_out_pin) | 5774 | if (spec->autocfg.dig_outs) |
5625 | spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; | 5775 | spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; |
5626 | if (spec->kctls.list) | 5776 | if (spec->kctls.list) |
5627 | add_mixer(spec, spec->kctls.list); | 5777 | add_mixer(spec, spec->kctls.list); |
@@ -5629,9 +5779,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
5629 | add_verb(spec, alc260_volume_init_verbs); | 5779 | add_verb(spec, alc260_volume_init_verbs); |
5630 | 5780 | ||
5631 | spec->num_mux_defs = 1; | 5781 | spec->num_mux_defs = 1; |
5632 | spec->input_mux = &spec->private_imux; | 5782 | spec->input_mux = &spec->private_imux[0]; |
5633 | 5783 | ||
5634 | store_pin_configs(codec); | ||
5635 | return 1; | 5784 | return 1; |
5636 | } | 5785 | } |
5637 | 5786 | ||
@@ -5668,6 +5817,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { | |||
5668 | [ALC260_ACER] = "acer", | 5817 | [ALC260_ACER] = "acer", |
5669 | [ALC260_WILL] = "will", | 5818 | [ALC260_WILL] = "will", |
5670 | [ALC260_REPLACER_672V] = "replacer", | 5819 | [ALC260_REPLACER_672V] = "replacer", |
5820 | [ALC260_FAVORIT100] = "favorit100", | ||
5671 | #ifdef CONFIG_SND_DEBUG | 5821 | #ifdef CONFIG_SND_DEBUG |
5672 | [ALC260_TEST] = "test", | 5822 | [ALC260_TEST] = "test", |
5673 | #endif | 5823 | #endif |
@@ -5677,6 +5827,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { | |||
5677 | static struct snd_pci_quirk alc260_cfg_tbl[] = { | 5827 | static struct snd_pci_quirk alc260_cfg_tbl[] = { |
5678 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), | 5828 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), |
5679 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), | 5829 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), |
5830 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), | ||
5680 | SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), | 5831 | SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), |
5681 | SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), | 5832 | SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), |
5682 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), | 5833 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), |
@@ -5699,8 +5850,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { | |||
5699 | static struct alc_config_preset alc260_presets[] = { | 5850 | static struct alc_config_preset alc260_presets[] = { |
5700 | [ALC260_BASIC] = { | 5851 | [ALC260_BASIC] = { |
5701 | .mixers = { alc260_base_output_mixer, | 5852 | .mixers = { alc260_base_output_mixer, |
5702 | alc260_input_mixer, | 5853 | alc260_input_mixer }, |
5703 | alc260_pc_beep_mixer }, | ||
5704 | .init_verbs = { alc260_init_verbs }, | 5854 | .init_verbs = { alc260_init_verbs }, |
5705 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | 5855 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), |
5706 | .dac_nids = alc260_dac_nids, | 5856 | .dac_nids = alc260_dac_nids, |
@@ -5779,6 +5929,18 @@ static struct alc_config_preset alc260_presets[] = { | |||
5779 | .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), | 5929 | .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), |
5780 | .input_mux = alc260_acer_capture_sources, | 5930 | .input_mux = alc260_acer_capture_sources, |
5781 | }, | 5931 | }, |
5932 | [ALC260_FAVORIT100] = { | ||
5933 | .mixers = { alc260_favorit100_mixer }, | ||
5934 | .init_verbs = { alc260_favorit100_init_verbs }, | ||
5935 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
5936 | .dac_nids = alc260_dac_nids, | ||
5937 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
5938 | .adc_nids = alc260_dual_adc_nids, | ||
5939 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
5940 | .channel_mode = alc260_modes, | ||
5941 | .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), | ||
5942 | .input_mux = alc260_favorit100_capture_sources, | ||
5943 | }, | ||
5782 | [ALC260_WILL] = { | 5944 | [ALC260_WILL] = { |
5783 | .mixers = { alc260_will_mixer }, | 5945 | .mixers = { alc260_will_mixer }, |
5784 | .init_verbs = { alc260_init_verbs, alc260_will_verbs }, | 5946 | .init_verbs = { alc260_init_verbs, alc260_will_verbs }, |
@@ -5855,6 +6017,12 @@ static int patch_alc260(struct hda_codec *codec) | |||
5855 | } | 6017 | } |
5856 | } | 6018 | } |
5857 | 6019 | ||
6020 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
6021 | if (err < 0) { | ||
6022 | alc_free(codec); | ||
6023 | return err; | ||
6024 | } | ||
6025 | |||
5858 | if (board_config != ALC260_AUTO) | 6026 | if (board_config != ALC260_AUTO) |
5859 | setup_preset(spec, &alc260_presets[board_config]); | 6027 | setup_preset(spec, &alc260_presets[board_config]); |
5860 | 6028 | ||
@@ -5880,6 +6048,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
5880 | } | 6048 | } |
5881 | } | 6049 | } |
5882 | set_capture_mixer(spec); | 6050 | set_capture_mixer(spec); |
6051 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | ||
5883 | 6052 | ||
5884 | spec->vmaster_nid = 0x08; | 6053 | spec->vmaster_nid = 0x08; |
5885 | 6054 | ||
@@ -6051,8 +6220,6 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { | |||
6051 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 6220 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
6052 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | 6221 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), |
6053 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 6222 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
6054 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
6055 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
6056 | { } /* end */ | 6223 | { } /* end */ |
6057 | }; | 6224 | }; |
6058 | 6225 | ||
@@ -6079,8 +6246,6 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = { | |||
6079 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 6246 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
6080 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 6247 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
6081 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 6248 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
6082 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
6083 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
6084 | { } /* end */ | 6249 | { } /* end */ |
6085 | }; | 6250 | }; |
6086 | 6251 | ||
@@ -6132,8 +6297,6 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { | |||
6132 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 6297 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
6133 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 6298 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
6134 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 6299 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
6135 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
6136 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
6137 | { } /* end */ | 6300 | { } /* end */ |
6138 | }; | 6301 | }; |
6139 | 6302 | ||
@@ -6242,8 +6405,10 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = { | |||
6242 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), | 6405 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), |
6243 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), | 6406 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), |
6244 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), | 6407 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), |
6408 | /* FIXME: this looks suspicious... | ||
6245 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), | 6409 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), |
6246 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), | 6410 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), |
6411 | */ | ||
6247 | { } /* end */ | 6412 | { } /* end */ |
6248 | }; | 6413 | }; |
6249 | 6414 | ||
@@ -6875,19 +7040,9 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) | |||
6875 | 7040 | ||
6876 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 7041 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
6877 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 7042 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
6878 | unsigned int vref; | ||
6879 | if (!nid) | 7043 | if (!nid) |
6880 | continue; | 7044 | continue; |
6881 | vref = PIN_IN; | 7045 | alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/); |
6882 | if (1 /*i <= AUTO_PIN_FRONT_MIC*/) { | ||
6883 | unsigned int pincap; | ||
6884 | pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | ||
6885 | if ((pincap >> AC_PINCAP_VREF_SHIFT) & | ||
6886 | AC_PINCAP_VREF_80) | ||
6887 | vref = PIN_VREF80; | ||
6888 | } | ||
6889 | snd_hda_codec_write(codec, nid, 0, | ||
6890 | AC_VERB_SET_PIN_WIDGET_CONTROL, vref); | ||
6891 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) | 7046 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) |
6892 | snd_hda_codec_write(codec, nid, 0, | 7047 | snd_hda_codec_write(codec, nid, 0, |
6893 | AC_VERB_SET_AMP_GAIN_MUTE, | 7048 | AC_VERB_SET_AMP_GAIN_MUTE, |
@@ -6898,18 +7053,21 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) | |||
6898 | static void alc882_auto_init_input_src(struct hda_codec *codec) | 7053 | static void alc882_auto_init_input_src(struct hda_codec *codec) |
6899 | { | 7054 | { |
6900 | struct alc_spec *spec = codec->spec; | 7055 | struct alc_spec *spec = codec->spec; |
6901 | const struct hda_input_mux *imux = spec->input_mux; | ||
6902 | int c; | 7056 | int c; |
6903 | 7057 | ||
6904 | for (c = 0; c < spec->num_adc_nids; c++) { | 7058 | for (c = 0; c < spec->num_adc_nids; c++) { |
6905 | hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; | 7059 | hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; |
6906 | hda_nid_t nid = spec->capsrc_nids[c]; | 7060 | hda_nid_t nid = spec->capsrc_nids[c]; |
7061 | unsigned int mux_idx; | ||
7062 | const struct hda_input_mux *imux; | ||
6907 | int conns, mute, idx, item; | 7063 | int conns, mute, idx, item; |
6908 | 7064 | ||
6909 | conns = snd_hda_get_connections(codec, nid, conn_list, | 7065 | conns = snd_hda_get_connections(codec, nid, conn_list, |
6910 | ARRAY_SIZE(conn_list)); | 7066 | ARRAY_SIZE(conn_list)); |
6911 | if (conns < 0) | 7067 | if (conns < 0) |
6912 | continue; | 7068 | continue; |
7069 | mux_idx = c >= spec->num_mux_defs ? 0 : c; | ||
7070 | imux = &spec->input_mux[mux_idx]; | ||
6913 | for (idx = 0; idx < conns; idx++) { | 7071 | for (idx = 0; idx < conns; idx++) { |
6914 | /* if the current connection is the selected one, | 7072 | /* if the current connection is the selected one, |
6915 | * unmute it as default - otherwise mute it | 7073 | * unmute it as default - otherwise mute it |
@@ -6922,8 +7080,20 @@ static void alc882_auto_init_input_src(struct hda_codec *codec) | |||
6922 | break; | 7080 | break; |
6923 | } | 7081 | } |
6924 | } | 7082 | } |
6925 | snd_hda_codec_write(codec, nid, 0, | 7083 | /* check if we have a selector or mixer |
6926 | AC_VERB_SET_AMP_GAIN_MUTE, mute); | 7084 | * we could check for the widget type instead, but |
7085 | * just check for Amp-In presence (in case of mixer | ||
7086 | * without amp-in there is something wrong, this | ||
7087 | * function shouldn't be used or capsrc nid is wrong) | ||
7088 | */ | ||
7089 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) | ||
7090 | snd_hda_codec_write(codec, nid, 0, | ||
7091 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
7092 | mute); | ||
7093 | else if (mute != AMP_IN_MUTE(idx)) | ||
7094 | snd_hda_codec_write(codec, nid, 0, | ||
7095 | AC_VERB_SET_CONNECT_SEL, | ||
7096 | idx); | ||
6927 | } | 7097 | } |
6928 | } | 7098 | } |
6929 | } | 7099 | } |
@@ -7012,12 +7182,15 @@ static int patch_alc882(struct hda_codec *codec) | |||
7012 | break; | 7182 | break; |
7013 | case 0x106b1000: /* iMac 24 */ | 7183 | case 0x106b1000: /* iMac 24 */ |
7014 | case 0x106b2800: /* AppleTV */ | 7184 | case 0x106b2800: /* AppleTV */ |
7185 | case 0x106b3e00: /* iMac 24 Aluminium */ | ||
7015 | board_config = ALC885_IMAC24; | 7186 | board_config = ALC885_IMAC24; |
7016 | break; | 7187 | break; |
7188 | case 0x106b00a0: /* MacBookPro3,1 - Another revision */ | ||
7017 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ | 7189 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ |
7018 | case 0x106b00a4: /* MacbookPro4,1 */ | 7190 | case 0x106b00a4: /* MacbookPro4,1 */ |
7019 | case 0x106b2c00: /* Macbook Pro rev3 */ | 7191 | case 0x106b2c00: /* Macbook Pro rev3 */ |
7020 | case 0x106b3600: /* Macbook 3.1 */ | 7192 | case 0x106b3600: /* Macbook 3.1 */ |
7193 | case 0x106b3800: /* MacbookPro4,1 - latter revision */ | ||
7021 | board_config = ALC885_MBP3; | 7194 | board_config = ALC885_MBP3; |
7022 | break; | 7195 | break; |
7023 | default: | 7196 | default: |
@@ -7049,6 +7222,12 @@ static int patch_alc882(struct hda_codec *codec) | |||
7049 | } | 7222 | } |
7050 | } | 7223 | } |
7051 | 7224 | ||
7225 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
7226 | if (err < 0) { | ||
7227 | alc_free(codec); | ||
7228 | return err; | ||
7229 | } | ||
7230 | |||
7052 | if (board_config != ALC882_AUTO) | 7231 | if (board_config != ALC882_AUTO) |
7053 | setup_preset(spec, &alc882_presets[board_config]); | 7232 | setup_preset(spec, &alc882_presets[board_config]); |
7054 | 7233 | ||
@@ -7069,7 +7248,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
7069 | spec->stream_digital_playback = &alc882_pcm_digital_playback; | 7248 | spec->stream_digital_playback = &alc882_pcm_digital_playback; |
7070 | spec->stream_digital_capture = &alc882_pcm_digital_capture; | 7249 | spec->stream_digital_capture = &alc882_pcm_digital_capture; |
7071 | 7250 | ||
7072 | spec->is_mix_capture = 1; /* matrix-style capture */ | 7251 | spec->capture_style = CAPT_MIX; /* matrix-style capture */ |
7073 | if (!spec->adc_nids && spec->input_mux) { | 7252 | if (!spec->adc_nids && spec->input_mux) { |
7074 | /* check whether NID 0x07 is valid */ | 7253 | /* check whether NID 0x07 is valid */ |
7075 | unsigned int wcap = get_wcaps(codec, 0x07); | 7254 | unsigned int wcap = get_wcaps(codec, 0x07); |
@@ -7086,6 +7265,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
7086 | } | 7265 | } |
7087 | } | 7266 | } |
7088 | set_capture_mixer(spec); | 7267 | set_capture_mixer(spec); |
7268 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | ||
7089 | 7269 | ||
7090 | spec->vmaster_nid = 0x0c; | 7270 | spec->vmaster_nid = 0x0c; |
7091 | 7271 | ||
@@ -7137,10 +7317,14 @@ static hda_nid_t alc883_adc_nids_rev[2] = { | |||
7137 | 0x09, 0x08 | 7317 | 0x09, 0x08 |
7138 | }; | 7318 | }; |
7139 | 7319 | ||
7320 | #define alc889_adc_nids alc880_adc_nids | ||
7321 | |||
7140 | static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 }; | 7322 | static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 }; |
7141 | 7323 | ||
7142 | static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; | 7324 | static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; |
7143 | 7325 | ||
7326 | #define alc889_capsrc_nids alc882_capsrc_nids | ||
7327 | |||
7144 | /* input MUX */ | 7328 | /* input MUX */ |
7145 | /* FIXME: should be a matrix-type input source selection */ | 7329 | /* FIXME: should be a matrix-type input source selection */ |
7146 | 7330 | ||
@@ -7358,8 +7542,6 @@ static struct snd_kcontrol_new alc883_base_mixer[] = { | |||
7358 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 7542 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
7359 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | 7543 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), |
7360 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 7544 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
7361 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
7362 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
7363 | { } /* end */ | 7545 | { } /* end */ |
7364 | }; | 7546 | }; |
7365 | 7547 | ||
@@ -7422,8 +7604,6 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { | |||
7422 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 7604 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
7423 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | 7605 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), |
7424 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 7606 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
7425 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
7426 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
7427 | { } /* end */ | 7607 | { } /* end */ |
7428 | }; | 7608 | }; |
7429 | 7609 | ||
@@ -7447,8 +7627,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | |||
7447 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 7627 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
7448 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | 7628 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), |
7449 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 7629 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
7450 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
7451 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
7452 | { } /* end */ | 7630 | { } /* end */ |
7453 | }; | 7631 | }; |
7454 | 7632 | ||
@@ -7473,8 +7651,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { | |||
7473 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 7651 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
7474 | HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), | 7652 | HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), |
7475 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 7653 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
7476 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
7477 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
7478 | { } /* end */ | 7654 | { } /* end */ |
7479 | }; | 7655 | }; |
7480 | 7656 | ||
@@ -7498,8 +7674,6 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = { | |||
7498 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 7674 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
7499 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | 7675 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), |
7500 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 7676 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
7501 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
7502 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
7503 | { } /* end */ | 7677 | { } /* end */ |
7504 | }; | 7678 | }; |
7505 | 7679 | ||
@@ -7907,36 +8081,83 @@ static struct hda_verb alc888_lenovo_sky_verbs[] = { | |||
7907 | { } /* end */ | 8081 | { } /* end */ |
7908 | }; | 8082 | }; |
7909 | 8083 | ||
8084 | static struct hda_verb alc888_6st_dell_verbs[] = { | ||
8085 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
8086 | { } | ||
8087 | }; | ||
8088 | |||
8089 | static void alc888_3st_hp_front_automute(struct hda_codec *codec) | ||
8090 | { | ||
8091 | unsigned int present, bits; | ||
8092 | |||
8093 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
8094 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
8095 | bits = present ? HDA_AMP_MUTE : 0; | ||
8096 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
8097 | HDA_AMP_MUTE, bits); | ||
8098 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
8099 | HDA_AMP_MUTE, bits); | ||
8100 | snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, | ||
8101 | HDA_AMP_MUTE, bits); | ||
8102 | } | ||
8103 | |||
8104 | static void alc888_3st_hp_unsol_event(struct hda_codec *codec, | ||
8105 | unsigned int res) | ||
8106 | { | ||
8107 | switch (res >> 26) { | ||
8108 | case ALC880_HP_EVENT: | ||
8109 | alc888_3st_hp_front_automute(codec); | ||
8110 | break; | ||
8111 | } | ||
8112 | } | ||
8113 | |||
7910 | static struct hda_verb alc888_3st_hp_verbs[] = { | 8114 | static struct hda_verb alc888_3st_hp_verbs[] = { |
7911 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ | 8115 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ |
7912 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ | 8116 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ |
7913 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ | 8117 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ |
7914 | { } | ||
7915 | }; | ||
7916 | |||
7917 | static struct hda_verb alc888_6st_dell_verbs[] = { | ||
7918 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 8118 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
7919 | { } | 8119 | { } /* end */ |
7920 | }; | 8120 | }; |
7921 | 8121 | ||
8122 | /* | ||
8123 | * 2ch mode | ||
8124 | */ | ||
7922 | static struct hda_verb alc888_3st_hp_2ch_init[] = { | 8125 | static struct hda_verb alc888_3st_hp_2ch_init[] = { |
7923 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 8126 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
7924 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 8127 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
7925 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 8128 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
7926 | { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 8129 | { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
7927 | { } | 8130 | { } /* end */ |
7928 | }; | 8131 | }; |
7929 | 8132 | ||
8133 | /* | ||
8134 | * 4ch mode | ||
8135 | */ | ||
8136 | static struct hda_verb alc888_3st_hp_4ch_init[] = { | ||
8137 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
8138 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
8139 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
8140 | { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
8141 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
8142 | { } /* end */ | ||
8143 | }; | ||
8144 | |||
8145 | /* | ||
8146 | * 6ch mode | ||
8147 | */ | ||
7930 | static struct hda_verb alc888_3st_hp_6ch_init[] = { | 8148 | static struct hda_verb alc888_3st_hp_6ch_init[] = { |
7931 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8149 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7932 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 8150 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
8151 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
7933 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8152 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7934 | { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 8153 | { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
7935 | { } | 8154 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, |
8155 | { } /* end */ | ||
7936 | }; | 8156 | }; |
7937 | 8157 | ||
7938 | static struct hda_channel_mode alc888_3st_hp_modes[2] = { | 8158 | static struct hda_channel_mode alc888_3st_hp_modes[3] = { |
7939 | { 2, alc888_3st_hp_2ch_init }, | 8159 | { 2, alc888_3st_hp_2ch_init }, |
8160 | { 4, alc888_3st_hp_4ch_init }, | ||
7940 | { 6, alc888_3st_hp_6ch_init }, | 8161 | { 6, alc888_3st_hp_6ch_init }, |
7941 | }; | 8162 | }; |
7942 | 8163 | ||
@@ -8197,7 +8418,7 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec, | |||
8197 | { | 8418 | { |
8198 | switch (res >> 26) { | 8419 | switch (res >> 26) { |
8199 | case ALC880_HP_EVENT: | 8420 | case ALC880_HP_EVENT: |
8200 | printk("hp_event\n"); | 8421 | /* printk(KERN_DEBUG "hp_event\n"); */ |
8201 | alc888_6st_dell_front_automute(codec); | 8422 | alc888_6st_dell_front_automute(codec); |
8202 | break; | 8423 | break; |
8203 | } | 8424 | } |
@@ -8456,6 +8677,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8456 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), | 8677 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), |
8457 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), | 8678 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), |
8458 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), | 8679 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), |
8680 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), | ||
8459 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), | 8681 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), |
8460 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), | 8682 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), |
8461 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), | 8683 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), |
@@ -8463,21 +8685,29 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8463 | ALC888_ACER_ASPIRE_4930G), | 8685 | ALC888_ACER_ASPIRE_4930G), |
8464 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", | 8686 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", |
8465 | ALC888_ACER_ASPIRE_4930G), | 8687 | ALC888_ACER_ASPIRE_4930G), |
8688 | SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), | ||
8689 | SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), | ||
8466 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", | 8690 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", |
8467 | ALC888_ACER_ASPIRE_4930G), | 8691 | ALC888_ACER_ASPIRE_4930G), |
8468 | SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ | 8692 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", |
8693 | ALC888_ACER_ASPIRE_4930G), | ||
8694 | /* default Acer */ | ||
8695 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), | ||
8469 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), | 8696 | SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), |
8470 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), | 8697 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), |
8471 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), | 8698 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), |
8472 | SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), | 8699 | SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), |
8473 | SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), | 8700 | SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), |
8474 | SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), | 8701 | SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), |
8702 | SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), | ||
8475 | SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), | 8703 | SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), |
8476 | SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), | 8704 | SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), |
8705 | SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), | ||
8477 | SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), | 8706 | SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), |
8478 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), | 8707 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), |
8479 | SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), | 8708 | SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), |
8480 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), | 8709 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), |
8710 | SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), | ||
8481 | SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), | 8711 | SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), |
8482 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), | 8712 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), |
8483 | SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), | 8713 | SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), |
@@ -8509,9 +8739,11 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8509 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), | 8739 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), |
8510 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), | 8740 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), |
8511 | SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), | 8741 | SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), |
8512 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), | 8742 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), |
8513 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), | 8743 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), |
8514 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), | 8744 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), |
8745 | SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550", | ||
8746 | ALC883_FUJITSU_PI2515), | ||
8515 | SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), | 8747 | SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), |
8516 | SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", | 8748 | SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", |
8517 | ALC888_FUJITSU_XA3530), | 8749 | ALC888_FUJITSU_XA3530), |
@@ -8526,11 +8758,20 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
8526 | SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), | 8758 | SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), |
8527 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), | 8759 | SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), |
8528 | SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), | 8760 | SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), |
8761 | SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), | ||
8529 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), | 8762 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), |
8530 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), | 8763 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), |
8531 | {} | 8764 | {} |
8532 | }; | 8765 | }; |
8533 | 8766 | ||
8767 | static hda_nid_t alc883_slave_dig_outs[] = { | ||
8768 | ALC1200_DIGOUT_NID, 0, | ||
8769 | }; | ||
8770 | |||
8771 | static hda_nid_t alc1200_slave_dig_outs[] = { | ||
8772 | ALC883_DIGOUT_NID, 0, | ||
8773 | }; | ||
8774 | |||
8534 | static struct alc_config_preset alc883_presets[] = { | 8775 | static struct alc_config_preset alc883_presets[] = { |
8535 | [ALC883_3ST_2ch_DIG] = { | 8776 | [ALC883_3ST_2ch_DIG] = { |
8536 | .mixers = { alc883_3ST_2ch_mixer }, | 8777 | .mixers = { alc883_3ST_2ch_mixer }, |
@@ -8572,6 +8813,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
8572 | .dac_nids = alc883_dac_nids, | 8813 | .dac_nids = alc883_dac_nids, |
8573 | .dig_out_nid = ALC883_DIGOUT_NID, | 8814 | .dig_out_nid = ALC883_DIGOUT_NID, |
8574 | .dig_in_nid = ALC883_DIGIN_NID, | 8815 | .dig_in_nid = ALC883_DIGIN_NID, |
8816 | .slave_dig_outs = alc883_slave_dig_outs, | ||
8575 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), | 8817 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), |
8576 | .channel_mode = alc883_3ST_6ch_intel_modes, | 8818 | .channel_mode = alc883_3ST_6ch_intel_modes, |
8577 | .need_dac_fix = 1, | 8819 | .need_dac_fix = 1, |
@@ -8766,6 +9008,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
8766 | .channel_mode = alc888_3st_hp_modes, | 9008 | .channel_mode = alc888_3st_hp_modes, |
8767 | .need_dac_fix = 1, | 9009 | .need_dac_fix = 1, |
8768 | .input_mux = &alc883_capture_source, | 9010 | .input_mux = &alc883_capture_source, |
9011 | .unsol_event = alc888_3st_hp_unsol_event, | ||
9012 | .init_hook = alc888_3st_hp_front_automute, | ||
8769 | }, | 9013 | }, |
8770 | [ALC888_6ST_DELL] = { | 9014 | [ALC888_6ST_DELL] = { |
8771 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 9015 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
@@ -8871,6 +9115,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
8871 | .dac_nids = alc883_dac_nids, | 9115 | .dac_nids = alc883_dac_nids, |
8872 | .dig_out_nid = ALC1200_DIGOUT_NID, | 9116 | .dig_out_nid = ALC1200_DIGOUT_NID, |
8873 | .dig_in_nid = ALC883_DIGIN_NID, | 9117 | .dig_in_nid = ALC883_DIGIN_NID, |
9118 | .slave_dig_outs = alc1200_slave_dig_outs, | ||
8874 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | 9119 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), |
8875 | .channel_mode = alc883_sixstack_modes, | 9120 | .channel_mode = alc883_sixstack_modes, |
8876 | .input_mux = &alc883_capture_source, | 9121 | .input_mux = &alc883_capture_source, |
@@ -8938,11 +9183,9 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec) | |||
8938 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 9183 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
8939 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 9184 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
8940 | if (alc883_is_input_pin(nid)) { | 9185 | if (alc883_is_input_pin(nid)) { |
8941 | snd_hda_codec_write(codec, nid, 0, | 9186 | alc_set_input_pin(codec, nid, i); |
8942 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 9187 | if (nid != ALC883_PIN_CD_NID && |
8943 | (i <= AUTO_PIN_FRONT_MIC ? | 9188 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
8944 | PIN_VREF80 : PIN_IN)); | ||
8945 | if (nid != ALC883_PIN_CD_NID) | ||
8946 | snd_hda_codec_write(codec, nid, 0, | 9189 | snd_hda_codec_write(codec, nid, 0, |
8947 | AC_VERB_SET_AMP_GAIN_MUTE, | 9190 | AC_VERB_SET_AMP_GAIN_MUTE, |
8948 | AMP_OUT_MUTE); | 9191 | AMP_OUT_MUTE); |
@@ -8957,6 +9200,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec) | |||
8957 | { | 9200 | { |
8958 | struct alc_spec *spec = codec->spec; | 9201 | struct alc_spec *spec = codec->spec; |
8959 | int err = alc880_parse_auto_config(codec); | 9202 | int err = alc880_parse_auto_config(codec); |
9203 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
9204 | int i; | ||
8960 | 9205 | ||
8961 | if (err < 0) | 9206 | if (err < 0) |
8962 | return err; | 9207 | return err; |
@@ -8970,6 +9215,26 @@ static int alc883_parse_auto_config(struct hda_codec *codec) | |||
8970 | /* hack - override the init verbs */ | 9215 | /* hack - override the init verbs */ |
8971 | spec->init_verbs[0] = alc883_auto_init_verbs; | 9216 | spec->init_verbs[0] = alc883_auto_init_verbs; |
8972 | 9217 | ||
9218 | /* setup input_mux for ALC889 */ | ||
9219 | if (codec->vendor_id == 0x10ec0889) { | ||
9220 | /* digital-mic input pin is excluded in alc880_auto_create..() | ||
9221 | * because it's under 0x18 | ||
9222 | */ | ||
9223 | if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || | ||
9224 | cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { | ||
9225 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
9226 | for (i = 1; i < 3; i++) | ||
9227 | memcpy(&spec->private_imux[i], | ||
9228 | &spec->private_imux[0], | ||
9229 | sizeof(spec->private_imux[0])); | ||
9230 | imux->items[imux->num_items].label = "Int DMic"; | ||
9231 | imux->items[imux->num_items].index = 0x0b; | ||
9232 | imux->num_items++; | ||
9233 | spec->num_mux_defs = 3; | ||
9234 | spec->input_mux = spec->private_imux; | ||
9235 | } | ||
9236 | } | ||
9237 | |||
8973 | return 1; /* config found */ | 9238 | return 1; /* config found */ |
8974 | } | 9239 | } |
8975 | 9240 | ||
@@ -9021,6 +9286,12 @@ static int patch_alc883(struct hda_codec *codec) | |||
9021 | } | 9286 | } |
9022 | } | 9287 | } |
9023 | 9288 | ||
9289 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
9290 | if (err < 0) { | ||
9291 | alc_free(codec); | ||
9292 | return err; | ||
9293 | } | ||
9294 | |||
9024 | if (board_config != ALC883_AUTO) | 9295 | if (board_config != ALC883_AUTO) |
9025 | setup_preset(spec, &alc883_presets[board_config]); | 9296 | setup_preset(spec, &alc883_presets[board_config]); |
9026 | 9297 | ||
@@ -9033,14 +9304,36 @@ static int patch_alc883(struct hda_codec *codec) | |||
9033 | spec->stream_name_analog = "ALC888 Analog"; | 9304 | spec->stream_name_analog = "ALC888 Analog"; |
9034 | spec->stream_name_digital = "ALC888 Digital"; | 9305 | spec->stream_name_digital = "ALC888 Digital"; |
9035 | } | 9306 | } |
9307 | if (!spec->num_adc_nids) { | ||
9308 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | ||
9309 | spec->adc_nids = alc883_adc_nids; | ||
9310 | } | ||
9311 | if (!spec->capsrc_nids) | ||
9312 | spec->capsrc_nids = alc883_capsrc_nids; | ||
9313 | spec->capture_style = CAPT_MIX; /* matrix-style capture */ | ||
9036 | break; | 9314 | break; |
9037 | case 0x10ec0889: | 9315 | case 0x10ec0889: |
9038 | spec->stream_name_analog = "ALC889 Analog"; | 9316 | spec->stream_name_analog = "ALC889 Analog"; |
9039 | spec->stream_name_digital = "ALC889 Digital"; | 9317 | spec->stream_name_digital = "ALC889 Digital"; |
9318 | if (!spec->num_adc_nids) { | ||
9319 | spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); | ||
9320 | spec->adc_nids = alc889_adc_nids; | ||
9321 | } | ||
9322 | if (!spec->capsrc_nids) | ||
9323 | spec->capsrc_nids = alc889_capsrc_nids; | ||
9324 | spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style | ||
9325 | capture */ | ||
9040 | break; | 9326 | break; |
9041 | default: | 9327 | default: |
9042 | spec->stream_name_analog = "ALC883 Analog"; | 9328 | spec->stream_name_analog = "ALC883 Analog"; |
9043 | spec->stream_name_digital = "ALC883 Digital"; | 9329 | spec->stream_name_digital = "ALC883 Digital"; |
9330 | if (!spec->num_adc_nids) { | ||
9331 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | ||
9332 | spec->adc_nids = alc883_adc_nids; | ||
9333 | } | ||
9334 | if (!spec->capsrc_nids) | ||
9335 | spec->capsrc_nids = alc883_capsrc_nids; | ||
9336 | spec->capture_style = CAPT_MIX; /* matrix-style capture */ | ||
9044 | break; | 9337 | break; |
9045 | } | 9338 | } |
9046 | 9339 | ||
@@ -9051,15 +9344,9 @@ static int patch_alc883(struct hda_codec *codec) | |||
9051 | spec->stream_digital_playback = &alc883_pcm_digital_playback; | 9344 | spec->stream_digital_playback = &alc883_pcm_digital_playback; |
9052 | spec->stream_digital_capture = &alc883_pcm_digital_capture; | 9345 | spec->stream_digital_capture = &alc883_pcm_digital_capture; |
9053 | 9346 | ||
9054 | if (!spec->num_adc_nids) { | ||
9055 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | ||
9056 | spec->adc_nids = alc883_adc_nids; | ||
9057 | } | ||
9058 | if (!spec->capsrc_nids) | ||
9059 | spec->capsrc_nids = alc883_capsrc_nids; | ||
9060 | spec->is_mix_capture = 1; /* matrix-style capture */ | ||
9061 | if (!spec->cap_mixer) | 9347 | if (!spec->cap_mixer) |
9062 | set_capture_mixer(spec); | 9348 | set_capture_mixer(spec); |
9349 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | ||
9063 | 9350 | ||
9064 | spec->vmaster_nid = 0x0c; | 9351 | spec->vmaster_nid = 0x0c; |
9065 | 9352 | ||
@@ -9112,8 +9399,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
9112 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 9399 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
9113 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | 9400 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), |
9114 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | 9401 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), |
9115 | /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
9116 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ | ||
9117 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), | 9402 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), |
9118 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 9403 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
9119 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 9404 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
@@ -9134,8 +9419,6 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { | |||
9134 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 9419 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
9135 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | 9420 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), |
9136 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | 9421 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), |
9137 | /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
9138 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ | ||
9139 | /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ | 9422 | /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ |
9140 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 9423 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
9141 | { } /* end */ | 9424 | { } /* end */ |
@@ -9244,8 +9527,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | |||
9244 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 9527 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
9245 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 9528 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
9246 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 9529 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
9247 | HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
9248 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
9249 | HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), | 9530 | HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), |
9250 | HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), | 9531 | HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), |
9251 | { } /* end */ | 9532 | { } /* end */ |
@@ -9274,8 +9555,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { | |||
9274 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), | 9555 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), |
9275 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 9556 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
9276 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 9557 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
9277 | HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
9278 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
9279 | { } /* end */ | 9558 | { } /* end */ |
9280 | }; | 9559 | }; |
9281 | 9560 | ||
@@ -9423,6 +9702,67 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { | |||
9423 | { } /* end */ | 9702 | { } /* end */ |
9424 | }; | 9703 | }; |
9425 | 9704 | ||
9705 | static struct snd_kcontrol_new alc262_tyan_mixer[] = { | ||
9706 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
9707 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), | ||
9708 | HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), | ||
9709 | HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), | ||
9710 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
9711 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
9712 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
9713 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
9714 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
9715 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
9716 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
9717 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
9718 | { } /* end */ | ||
9719 | }; | ||
9720 | |||
9721 | static struct hda_verb alc262_tyan_verbs[] = { | ||
9722 | /* Headphone automute */ | ||
9723 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
9724 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
9725 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
9726 | |||
9727 | /* P11 AUX_IN, white 4-pin connector */ | ||
9728 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
9729 | {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, | ||
9730 | {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, | ||
9731 | {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, | ||
9732 | |||
9733 | {} | ||
9734 | }; | ||
9735 | |||
9736 | /* unsolicited event for HP jack sensing */ | ||
9737 | static void alc262_tyan_automute(struct hda_codec *codec) | ||
9738 | { | ||
9739 | unsigned int mute; | ||
9740 | unsigned int present; | ||
9741 | |||
9742 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
9743 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
9744 | AC_VERB_GET_PIN_SENSE, 0); | ||
9745 | present = (present & 0x80000000) != 0; | ||
9746 | if (present) { | ||
9747 | /* mute line output on ATX panel */ | ||
9748 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
9749 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
9750 | } else { | ||
9751 | /* unmute line output if necessary */ | ||
9752 | mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); | ||
9753 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
9754 | HDA_AMP_MUTE, mute); | ||
9755 | } | ||
9756 | } | ||
9757 | |||
9758 | static void alc262_tyan_unsol_event(struct hda_codec *codec, | ||
9759 | unsigned int res) | ||
9760 | { | ||
9761 | if ((res >> 26) != ALC880_HP_EVENT) | ||
9762 | return; | ||
9763 | alc262_tyan_automute(codec); | ||
9764 | } | ||
9765 | |||
9426 | #define alc262_capture_mixer alc882_capture_mixer | 9766 | #define alc262_capture_mixer alc882_capture_mixer |
9427 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer | 9767 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer |
9428 | 9768 | ||
@@ -9889,8 +10229,6 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { | |||
9889 | }, | 10229 | }, |
9890 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 10230 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
9891 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 10231 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
9892 | HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT), | ||
9893 | HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT), | ||
9894 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 10232 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
9895 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 10233 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
9896 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 10234 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
@@ -10462,8 +10800,14 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
10462 | alc262_ignore); | 10800 | alc262_ignore); |
10463 | if (err < 0) | 10801 | if (err < 0) |
10464 | return err; | 10802 | return err; |
10465 | if (!spec->autocfg.line_outs) | 10803 | if (!spec->autocfg.line_outs) { |
10804 | if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { | ||
10805 | spec->multiout.max_channels = 2; | ||
10806 | spec->no_analog = 1; | ||
10807 | goto dig_only; | ||
10808 | } | ||
10466 | return 0; /* can't find valid BIOS pin config */ | 10809 | return 0; /* can't find valid BIOS pin config */ |
10810 | } | ||
10467 | err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); | 10811 | err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); |
10468 | if (err < 0) | 10812 | if (err < 0) |
10469 | return err; | 10813 | return err; |
@@ -10473,8 +10817,11 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
10473 | 10817 | ||
10474 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 10818 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
10475 | 10819 | ||
10476 | if (spec->autocfg.dig_out_pin) | 10820 | dig_only: |
10821 | if (spec->autocfg.dig_outs) { | ||
10477 | spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; | 10822 | spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; |
10823 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
10824 | } | ||
10478 | if (spec->autocfg.dig_in_pin) | 10825 | if (spec->autocfg.dig_in_pin) |
10479 | spec->dig_in_nid = ALC262_DIGIN_NID; | 10826 | spec->dig_in_nid = ALC262_DIGIN_NID; |
10480 | 10827 | ||
@@ -10483,13 +10830,12 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
10483 | 10830 | ||
10484 | add_verb(spec, alc262_volume_init_verbs); | 10831 | add_verb(spec, alc262_volume_init_verbs); |
10485 | spec->num_mux_defs = 1; | 10832 | spec->num_mux_defs = 1; |
10486 | spec->input_mux = &spec->private_imux; | 10833 | spec->input_mux = &spec->private_imux[0]; |
10487 | 10834 | ||
10488 | err = alc_auto_add_mic_boost(codec); | 10835 | err = alc_auto_add_mic_boost(codec); |
10489 | if (err < 0) | 10836 | if (err < 0) |
10490 | return err; | 10837 | return err; |
10491 | 10838 | ||
10492 | store_pin_configs(codec); | ||
10493 | return 1; | 10839 | return 1; |
10494 | } | 10840 | } |
10495 | 10841 | ||
@@ -10531,20 +10877,19 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { | |||
10531 | [ALC262_ULTRA] = "ultra", | 10877 | [ALC262_ULTRA] = "ultra", |
10532 | [ALC262_LENOVO_3000] = "lenovo-3000", | 10878 | [ALC262_LENOVO_3000] = "lenovo-3000", |
10533 | [ALC262_NEC] = "nec", | 10879 | [ALC262_NEC] = "nec", |
10880 | [ALC262_TYAN] = "tyan", | ||
10534 | [ALC262_AUTO] = "auto", | 10881 | [ALC262_AUTO] = "auto", |
10535 | }; | 10882 | }; |
10536 | 10883 | ||
10537 | static struct snd_pci_quirk alc262_cfg_tbl[] = { | 10884 | static struct snd_pci_quirk alc262_cfg_tbl[] = { |
10538 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), | 10885 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), |
10539 | SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), | 10886 | SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), |
10540 | SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), | 10887 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", |
10541 | SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), | 10888 | ALC262_HP_BPC), |
10542 | SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), | 10889 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", |
10543 | SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), | 10890 | ALC262_HP_BPC), |
10544 | SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), | 10891 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", |
10545 | SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC), | 10892 | ALC262_HP_BPC), |
10546 | SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC), | ||
10547 | SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC), | ||
10548 | SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), | 10893 | SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), |
10549 | SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), | 10894 | SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), |
10550 | SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), | 10895 | SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), |
@@ -10562,17 +10907,18 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { | |||
10562 | SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), | 10907 | SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), |
10563 | SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), | 10908 | SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), |
10564 | SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), | 10909 | SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), |
10565 | SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), | 10910 | SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ |
10566 | SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), | 10911 | SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", |
10567 | SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN", | 10912 | ALC262_SONY_ASSAMD), |
10568 | ALC262_SONY_ASSAMD), | ||
10569 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", | 10913 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", |
10570 | ALC262_TOSHIBA_RX1), | 10914 | ALC262_TOSHIBA_RX1), |
10571 | SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), | 10915 | SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), |
10572 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), | 10916 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), |
10573 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), | 10917 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), |
10574 | SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), | 10918 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), |
10575 | SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA), | 10919 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", |
10920 | ALC262_ULTRA), | ||
10921 | SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), | ||
10576 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), | 10922 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), |
10577 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), | 10923 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), |
10578 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), | 10924 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), |
@@ -10788,6 +11134,19 @@ static struct alc_config_preset alc262_presets[] = { | |||
10788 | .unsol_event = alc262_hippo_unsol_event, | 11134 | .unsol_event = alc262_hippo_unsol_event, |
10789 | .init_hook = alc262_hippo_automute, | 11135 | .init_hook = alc262_hippo_automute, |
10790 | }, | 11136 | }, |
11137 | [ALC262_TYAN] = { | ||
11138 | .mixers = { alc262_tyan_mixer }, | ||
11139 | .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, | ||
11140 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
11141 | .dac_nids = alc262_dac_nids, | ||
11142 | .hp_nid = 0x02, | ||
11143 | .dig_out_nid = ALC262_DIGOUT_NID, | ||
11144 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
11145 | .channel_mode = alc262_modes, | ||
11146 | .input_mux = &alc262_capture_source, | ||
11147 | .unsol_event = alc262_tyan_unsol_event, | ||
11148 | .init_hook = alc262_tyan_automute, | ||
11149 | }, | ||
10791 | }; | 11150 | }; |
10792 | 11151 | ||
10793 | static int patch_alc262(struct hda_codec *codec) | 11152 | static int patch_alc262(struct hda_codec *codec) |
@@ -10840,6 +11199,14 @@ static int patch_alc262(struct hda_codec *codec) | |||
10840 | } | 11199 | } |
10841 | } | 11200 | } |
10842 | 11201 | ||
11202 | if (!spec->no_analog) { | ||
11203 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
11204 | if (err < 0) { | ||
11205 | alc_free(codec); | ||
11206 | return err; | ||
11207 | } | ||
11208 | } | ||
11209 | |||
10843 | if (board_config != ALC262_AUTO) | 11210 | if (board_config != ALC262_AUTO) |
10844 | setup_preset(spec, &alc262_presets[board_config]); | 11211 | setup_preset(spec, &alc262_presets[board_config]); |
10845 | 11212 | ||
@@ -10851,7 +11218,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
10851 | spec->stream_digital_playback = &alc262_pcm_digital_playback; | 11218 | spec->stream_digital_playback = &alc262_pcm_digital_playback; |
10852 | spec->stream_digital_capture = &alc262_pcm_digital_capture; | 11219 | spec->stream_digital_capture = &alc262_pcm_digital_capture; |
10853 | 11220 | ||
10854 | spec->is_mix_capture = 1; | 11221 | spec->capture_style = CAPT_MIX; |
10855 | if (!spec->adc_nids && spec->input_mux) { | 11222 | if (!spec->adc_nids && spec->input_mux) { |
10856 | /* check whether NID 0x07 is valid */ | 11223 | /* check whether NID 0x07 is valid */ |
10857 | unsigned int wcap = get_wcaps(codec, 0x07); | 11224 | unsigned int wcap = get_wcaps(codec, 0x07); |
@@ -10868,8 +11235,10 @@ static int patch_alc262(struct hda_codec *codec) | |||
10868 | spec->capsrc_nids = alc262_capsrc_nids; | 11235 | spec->capsrc_nids = alc262_capsrc_nids; |
10869 | } | 11236 | } |
10870 | } | 11237 | } |
10871 | if (!spec->cap_mixer) | 11238 | if (!spec->cap_mixer && !spec->no_analog) |
10872 | set_capture_mixer(spec); | 11239 | set_capture_mixer(spec); |
11240 | if (!spec->no_analog) | ||
11241 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | ||
10873 | 11242 | ||
10874 | spec->vmaster_nid = 0x0c; | 11243 | spec->vmaster_nid = 0x0c; |
10875 | 11244 | ||
@@ -11249,19 +11618,13 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, | |||
11249 | static struct hda_verb alc268_base_init_verbs[] = { | 11618 | static struct hda_verb alc268_base_init_verbs[] = { |
11250 | /* Unmute DAC0-1 and set vol = 0 */ | 11619 | /* Unmute DAC0-1 and set vol = 0 */ |
11251 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 11620 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
11252 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
11253 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
11254 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 11621 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
11255 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
11256 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
11257 | 11622 | ||
11258 | /* | 11623 | /* |
11259 | * Set up output mixers (0x0c - 0x0e) | 11624 | * Set up output mixers (0x0c - 0x0e) |
11260 | */ | 11625 | */ |
11261 | /* set vol=0 to output mixers */ | 11626 | /* set vol=0 to output mixers */ |
11262 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11627 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
11263 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
11264 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
11265 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, | 11628 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, |
11266 | 11629 | ||
11267 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11630 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -11280,9 +11643,7 @@ static struct hda_verb alc268_base_init_verbs[] = { | |||
11280 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 11643 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
11281 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 11644 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
11282 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 11645 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
11283 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
11284 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 11646 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
11285 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
11286 | 11647 | ||
11287 | /* set PCBEEP vol = 0, mute connections */ | 11648 | /* set PCBEEP vol = 0, mute connections */ |
11288 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11649 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -11304,10 +11665,8 @@ static struct hda_verb alc268_base_init_verbs[] = { | |||
11304 | */ | 11665 | */ |
11305 | static struct hda_verb alc268_volume_init_verbs[] = { | 11666 | static struct hda_verb alc268_volume_init_verbs[] = { |
11306 | /* set output DAC */ | 11667 | /* set output DAC */ |
11307 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11668 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
11308 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 11669 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
11309 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
11310 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
11311 | 11670 | ||
11312 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | 11671 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, |
11313 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | 11672 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, |
@@ -11315,16 +11674,12 @@ static struct hda_verb alc268_volume_init_verbs[] = { | |||
11315 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | 11674 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, |
11316 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | 11675 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, |
11317 | 11676 | ||
11318 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
11319 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11677 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
11320 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
11321 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11678 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
11322 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11679 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
11323 | 11680 | ||
11324 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 11681 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
11325 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
11326 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 11682 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
11327 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
11328 | 11683 | ||
11329 | /* set PCBEEP vol = 0, mute connections */ | 11684 | /* set PCBEEP vol = 0, mute connections */ |
11330 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 11685 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -11523,7 +11878,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
11523 | static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, | 11878 | static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, |
11524 | const struct auto_pin_cfg *cfg) | 11879 | const struct auto_pin_cfg *cfg) |
11525 | { | 11880 | { |
11526 | struct hda_input_mux *imux = &spec->private_imux; | 11881 | struct hda_input_mux *imux = &spec->private_imux[0]; |
11527 | int i, idx1; | 11882 | int i, idx1; |
11528 | 11883 | ||
11529 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 11884 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
@@ -11617,9 +11972,14 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
11617 | alc268_ignore); | 11972 | alc268_ignore); |
11618 | if (err < 0) | 11973 | if (err < 0) |
11619 | return err; | 11974 | return err; |
11620 | if (!spec->autocfg.line_outs) | 11975 | if (!spec->autocfg.line_outs) { |
11976 | if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { | ||
11977 | spec->multiout.max_channels = 2; | ||
11978 | spec->no_analog = 1; | ||
11979 | goto dig_only; | ||
11980 | } | ||
11621 | return 0; /* can't find valid BIOS pin config */ | 11981 | return 0; /* can't find valid BIOS pin config */ |
11622 | 11982 | } | |
11623 | err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); | 11983 | err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); |
11624 | if (err < 0) | 11984 | if (err < 0) |
11625 | return err; | 11985 | return err; |
@@ -11629,25 +11989,26 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
11629 | 11989 | ||
11630 | spec->multiout.max_channels = 2; | 11990 | spec->multiout.max_channels = 2; |
11631 | 11991 | ||
11992 | dig_only: | ||
11632 | /* digital only support output */ | 11993 | /* digital only support output */ |
11633 | if (spec->autocfg.dig_out_pin) | 11994 | if (spec->autocfg.dig_outs) { |
11634 | spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; | 11995 | spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; |
11635 | 11996 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | |
11997 | } | ||
11636 | if (spec->kctls.list) | 11998 | if (spec->kctls.list) |
11637 | add_mixer(spec, spec->kctls.list); | 11999 | add_mixer(spec, spec->kctls.list); |
11638 | 12000 | ||
11639 | if (spec->autocfg.speaker_pins[0] != 0x1d) | 12001 | if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) |
11640 | add_mixer(spec, alc268_beep_mixer); | 12002 | add_mixer(spec, alc268_beep_mixer); |
11641 | 12003 | ||
11642 | add_verb(spec, alc268_volume_init_verbs); | 12004 | add_verb(spec, alc268_volume_init_verbs); |
11643 | spec->num_mux_defs = 1; | 12005 | spec->num_mux_defs = 1; |
11644 | spec->input_mux = &spec->private_imux; | 12006 | spec->input_mux = &spec->private_imux[0]; |
11645 | 12007 | ||
11646 | err = alc_auto_add_mic_boost(codec); | 12008 | err = alc_auto_add_mic_boost(codec); |
11647 | if (err < 0) | 12009 | if (err < 0) |
11648 | return err; | 12010 | return err; |
11649 | 12011 | ||
11650 | store_pin_configs(codec); | ||
11651 | return 1; | 12012 | return 1; |
11652 | } | 12013 | } |
11653 | 12014 | ||
@@ -11709,7 +12070,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { | |||
11709 | 12070 | ||
11710 | static struct alc_config_preset alc268_presets[] = { | 12071 | static struct alc_config_preset alc268_presets[] = { |
11711 | [ALC267_QUANTA_IL1] = { | 12072 | [ALC267_QUANTA_IL1] = { |
11712 | .mixers = { alc267_quanta_il1_mixer }, | 12073 | .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer }, |
11713 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | 12074 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, |
11714 | alc267_quanta_il1_verbs }, | 12075 | alc267_quanta_il1_verbs }, |
11715 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | 12076 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), |
@@ -11791,7 +12152,8 @@ static struct alc_config_preset alc268_presets[] = { | |||
11791 | }, | 12152 | }, |
11792 | [ALC268_ACER_ASPIRE_ONE] = { | 12153 | [ALC268_ACER_ASPIRE_ONE] = { |
11793 | .mixers = { alc268_acer_aspire_one_mixer, | 12154 | .mixers = { alc268_acer_aspire_one_mixer, |
11794 | alc268_capture_alt_mixer }, | 12155 | alc268_beep_mixer, |
12156 | alc268_capture_alt_mixer }, | ||
11795 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | 12157 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, |
11796 | alc268_acer_aspire_one_verbs }, | 12158 | alc268_acer_aspire_one_verbs }, |
11797 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | 12159 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), |
@@ -11860,7 +12222,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
11860 | { | 12222 | { |
11861 | struct alc_spec *spec; | 12223 | struct alc_spec *spec; |
11862 | int board_config; | 12224 | int board_config; |
11863 | int err; | 12225 | int i, has_beep, err; |
11864 | 12226 | ||
11865 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | 12227 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); |
11866 | if (spec == NULL) | 12228 | if (spec == NULL) |
@@ -11909,15 +12271,30 @@ static int patch_alc268(struct hda_codec *codec) | |||
11909 | 12271 | ||
11910 | spec->stream_digital_playback = &alc268_pcm_digital_playback; | 12272 | spec->stream_digital_playback = &alc268_pcm_digital_playback; |
11911 | 12273 | ||
11912 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) | 12274 | has_beep = 0; |
11913 | /* override the amp caps for beep generator */ | 12275 | for (i = 0; i < spec->num_mixers; i++) { |
11914 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, | 12276 | if (spec->mixers[i] == alc268_beep_mixer) { |
12277 | has_beep = 1; | ||
12278 | break; | ||
12279 | } | ||
12280 | } | ||
12281 | |||
12282 | if (has_beep) { | ||
12283 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
12284 | if (err < 0) { | ||
12285 | alc_free(codec); | ||
12286 | return err; | ||
12287 | } | ||
12288 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) | ||
12289 | /* override the amp caps for beep generator */ | ||
12290 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, | ||
11915 | (0x0c << AC_AMPCAP_OFFSET_SHIFT) | | 12291 | (0x0c << AC_AMPCAP_OFFSET_SHIFT) | |
11916 | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | | 12292 | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | |
11917 | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 12293 | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
11918 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 12294 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
12295 | } | ||
11919 | 12296 | ||
11920 | if (!spec->adc_nids && spec->input_mux) { | 12297 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { |
11921 | /* check whether NID 0x07 is valid */ | 12298 | /* check whether NID 0x07 is valid */ |
11922 | unsigned int wcap = get_wcaps(codec, 0x07); | 12299 | unsigned int wcap = get_wcaps(codec, 0x07); |
11923 | int i; | 12300 | int i; |
@@ -11998,8 +12375,6 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { | |||
11998 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 12375 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
11999 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 12376 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
12000 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 12377 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
12001 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT), | ||
12002 | HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT), | ||
12003 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | 12378 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), |
12004 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 12379 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
12005 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | 12380 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), |
@@ -12026,8 +12401,6 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { | |||
12026 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 12401 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
12027 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | 12402 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), |
12028 | HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), | 12403 | HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), |
12029 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
12030 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
12031 | { } | 12404 | { } |
12032 | }; | 12405 | }; |
12033 | 12406 | ||
@@ -12051,8 +12424,6 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { | |||
12051 | HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), | 12424 | HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), |
12052 | HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), | 12425 | HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), |
12053 | HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), | 12426 | HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), |
12054 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
12055 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
12056 | { } | 12427 | { } |
12057 | }; | 12428 | }; |
12058 | 12429 | ||
@@ -12089,13 +12460,6 @@ static struct snd_kcontrol_new alc269_fujitsu_mixer[] = { | |||
12089 | { } /* end */ | 12460 | { } /* end */ |
12090 | }; | 12461 | }; |
12091 | 12462 | ||
12092 | /* beep control */ | ||
12093 | static struct snd_kcontrol_new alc269_beep_mixer[] = { | ||
12094 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT), | ||
12095 | HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT), | ||
12096 | { } /* end */ | ||
12097 | }; | ||
12098 | |||
12099 | static struct hda_verb alc269_quanta_fl1_verbs[] = { | 12463 | static struct hda_verb alc269_quanta_fl1_verbs[] = { |
12100 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 12464 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
12101 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 12465 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
@@ -12495,7 +12859,7 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
12495 | */ | 12859 | */ |
12496 | if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || | 12860 | if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || |
12497 | cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { | 12861 | cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { |
12498 | struct hda_input_mux *imux = &spec->private_imux; | 12862 | struct hda_input_mux *imux = &spec->private_imux[0]; |
12499 | imux->items[imux->num_items].label = "Int Mic"; | 12863 | imux->items[imux->num_items].label = "Int Mic"; |
12500 | imux->items[imux->num_items].index = 0x05; | 12864 | imux->items[imux->num_items].index = 0x05; |
12501 | imux->num_items++; | 12865 | imux->num_items++; |
@@ -12513,13 +12877,34 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, | |||
12513 | #define alc269_pcm_digital_playback alc880_pcm_digital_playback | 12877 | #define alc269_pcm_digital_playback alc880_pcm_digital_playback |
12514 | #define alc269_pcm_digital_capture alc880_pcm_digital_capture | 12878 | #define alc269_pcm_digital_capture alc880_pcm_digital_capture |
12515 | 12879 | ||
12880 | static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | ||
12881 | .substreams = 1, | ||
12882 | .channels_min = 2, | ||
12883 | .channels_max = 8, | ||
12884 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | ||
12885 | /* NID is set in alc_build_pcms */ | ||
12886 | .ops = { | ||
12887 | .open = alc880_playback_pcm_open, | ||
12888 | .prepare = alc880_playback_pcm_prepare, | ||
12889 | .cleanup = alc880_playback_pcm_cleanup | ||
12890 | }, | ||
12891 | }; | ||
12892 | |||
12893 | static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { | ||
12894 | .substreams = 1, | ||
12895 | .channels_min = 2, | ||
12896 | .channels_max = 2, | ||
12897 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | ||
12898 | /* NID is set in alc_build_pcms */ | ||
12899 | }; | ||
12900 | |||
12516 | /* | 12901 | /* |
12517 | * BIOS auto configuration | 12902 | * BIOS auto configuration |
12518 | */ | 12903 | */ |
12519 | static int alc269_parse_auto_config(struct hda_codec *codec) | 12904 | static int alc269_parse_auto_config(struct hda_codec *codec) |
12520 | { | 12905 | { |
12521 | struct alc_spec *spec = codec->spec; | 12906 | struct alc_spec *spec = codec->spec; |
12522 | int i, err; | 12907 | int err; |
12523 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; | 12908 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
12524 | 12909 | ||
12525 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 12910 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
@@ -12536,22 +12921,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
12536 | 12921 | ||
12537 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 12922 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
12538 | 12923 | ||
12539 | if (spec->autocfg.dig_out_pin) | 12924 | if (spec->autocfg.dig_outs) |
12540 | spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; | 12925 | spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; |
12541 | 12926 | ||
12542 | if (spec->kctls.list) | 12927 | if (spec->kctls.list) |
12543 | add_mixer(spec, spec->kctls.list); | 12928 | add_mixer(spec, spec->kctls.list); |
12544 | 12929 | ||
12545 | /* create a beep mixer control if the pin 0x1d isn't assigned */ | ||
12546 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++) | ||
12547 | if (spec->autocfg.input_pins[i] == 0x1d) | ||
12548 | break; | ||
12549 | if (i >= ARRAY_SIZE(spec->autocfg.input_pins)) | ||
12550 | add_mixer(spec, alc269_beep_mixer); | ||
12551 | |||
12552 | add_verb(spec, alc269_init_verbs); | 12930 | add_verb(spec, alc269_init_verbs); |
12553 | spec->num_mux_defs = 1; | 12931 | spec->num_mux_defs = 1; |
12554 | spec->input_mux = &spec->private_imux; | 12932 | spec->input_mux = &spec->private_imux[0]; |
12555 | /* set default input source */ | 12933 | /* set default input source */ |
12556 | snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], | 12934 | snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], |
12557 | 0, AC_VERB_SET_CONNECT_SEL, | 12935 | 0, AC_VERB_SET_CONNECT_SEL, |
@@ -12561,10 +12939,9 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
12561 | if (err < 0) | 12939 | if (err < 0) |
12562 | return err; | 12940 | return err; |
12563 | 12941 | ||
12564 | if (!spec->cap_mixer) | 12942 | if (!spec->cap_mixer && !spec->no_analog) |
12565 | set_capture_mixer(spec); | 12943 | set_capture_mixer(spec); |
12566 | 12944 | ||
12567 | store_pin_configs(codec); | ||
12568 | return 1; | 12945 | return 1; |
12569 | } | 12946 | } |
12570 | 12947 | ||
@@ -12661,7 +13038,7 @@ static struct alc_config_preset alc269_presets[] = { | |||
12661 | .init_hook = alc269_eeepc_dmic_inithook, | 13038 | .init_hook = alc269_eeepc_dmic_inithook, |
12662 | }, | 13039 | }, |
12663 | [ALC269_FUJITSU] = { | 13040 | [ALC269_FUJITSU] = { |
12664 | .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer }, | 13041 | .mixers = { alc269_fujitsu_mixer }, |
12665 | .cap_mixer = alc269_epc_capture_mixer, | 13042 | .cap_mixer = alc269_epc_capture_mixer, |
12666 | .init_verbs = { alc269_init_verbs, | 13043 | .init_verbs = { alc269_init_verbs, |
12667 | alc269_eeepc_dmic_init_verbs }, | 13044 | alc269_eeepc_dmic_init_verbs }, |
@@ -12726,13 +13103,26 @@ static int patch_alc269(struct hda_codec *codec) | |||
12726 | } | 13103 | } |
12727 | } | 13104 | } |
12728 | 13105 | ||
13106 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
13107 | if (err < 0) { | ||
13108 | alc_free(codec); | ||
13109 | return err; | ||
13110 | } | ||
13111 | |||
12729 | if (board_config != ALC269_AUTO) | 13112 | if (board_config != ALC269_AUTO) |
12730 | setup_preset(spec, &alc269_presets[board_config]); | 13113 | setup_preset(spec, &alc269_presets[board_config]); |
12731 | 13114 | ||
12732 | spec->stream_name_analog = "ALC269 Analog"; | 13115 | spec->stream_name_analog = "ALC269 Analog"; |
12733 | spec->stream_analog_playback = &alc269_pcm_analog_playback; | 13116 | if (codec->subsystem_id == 0x17aa3bf8) { |
12734 | spec->stream_analog_capture = &alc269_pcm_analog_capture; | 13117 | /* Due to a hardware problem on Lenovo Ideadpad, we need to |
12735 | 13118 | * fix the sample rate of analog I/O to 44.1kHz | |
13119 | */ | ||
13120 | spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; | ||
13121 | spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; | ||
13122 | } else { | ||
13123 | spec->stream_analog_playback = &alc269_pcm_analog_playback; | ||
13124 | spec->stream_analog_capture = &alc269_pcm_analog_capture; | ||
13125 | } | ||
12736 | spec->stream_name_digital = "ALC269 Digital"; | 13126 | spec->stream_name_digital = "ALC269 Digital"; |
12737 | spec->stream_digital_playback = &alc269_pcm_digital_playback; | 13127 | spec->stream_digital_playback = &alc269_pcm_digital_playback; |
12738 | spec->stream_digital_capture = &alc269_pcm_digital_capture; | 13128 | spec->stream_digital_capture = &alc269_pcm_digital_capture; |
@@ -12742,6 +13132,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
12742 | spec->capsrc_nids = alc269_capsrc_nids; | 13132 | spec->capsrc_nids = alc269_capsrc_nids; |
12743 | if (!spec->cap_mixer) | 13133 | if (!spec->cap_mixer) |
12744 | set_capture_mixer(spec); | 13134 | set_capture_mixer(spec); |
13135 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | ||
12745 | 13136 | ||
12746 | codec->patch_ops = alc_patch_ops; | 13137 | codec->patch_ops = alc_patch_ops; |
12747 | if (board_config == ALC269_AUTO) | 13138 | if (board_config == ALC269_AUTO) |
@@ -12992,8 +13383,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { | |||
12992 | static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { | 13383 | static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { |
12993 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | 13384 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), |
12994 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | 13385 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), |
12995 | HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT), | ||
12996 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT), | ||
12997 | { } | 13386 | { } |
12998 | }; | 13387 | }; |
12999 | 13388 | ||
@@ -13467,7 +13856,7 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) | |||
13467 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, | 13856 | static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, |
13468 | const struct auto_pin_cfg *cfg) | 13857 | const struct auto_pin_cfg *cfg) |
13469 | { | 13858 | { |
13470 | struct hda_input_mux *imux = &spec->private_imux; | 13859 | struct hda_input_mux *imux = &spec->private_imux[0]; |
13471 | int i, err, idx, idx1; | 13860 | int i, err, idx, idx1; |
13472 | 13861 | ||
13473 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 13862 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
@@ -13554,12 +13943,8 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec) | |||
13554 | 13943 | ||
13555 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 13944 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
13556 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 13945 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
13557 | if (nid >= 0x0c && nid <= 0x11) { | 13946 | if (nid >= 0x0c && nid <= 0x11) |
13558 | snd_hda_codec_write(codec, nid, 0, | 13947 | alc_set_input_pin(codec, nid, i); |
13559 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
13560 | i <= AUTO_PIN_FRONT_MIC ? | ||
13561 | PIN_VREF80 : PIN_IN); | ||
13562 | } | ||
13563 | } | 13948 | } |
13564 | } | 13949 | } |
13565 | 13950 | ||
@@ -13595,7 +13980,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
13595 | 13980 | ||
13596 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 13981 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
13597 | 13982 | ||
13598 | if (spec->autocfg.dig_out_pin) | 13983 | if (spec->autocfg.dig_outs) |
13599 | spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; | 13984 | spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; |
13600 | 13985 | ||
13601 | if (spec->kctls.list) | 13986 | if (spec->kctls.list) |
@@ -13604,13 +13989,12 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
13604 | add_verb(spec, alc861_auto_init_verbs); | 13989 | add_verb(spec, alc861_auto_init_verbs); |
13605 | 13990 | ||
13606 | spec->num_mux_defs = 1; | 13991 | spec->num_mux_defs = 1; |
13607 | spec->input_mux = &spec->private_imux; | 13992 | spec->input_mux = &spec->private_imux[0]; |
13608 | 13993 | ||
13609 | spec->adc_nids = alc861_adc_nids; | 13994 | spec->adc_nids = alc861_adc_nids; |
13610 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); | 13995 | spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); |
13611 | set_capture_mixer(spec); | 13996 | set_capture_mixer(spec); |
13612 | 13997 | ||
13613 | store_pin_configs(codec); | ||
13614 | return 1; | 13998 | return 1; |
13615 | } | 13999 | } |
13616 | 14000 | ||
@@ -13819,6 +14203,12 @@ static int patch_alc861(struct hda_codec *codec) | |||
13819 | } | 14203 | } |
13820 | } | 14204 | } |
13821 | 14205 | ||
14206 | err = snd_hda_attach_beep_device(codec, 0x23); | ||
14207 | if (err < 0) { | ||
14208 | alc_free(codec); | ||
14209 | return err; | ||
14210 | } | ||
14211 | |||
13822 | if (board_config != ALC861_AUTO) | 14212 | if (board_config != ALC861_AUTO) |
13823 | setup_preset(spec, &alc861_presets[board_config]); | 14213 | setup_preset(spec, &alc861_presets[board_config]); |
13824 | 14214 | ||
@@ -13830,6 +14220,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
13830 | spec->stream_digital_playback = &alc861_pcm_digital_playback; | 14220 | spec->stream_digital_playback = &alc861_pcm_digital_playback; |
13831 | spec->stream_digital_capture = &alc861_pcm_digital_capture; | 14221 | spec->stream_digital_capture = &alc861_pcm_digital_capture; |
13832 | 14222 | ||
14223 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | ||
14224 | |||
13833 | spec->vmaster_nid = 0x03; | 14225 | spec->vmaster_nid = 0x03; |
13834 | 14226 | ||
13835 | codec->patch_ops = alc_patch_ops; | 14227 | codec->patch_ops = alc_patch_ops; |
@@ -13986,9 +14378,6 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = { | |||
13986 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 14378 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
13987 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 14379 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
13988 | 14380 | ||
13989 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
13990 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
13991 | |||
13992 | { } /* end */ | 14381 | { } /* end */ |
13993 | }; | 14382 | }; |
13994 | 14383 | ||
@@ -14012,9 +14401,6 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { | |||
14012 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 14401 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
14013 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 14402 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
14014 | 14403 | ||
14015 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
14016 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
14017 | |||
14018 | { } /* end */ | 14404 | { } /* end */ |
14019 | }; | 14405 | }; |
14020 | 14406 | ||
@@ -14053,8 +14439,6 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { | |||
14053 | HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), | 14439 | HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), |
14054 | HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 14440 | HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
14055 | HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 14441 | HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
14056 | HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT), | ||
14057 | HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT), | ||
14058 | { } /* end */ | 14442 | { } /* end */ |
14059 | }; | 14443 | }; |
14060 | 14444 | ||
@@ -14365,9 +14749,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | |||
14365 | SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), | 14749 | SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), |
14366 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), | 14750 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), |
14367 | SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), | 14751 | SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), |
14368 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), | 14752 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), |
14369 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), | ||
14370 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO), | ||
14371 | SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), | 14753 | SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), |
14372 | {} | 14754 | {} |
14373 | }; | 14755 | }; |
@@ -14529,11 +14911,9 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) | |||
14529 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 14911 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
14530 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 14912 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
14531 | if (alc861vd_is_input_pin(nid)) { | 14913 | if (alc861vd_is_input_pin(nid)) { |
14532 | snd_hda_codec_write(codec, nid, 0, | 14914 | alc_set_input_pin(codec, nid, i); |
14533 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 14915 | if (nid != ALC861VD_PIN_CD_NID && |
14534 | i <= AUTO_PIN_FRONT_MIC ? | 14916 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
14535 | PIN_VREF80 : PIN_IN); | ||
14536 | if (nid != ALC861VD_PIN_CD_NID) | ||
14537 | snd_hda_codec_write(codec, nid, 0, | 14917 | snd_hda_codec_write(codec, nid, 0, |
14538 | AC_VERB_SET_AMP_GAIN_MUTE, | 14918 | AC_VERB_SET_AMP_GAIN_MUTE, |
14539 | AMP_OUT_MUTE); | 14919 | AMP_OUT_MUTE); |
@@ -14699,7 +15079,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
14699 | 15079 | ||
14700 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 15080 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
14701 | 15081 | ||
14702 | if (spec->autocfg.dig_out_pin) | 15082 | if (spec->autocfg.dig_outs) |
14703 | spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; | 15083 | spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; |
14704 | 15084 | ||
14705 | if (spec->kctls.list) | 15085 | if (spec->kctls.list) |
@@ -14708,13 +15088,12 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
14708 | add_verb(spec, alc861vd_volume_init_verbs); | 15088 | add_verb(spec, alc861vd_volume_init_verbs); |
14709 | 15089 | ||
14710 | spec->num_mux_defs = 1; | 15090 | spec->num_mux_defs = 1; |
14711 | spec->input_mux = &spec->private_imux; | 15091 | spec->input_mux = &spec->private_imux[0]; |
14712 | 15092 | ||
14713 | err = alc_auto_add_mic_boost(codec); | 15093 | err = alc_auto_add_mic_boost(codec); |
14714 | if (err < 0) | 15094 | if (err < 0) |
14715 | return err; | 15095 | return err; |
14716 | 15096 | ||
14717 | store_pin_configs(codec); | ||
14718 | return 1; | 15097 | return 1; |
14719 | } | 15098 | } |
14720 | 15099 | ||
@@ -14765,6 +15144,12 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
14765 | } | 15144 | } |
14766 | } | 15145 | } |
14767 | 15146 | ||
15147 | err = snd_hda_attach_beep_device(codec, 0x23); | ||
15148 | if (err < 0) { | ||
15149 | alc_free(codec); | ||
15150 | return err; | ||
15151 | } | ||
15152 | |||
14768 | if (board_config != ALC861VD_AUTO) | 15153 | if (board_config != ALC861VD_AUTO) |
14769 | setup_preset(spec, &alc861vd_presets[board_config]); | 15154 | setup_preset(spec, &alc861vd_presets[board_config]); |
14770 | 15155 | ||
@@ -14787,9 +15172,10 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
14787 | spec->adc_nids = alc861vd_adc_nids; | 15172 | spec->adc_nids = alc861vd_adc_nids; |
14788 | spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); | 15173 | spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); |
14789 | spec->capsrc_nids = alc861vd_capsrc_nids; | 15174 | spec->capsrc_nids = alc861vd_capsrc_nids; |
14790 | spec->is_mix_capture = 1; | 15175 | spec->capture_style = CAPT_MIX; |
14791 | 15176 | ||
14792 | set_capture_mixer(spec); | 15177 | set_capture_mixer(spec); |
15178 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | ||
14793 | 15179 | ||
14794 | spec->vmaster_nid = 0x02; | 15180 | spec->vmaster_nid = 0x02; |
14795 | 15181 | ||
@@ -14978,8 +15364,6 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { | |||
14978 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 15364 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
14979 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 15365 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
14980 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 15366 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
14981 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
14982 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
14983 | { } /* end */ | 15367 | { } /* end */ |
14984 | }; | 15368 | }; |
14985 | 15369 | ||
@@ -15001,8 +15385,6 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { | |||
15001 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 15385 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
15002 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 15386 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
15003 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 15387 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
15004 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
15005 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
15006 | { } /* end */ | 15388 | { } /* end */ |
15007 | }; | 15389 | }; |
15008 | 15390 | ||
@@ -15978,56 +16360,55 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { | |||
15978 | }; | 16360 | }; |
15979 | 16361 | ||
15980 | static struct snd_pci_quirk alc662_cfg_tbl[] = { | 16362 | static struct snd_pci_quirk alc662_cfg_tbl[] = { |
15981 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), | 16363 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), |
15982 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), | ||
15983 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), | ||
15984 | SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), | ||
15985 | SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), | ||
15986 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), | ||
15987 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1), | ||
15988 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), | 16364 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), |
15989 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), | 16365 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), |
15990 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), | 16366 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), |
15991 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1), | ||
15992 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), | 16367 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), |
16368 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), | ||
15993 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), | 16369 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), |
15994 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), | ||
15995 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), | ||
15996 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), | ||
15997 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), | 16370 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), |
15998 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), | 16371 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), |
15999 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), | 16372 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), |
16373 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), | ||
16374 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), | ||
16375 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), | ||
16000 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), | 16376 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), |
16001 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), | 16377 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), |
16002 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), | 16378 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), |
16379 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), | ||
16003 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), | 16380 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), |
16004 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), | 16381 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), |
16005 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), | 16382 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), |
16006 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), | 16383 | /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ |
16007 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), | ||
16008 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), | 16384 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), |
16009 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), | ||
16010 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), | ||
16011 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), | 16385 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), |
16012 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), | 16386 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), |
16387 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), | ||
16388 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), | ||
16389 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), | ||
16390 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), | ||
16391 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), | ||
16392 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), | ||
16393 | /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ | ||
16394 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), | ||
16395 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), | ||
16396 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), | ||
16013 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), | 16397 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), |
16014 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), | 16398 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), |
16015 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), | 16399 | SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), |
16016 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), | 16400 | SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), |
16017 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), | 16401 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), |
16018 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", | 16402 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", |
16019 | ALC662_3ST_6ch_DIG), | 16403 | ALC662_3ST_6ch_DIG), |
16020 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), | ||
16021 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), | ||
16022 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), | ||
16023 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", | 16404 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", |
16024 | ALC662_3ST_6ch_DIG), | 16405 | ALC662_3ST_6ch_DIG), |
16025 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), | 16406 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), |
16407 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), | ||
16026 | SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", | 16408 | SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", |
16027 | ALC662_3ST_6ch_DIG), | 16409 | ALC662_3ST_6ch_DIG), |
16028 | SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), | 16410 | SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", |
16029 | SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), | 16411 | ALC663_ASUS_H13), |
16030 | SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), | ||
16031 | {} | 16412 | {} |
16032 | }; | 16413 | }; |
16033 | 16414 | ||
@@ -16347,7 +16728,7 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
16347 | 16728 | ||
16348 | if (alc880_is_fixed_pin(pin)) { | 16729 | if (alc880_is_fixed_pin(pin)) { |
16349 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | 16730 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); |
16350 | /* printk("DAC nid=%x\n",nid); */ | 16731 | /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */ |
16351 | /* specify the DAC as the extra output */ | 16732 | /* specify the DAC as the extra output */ |
16352 | if (!spec->multiout.hp_nid) | 16733 | if (!spec->multiout.hp_nid) |
16353 | spec->multiout.hp_nid = nid; | 16734 | spec->multiout.hp_nid = nid; |
@@ -16377,26 +16758,58 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
16377 | return 0; | 16758 | return 0; |
16378 | } | 16759 | } |
16379 | 16760 | ||
16761 | /* return the index of the src widget from the connection list of the nid. | ||
16762 | * return -1 if not found | ||
16763 | */ | ||
16764 | static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid, | ||
16765 | hda_nid_t src) | ||
16766 | { | ||
16767 | hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; | ||
16768 | int i, conns; | ||
16769 | |||
16770 | conns = snd_hda_get_connections(codec, nid, conn_list, | ||
16771 | ARRAY_SIZE(conn_list)); | ||
16772 | if (conns < 0) | ||
16773 | return -1; | ||
16774 | for (i = 0; i < conns; i++) | ||
16775 | if (conn_list[i] == src) | ||
16776 | return i; | ||
16777 | return -1; | ||
16778 | } | ||
16779 | |||
16780 | static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid) | ||
16781 | { | ||
16782 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); | ||
16783 | return (pincap & AC_PINCAP_IN) != 0; | ||
16784 | } | ||
16785 | |||
16380 | /* create playback/capture controls for input pins */ | 16786 | /* create playback/capture controls for input pins */ |
16381 | static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, | 16787 | static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec, |
16382 | const struct auto_pin_cfg *cfg) | 16788 | const struct auto_pin_cfg *cfg) |
16383 | { | 16789 | { |
16384 | struct hda_input_mux *imux = &spec->private_imux; | 16790 | struct alc_spec *spec = codec->spec; |
16791 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
16385 | int i, err, idx; | 16792 | int i, err, idx; |
16386 | 16793 | ||
16387 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 16794 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
16388 | if (alc880_is_input_pin(cfg->input_pins[i])) { | 16795 | if (alc662_is_input_pin(codec, cfg->input_pins[i])) { |
16389 | idx = alc880_input_pin_idx(cfg->input_pins[i]); | 16796 | idx = alc662_input_pin_idx(codec, 0x0b, |
16390 | err = new_analog_input(spec, cfg->input_pins[i], | 16797 | cfg->input_pins[i]); |
16391 | auto_pin_cfg_labels[i], | 16798 | if (idx >= 0) { |
16392 | idx, 0x0b); | 16799 | err = new_analog_input(spec, cfg->input_pins[i], |
16393 | if (err < 0) | 16800 | auto_pin_cfg_labels[i], |
16394 | return err; | 16801 | idx, 0x0b); |
16395 | imux->items[imux->num_items].label = | 16802 | if (err < 0) |
16396 | auto_pin_cfg_labels[i]; | 16803 | return err; |
16397 | imux->items[imux->num_items].index = | 16804 | } |
16398 | alc880_input_pin_idx(cfg->input_pins[i]); | 16805 | idx = alc662_input_pin_idx(codec, 0x22, |
16399 | imux->num_items++; | 16806 | cfg->input_pins[i]); |
16807 | if (idx >= 0) { | ||
16808 | imux->items[imux->num_items].label = | ||
16809 | auto_pin_cfg_labels[i]; | ||
16810 | imux->items[imux->num_items].index = idx; | ||
16811 | imux->num_items++; | ||
16812 | } | ||
16400 | } | 16813 | } |
16401 | } | 16814 | } |
16402 | return 0; | 16815 | return 0; |
@@ -16446,7 +16859,6 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec) | |||
16446 | alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | 16859 | alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); |
16447 | } | 16860 | } |
16448 | 16861 | ||
16449 | #define alc662_is_input_pin(nid) alc880_is_input_pin(nid) | ||
16450 | #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID | 16862 | #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID |
16451 | 16863 | ||
16452 | static void alc662_auto_init_analog_input(struct hda_codec *codec) | 16864 | static void alc662_auto_init_analog_input(struct hda_codec *codec) |
@@ -16456,12 +16868,10 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec) | |||
16456 | 16868 | ||
16457 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 16869 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
16458 | hda_nid_t nid = spec->autocfg.input_pins[i]; | 16870 | hda_nid_t nid = spec->autocfg.input_pins[i]; |
16459 | if (alc662_is_input_pin(nid)) { | 16871 | if (alc662_is_input_pin(codec, nid)) { |
16460 | snd_hda_codec_write(codec, nid, 0, | 16872 | alc_set_input_pin(codec, nid, i); |
16461 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 16873 | if (nid != ALC662_PIN_CD_NID && |
16462 | (i <= AUTO_PIN_FRONT_MIC ? | 16874 | (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) |
16463 | PIN_VREF80 : PIN_IN)); | ||
16464 | if (nid != ALC662_PIN_CD_NID) | ||
16465 | snd_hda_codec_write(codec, nid, 0, | 16875 | snd_hda_codec_write(codec, nid, 0, |
16466 | AC_VERB_SET_AMP_GAIN_MUTE, | 16876 | AC_VERB_SET_AMP_GAIN_MUTE, |
16467 | AMP_OUT_MUTE); | 16877 | AMP_OUT_MUTE); |
@@ -16499,20 +16909,20 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
16499 | "Headphone"); | 16909 | "Headphone"); |
16500 | if (err < 0) | 16910 | if (err < 0) |
16501 | return err; | 16911 | return err; |
16502 | err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); | 16912 | err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg); |
16503 | if (err < 0) | 16913 | if (err < 0) |
16504 | return err; | 16914 | return err; |
16505 | 16915 | ||
16506 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 16916 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
16507 | 16917 | ||
16508 | if (spec->autocfg.dig_out_pin) | 16918 | if (spec->autocfg.dig_outs) |
16509 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | 16919 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; |
16510 | 16920 | ||
16511 | if (spec->kctls.list) | 16921 | if (spec->kctls.list) |
16512 | add_mixer(spec, spec->kctls.list); | 16922 | add_mixer(spec, spec->kctls.list); |
16513 | 16923 | ||
16514 | spec->num_mux_defs = 1; | 16924 | spec->num_mux_defs = 1; |
16515 | spec->input_mux = &spec->private_imux; | 16925 | spec->input_mux = &spec->private_imux[0]; |
16516 | 16926 | ||
16517 | add_verb(spec, alc662_auto_init_verbs); | 16927 | add_verb(spec, alc662_auto_init_verbs); |
16518 | if (codec->vendor_id == 0x10ec0663) | 16928 | if (codec->vendor_id == 0x10ec0663) |
@@ -16522,7 +16932,6 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
16522 | if (err < 0) | 16932 | if (err < 0) |
16523 | return err; | 16933 | return err; |
16524 | 16934 | ||
16525 | store_pin_configs(codec); | ||
16526 | return 1; | 16935 | return 1; |
16527 | } | 16936 | } |
16528 | 16937 | ||
@@ -16574,6 +16983,12 @@ static int patch_alc662(struct hda_codec *codec) | |||
16574 | } | 16983 | } |
16575 | } | 16984 | } |
16576 | 16985 | ||
16986 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
16987 | if (err < 0) { | ||
16988 | alc_free(codec); | ||
16989 | return err; | ||
16990 | } | ||
16991 | |||
16577 | if (board_config != ALC662_AUTO) | 16992 | if (board_config != ALC662_AUTO) |
16578 | setup_preset(spec, &alc662_presets[board_config]); | 16993 | setup_preset(spec, &alc662_presets[board_config]); |
16579 | 16994 | ||
@@ -16597,10 +17012,14 @@ static int patch_alc662(struct hda_codec *codec) | |||
16597 | spec->adc_nids = alc662_adc_nids; | 17012 | spec->adc_nids = alc662_adc_nids; |
16598 | spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); | 17013 | spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); |
16599 | spec->capsrc_nids = alc662_capsrc_nids; | 17014 | spec->capsrc_nids = alc662_capsrc_nids; |
16600 | spec->is_mix_capture = 1; | 17015 | spec->capture_style = CAPT_MIX; |
16601 | 17016 | ||
16602 | if (!spec->cap_mixer) | 17017 | if (!spec->cap_mixer) |
16603 | set_capture_mixer(spec); | 17018 | set_capture_mixer(spec); |
17019 | if (codec->vendor_id == 0x10ec0662) | ||
17020 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | ||
17021 | else | ||
17022 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | ||
16604 | 17023 | ||
16605 | spec->vmaster_nid = 0x02; | 17024 | spec->vmaster_nid = 0x02; |
16606 | 17025 | ||