diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2367 |
1 files changed, 2090 insertions, 277 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4e0c3c1b908b..145682b78071 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -32,6 +32,10 @@ | |||
32 | #include "hda_codec.h" | 32 | #include "hda_codec.h" |
33 | #include "hda_local.h" | 33 | #include "hda_local.h" |
34 | 34 | ||
35 | #define ALC880_FRONT_EVENT 0x01 | ||
36 | #define ALC880_DCVOL_EVENT 0x02 | ||
37 | #define ALC880_HP_EVENT 0x04 | ||
38 | #define ALC880_MIC_EVENT 0x08 | ||
35 | 39 | ||
36 | /* ALC880 board config type */ | 40 | /* ALC880 board config type */ |
37 | enum { | 41 | enum { |
@@ -48,7 +52,10 @@ enum { | |||
48 | ALC880_ASUS_DIG, | 52 | ALC880_ASUS_DIG, |
49 | ALC880_ASUS_W1V, | 53 | ALC880_ASUS_W1V, |
50 | ALC880_ASUS_DIG2, | 54 | ALC880_ASUS_DIG2, |
55 | ALC880_FUJITSU, | ||
51 | ALC880_UNIWILL_DIG, | 56 | ALC880_UNIWILL_DIG, |
57 | ALC880_UNIWILL, | ||
58 | ALC880_UNIWILL_P53, | ||
52 | ALC880_CLEVO, | 59 | ALC880_CLEVO, |
53 | ALC880_TCL_S700, | 60 | ALC880_TCL_S700, |
54 | ALC880_LG, | 61 | ALC880_LG, |
@@ -77,8 +84,12 @@ enum { | |||
77 | /* ALC262 models */ | 84 | /* ALC262 models */ |
78 | enum { | 85 | enum { |
79 | ALC262_BASIC, | 86 | ALC262_BASIC, |
87 | ALC262_HIPPO, | ||
88 | ALC262_HIPPO_1, | ||
80 | ALC262_FUJITSU, | 89 | ALC262_FUJITSU, |
81 | ALC262_HP_BPC, | 90 | ALC262_HP_BPC, |
91 | ALC262_HP_BPC_D7000_WL, | ||
92 | ALC262_HP_BPC_D7000_WF, | ||
82 | ALC262_BENQ_ED8, | 93 | ALC262_BENQ_ED8, |
83 | ALC262_AUTO, | 94 | ALC262_AUTO, |
84 | ALC262_MODEL_LAST /* last tag */ | 95 | ALC262_MODEL_LAST /* last tag */ |
@@ -91,16 +102,30 @@ enum { | |||
91 | ALC861_3ST_DIG, | 102 | ALC861_3ST_DIG, |
92 | ALC861_6ST_DIG, | 103 | ALC861_6ST_DIG, |
93 | ALC861_UNIWILL_M31, | 104 | ALC861_UNIWILL_M31, |
105 | ALC861_TOSHIBA, | ||
106 | ALC861_ASUS, | ||
107 | ALC861_ASUS_LAPTOP, | ||
94 | ALC861_AUTO, | 108 | ALC861_AUTO, |
95 | ALC861_MODEL_LAST, | 109 | ALC861_MODEL_LAST, |
96 | }; | 110 | }; |
97 | 111 | ||
112 | /* ALC861-VD models */ | ||
113 | enum { | ||
114 | ALC660VD_3ST, | ||
115 | ALC861VD_3ST, | ||
116 | ALC861VD_3ST_DIG, | ||
117 | ALC861VD_6ST_DIG, | ||
118 | ALC861VD_AUTO, | ||
119 | ALC861VD_MODEL_LAST, | ||
120 | }; | ||
121 | |||
98 | /* ALC882 models */ | 122 | /* ALC882 models */ |
99 | enum { | 123 | enum { |
100 | ALC882_3ST_DIG, | 124 | ALC882_3ST_DIG, |
101 | ALC882_6ST_DIG, | 125 | ALC882_6ST_DIG, |
102 | ALC882_ARIMA, | 126 | ALC882_ARIMA, |
103 | ALC882_AUTO, | 127 | ALC882_AUTO, |
128 | ALC885_MACPRO, | ||
104 | ALC882_MODEL_LAST, | 129 | ALC882_MODEL_LAST, |
105 | }; | 130 | }; |
106 | 131 | ||
@@ -110,8 +135,12 @@ enum { | |||
110 | ALC883_3ST_6ch_DIG, | 135 | ALC883_3ST_6ch_DIG, |
111 | ALC883_3ST_6ch, | 136 | ALC883_3ST_6ch, |
112 | ALC883_6ST_DIG, | 137 | ALC883_6ST_DIG, |
138 | ALC883_TARGA_DIG, | ||
139 | ALC883_TARGA_2ch_DIG, | ||
113 | ALC888_DEMO_BOARD, | 140 | ALC888_DEMO_BOARD, |
114 | ALC883_ACER, | 141 | ALC883_ACER, |
142 | ALC883_MEDION, | ||
143 | ALC883_LAPTOP_EAPD, | ||
115 | ALC883_AUTO, | 144 | ALC883_AUTO, |
116 | ALC883_MODEL_LAST, | 145 | ALC883_MODEL_LAST, |
117 | }; | 146 | }; |
@@ -1015,6 +1044,60 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { | |||
1015 | { } /* end */ | 1044 | { } /* end */ |
1016 | }; | 1045 | }; |
1017 | 1046 | ||
1047 | /* Uniwill */ | ||
1048 | static struct snd_kcontrol_new alc880_uniwill_mixer[] = { | ||
1049 | HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
1050 | HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), | ||
1051 | HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
1052 | HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
1053 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
1054 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
1055 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
1056 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
1057 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
1058 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
1059 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
1060 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
1061 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
1062 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
1063 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
1064 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
1065 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
1066 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
1067 | { | ||
1068 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1069 | .name = "Channel Mode", | ||
1070 | .info = alc_ch_mode_info, | ||
1071 | .get = alc_ch_mode_get, | ||
1072 | .put = alc_ch_mode_put, | ||
1073 | }, | ||
1074 | { } /* end */ | ||
1075 | }; | ||
1076 | |||
1077 | static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { | ||
1078 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
1079 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | ||
1080 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
1081 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
1082 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
1083 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
1084 | HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
1085 | HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
1086 | HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
1087 | HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
1088 | { } /* end */ | ||
1089 | }; | ||
1090 | |||
1091 | static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { | ||
1092 | HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
1093 | HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT), | ||
1094 | HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
1095 | HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
1096 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
1097 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
1098 | { } /* end */ | ||
1099 | }; | ||
1100 | |||
1018 | /* | 1101 | /* |
1019 | * build control elements | 1102 | * build control elements |
1020 | */ | 1103 | */ |
@@ -1248,6 +1331,159 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = { | |||
1248 | { } | 1331 | { } |
1249 | }; | 1332 | }; |
1250 | 1333 | ||
1334 | /* | ||
1335 | * Uniwill pin configuration: | ||
1336 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, | ||
1337 | * line = 0x1a | ||
1338 | */ | ||
1339 | static struct hda_verb alc880_uniwill_init_verbs[] = { | ||
1340 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
1341 | |||
1342 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1343 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1344 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1345 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1346 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1347 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1348 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1349 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1350 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
1351 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
1352 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
1353 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
1354 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
1355 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
1356 | |||
1357 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1358 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1359 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1360 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1361 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1362 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1363 | /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ | ||
1364 | /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ | ||
1365 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1366 | |||
1367 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
1368 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | ||
1369 | |||
1370 | { } | ||
1371 | }; | ||
1372 | |||
1373 | /* | ||
1374 | * Uniwill P53 | ||
1375 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, | ||
1376 | */ | ||
1377 | static struct hda_verb alc880_uniwill_p53_init_verbs[] = { | ||
1378 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
1379 | |||
1380 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1381 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1382 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1383 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1384 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1385 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1386 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
1387 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
1388 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
1389 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
1390 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
1391 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
1392 | |||
1393 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1394 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1395 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1396 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1397 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1398 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1399 | |||
1400 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
1401 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, | ||
1402 | |||
1403 | { } | ||
1404 | }; | ||
1405 | |||
1406 | static struct hda_verb alc880_beep_init_verbs[] = { | ||
1407 | { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, | ||
1408 | { } | ||
1409 | }; | ||
1410 | |||
1411 | /* toggle speaker-output according to the hp-jack state */ | ||
1412 | static void alc880_uniwill_automute(struct hda_codec *codec) | ||
1413 | { | ||
1414 | unsigned int present; | ||
1415 | |||
1416 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
1417 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1418 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
1419 | 0x80, present ? 0x80 : 0); | ||
1420 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
1421 | 0x80, present ? 0x80 : 0); | ||
1422 | snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, | ||
1423 | 0x80, present ? 0x80 : 0); | ||
1424 | snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, | ||
1425 | 0x80, present ? 0x80 : 0); | ||
1426 | |||
1427 | present = snd_hda_codec_read(codec, 0x18, 0, | ||
1428 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1429 | snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1430 | 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); | ||
1431 | } | ||
1432 | |||
1433 | static void alc880_uniwill_unsol_event(struct hda_codec *codec, | ||
1434 | unsigned int res) | ||
1435 | { | ||
1436 | /* Looks like the unsol event is incompatible with the standard | ||
1437 | * definition. 4bit tag is placed at 28 bit! | ||
1438 | */ | ||
1439 | if ((res >> 28) == ALC880_HP_EVENT || | ||
1440 | (res >> 28) == ALC880_MIC_EVENT) | ||
1441 | alc880_uniwill_automute(codec); | ||
1442 | } | ||
1443 | |||
1444 | static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) | ||
1445 | { | ||
1446 | unsigned int present; | ||
1447 | |||
1448 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
1449 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1450 | |||
1451 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, | ||
1452 | 0x80, present ? 0x80 : 0); | ||
1453 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, | ||
1454 | 0x80, present ? 0x80 : 0); | ||
1455 | } | ||
1456 | |||
1457 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | ||
1458 | { | ||
1459 | unsigned int present; | ||
1460 | |||
1461 | present = snd_hda_codec_read(codec, 0x21, 0, | ||
1462 | AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f; | ||
1463 | |||
1464 | snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0, | ||
1465 | 0x7f, present); | ||
1466 | snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0, | ||
1467 | 0x7f, present); | ||
1468 | |||
1469 | snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0, | ||
1470 | 0x7f, present); | ||
1471 | snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0, | ||
1472 | 0x7f, present); | ||
1473 | |||
1474 | } | ||
1475 | static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | ||
1476 | unsigned int res) | ||
1477 | { | ||
1478 | /* Looks like the unsol event is incompatible with the standard | ||
1479 | * definition. 4bit tag is placed at 28 bit! | ||
1480 | */ | ||
1481 | if ((res >> 28) == ALC880_HP_EVENT) | ||
1482 | alc880_uniwill_p53_hp_automute(codec); | ||
1483 | if ((res >> 28) == ALC880_DCVOL_EVENT) | ||
1484 | alc880_uniwill_p53_dcvol_automute(codec); | ||
1485 | } | ||
1486 | |||
1251 | /* FIXME! */ | 1487 | /* FIXME! */ |
1252 | /* | 1488 | /* |
1253 | * F1734 pin configuration: | 1489 | * F1734 pin configuration: |
@@ -2125,159 +2361,112 @@ static struct hda_verb alc880_test_init_verbs[] = { | |||
2125 | /* | 2361 | /* |
2126 | */ | 2362 | */ |
2127 | 2363 | ||
2128 | static struct hda_board_config alc880_cfg_tbl[] = { | 2364 | static const char *alc880_models[ALC880_MODEL_LAST] = { |
2129 | /* Back 3 jack, front 2 jack */ | 2365 | [ALC880_3ST] = "3stack", |
2130 | { .modelname = "3stack", .config = ALC880_3ST }, | 2366 | [ALC880_TCL_S700] = "tcl", |
2131 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST }, | 2367 | [ALC880_3ST_DIG] = "3stack-digout", |
2132 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST }, | 2368 | [ALC880_CLEVO] = "clevo", |
2133 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST }, | 2369 | [ALC880_5ST] = "5stack", |
2134 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST }, | 2370 | [ALC880_5ST_DIG] = "5stack-digout", |
2135 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST }, | 2371 | [ALC880_W810] = "w810", |
2136 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST }, | 2372 | [ALC880_Z71V] = "z71v", |
2137 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST }, | 2373 | [ALC880_6ST] = "6stack", |
2138 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST }, | 2374 | [ALC880_6ST_DIG] = "6stack-digout", |
2139 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST }, | 2375 | [ALC880_ASUS] = "asus", |
2140 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST }, | 2376 | [ALC880_ASUS_W1V] = "asus-w1v", |
2141 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST }, | 2377 | [ALC880_ASUS_DIG] = "asus-dig", |
2142 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST }, | 2378 | [ALC880_ASUS_DIG2] = "asus-dig2", |
2143 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST }, | 2379 | [ALC880_UNIWILL_DIG] = "uniwill", |
2144 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST }, | 2380 | [ALC880_UNIWILL_P53] = "uniwill-p53", |
2145 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST }, | 2381 | [ALC880_FUJITSU] = "fujitsu", |
2146 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST }, | 2382 | [ALC880_F1734] = "F1734", |
2147 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST }, | 2383 | [ALC880_LG] = "lg", |
2148 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST }, | 2384 | [ALC880_LG_LW] = "lg-lw", |
2149 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe212, .config = ALC880_3ST }, | ||
2150 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe213, .config = ALC880_3ST }, | ||
2151 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST }, | ||
2152 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe234, .config = ALC880_3ST }, | ||
2153 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST }, | ||
2154 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST }, | ||
2155 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST }, | ||
2156 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST }, | ||
2157 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST }, | ||
2158 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST }, | ||
2159 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST }, | ||
2160 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST }, | ||
2161 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST }, | ||
2162 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST }, | ||
2163 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST }, | ||
2164 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST }, | ||
2165 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST }, | ||
2166 | /* TCL S700 */ | ||
2167 | { .modelname = "tcl", .config = ALC880_TCL_S700 }, | ||
2168 | { .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 }, | ||
2169 | |||
2170 | /* Back 3 jack, front 2 jack (Internal add Aux-In) */ | ||
2171 | { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST }, | ||
2172 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, | ||
2173 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST }, | ||
2174 | |||
2175 | /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */ | ||
2176 | { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, | ||
2177 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, | ||
2178 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG }, | ||
2179 | |||
2180 | /* Clevo laptops */ | ||
2181 | { .modelname = "clevo", .config = ALC880_CLEVO }, | ||
2182 | { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, | ||
2183 | .config = ALC880_CLEVO }, /* Clevo m520G NB */ | ||
2184 | { .pci_subvendor = 0x1558, .pci_subdevice = 0x0660, | ||
2185 | .config = ALC880_CLEVO }, /* Clevo m665n */ | ||
2186 | |||
2187 | /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ | ||
2188 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, | ||
2189 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG }, | ||
2190 | { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG }, | ||
2191 | |||
2192 | /* Back 5 jack, front 2 jack */ | ||
2193 | { .modelname = "5stack", .config = ALC880_5ST }, | ||
2194 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST }, | ||
2195 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST }, | ||
2196 | { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST }, | ||
2197 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST }, | ||
2198 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST }, | ||
2199 | |||
2200 | /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */ | ||
2201 | { .modelname = "5stack-digout", .config = ALC880_5ST_DIG }, | ||
2202 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG }, | ||
2203 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG }, | ||
2204 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG }, | ||
2205 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG }, | ||
2206 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG }, | ||
2207 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG }, | ||
2208 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, | ||
2209 | { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, | ||
2210 | { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, | ||
2211 | { .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560, | ||
2212 | .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */ | ||
2213 | /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ | ||
2214 | { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, | ||
2215 | /* note subvendor = 0 below */ | ||
2216 | /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */ | ||
2217 | |||
2218 | { .modelname = "w810", .config = ALC880_W810 }, | ||
2219 | { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, | ||
2220 | |||
2221 | { .modelname = "z71v", .config = ALC880_Z71V }, | ||
2222 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, | ||
2223 | |||
2224 | { .modelname = "6stack", .config = ALC880_6ST }, | ||
2225 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */ | ||
2226 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST }, | ||
2227 | { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */ | ||
2228 | { .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */ | ||
2229 | |||
2230 | { .modelname = "6stack-digout", .config = ALC880_6ST_DIG }, | ||
2231 | { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, | ||
2232 | { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG }, | ||
2233 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, | ||
2234 | { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG }, | ||
2235 | { .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG }, | ||
2236 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG }, | ||
2237 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG }, | ||
2238 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG }, | ||
2239 | { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */ | ||
2240 | { .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */ | ||
2241 | { .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */ | ||
2242 | |||
2243 | { .modelname = "asus", .config = ALC880_ASUS }, | ||
2244 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, | ||
2245 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG }, | ||
2246 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG }, | ||
2247 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG }, | ||
2248 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG }, | ||
2249 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS }, | ||
2250 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c2, .config = ALC880_ASUS_DIG }, /* Asus W6A */ | ||
2251 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG }, | ||
2252 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS }, | ||
2253 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG }, | ||
2254 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS }, | ||
2255 | { .modelname = "asus-w1v", .config = ALC880_ASUS_W1V }, | ||
2256 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V }, | ||
2257 | { .modelname = "asus-dig", .config = ALC880_ASUS_DIG }, | ||
2258 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */ | ||
2259 | { .modelname = "asus-dig2", .config = ALC880_ASUS_DIG2 }, | ||
2260 | { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, | ||
2261 | |||
2262 | { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, | ||
2263 | { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG }, | ||
2264 | |||
2265 | { .modelname = "F1734", .config = ALC880_F1734 }, | ||
2266 | { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 }, | ||
2267 | { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 }, | ||
2268 | |||
2269 | { .modelname = "lg", .config = ALC880_LG }, | ||
2270 | { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, | ||
2271 | { .pci_subvendor = 0x1854, .pci_subdevice = 0x0068, .config = ALC880_LG }, | ||
2272 | |||
2273 | { .modelname = "lg-lw", .config = ALC880_LG_LW }, | ||
2274 | { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW }, | ||
2275 | { .pci_subvendor = 0x1854, .pci_subdevice = 0x0077, .config = ALC880_LG_LW }, | ||
2276 | |||
2277 | #ifdef CONFIG_SND_DEBUG | 2385 | #ifdef CONFIG_SND_DEBUG |
2278 | { .modelname = "test", .config = ALC880_TEST }, | 2386 | [ALC880_TEST] = "test", |
2279 | #endif | 2387 | #endif |
2280 | { .modelname = "auto", .config = ALC880_AUTO }, | 2388 | [ALC880_AUTO] = "auto", |
2389 | }; | ||
2390 | |||
2391 | static struct snd_pci_quirk alc880_cfg_tbl[] = { | ||
2392 | /* Broken BIOS configuration */ | ||
2393 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), | ||
2394 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), | ||
2395 | |||
2396 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), | ||
2397 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), | ||
2398 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), | ||
2399 | SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), | ||
2400 | SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), | ||
2401 | SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), | ||
2402 | SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), | ||
2403 | SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), | ||
2404 | SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), | ||
2405 | |||
2406 | SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), | ||
2407 | SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), | ||
2408 | |||
2409 | SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), | ||
2410 | SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), | ||
2411 | SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), | ||
2412 | SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), | ||
2413 | SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), | ||
2414 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), | ||
2415 | SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), | ||
2416 | /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ | ||
2417 | SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), | ||
2418 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), | ||
2419 | SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), | ||
2420 | SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), | ||
2421 | SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), | ||
2422 | SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), | ||
2423 | SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), | ||
2424 | |||
2425 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), | ||
2426 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), | ||
2427 | SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), | ||
2428 | SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), | ||
2429 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), | ||
2430 | SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), | ||
2431 | SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), | ||
2432 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), | ||
2433 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), | ||
2434 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), | ||
2435 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), | ||
2436 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), | ||
2437 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), | ||
2438 | SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), | ||
2439 | SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), | ||
2440 | SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), | ||
2441 | SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), | ||
2442 | SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), | ||
2443 | |||
2444 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), | ||
2445 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), | ||
2446 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), | ||
2447 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), | ||
2448 | |||
2449 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), | ||
2450 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), | ||
2451 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), | ||
2452 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), | ||
2453 | |||
2454 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), | ||
2455 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), | ||
2456 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), | ||
2457 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), | ||
2458 | |||
2459 | SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), | ||
2460 | SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), | ||
2461 | SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), | ||
2462 | SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), | ||
2463 | SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), | ||
2464 | SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), | ||
2465 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), | ||
2466 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), | ||
2467 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), | ||
2468 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), | ||
2469 | SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), | ||
2281 | 2470 | ||
2282 | {} | 2471 | {} |
2283 | }; | 2472 | }; |
@@ -2438,7 +2627,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
2438 | }, | 2627 | }, |
2439 | [ALC880_UNIWILL_DIG] = { | 2628 | [ALC880_UNIWILL_DIG] = { |
2440 | .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, | 2629 | .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, |
2441 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, | 2630 | .init_verbs = { alc880_volume_init_verbs, |
2631 | alc880_pin_asus_init_verbs }, | ||
2442 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 2632 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
2443 | .dac_nids = alc880_asus_dac_nids, | 2633 | .dac_nids = alc880_asus_dac_nids, |
2444 | .dig_out_nid = ALC880_DIGOUT_NID, | 2634 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -2447,6 +2637,46 @@ static struct alc_config_preset alc880_presets[] = { | |||
2447 | .need_dac_fix = 1, | 2637 | .need_dac_fix = 1, |
2448 | .input_mux = &alc880_capture_source, | 2638 | .input_mux = &alc880_capture_source, |
2449 | }, | 2639 | }, |
2640 | [ALC880_UNIWILL] = { | ||
2641 | .mixers = { alc880_uniwill_mixer }, | ||
2642 | .init_verbs = { alc880_volume_init_verbs, | ||
2643 | alc880_uniwill_init_verbs }, | ||
2644 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
2645 | .dac_nids = alc880_asus_dac_nids, | ||
2646 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
2647 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
2648 | .channel_mode = alc880_threestack_modes, | ||
2649 | .need_dac_fix = 1, | ||
2650 | .input_mux = &alc880_capture_source, | ||
2651 | .unsol_event = alc880_uniwill_unsol_event, | ||
2652 | .init_hook = alc880_uniwill_automute, | ||
2653 | }, | ||
2654 | [ALC880_UNIWILL_P53] = { | ||
2655 | .mixers = { alc880_uniwill_p53_mixer }, | ||
2656 | .init_verbs = { alc880_volume_init_verbs, | ||
2657 | alc880_uniwill_p53_init_verbs }, | ||
2658 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
2659 | .dac_nids = alc880_asus_dac_nids, | ||
2660 | .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), | ||
2661 | .channel_mode = alc880_threestack_modes, | ||
2662 | .input_mux = &alc880_capture_source, | ||
2663 | .unsol_event = alc880_uniwill_p53_unsol_event, | ||
2664 | .init_hook = alc880_uniwill_p53_hp_automute, | ||
2665 | }, | ||
2666 | [ALC880_FUJITSU] = { | ||
2667 | .mixers = { alc880_fujitsu_mixer, | ||
2668 | alc880_pcbeep_mixer, }, | ||
2669 | .init_verbs = { alc880_volume_init_verbs, | ||
2670 | alc880_uniwill_p53_init_verbs, | ||
2671 | alc880_beep_init_verbs }, | ||
2672 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
2673 | .dac_nids = alc880_dac_nids, | ||
2674 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | ||
2675 | .channel_mode = alc880_2_jack_modes, | ||
2676 | .input_mux = &alc880_capture_source, | ||
2677 | .unsol_event = alc880_uniwill_p53_unsol_event, | ||
2678 | .init_hook = alc880_uniwill_p53_hp_automute, | ||
2679 | }, | ||
2450 | [ALC880_CLEVO] = { | 2680 | [ALC880_CLEVO] = { |
2451 | .mixers = { alc880_three_stack_mixer }, | 2681 | .mixers = { alc880_three_stack_mixer }, |
2452 | .init_verbs = { alc880_volume_init_verbs, | 2682 | .init_verbs = { alc880_volume_init_verbs, |
@@ -2841,8 +3071,10 @@ static int patch_alc880(struct hda_codec *codec) | |||
2841 | 3071 | ||
2842 | codec->spec = spec; | 3072 | codec->spec = spec; |
2843 | 3073 | ||
2844 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); | 3074 | board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, |
2845 | if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { | 3075 | alc880_models, |
3076 | alc880_cfg_tbl); | ||
3077 | if (board_config < 0) { | ||
2846 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, " | 3078 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, " |
2847 | "trying auto-probe from BIOS...\n"); | 3079 | "trying auto-probe from BIOS...\n"); |
2848 | board_config = ALC880_AUTO; | 3080 | board_config = ALC880_AUTO; |
@@ -3090,11 +3322,20 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { | |||
3090 | * and the output jack. If this turns out to be the case for all such | 3322 | * and the output jack. If this turns out to be the case for all such |
3091 | * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT | 3323 | * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT |
3092 | * to ALC_PIN_DIR_INOUT_NOMICBIAS. | 3324 | * to ALC_PIN_DIR_INOUT_NOMICBIAS. |
3325 | * | ||
3326 | * The C20x Tablet series have a mono internal speaker which is controlled | ||
3327 | * via the chip's Mono sum widget and pin complex, so include the necessary | ||
3328 | * controls for such models. On models without a "mono speaker" the control | ||
3329 | * won't do anything. | ||
3093 | */ | 3330 | */ |
3094 | static struct snd_kcontrol_new alc260_acer_mixer[] = { | 3331 | static struct snd_kcontrol_new alc260_acer_mixer[] = { |
3095 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 3332 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
3096 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | 3333 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), |
3097 | ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), | 3334 | ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), |
3335 | HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, | ||
3336 | HDA_OUTPUT), | ||
3337 | HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, | ||
3338 | HDA_INPUT), | ||
3098 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 3339 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
3099 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 3340 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
3100 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | 3341 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), |
@@ -3409,11 +3650,11 @@ static struct hda_verb alc260_acer_init_verbs[] = { | |||
3409 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | 3650 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, |
3410 | /* Line In jack is connected to Line1 pin */ | 3651 | /* Line In jack is connected to Line1 pin */ |
3411 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 3652 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
3653 | /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ | ||
3654 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3412 | /* Ensure all other unused pins are disabled and muted. */ | 3655 | /* Ensure all other unused pins are disabled and muted. */ |
3413 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 3656 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
3414 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 3657 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
3415 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
3416 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3417 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 3658 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
3418 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 3659 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
3419 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 3660 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
@@ -3441,6 +3682,8 @@ static struct hda_verb alc260_acer_init_verbs[] = { | |||
3441 | 3682 | ||
3442 | /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ | 3683 | /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ |
3443 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3684 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
3685 | /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ | ||
3686 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3444 | /* Unmute Mic1 and Line1 pin widget input buffers since they start as | 3687 | /* Unmute Mic1 and Line1 pin widget input buffers since they start as |
3445 | * inputs. If the pin mode is changed by the user the pin mode control | 3688 | * inputs. If the pin mode is changed by the user the pin mode control |
3446 | * will take care of enabling the pin's input/output buffers as needed. | 3689 | * will take care of enabling the pin's input/output buffers as needed. |
@@ -3928,33 +4171,33 @@ static void alc260_auto_init(struct hda_codec *codec) | |||
3928 | /* | 4171 | /* |
3929 | * ALC260 configurations | 4172 | * ALC260 configurations |
3930 | */ | 4173 | */ |
3931 | static struct hda_board_config alc260_cfg_tbl[] = { | 4174 | static const char *alc260_models[ALC260_MODEL_LAST] = { |
3932 | { .modelname = "basic", .config = ALC260_BASIC }, | 4175 | [ALC260_BASIC] = "basic", |
3933 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, | 4176 | [ALC260_HP] = "hp", |
3934 | .config = ALC260_BASIC }, /* Sony VAIO */ | 4177 | [ALC260_HP_3013] = "hp-3013", |
3935 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cc, | 4178 | [ALC260_FUJITSU_S702X] = "fujitsu", |
3936 | .config = ALC260_BASIC }, /* Sony VAIO VGN-S3HP */ | 4179 | [ALC260_ACER] = "acer", |
3937 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cd, | ||
3938 | .config = ALC260_BASIC }, /* Sony VAIO */ | ||
3939 | { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, | ||
3940 | .config = ALC260_BASIC }, /* CTL Travel Master U553W */ | ||
3941 | { .modelname = "hp", .config = ALC260_HP }, | ||
3942 | { .modelname = "hp-3013", .config = ALC260_HP_3013 }, | ||
3943 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP_3013 }, | ||
3944 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, | ||
3945 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 }, | ||
3946 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 }, | ||
3947 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP }, | ||
3948 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP }, | ||
3949 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, | ||
3950 | { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, | ||
3951 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, | ||
3952 | { .modelname = "acer", .config = ALC260_ACER }, | ||
3953 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER }, | ||
3954 | #ifdef CONFIG_SND_DEBUG | 4180 | #ifdef CONFIG_SND_DEBUG |
3955 | { .modelname = "test", .config = ALC260_TEST }, | 4181 | [ALC260_TEST] = "test", |
3956 | #endif | 4182 | #endif |
3957 | { .modelname = "auto", .config = ALC260_AUTO }, | 4183 | [ALC260_AUTO] = "auto", |
4184 | }; | ||
4185 | |||
4186 | static struct snd_pci_quirk alc260_cfg_tbl[] = { | ||
4187 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), | ||
4188 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), | ||
4189 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), | ||
4190 | SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), | ||
4191 | SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), | ||
4192 | SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), | ||
4193 | SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), | ||
4194 | SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), | ||
4195 | SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), | ||
4196 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), | ||
4197 | SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), | ||
4198 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), | ||
4199 | SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), | ||
4200 | SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), | ||
3958 | {} | 4201 | {} |
3959 | }; | 4202 | }; |
3960 | 4203 | ||
@@ -4053,8 +4296,10 @@ static int patch_alc260(struct hda_codec *codec) | |||
4053 | 4296 | ||
4054 | codec->spec = spec; | 4297 | codec->spec = spec; |
4055 | 4298 | ||
4056 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); | 4299 | board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, |
4057 | if (board_config < 0 || board_config >= ALC260_MODEL_LAST) { | 4300 | alc260_models, |
4301 | alc260_cfg_tbl); | ||
4302 | if (board_config < 0) { | ||
4058 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " | 4303 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " |
4059 | "trying auto-probe from BIOS...\n"); | 4304 | "trying auto-probe from BIOS...\n"); |
4060 | board_config = ALC260_AUTO; | 4305 | board_config = ALC260_AUTO; |
@@ -4207,8 +4452,10 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { | |||
4207 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 4452 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
4208 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 4453 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
4209 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 4454 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
4455 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
4210 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 4456 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
4211 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 4457 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
4458 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
4212 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 4459 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
4213 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | 4460 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), |
4214 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | 4461 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), |
@@ -4313,6 +4560,100 @@ static struct hda_verb alc882_eapd_verbs[] = { | |||
4313 | { } | 4560 | { } |
4314 | }; | 4561 | }; |
4315 | 4562 | ||
4563 | /* Mac Pro test */ | ||
4564 | static struct snd_kcontrol_new alc882_macpro_mixer[] = { | ||
4565 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4566 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4567 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), | ||
4568 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
4569 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
4570 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4571 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4572 | { } /* end */ | ||
4573 | }; | ||
4574 | |||
4575 | static struct hda_verb alc882_macpro_init_verbs[] = { | ||
4576 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
4577 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4578 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4579 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4580 | /* Front Pin: output 0 (0x0c) */ | ||
4581 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4582 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4583 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4584 | /* Front Mic pin: input vref at 80% */ | ||
4585 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
4586 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
4587 | /* Speaker: output */ | ||
4588 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4589 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4590 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, | ||
4591 | /* Headphone output (output 0 - 0x0c) */ | ||
4592 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
4593 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4594 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4595 | |||
4596 | /* FIXME: use matrix-type input source selection */ | ||
4597 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
4598 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
4599 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4600 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
4601 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
4602 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
4603 | /* Input mixer2 */ | ||
4604 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4605 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
4606 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
4607 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
4608 | /* Input mixer3 */ | ||
4609 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4610 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
4611 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
4612 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
4613 | /* ADC1: mute amp left and right */ | ||
4614 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4615 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4616 | /* ADC2: mute amp left and right */ | ||
4617 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4618 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4619 | /* ADC3: mute amp left and right */ | ||
4620 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4621 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4622 | |||
4623 | { } | ||
4624 | }; | ||
4625 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) | ||
4626 | { | ||
4627 | unsigned int gpiostate, gpiomask, gpiodir; | ||
4628 | |||
4629 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, | ||
4630 | AC_VERB_GET_GPIO_DATA, 0); | ||
4631 | |||
4632 | if (!muted) | ||
4633 | gpiostate |= (1 << pin); | ||
4634 | else | ||
4635 | gpiostate &= ~(1 << pin); | ||
4636 | |||
4637 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, | ||
4638 | AC_VERB_GET_GPIO_MASK, 0); | ||
4639 | gpiomask |= (1 << pin); | ||
4640 | |||
4641 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, | ||
4642 | AC_VERB_GET_GPIO_DIRECTION, 0); | ||
4643 | gpiodir |= (1 << pin); | ||
4644 | |||
4645 | |||
4646 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4647 | AC_VERB_SET_GPIO_MASK, gpiomask); | ||
4648 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4649 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); | ||
4650 | |||
4651 | msleep(1); | ||
4652 | |||
4653 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4654 | AC_VERB_SET_GPIO_DATA, gpiostate); | ||
4655 | } | ||
4656 | |||
4316 | /* | 4657 | /* |
4317 | * generic initialization of ADC, input mixers and output mixers | 4658 | * generic initialization of ADC, input mixers and output mixers |
4318 | */ | 4659 | */ |
@@ -4435,19 +4776,20 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = { | |||
4435 | /* | 4776 | /* |
4436 | * configuration and preset | 4777 | * configuration and preset |
4437 | */ | 4778 | */ |
4438 | static struct hda_board_config alc882_cfg_tbl[] = { | 4779 | static const char *alc882_models[ALC882_MODEL_LAST] = { |
4439 | { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, | 4780 | [ALC882_3ST_DIG] = "3stack-dig", |
4440 | { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, | 4781 | [ALC882_6ST_DIG] = "6stack-dig", |
4441 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, | 4782 | [ALC882_ARIMA] = "arima", |
4442 | .config = ALC882_6ST_DIG }, /* MSI */ | 4783 | [ALC885_MACPRO] = "macpro", |
4443 | { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, | 4784 | [ALC882_AUTO] = "auto", |
4444 | .config = ALC882_6ST_DIG }, /* Foxconn */ | 4785 | }; |
4445 | { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, | 4786 | |
4446 | .config = ALC882_6ST_DIG }, /* ECS to Intel*/ | 4787 | static struct snd_pci_quirk alc882_cfg_tbl[] = { |
4447 | { .modelname = "arima", .config = ALC882_ARIMA }, | 4788 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), |
4448 | { .pci_subvendor = 0x161f, .pci_subdevice = 0x2054, | 4789 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), |
4449 | .config = ALC882_ARIMA }, /* Arima W820Di1 */ | 4790 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), |
4450 | { .modelname = "auto", .config = ALC882_AUTO }, | 4791 | SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), |
4792 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), | ||
4451 | {} | 4793 | {} |
4452 | }; | 4794 | }; |
4453 | 4795 | ||
@@ -4484,6 +4826,17 @@ static struct alc_config_preset alc882_presets[] = { | |||
4484 | .channel_mode = alc882_sixstack_modes, | 4826 | .channel_mode = alc882_sixstack_modes, |
4485 | .input_mux = &alc882_capture_source, | 4827 | .input_mux = &alc882_capture_source, |
4486 | }, | 4828 | }, |
4829 | [ALC885_MACPRO] = { | ||
4830 | .mixers = { alc882_macpro_mixer }, | ||
4831 | .init_verbs = { alc882_macpro_init_verbs }, | ||
4832 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
4833 | .dac_nids = alc882_dac_nids, | ||
4834 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
4835 | .dig_in_nid = ALC882_DIGIN_NID, | ||
4836 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | ||
4837 | .channel_mode = alc882_ch_modes, | ||
4838 | .input_mux = &alc882_capture_source, | ||
4839 | }, | ||
4487 | }; | 4840 | }; |
4488 | 4841 | ||
4489 | 4842 | ||
@@ -4584,7 +4937,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
4584 | 4937 | ||
4585 | codec->spec = spec; | 4938 | codec->spec = spec; |
4586 | 4939 | ||
4587 | board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); | 4940 | board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, |
4941 | alc882_models, | ||
4942 | alc882_cfg_tbl); | ||
4588 | 4943 | ||
4589 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { | 4944 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { |
4590 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " | 4945 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " |
@@ -4609,6 +4964,11 @@ static int patch_alc882(struct hda_codec *codec) | |||
4609 | if (board_config != ALC882_AUTO) | 4964 | if (board_config != ALC882_AUTO) |
4610 | setup_preset(spec, &alc882_presets[board_config]); | 4965 | setup_preset(spec, &alc882_presets[board_config]); |
4611 | 4966 | ||
4967 | if (board_config == ALC885_MACPRO) { | ||
4968 | alc882_gpio_mute(codec, 0, 0); | ||
4969 | alc882_gpio_mute(codec, 1, 0); | ||
4970 | } | ||
4971 | |||
4612 | spec->stream_name_analog = "ALC882 Analog"; | 4972 | spec->stream_name_analog = "ALC882 Analog"; |
4613 | spec->stream_analog_playback = &alc882_pcm_analog_playback; | 4973 | spec->stream_analog_playback = &alc882_pcm_analog_playback; |
4614 | spec->stream_analog_capture = &alc882_pcm_analog_capture; | 4974 | spec->stream_analog_capture = &alc882_pcm_analog_capture; |
@@ -4767,6 +5127,13 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = { | |||
4767 | { 8, alc883_sixstack_ch8_init }, | 5127 | { 8, alc883_sixstack_ch8_init }, |
4768 | }; | 5128 | }; |
4769 | 5129 | ||
5130 | static struct hda_verb alc883_medion_eapd_verbs[] = { | ||
5131 | /* eanable EAPD on medion laptop */ | ||
5132 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
5133 | {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, | ||
5134 | { } | ||
5135 | }; | ||
5136 | |||
4770 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | 5137 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 |
4771 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | 5138 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b |
4772 | */ | 5139 | */ |
@@ -4788,8 +5155,10 @@ static struct snd_kcontrol_new alc883_base_mixer[] = { | |||
4788 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 5155 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
4789 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 5156 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
4790 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 5157 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
5158 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
4791 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 5159 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
4792 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 5160 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
5161 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
4793 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 5162 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
4794 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | 5163 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), |
4795 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | 5164 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), |
@@ -4818,8 +5187,10 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { | |||
4818 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 5187 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
4819 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 5188 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
4820 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 5189 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
5190 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
4821 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 5191 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
4822 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 5192 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
5193 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
4823 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 5194 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
4824 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | 5195 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), |
4825 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | 5196 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), |
@@ -4854,8 +5225,10 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | |||
4854 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 5225 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
4855 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 5226 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
4856 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 5227 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
5228 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
4857 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 5229 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
4858 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 5230 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
5231 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
4859 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | 5232 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), |
4860 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | 5233 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), |
4861 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | 5234 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), |
@@ -4875,6 +5248,101 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | |||
4875 | { } /* end */ | 5248 | { } /* end */ |
4876 | }; | 5249 | }; |
4877 | 5250 | ||
5251 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { | ||
5252 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5253 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
5254 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
5255 | HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
5256 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
5257 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
5258 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), | ||
5259 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | ||
5260 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5261 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
5262 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
5263 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
5264 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
5265 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
5266 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
5267 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
5268 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
5269 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
5270 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
5271 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
5272 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
5273 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
5274 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
5275 | |||
5276 | { | ||
5277 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5278 | /* .name = "Capture Source", */ | ||
5279 | .name = "Input Source", | ||
5280 | .count = 1, | ||
5281 | .info = alc883_mux_enum_info, | ||
5282 | .get = alc883_mux_enum_get, | ||
5283 | .put = alc883_mux_enum_put, | ||
5284 | }, | ||
5285 | { } /* end */ | ||
5286 | }; | ||
5287 | |||
5288 | static struct snd_kcontrol_new alc883_tagra_mixer[] = { | ||
5289 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5290 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
5291 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5292 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
5293 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
5294 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
5295 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
5296 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
5297 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
5298 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
5299 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
5300 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
5301 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
5302 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
5303 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
5304 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
5305 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
5306 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
5307 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
5308 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
5309 | { | ||
5310 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5311 | /* .name = "Capture Source", */ | ||
5312 | .name = "Input Source", | ||
5313 | .count = 2, | ||
5314 | .info = alc883_mux_enum_info, | ||
5315 | .get = alc883_mux_enum_get, | ||
5316 | .put = alc883_mux_enum_put, | ||
5317 | }, | ||
5318 | { } /* end */ | ||
5319 | }; | ||
5320 | |||
5321 | static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { | ||
5322 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5323 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
5324 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5325 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
5326 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
5327 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
5328 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
5329 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
5330 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
5331 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
5332 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
5333 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
5334 | { | ||
5335 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5336 | /* .name = "Capture Source", */ | ||
5337 | .name = "Input Source", | ||
5338 | .count = 2, | ||
5339 | .info = alc883_mux_enum_info, | ||
5340 | .get = alc883_mux_enum_get, | ||
5341 | .put = alc883_mux_enum_put, | ||
5342 | }, | ||
5343 | { } /* end */ | ||
5344 | }; | ||
5345 | |||
4878 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | 5346 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { |
4879 | { | 5347 | { |
4880 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 5348 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -4963,6 +5431,45 @@ static struct hda_verb alc883_init_verbs[] = { | |||
4963 | { } | 5431 | { } |
4964 | }; | 5432 | }; |
4965 | 5433 | ||
5434 | static struct hda_verb alc883_tagra_verbs[] = { | ||
5435 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5436 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5437 | |||
5438 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
5439 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
5440 | |||
5441 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ | ||
5442 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ | ||
5443 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
5444 | |||
5445 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
5446 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | ||
5447 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | ||
5448 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | ||
5449 | |||
5450 | { } /* end */ | ||
5451 | }; | ||
5452 | |||
5453 | /* toggle speaker-output according to the hp-jack state */ | ||
5454 | static void alc883_tagra_automute(struct hda_codec *codec) | ||
5455 | { | ||
5456 | unsigned int present; | ||
5457 | |||
5458 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
5459 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
5460 | snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, | ||
5461 | 0x80, present ? 0x80 : 0); | ||
5462 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, | ||
5463 | 0x80, present ? 0x80 : 0); | ||
5464 | snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); | ||
5465 | } | ||
5466 | |||
5467 | static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) | ||
5468 | { | ||
5469 | if ((res >> 26) == ALC880_HP_EVENT) | ||
5470 | alc883_tagra_automute(codec); | ||
5471 | } | ||
5472 | |||
4966 | /* | 5473 | /* |
4967 | * generic initialization of ADC, input mixers and output mixers | 5474 | * generic initialization of ADC, input mixers and output mixers |
4968 | */ | 5475 | */ |
@@ -5057,32 +5564,42 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = { | |||
5057 | /* | 5564 | /* |
5058 | * configuration and preset | 5565 | * configuration and preset |
5059 | */ | 5566 | */ |
5060 | static struct hda_board_config alc883_cfg_tbl[] = { | 5567 | static const char *alc883_models[ALC883_MODEL_LAST] = { |
5061 | { .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG }, | 5568 | [ALC883_3ST_2ch_DIG] = "3stack-dig", |
5062 | { .modelname = "3stack-6ch-dig", .config = ALC883_3ST_6ch_DIG }, | 5569 | [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", |
5063 | { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, | 5570 | [ALC883_3ST_6ch] = "3stack-6ch", |
5064 | .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ | 5571 | [ALC883_6ST_DIG] = "6stack-dig", |
5065 | { .modelname = "3stack-6ch", .config = ALC883_3ST_6ch }, | 5572 | [ALC883_TARGA_DIG] = "targa-dig", |
5066 | { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, | 5573 | [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", |
5067 | .config = ALC883_3ST_6ch }, | 5574 | [ALC888_DEMO_BOARD] = "6stack-dig-demo", |
5068 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd601, | 5575 | [ALC883_ACER] = "acer", |
5069 | .config = ALC883_3ST_6ch }, /* D102GGC */ | 5576 | [ALC883_MEDION] = "medion", |
5070 | { .modelname = "6stack-dig", .config = ALC883_6ST_DIG }, | 5577 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", |
5071 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, | 5578 | [ALC883_AUTO] = "auto", |
5072 | .config = ALC883_6ST_DIG }, /* MSI */ | 5579 | }; |
5073 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x7280, | 5580 | |
5074 | .config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */ | 5581 | static struct snd_pci_quirk alc883_cfg_tbl[] = { |
5075 | { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, | 5582 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), |
5076 | .config = ALC883_6ST_DIG }, /* Foxconn */ | 5583 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), |
5077 | { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, | 5584 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), |
5078 | { .modelname = "acer", .config = ALC883_ACER }, | 5585 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), |
5079 | { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/, | 5586 | SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), |
5080 | .config = ALC883_ACER }, | 5587 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), |
5081 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102, | 5588 | SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), |
5082 | .config = ALC883_ACER }, | 5589 | SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), |
5083 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f, | 5590 | SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), |
5084 | .config = ALC883_ACER }, | 5591 | SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), |
5085 | { .modelname = "auto", .config = ALC883_AUTO }, | 5592 | SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), |
5593 | SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), | ||
5594 | SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), | ||
5595 | SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), | ||
5596 | SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), | ||
5597 | SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), | ||
5598 | SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), | ||
5599 | SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), | ||
5600 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), | ||
5601 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), | ||
5602 | SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), | ||
5086 | {} | 5603 | {} |
5087 | }; | 5604 | }; |
5088 | 5605 | ||
@@ -5139,6 +5656,35 @@ static struct alc_config_preset alc883_presets[] = { | |||
5139 | .channel_mode = alc883_sixstack_modes, | 5656 | .channel_mode = alc883_sixstack_modes, |
5140 | .input_mux = &alc883_capture_source, | 5657 | .input_mux = &alc883_capture_source, |
5141 | }, | 5658 | }, |
5659 | [ALC883_TARGA_DIG] = { | ||
5660 | .mixers = { alc883_tagra_mixer, alc883_chmode_mixer }, | ||
5661 | .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, | ||
5662 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5663 | .dac_nids = alc883_dac_nids, | ||
5664 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5665 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5666 | .adc_nids = alc883_adc_nids, | ||
5667 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | ||
5668 | .channel_mode = alc883_3ST_6ch_modes, | ||
5669 | .need_dac_fix = 1, | ||
5670 | .input_mux = &alc883_capture_source, | ||
5671 | .unsol_event = alc883_tagra_unsol_event, | ||
5672 | .init_hook = alc883_tagra_automute, | ||
5673 | }, | ||
5674 | [ALC883_TARGA_2ch_DIG] = { | ||
5675 | .mixers = { alc883_tagra_2ch_mixer}, | ||
5676 | .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, | ||
5677 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5678 | .dac_nids = alc883_dac_nids, | ||
5679 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5680 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5681 | .adc_nids = alc883_adc_nids, | ||
5682 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
5683 | .channel_mode = alc883_3ST_2ch_modes, | ||
5684 | .input_mux = &alc883_capture_source, | ||
5685 | .unsol_event = alc883_tagra_unsol_event, | ||
5686 | .init_hook = alc883_tagra_automute, | ||
5687 | }, | ||
5142 | [ALC888_DEMO_BOARD] = { | 5688 | [ALC888_DEMO_BOARD] = { |
5143 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 5689 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
5144 | .init_verbs = { alc883_init_verbs }, | 5690 | .init_verbs = { alc883_init_verbs }, |
@@ -5169,6 +5715,31 @@ static struct alc_config_preset alc883_presets[] = { | |||
5169 | .channel_mode = alc883_3ST_2ch_modes, | 5715 | .channel_mode = alc883_3ST_2ch_modes, |
5170 | .input_mux = &alc883_capture_source, | 5716 | .input_mux = &alc883_capture_source, |
5171 | }, | 5717 | }, |
5718 | [ALC883_MEDION] = { | ||
5719 | .mixers = { alc883_fivestack_mixer, | ||
5720 | alc883_chmode_mixer }, | ||
5721 | .init_verbs = { alc883_init_verbs, | ||
5722 | alc883_medion_eapd_verbs }, | ||
5723 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5724 | .dac_nids = alc883_dac_nids, | ||
5725 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5726 | .adc_nids = alc883_adc_nids, | ||
5727 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | ||
5728 | .channel_mode = alc883_sixstack_modes, | ||
5729 | .input_mux = &alc883_capture_source, | ||
5730 | }, | ||
5731 | [ALC883_LAPTOP_EAPD] = { | ||
5732 | .mixers = { alc883_base_mixer, | ||
5733 | alc883_chmode_mixer }, | ||
5734 | .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, | ||
5735 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5736 | .dac_nids = alc883_dac_nids, | ||
5737 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5738 | .adc_nids = alc883_adc_nids, | ||
5739 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
5740 | .channel_mode = alc883_3ST_2ch_modes, | ||
5741 | .input_mux = &alc883_capture_source, | ||
5742 | }, | ||
5172 | }; | 5743 | }; |
5173 | 5744 | ||
5174 | 5745 | ||
@@ -5277,8 +5848,10 @@ static int patch_alc883(struct hda_codec *codec) | |||
5277 | 5848 | ||
5278 | codec->spec = spec; | 5849 | codec->spec = spec; |
5279 | 5850 | ||
5280 | board_config = snd_hda_check_board_config(codec, alc883_cfg_tbl); | 5851 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, |
5281 | if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { | 5852 | alc883_models, |
5853 | alc883_cfg_tbl); | ||
5854 | if (board_config < 0) { | ||
5282 | printk(KERN_INFO "hda_codec: Unknown model for ALC883, " | 5855 | printk(KERN_INFO "hda_codec: Unknown model for ALC883, " |
5283 | "trying auto-probe from BIOS...\n"); | 5856 | "trying auto-probe from BIOS...\n"); |
5284 | board_config = ALC883_AUTO; | 5857 | board_config = ALC883_AUTO; |
@@ -5355,6 +5928,24 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
5355 | { } /* end */ | 5928 | { } /* end */ |
5356 | }; | 5929 | }; |
5357 | 5930 | ||
5931 | static struct snd_kcontrol_new alc262_hippo1_mixer[] = { | ||
5932 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5933 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
5934 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
5935 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
5936 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
5937 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
5938 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
5939 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
5940 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
5941 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
5942 | /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
5943 | HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ | ||
5944 | /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ | ||
5945 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5946 | { } /* end */ | ||
5947 | }; | ||
5948 | |||
5358 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | 5949 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { |
5359 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 5950 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
5360 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 5951 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -5377,6 +5968,30 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | |||
5377 | { } /* end */ | 5968 | { } /* end */ |
5378 | }; | 5969 | }; |
5379 | 5970 | ||
5971 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { | ||
5972 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5973 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5974 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
5975 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
5976 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
5977 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | ||
5978 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
5979 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
5980 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
5981 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
5982 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
5983 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
5984 | HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
5985 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
5986 | { } /* end */ | ||
5987 | }; | ||
5988 | |||
5989 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { | ||
5990 | HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
5991 | HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
5992 | { } /* end */ | ||
5993 | }; | ||
5994 | |||
5380 | #define alc262_capture_mixer alc882_capture_mixer | 5995 | #define alc262_capture_mixer alc882_capture_mixer |
5381 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer | 5996 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer |
5382 | 5997 | ||
@@ -5459,6 +6074,103 @@ static struct hda_verb alc262_init_verbs[] = { | |||
5459 | { } | 6074 | { } |
5460 | }; | 6075 | }; |
5461 | 6076 | ||
6077 | static struct hda_verb alc262_hippo_unsol_verbs[] = { | ||
6078 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
6079 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
6080 | {} | ||
6081 | }; | ||
6082 | |||
6083 | static struct hda_verb alc262_hippo1_unsol_verbs[] = { | ||
6084 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
6085 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
6086 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
6087 | |||
6088 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
6089 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
6090 | {} | ||
6091 | }; | ||
6092 | |||
6093 | /* mute/unmute internal speaker according to the hp jack and mute state */ | ||
6094 | static void alc262_hippo_automute(struct hda_codec *codec, int force) | ||
6095 | { | ||
6096 | struct alc_spec *spec = codec->spec; | ||
6097 | unsigned int mute; | ||
6098 | |||
6099 | if (force || ! spec->sense_updated) { | ||
6100 | unsigned int present; | ||
6101 | /* need to execute and sync at first */ | ||
6102 | snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
6103 | present = snd_hda_codec_read(codec, 0x15, 0, | ||
6104 | AC_VERB_GET_PIN_SENSE, 0); | ||
6105 | spec->jack_present = (present & 0x80000000) != 0; | ||
6106 | spec->sense_updated = 1; | ||
6107 | } | ||
6108 | if (spec->jack_present) { | ||
6109 | /* mute internal speaker */ | ||
6110 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
6111 | 0x80, 0x80); | ||
6112 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
6113 | 0x80, 0x80); | ||
6114 | } else { | ||
6115 | /* unmute internal speaker if necessary */ | ||
6116 | mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); | ||
6117 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
6118 | 0x80, mute & 0x80); | ||
6119 | mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0); | ||
6120 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
6121 | 0x80, mute & 0x80); | ||
6122 | } | ||
6123 | } | ||
6124 | |||
6125 | /* unsolicited event for HP jack sensing */ | ||
6126 | static void alc262_hippo_unsol_event(struct hda_codec *codec, | ||
6127 | unsigned int res) | ||
6128 | { | ||
6129 | if ((res >> 26) != ALC880_HP_EVENT) | ||
6130 | return; | ||
6131 | alc262_hippo_automute(codec, 1); | ||
6132 | } | ||
6133 | |||
6134 | static void alc262_hippo1_automute(struct hda_codec *codec, int force) | ||
6135 | { | ||
6136 | struct alc_spec *spec = codec->spec; | ||
6137 | unsigned int mute; | ||
6138 | |||
6139 | if (force || ! spec->sense_updated) { | ||
6140 | unsigned int present; | ||
6141 | /* need to execute and sync at first */ | ||
6142 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
6143 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
6144 | AC_VERB_GET_PIN_SENSE, 0); | ||
6145 | spec->jack_present = (present & 0x80000000) != 0; | ||
6146 | spec->sense_updated = 1; | ||
6147 | } | ||
6148 | if (spec->jack_present) { | ||
6149 | /* mute internal speaker */ | ||
6150 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
6151 | 0x80, 0x80); | ||
6152 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
6153 | 0x80, 0x80); | ||
6154 | } else { | ||
6155 | /* unmute internal speaker if necessary */ | ||
6156 | mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); | ||
6157 | snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
6158 | 0x80, mute & 0x80); | ||
6159 | mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0); | ||
6160 | snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
6161 | 0x80, mute & 0x80); | ||
6162 | } | ||
6163 | } | ||
6164 | |||
6165 | /* unsolicited event for HP jack sensing */ | ||
6166 | static void alc262_hippo1_unsol_event(struct hda_codec *codec, | ||
6167 | unsigned int res) | ||
6168 | { | ||
6169 | if ((res >> 26) != ALC880_HP_EVENT) | ||
6170 | return; | ||
6171 | alc262_hippo1_automute(codec, 1); | ||
6172 | } | ||
6173 | |||
5462 | /* | 6174 | /* |
5463 | * fujitsu model | 6175 | * fujitsu model |
5464 | * 0x14 = headphone/spdif-out, 0x15 = internal speaker | 6176 | * 0x14 = headphone/spdif-out, 0x15 = internal speaker |
@@ -5809,6 +6521,100 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { | |||
5809 | { } | 6521 | { } |
5810 | }; | 6522 | }; |
5811 | 6523 | ||
6524 | static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { | ||
6525 | /* | ||
6526 | * Unmute ADC0-2 and set the default input to mic-in | ||
6527 | */ | ||
6528 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
6529 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
6530 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
6531 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
6532 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
6533 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
6534 | |||
6535 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
6536 | * mixer widget | ||
6537 | * Note: PASD motherboards uses the Line In 2 as the input for front | ||
6538 | * panel mic (mic 2) | ||
6539 | */ | ||
6540 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
6541 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
6542 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
6543 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
6544 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
6545 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
6546 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, | ||
6547 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, | ||
6548 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)}, | ||
6549 | /* | ||
6550 | * Set up output mixers (0x0c - 0x0e) | ||
6551 | */ | ||
6552 | /* set vol=0 to output mixers */ | ||
6553 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6554 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6555 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
6556 | |||
6557 | /* set up input amps for analog loopback */ | ||
6558 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
6559 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
6560 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
6561 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
6562 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
6563 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
6564 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
6565 | |||
6566 | |||
6567 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ | ||
6568 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ | ||
6569 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ | ||
6570 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ | ||
6571 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ | ||
6572 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ | ||
6573 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ | ||
6574 | |||
6575 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6576 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6577 | |||
6578 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
6579 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
6580 | |||
6581 | /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ | ||
6582 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
6583 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
6584 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, | ||
6585 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
6586 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
6587 | |||
6588 | /* FIXME: use matrix-type input source selection */ | ||
6589 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
6590 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
6591 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ | ||
6592 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ | ||
6593 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ | ||
6594 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ | ||
6595 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ | ||
6596 | /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ | ||
6597 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ | ||
6598 | /* Input mixer2 */ | ||
6599 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
6600 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
6601 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
6602 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
6603 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
6604 | /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ | ||
6605 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, | ||
6606 | /* Input mixer3 */ | ||
6607 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
6608 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
6609 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
6610 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
6611 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
6612 | /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ | ||
6613 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, | ||
6614 | |||
6615 | { } | ||
6616 | }; | ||
6617 | |||
5812 | /* pcm configuration: identiacal with ALC880 */ | 6618 | /* pcm configuration: identiacal with ALC880 */ |
5813 | #define alc262_pcm_analog_playback alc880_pcm_analog_playback | 6619 | #define alc262_pcm_analog_playback alc880_pcm_analog_playback |
5814 | #define alc262_pcm_analog_capture alc880_pcm_analog_capture | 6620 | #define alc262_pcm_analog_capture alc880_pcm_analog_capture |
@@ -5866,26 +6672,35 @@ static void alc262_auto_init(struct hda_codec *codec) | |||
5866 | /* | 6672 | /* |
5867 | * configuration and preset | 6673 | * configuration and preset |
5868 | */ | 6674 | */ |
5869 | static struct hda_board_config alc262_cfg_tbl[] = { | 6675 | static const char *alc262_models[ALC262_MODEL_LAST] = { |
5870 | { .modelname = "basic", .config = ALC262_BASIC }, | 6676 | [ALC262_BASIC] = "basic", |
5871 | { .modelname = "fujitsu", .config = ALC262_FUJITSU }, | 6677 | [ALC262_HIPPO] = "hippo", |
5872 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, | 6678 | [ALC262_HIPPO_1] = "hippo_1", |
5873 | .config = ALC262_FUJITSU }, | 6679 | [ALC262_FUJITSU] = "fujitsu", |
5874 | { .modelname = "hp-bpc", .config = ALC262_HP_BPC }, | 6680 | [ALC262_HP_BPC] = "hp-bpc", |
5875 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x280c, | 6681 | [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", |
5876 | .config = ALC262_HP_BPC }, /* xw4400 */ | 6682 | [ALC262_BENQ_ED8] = "benq", |
5877 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x2801, | 6683 | [ALC262_AUTO] = "auto", |
5878 | .config = ALC262_HP_BPC }, /* q965 */ | 6684 | }; |
5879 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, | 6685 | |
5880 | .config = ALC262_HP_BPC }, /* xw6400 */ | 6686 | static struct snd_pci_quirk alc262_cfg_tbl[] = { |
5881 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, | 6687 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), |
5882 | .config = ALC262_HP_BPC }, /* xw8400 */ | 6688 | SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), |
5883 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe, | 6689 | SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), |
5884 | .config = ALC262_HP_BPC }, /* xw9400 */ | 6690 | SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), |
5885 | { .modelname = "benq", .config = ALC262_BENQ_ED8 }, | 6691 | SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), |
5886 | { .pci_subvendor = 0x17ff, .pci_subdevice = 0x0560, | 6692 | SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), |
5887 | .config = ALC262_BENQ_ED8 }, | 6693 | SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), |
5888 | { .modelname = "auto", .config = ALC262_AUTO }, | 6694 | SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), |
6695 | SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), | ||
6696 | SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), | ||
6697 | SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), | ||
6698 | SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), | ||
6699 | SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), | ||
6700 | SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), | ||
6701 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), | ||
6702 | SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), | ||
6703 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), | ||
5889 | {} | 6704 | {} |
5890 | }; | 6705 | }; |
5891 | 6706 | ||
@@ -5900,6 +6715,30 @@ static struct alc_config_preset alc262_presets[] = { | |||
5900 | .channel_mode = alc262_modes, | 6715 | .channel_mode = alc262_modes, |
5901 | .input_mux = &alc262_capture_source, | 6716 | .input_mux = &alc262_capture_source, |
5902 | }, | 6717 | }, |
6718 | [ALC262_HIPPO] = { | ||
6719 | .mixers = { alc262_base_mixer }, | ||
6720 | .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, | ||
6721 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
6722 | .dac_nids = alc262_dac_nids, | ||
6723 | .hp_nid = 0x03, | ||
6724 | .dig_out_nid = ALC262_DIGOUT_NID, | ||
6725 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
6726 | .channel_mode = alc262_modes, | ||
6727 | .input_mux = &alc262_capture_source, | ||
6728 | .unsol_event = alc262_hippo_unsol_event, | ||
6729 | }, | ||
6730 | [ALC262_HIPPO_1] = { | ||
6731 | .mixers = { alc262_hippo1_mixer }, | ||
6732 | .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, | ||
6733 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
6734 | .dac_nids = alc262_dac_nids, | ||
6735 | .hp_nid = 0x02, | ||
6736 | .dig_out_nid = ALC262_DIGOUT_NID, | ||
6737 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
6738 | .channel_mode = alc262_modes, | ||
6739 | .input_mux = &alc262_capture_source, | ||
6740 | .unsol_event = alc262_hippo1_unsol_event, | ||
6741 | }, | ||
5903 | [ALC262_FUJITSU] = { | 6742 | [ALC262_FUJITSU] = { |
5904 | .mixers = { alc262_fujitsu_mixer }, | 6743 | .mixers = { alc262_fujitsu_mixer }, |
5905 | .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, | 6744 | .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, |
@@ -5922,6 +6761,27 @@ static struct alc_config_preset alc262_presets[] = { | |||
5922 | .channel_mode = alc262_modes, | 6761 | .channel_mode = alc262_modes, |
5923 | .input_mux = &alc262_HP_capture_source, | 6762 | .input_mux = &alc262_HP_capture_source, |
5924 | }, | 6763 | }, |
6764 | [ALC262_HP_BPC_D7000_WF] = { | ||
6765 | .mixers = { alc262_HP_BPC_WildWest_mixer }, | ||
6766 | .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, | ||
6767 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
6768 | .dac_nids = alc262_dac_nids, | ||
6769 | .hp_nid = 0x03, | ||
6770 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
6771 | .channel_mode = alc262_modes, | ||
6772 | .input_mux = &alc262_HP_capture_source, | ||
6773 | }, | ||
6774 | [ALC262_HP_BPC_D7000_WL] = { | ||
6775 | .mixers = { alc262_HP_BPC_WildWest_mixer, | ||
6776 | alc262_HP_BPC_WildWest_option_mixer }, | ||
6777 | .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, | ||
6778 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
6779 | .dac_nids = alc262_dac_nids, | ||
6780 | .hp_nid = 0x03, | ||
6781 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
6782 | .channel_mode = alc262_modes, | ||
6783 | .input_mux = &alc262_HP_capture_source, | ||
6784 | }, | ||
5925 | [ALC262_BENQ_ED8] = { | 6785 | [ALC262_BENQ_ED8] = { |
5926 | .mixers = { alc262_base_mixer }, | 6786 | .mixers = { alc262_base_mixer }, |
5927 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, | 6787 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, |
@@ -5940,7 +6800,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
5940 | int board_config; | 6800 | int board_config; |
5941 | int err; | 6801 | int err; |
5942 | 6802 | ||
5943 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | 6803 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5944 | if (spec == NULL) | 6804 | if (spec == NULL) |
5945 | return -ENOMEM; | 6805 | return -ENOMEM; |
5946 | 6806 | ||
@@ -5956,9 +6816,11 @@ static int patch_alc262(struct hda_codec *codec) | |||
5956 | } | 6816 | } |
5957 | #endif | 6817 | #endif |
5958 | 6818 | ||
5959 | board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); | 6819 | board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, |
5960 | 6820 | alc262_models, | |
5961 | if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { | 6821 | alc262_cfg_tbl); |
6822 | |||
6823 | if (board_config < 0) { | ||
5962 | printk(KERN_INFO "hda_codec: Unknown model for ALC262, " | 6824 | printk(KERN_INFO "hda_codec: Unknown model for ALC262, " |
5963 | "trying auto-probe from BIOS...\n"); | 6825 | "trying auto-probe from BIOS...\n"); |
5964 | board_config = ALC262_AUTO; | 6826 | board_config = ALC262_AUTO; |
@@ -6078,6 +6940,44 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { | |||
6078 | { 4, alc861_uniwill_m31_ch4_init }, | 6940 | { 4, alc861_uniwill_m31_ch4_init }, |
6079 | }; | 6941 | }; |
6080 | 6942 | ||
6943 | /* Set mic1 and line-in as input and unmute the mixer */ | ||
6944 | static struct hda_verb alc861_asus_ch2_init[] = { | ||
6945 | /* set pin widget 1Ah (line in) for input */ | ||
6946 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
6947 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ | ||
6948 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
6949 | |||
6950 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | ||
6951 | #if 0 | ||
6952 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ | ||
6953 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ | ||
6954 | #endif | ||
6955 | { } /* end */ | ||
6956 | }; | ||
6957 | /* Set mic1 nad line-in as output and mute mixer */ | ||
6958 | static struct hda_verb alc861_asus_ch6_init[] = { | ||
6959 | /* set pin widget 1Ah (line in) for output (Back Surround)*/ | ||
6960 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
6961 | /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ | ||
6962 | /* set pin widget 18h (mic1) for output (CLFE)*/ | ||
6963 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
6964 | /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ | ||
6965 | { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6966 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
6967 | |||
6968 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, | ||
6969 | #if 0 | ||
6970 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ | ||
6971 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ | ||
6972 | #endif | ||
6973 | { } /* end */ | ||
6974 | }; | ||
6975 | |||
6976 | static struct hda_channel_mode alc861_asus_modes[2] = { | ||
6977 | { 2, alc861_asus_ch2_init }, | ||
6978 | { 6, alc861_asus_ch6_init }, | ||
6979 | }; | ||
6980 | |||
6081 | /* patch-ALC861 */ | 6981 | /* patch-ALC861 */ |
6082 | 6982 | ||
6083 | static struct snd_kcontrol_new alc861_base_mixer[] = { | 6983 | static struct snd_kcontrol_new alc861_base_mixer[] = { |
@@ -6154,7 +7054,29 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { | |||
6154 | .private_value = ARRAY_SIZE(alc861_threestack_modes), | 7054 | .private_value = ARRAY_SIZE(alc861_threestack_modes), |
6155 | }, | 7055 | }, |
6156 | { } /* end */ | 7056 | { } /* end */ |
6157 | }; | 7057 | }; |
7058 | |||
7059 | static struct snd_kcontrol_new alc861_toshiba_mixer[] = { | ||
7060 | /* output mixer control */ | ||
7061 | HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
7062 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | ||
7063 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | ||
7064 | |||
7065 | /*Capture mixer control */ | ||
7066 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
7067 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
7068 | { | ||
7069 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
7070 | .name = "Capture Source", | ||
7071 | .count = 1, | ||
7072 | .info = alc_mux_enum_info, | ||
7073 | .get = alc_mux_enum_get, | ||
7074 | .put = alc_mux_enum_put, | ||
7075 | }, | ||
7076 | |||
7077 | { } /* end */ | ||
7078 | }; | ||
7079 | |||
6158 | static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | 7080 | static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { |
6159 | /* output mixer control */ | 7081 | /* output mixer control */ |
6160 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 7082 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
@@ -6196,7 +7118,58 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | |||
6196 | }, | 7118 | }, |
6197 | { } /* end */ | 7119 | { } /* end */ |
6198 | }; | 7120 | }; |
6199 | 7121 | ||
7122 | static struct snd_kcontrol_new alc861_asus_mixer[] = { | ||
7123 | /* output mixer control */ | ||
7124 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
7125 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | ||
7126 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), | ||
7127 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), | ||
7128 | HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), | ||
7129 | |||
7130 | /* Input mixer control */ | ||
7131 | HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), | ||
7132 | HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
7133 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | ||
7134 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | ||
7135 | HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), | ||
7136 | HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), | ||
7137 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | ||
7138 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | ||
7139 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | ||
7140 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */ | ||
7141 | |||
7142 | /* Capture mixer control */ | ||
7143 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
7144 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
7145 | { | ||
7146 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
7147 | .name = "Capture Source", | ||
7148 | .count = 1, | ||
7149 | .info = alc_mux_enum_info, | ||
7150 | .get = alc_mux_enum_get, | ||
7151 | .put = alc_mux_enum_put, | ||
7152 | }, | ||
7153 | { | ||
7154 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
7155 | .name = "Channel Mode", | ||
7156 | .info = alc_ch_mode_info, | ||
7157 | .get = alc_ch_mode_get, | ||
7158 | .put = alc_ch_mode_put, | ||
7159 | .private_value = ARRAY_SIZE(alc861_asus_modes), | ||
7160 | }, | ||
7161 | { } | ||
7162 | }; | ||
7163 | |||
7164 | /* additional mixer */ | ||
7165 | static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { | ||
7166 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | ||
7167 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | ||
7168 | HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT), | ||
7169 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT), | ||
7170 | { } | ||
7171 | }; | ||
7172 | |||
6200 | /* | 7173 | /* |
6201 | * generic initialization of ADC, input mixers and output mixers | 7174 | * generic initialization of ADC, input mixers and output mixers |
6202 | */ | 7175 | */ |
@@ -6217,7 +7190,7 @@ static struct hda_verb alc861_base_init_verbs[] = { | |||
6217 | /* port-E for HP out (front panel) */ | 7190 | /* port-E for HP out (front panel) */ |
6218 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 7191 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, |
6219 | /* route front PCM to HP */ | 7192 | /* route front PCM to HP */ |
6220 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 7193 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
6221 | /* port-F for mic-in (front panel) with vref */ | 7194 | /* port-F for mic-in (front panel) with vref */ |
6222 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 7195 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
6223 | /* port-G for CLFE (rear panel) */ | 7196 | /* port-G for CLFE (rear panel) */ |
@@ -6281,7 +7254,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { | |||
6281 | /* port-E for HP out (front panel) */ | 7254 | /* port-E for HP out (front panel) */ |
6282 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | 7255 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, |
6283 | /* route front PCM to HP */ | 7256 | /* route front PCM to HP */ |
6284 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 7257 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
6285 | /* port-F for mic-in (front panel) with vref */ | 7258 | /* port-F for mic-in (front panel) with vref */ |
6286 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 7259 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
6287 | /* port-G for CLFE (rear panel) */ | 7260 | /* port-G for CLFE (rear panel) */ |
@@ -6341,7 +7314,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
6341 | /* port-E for HP out (front panel) */ | 7314 | /* port-E for HP out (front panel) */ |
6342 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 | 7315 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 |
6343 | /* route front PCM to HP */ | 7316 | /* route front PCM to HP */ |
6344 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 7317 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
6345 | /* port-F for mic-in (front panel) with vref */ | 7318 | /* port-F for mic-in (front panel) with vref */ |
6346 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 7319 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
6347 | /* port-G for CLFE (rear panel) */ | 7320 | /* port-G for CLFE (rear panel) */ |
@@ -6385,6 +7358,74 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
6385 | { } | 7358 | { } |
6386 | }; | 7359 | }; |
6387 | 7360 | ||
7361 | static struct hda_verb alc861_asus_init_verbs[] = { | ||
7362 | /* | ||
7363 | * Unmute ADC0 and set the default input to mic-in | ||
7364 | */ | ||
7365 | /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/ | ||
7366 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ | ||
7367 | /* route front PCM to HP */ | ||
7368 | { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
7369 | /* port-B for mic-in (rear panel) with vref */ | ||
7370 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
7371 | /* port-C for line-in (rear panel) */ | ||
7372 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
7373 | /* port-D for Front */ | ||
7374 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
7375 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
7376 | /* port-E for HP out (front panel) */ | ||
7377 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */ | ||
7378 | /* route front PCM to HP */ | ||
7379 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
7380 | /* port-F for mic-in (front panel) with vref */ | ||
7381 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
7382 | /* port-G for CLFE (rear panel) */ | ||
7383 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
7384 | /* port-H for side (rear panel) */ | ||
7385 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
7386 | /* CD-in */ | ||
7387 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
7388 | /* route front mic to ADC1*/ | ||
7389 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7390 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7391 | /* Unmute DAC0~3 & spdif out*/ | ||
7392 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7393 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7394 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7395 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7396 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
7397 | /* Unmute Mixer 14 (mic) 1c (Line in)*/ | ||
7398 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7399 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
7400 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7401 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
7402 | |||
7403 | /* Unmute Stereo Mixer 15 */ | ||
7404 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7405 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
7406 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
7407 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, /* Output 0~12 step */ | ||
7408 | |||
7409 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7410 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
7411 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7412 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
7413 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7414 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
7415 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
7416 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
7417 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */ | ||
7418 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
7419 | { } | ||
7420 | }; | ||
7421 | |||
7422 | /* additional init verbs for ASUS laptops */ | ||
7423 | static struct hda_verb alc861_asus_laptop_init_verbs[] = { | ||
7424 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ | ||
7425 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ | ||
7426 | { } | ||
7427 | }; | ||
7428 | |||
6388 | /* | 7429 | /* |
6389 | * generic initialization of ADC, input mixers and output mixers | 7430 | * generic initialization of ADC, input mixers and output mixers |
6390 | */ | 7431 | */ |
@@ -6437,6 +7478,39 @@ static struct hda_verb alc861_auto_init_verbs[] = { | |||
6437 | { } | 7478 | { } |
6438 | }; | 7479 | }; |
6439 | 7480 | ||
7481 | static struct hda_verb alc861_toshiba_init_verbs[] = { | ||
7482 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | ||
7483 | |||
7484 | { } | ||
7485 | }; | ||
7486 | |||
7487 | /* toggle speaker-output according to the hp-jack state */ | ||
7488 | static void alc861_toshiba_automute(struct hda_codec *codec) | ||
7489 | { | ||
7490 | unsigned int present; | ||
7491 | |||
7492 | present = snd_hda_codec_read(codec, 0x0f, 0, | ||
7493 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
7494 | snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0, | ||
7495 | 0x80, present ? 0x80 : 0); | ||
7496 | snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0, | ||
7497 | 0x80, present ? 0x80 : 0); | ||
7498 | snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3, | ||
7499 | 0x80, present ? 0 : 0x80); | ||
7500 | snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3, | ||
7501 | 0x80, present ? 0 : 0x80); | ||
7502 | } | ||
7503 | |||
7504 | static void alc861_toshiba_unsol_event(struct hda_codec *codec, | ||
7505 | unsigned int res) | ||
7506 | { | ||
7507 | /* Looks like the unsol event is incompatible with the standard | ||
7508 | * definition. 6bit tag is placed at 26 bit! | ||
7509 | */ | ||
7510 | if ((res >> 26) == ALC880_HP_EVENT) | ||
7511 | alc861_toshiba_automute(codec); | ||
7512 | } | ||
7513 | |||
6440 | /* pcm configuration: identiacal with ALC880 */ | 7514 | /* pcm configuration: identiacal with ALC880 */ |
6441 | #define alc861_pcm_analog_playback alc880_pcm_analog_playback | 7515 | #define alc861_pcm_analog_playback alc880_pcm_analog_playback |
6442 | #define alc861_pcm_analog_capture alc880_pcm_analog_capture | 7516 | #define alc861_pcm_analog_capture alc880_pcm_analog_capture |
@@ -6710,19 +7784,29 @@ static void alc861_auto_init(struct hda_codec *codec) | |||
6710 | /* | 7784 | /* |
6711 | * configuration and preset | 7785 | * configuration and preset |
6712 | */ | 7786 | */ |
6713 | static struct hda_board_config alc861_cfg_tbl[] = { | 7787 | static const char *alc861_models[ALC861_MODEL_LAST] = { |
6714 | { .modelname = "3stack", .config = ALC861_3ST }, | 7788 | [ALC861_3ST] = "3stack", |
6715 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, | 7789 | [ALC660_3ST] = "3stack-660", |
6716 | .config = ALC861_3ST }, | 7790 | [ALC861_3ST_DIG] = "3stack-dig", |
6717 | { .modelname = "3stack-660", .config = ALC660_3ST }, | 7791 | [ALC861_6ST_DIG] = "6stack-dig", |
6718 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7, | 7792 | [ALC861_UNIWILL_M31] = "uniwill-m31", |
6719 | .config = ALC660_3ST }, | 7793 | [ALC861_TOSHIBA] = "toshiba", |
6720 | { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, | 7794 | [ALC861_ASUS] = "asus", |
6721 | { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, | 7795 | [ALC861_ASUS_LAPTOP] = "asus-laptop", |
6722 | { .modelname = "uniwill-m31", .config = ALC861_UNIWILL_M31}, | 7796 | [ALC861_AUTO] = "auto", |
6723 | { .pci_subvendor = 0x1584, .pci_subdevice = 0x9072, | 7797 | }; |
6724 | .config = ALC861_UNIWILL_M31 }, | 7798 | |
6725 | { .modelname = "auto", .config = ALC861_AUTO }, | 7799 | static struct snd_pci_quirk alc861_cfg_tbl[] = { |
7800 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), | ||
7801 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), | ||
7802 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), | ||
7803 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), | ||
7804 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST), | ||
7805 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), | ||
7806 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), | ||
7807 | SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), | ||
7808 | SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), | ||
7809 | SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), | ||
6726 | {} | 7810 | {} |
6727 | }; | 7811 | }; |
6728 | 7812 | ||
@@ -6789,8 +7873,48 @@ static struct alc_config_preset alc861_presets[] = { | |||
6789 | .adc_nids = alc861_adc_nids, | 7873 | .adc_nids = alc861_adc_nids, |
6790 | .input_mux = &alc861_capture_source, | 7874 | .input_mux = &alc861_capture_source, |
6791 | }, | 7875 | }, |
6792 | 7876 | [ALC861_TOSHIBA] = { | |
6793 | }; | 7877 | .mixers = { alc861_toshiba_mixer }, |
7878 | .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs }, | ||
7879 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
7880 | .dac_nids = alc861_dac_nids, | ||
7881 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
7882 | .channel_mode = alc883_3ST_2ch_modes, | ||
7883 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
7884 | .adc_nids = alc861_adc_nids, | ||
7885 | .input_mux = &alc861_capture_source, | ||
7886 | .unsol_event = alc861_toshiba_unsol_event, | ||
7887 | .init_hook = alc861_toshiba_automute, | ||
7888 | }, | ||
7889 | [ALC861_ASUS] = { | ||
7890 | .mixers = { alc861_asus_mixer }, | ||
7891 | .init_verbs = { alc861_asus_init_verbs }, | ||
7892 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
7893 | .dac_nids = alc861_dac_nids, | ||
7894 | .dig_out_nid = ALC861_DIGOUT_NID, | ||
7895 | .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), | ||
7896 | .channel_mode = alc861_asus_modes, | ||
7897 | .need_dac_fix = 1, | ||
7898 | .hp_nid = 0x06, | ||
7899 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
7900 | .adc_nids = alc861_adc_nids, | ||
7901 | .input_mux = &alc861_capture_source, | ||
7902 | }, | ||
7903 | [ALC861_ASUS_LAPTOP] = { | ||
7904 | .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, | ||
7905 | .init_verbs = { alc861_asus_init_verbs, | ||
7906 | alc861_asus_laptop_init_verbs }, | ||
7907 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
7908 | .dac_nids = alc861_dac_nids, | ||
7909 | .dig_out_nid = ALC861_DIGOUT_NID, | ||
7910 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
7911 | .channel_mode = alc883_3ST_2ch_modes, | ||
7912 | .need_dac_fix = 1, | ||
7913 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
7914 | .adc_nids = alc861_adc_nids, | ||
7915 | .input_mux = &alc861_capture_source, | ||
7916 | }, | ||
7917 | }; | ||
6794 | 7918 | ||
6795 | 7919 | ||
6796 | static int patch_alc861(struct hda_codec *codec) | 7920 | static int patch_alc861(struct hda_codec *codec) |
@@ -6799,15 +7923,17 @@ static int patch_alc861(struct hda_codec *codec) | |||
6799 | int board_config; | 7923 | int board_config; |
6800 | int err; | 7924 | int err; |
6801 | 7925 | ||
6802 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | 7926 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
6803 | if (spec == NULL) | 7927 | if (spec == NULL) |
6804 | return -ENOMEM; | 7928 | return -ENOMEM; |
6805 | 7929 | ||
6806 | codec->spec = spec; | 7930 | codec->spec = spec; |
6807 | 7931 | ||
6808 | board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl); | 7932 | board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, |
7933 | alc861_models, | ||
7934 | alc861_cfg_tbl); | ||
6809 | 7935 | ||
6810 | if (board_config < 0 || board_config >= ALC861_MODEL_LAST) { | 7936 | if (board_config < 0) { |
6811 | printk(KERN_INFO "hda_codec: Unknown model for ALC861, " | 7937 | printk(KERN_INFO "hda_codec: Unknown model for ALC861, " |
6812 | "trying auto-probe from BIOS...\n"); | 7938 | "trying auto-probe from BIOS...\n"); |
6813 | board_config = ALC861_AUTO; | 7939 | board_config = ALC861_AUTO; |
@@ -6846,19 +7972,706 @@ static int patch_alc861(struct hda_codec *codec) | |||
6846 | } | 7972 | } |
6847 | 7973 | ||
6848 | /* | 7974 | /* |
7975 | * ALC861-VD support | ||
7976 | * | ||
7977 | * Based on ALC882 | ||
7978 | * | ||
7979 | * In addition, an independent DAC | ||
7980 | */ | ||
7981 | #define ALC861VD_DIGOUT_NID 0x06 | ||
7982 | |||
7983 | static hda_nid_t alc861vd_dac_nids[4] = { | ||
7984 | /* front, surr, clfe, side surr */ | ||
7985 | 0x02, 0x03, 0x04, 0x05 | ||
7986 | }; | ||
7987 | |||
7988 | /* dac_nids for ALC660vd are in a different order - according to | ||
7989 | * Realtek's driver. | ||
7990 | * This should probably tesult in a different mixer for 6stack models | ||
7991 | * of ALC660vd codecs, but for now there is only 3stack mixer | ||
7992 | * - and it is the same as in 861vd. | ||
7993 | * adc_nids in ALC660vd are (is) the same as in 861vd | ||
7994 | */ | ||
7995 | static hda_nid_t alc660vd_dac_nids[3] = { | ||
7996 | /* front, rear, clfe, rear_surr */ | ||
7997 | 0x02, 0x04, 0x03 | ||
7998 | }; | ||
7999 | |||
8000 | static hda_nid_t alc861vd_adc_nids[1] = { | ||
8001 | /* ADC0 */ | ||
8002 | 0x09, | ||
8003 | }; | ||
8004 | |||
8005 | /* input MUX */ | ||
8006 | /* FIXME: should be a matrix-type input source selection */ | ||
8007 | static struct hda_input_mux alc861vd_capture_source = { | ||
8008 | .num_items = 4, | ||
8009 | .items = { | ||
8010 | { "Mic", 0x0 }, | ||
8011 | { "Front Mic", 0x1 }, | ||
8012 | { "Line", 0x2 }, | ||
8013 | { "CD", 0x4 }, | ||
8014 | }, | ||
8015 | }; | ||
8016 | |||
8017 | #define alc861vd_mux_enum_info alc_mux_enum_info | ||
8018 | #define alc861vd_mux_enum_get alc_mux_enum_get | ||
8019 | |||
8020 | static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
8021 | struct snd_ctl_elem_value *ucontrol) | ||
8022 | { | ||
8023 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
8024 | struct alc_spec *spec = codec->spec; | ||
8025 | const struct hda_input_mux *imux = spec->input_mux; | ||
8026 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
8027 | static hda_nid_t capture_mixers[1] = { 0x22 }; | ||
8028 | hda_nid_t nid = capture_mixers[adc_idx]; | ||
8029 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | ||
8030 | unsigned int i, idx; | ||
8031 | |||
8032 | idx = ucontrol->value.enumerated.item[0]; | ||
8033 | if (idx >= imux->num_items) | ||
8034 | idx = imux->num_items - 1; | ||
8035 | if (*cur_val == idx && ! codec->in_resume) | ||
8036 | return 0; | ||
8037 | for (i = 0; i < imux->num_items; i++) { | ||
8038 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | ||
8039 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
8040 | v | (imux->items[i].index << 8)); | ||
8041 | } | ||
8042 | *cur_val = idx; | ||
8043 | return 1; | ||
8044 | } | ||
8045 | |||
8046 | /* | ||
8047 | * 2ch mode | ||
8048 | */ | ||
8049 | static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { | ||
8050 | { 2, NULL } | ||
8051 | }; | ||
8052 | |||
8053 | /* | ||
8054 | * 6ch mode | ||
8055 | */ | ||
8056 | static struct hda_verb alc861vd_6stack_ch6_init[] = { | ||
8057 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
8058 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
8059 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
8060 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
8061 | { } /* end */ | ||
8062 | }; | ||
8063 | |||
8064 | /* | ||
8065 | * 8ch mode | ||
8066 | */ | ||
8067 | static struct hda_verb alc861vd_6stack_ch8_init[] = { | ||
8068 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
8069 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
8070 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
8071 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
8072 | { } /* end */ | ||
8073 | }; | ||
8074 | |||
8075 | static struct hda_channel_mode alc861vd_6stack_modes[2] = { | ||
8076 | { 6, alc861vd_6stack_ch6_init }, | ||
8077 | { 8, alc861vd_6stack_ch8_init }, | ||
8078 | }; | ||
8079 | |||
8080 | static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { | ||
8081 | { | ||
8082 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
8083 | .name = "Channel Mode", | ||
8084 | .info = alc_ch_mode_info, | ||
8085 | .get = alc_ch_mode_get, | ||
8086 | .put = alc_ch_mode_put, | ||
8087 | }, | ||
8088 | { } /* end */ | ||
8089 | }; | ||
8090 | |||
8091 | static struct snd_kcontrol_new alc861vd_capture_mixer[] = { | ||
8092 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
8093 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
8094 | |||
8095 | { | ||
8096 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
8097 | /* The multiple "Capture Source" controls confuse alsamixer | ||
8098 | * So call somewhat different.. | ||
8099 | *FIXME: the controls appear in the "playback" view! | ||
8100 | */ | ||
8101 | /* .name = "Capture Source", */ | ||
8102 | .name = "Input Source", | ||
8103 | .count = 1, | ||
8104 | .info = alc861vd_mux_enum_info, | ||
8105 | .get = alc861vd_mux_enum_get, | ||
8106 | .put = alc861vd_mux_enum_put, | ||
8107 | }, | ||
8108 | { } /* end */ | ||
8109 | }; | ||
8110 | |||
8111 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | ||
8112 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | ||
8113 | */ | ||
8114 | static struct snd_kcontrol_new alc861vd_6st_mixer[] = { | ||
8115 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
8116 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
8117 | |||
8118 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
8119 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
8120 | |||
8121 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, | ||
8122 | HDA_OUTPUT), | ||
8123 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, | ||
8124 | HDA_OUTPUT), | ||
8125 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
8126 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
8127 | |||
8128 | HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), | ||
8129 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | ||
8130 | |||
8131 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
8132 | |||
8133 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
8134 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
8135 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
8136 | |||
8137 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
8138 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
8139 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
8140 | |||
8141 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
8142 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
8143 | |||
8144 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
8145 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
8146 | |||
8147 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
8148 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
8149 | |||
8150 | { } /* end */ | ||
8151 | }; | ||
8152 | |||
8153 | static struct snd_kcontrol_new alc861vd_3st_mixer[] = { | ||
8154 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
8155 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
8156 | |||
8157 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
8158 | |||
8159 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
8160 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
8161 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
8162 | |||
8163 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
8164 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
8165 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
8166 | |||
8167 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
8168 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
8169 | |||
8170 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
8171 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
8172 | |||
8173 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
8174 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
8175 | |||
8176 | { } /* end */ | ||
8177 | }; | ||
8178 | |||
8179 | /* | ||
8180 | * generic initialization of ADC, input mixers and output mixers | ||
8181 | */ | ||
8182 | static struct hda_verb alc861vd_volume_init_verbs[] = { | ||
8183 | /* | ||
8184 | * Unmute ADC0 and set the default input to mic-in | ||
8185 | */ | ||
8186 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8187 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8188 | |||
8189 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of | ||
8190 | * the analog-loopback mixer widget | ||
8191 | */ | ||
8192 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
8193 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8194 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8195 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
8196 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
8197 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
8198 | |||
8199 | /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ | ||
8200 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
8201 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, | ||
8202 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, | ||
8203 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)}, | ||
8204 | |||
8205 | /* | ||
8206 | * Set up output mixers (0x02 - 0x05) | ||
8207 | */ | ||
8208 | /* set vol=0 to output mixers */ | ||
8209 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
8210 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
8211 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
8212 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
8213 | |||
8214 | /* set up input amps for analog loopback */ | ||
8215 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
8216 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
8217 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
8218 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
8219 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
8220 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
8221 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
8222 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
8223 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
8224 | |||
8225 | { } | ||
8226 | }; | ||
8227 | |||
8228 | /* | ||
8229 | * 3-stack pin configuration: | ||
8230 | * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b | ||
8231 | */ | ||
8232 | static struct hda_verb alc861vd_3stack_init_verbs[] = { | ||
8233 | /* | ||
8234 | * Set pin mode and muting | ||
8235 | */ | ||
8236 | /* set front pin widgets 0x14 for output */ | ||
8237 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
8238 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8239 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8240 | |||
8241 | /* Mic (rear) pin: input vref at 80% */ | ||
8242 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
8243 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8244 | /* Front Mic pin: input vref at 80% */ | ||
8245 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
8246 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8247 | /* Line In pin: input */ | ||
8248 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
8249 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8250 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
8251 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
8252 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8253 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8254 | /* CD pin widget for input */ | ||
8255 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
8256 | |||
8257 | { } | ||
8258 | }; | ||
8259 | |||
8260 | /* | ||
8261 | * 6-stack pin configuration: | ||
8262 | */ | ||
8263 | static struct hda_verb alc861vd_6stack_init_verbs[] = { | ||
8264 | /* | ||
8265 | * Set pin mode and muting | ||
8266 | */ | ||
8267 | /* set front pin widgets 0x14 for output */ | ||
8268 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
8269 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8270 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8271 | |||
8272 | /* Rear Pin: output 1 (0x0d) */ | ||
8273 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
8274 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8275 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
8276 | /* CLFE Pin: output 2 (0x0e) */ | ||
8277 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
8278 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8279 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
8280 | /* Side Pin: output 3 (0x0f) */ | ||
8281 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
8282 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8283 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
8284 | |||
8285 | /* Mic (rear) pin: input vref at 80% */ | ||
8286 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
8287 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8288 | /* Front Mic pin: input vref at 80% */ | ||
8289 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
8290 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8291 | /* Line In pin: input */ | ||
8292 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
8293 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8294 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
8295 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
8296 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8297 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8298 | /* CD pin widget for input */ | ||
8299 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
8300 | |||
8301 | { } | ||
8302 | }; | ||
8303 | |||
8304 | /* pcm configuration: identiacal with ALC880 */ | ||
8305 | #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback | ||
8306 | #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture | ||
8307 | #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback | ||
8308 | #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture | ||
8309 | |||
8310 | /* | ||
8311 | * configuration and preset | ||
8312 | */ | ||
8313 | static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { | ||
8314 | [ALC660VD_3ST] = "3stack-660", | ||
8315 | [ALC861VD_3ST] = "3stack", | ||
8316 | [ALC861VD_3ST_DIG] = "3stack-digout", | ||
8317 | [ALC861VD_6ST_DIG] = "6stack-digout", | ||
8318 | [ALC861VD_AUTO] = "auto", | ||
8319 | }; | ||
8320 | |||
8321 | static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | ||
8322 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), | ||
8323 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), | ||
8324 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), | ||
8325 | |||
8326 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST), | ||
8327 | {} | ||
8328 | }; | ||
8329 | |||
8330 | static struct alc_config_preset alc861vd_presets[] = { | ||
8331 | [ALC660VD_3ST] = { | ||
8332 | .mixers = { alc861vd_3st_mixer }, | ||
8333 | .init_verbs = { alc861vd_volume_init_verbs, | ||
8334 | alc861vd_3stack_init_verbs }, | ||
8335 | .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), | ||
8336 | .dac_nids = alc660vd_dac_nids, | ||
8337 | .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), | ||
8338 | .adc_nids = alc861vd_adc_nids, | ||
8339 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
8340 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
8341 | .input_mux = &alc861vd_capture_source, | ||
8342 | }, | ||
8343 | [ALC861VD_3ST] = { | ||
8344 | .mixers = { alc861vd_3st_mixer }, | ||
8345 | .init_verbs = { alc861vd_volume_init_verbs, | ||
8346 | alc861vd_3stack_init_verbs }, | ||
8347 | .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), | ||
8348 | .dac_nids = alc861vd_dac_nids, | ||
8349 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
8350 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
8351 | .input_mux = &alc861vd_capture_source, | ||
8352 | }, | ||
8353 | [ALC861VD_3ST_DIG] = { | ||
8354 | .mixers = { alc861vd_3st_mixer }, | ||
8355 | .init_verbs = { alc861vd_volume_init_verbs, | ||
8356 | alc861vd_3stack_init_verbs }, | ||
8357 | .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), | ||
8358 | .dac_nids = alc861vd_dac_nids, | ||
8359 | .dig_out_nid = ALC861VD_DIGOUT_NID, | ||
8360 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
8361 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
8362 | .input_mux = &alc861vd_capture_source, | ||
8363 | }, | ||
8364 | [ALC861VD_6ST_DIG] = { | ||
8365 | .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, | ||
8366 | .init_verbs = { alc861vd_volume_init_verbs, | ||
8367 | alc861vd_6stack_init_verbs }, | ||
8368 | .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), | ||
8369 | .dac_nids = alc861vd_dac_nids, | ||
8370 | .dig_out_nid = ALC861VD_DIGOUT_NID, | ||
8371 | .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), | ||
8372 | .channel_mode = alc861vd_6stack_modes, | ||
8373 | .input_mux = &alc861vd_capture_source, | ||
8374 | }, | ||
8375 | }; | ||
8376 | |||
8377 | /* | ||
8378 | * BIOS auto configuration | ||
8379 | */ | ||
8380 | static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, | ||
8381 | hda_nid_t nid, int pin_type, int dac_idx) | ||
8382 | { | ||
8383 | /* set as output */ | ||
8384 | snd_hda_codec_write(codec, nid, 0, | ||
8385 | AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | ||
8386 | snd_hda_codec_write(codec, nid, 0, | ||
8387 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | ||
8388 | } | ||
8389 | |||
8390 | static void alc861vd_auto_init_multi_out(struct hda_codec *codec) | ||
8391 | { | ||
8392 | struct alc_spec *spec = codec->spec; | ||
8393 | int i; | ||
8394 | |||
8395 | for (i = 0; i <= HDA_SIDE; i++) { | ||
8396 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
8397 | if (nid) | ||
8398 | alc861vd_auto_set_output_and_unmute(codec, nid, | ||
8399 | PIN_OUT, i); | ||
8400 | } | ||
8401 | } | ||
8402 | |||
8403 | |||
8404 | static void alc861vd_auto_init_hp_out(struct hda_codec *codec) | ||
8405 | { | ||
8406 | struct alc_spec *spec = codec->spec; | ||
8407 | hda_nid_t pin; | ||
8408 | |||
8409 | pin = spec->autocfg.hp_pins[0]; | ||
8410 | if (pin) /* connect to front and use dac 0 */ | ||
8411 | alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
8412 | } | ||
8413 | |||
8414 | #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid) | ||
8415 | #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID | ||
8416 | |||
8417 | static void alc861vd_auto_init_analog_input(struct hda_codec *codec) | ||
8418 | { | ||
8419 | struct alc_spec *spec = codec->spec; | ||
8420 | int i; | ||
8421 | |||
8422 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
8423 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
8424 | if (alc861vd_is_input_pin(nid)) { | ||
8425 | snd_hda_codec_write(codec, nid, 0, | ||
8426 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
8427 | i <= AUTO_PIN_FRONT_MIC ? | ||
8428 | PIN_VREF80 : PIN_IN); | ||
8429 | if (nid != ALC861VD_PIN_CD_NID) | ||
8430 | snd_hda_codec_write(codec, nid, 0, | ||
8431 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
8432 | AMP_OUT_MUTE); | ||
8433 | } | ||
8434 | } | ||
8435 | } | ||
8436 | |||
8437 | #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) | ||
8438 | #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) | ||
8439 | |||
8440 | /* add playback controls from the parsed DAC table */ | ||
8441 | /* Based on ALC880 version. But ALC861VD has separate, | ||
8442 | * different NIDs for mute/unmute switch and volume control */ | ||
8443 | static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | ||
8444 | const struct auto_pin_cfg *cfg) | ||
8445 | { | ||
8446 | char name[32]; | ||
8447 | static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; | ||
8448 | hda_nid_t nid_v, nid_s; | ||
8449 | int i, err; | ||
8450 | |||
8451 | for (i = 0; i < cfg->line_outs; i++) { | ||
8452 | if (! spec->multiout.dac_nids[i]) | ||
8453 | continue; | ||
8454 | nid_v = alc861vd_idx_to_mixer_vol( | ||
8455 | alc880_dac_to_idx( | ||
8456 | spec->multiout.dac_nids[i])); | ||
8457 | nid_s = alc861vd_idx_to_mixer_switch( | ||
8458 | alc880_dac_to_idx( | ||
8459 | spec->multiout.dac_nids[i])); | ||
8460 | |||
8461 | if (i == 2) { | ||
8462 | /* Center/LFE */ | ||
8463 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
8464 | "Center Playback Volume", | ||
8465 | HDA_COMPOSE_AMP_VAL(nid_v, 1, | ||
8466 | 0, HDA_OUTPUT))) < 0) | ||
8467 | return err; | ||
8468 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
8469 | "LFE Playback Volume", | ||
8470 | HDA_COMPOSE_AMP_VAL(nid_v, 2, | ||
8471 | 0, HDA_OUTPUT))) < 0) | ||
8472 | return err; | ||
8473 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, | ||
8474 | "Center Playback Switch", | ||
8475 | HDA_COMPOSE_AMP_VAL(nid_s, 1, | ||
8476 | 2, HDA_INPUT))) < 0) | ||
8477 | return err; | ||
8478 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, | ||
8479 | "LFE Playback Switch", | ||
8480 | HDA_COMPOSE_AMP_VAL(nid_s, 2, | ||
8481 | 2, HDA_INPUT))) < 0) | ||
8482 | return err; | ||
8483 | } else { | ||
8484 | sprintf(name, "%s Playback Volume", chname[i]); | ||
8485 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
8486 | HDA_COMPOSE_AMP_VAL(nid_v, 3, | ||
8487 | 0, HDA_OUTPUT))) < 0) | ||
8488 | return err; | ||
8489 | sprintf(name, "%s Playback Switch", chname[i]); | ||
8490 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
8491 | HDA_COMPOSE_AMP_VAL(nid_v, 3, | ||
8492 | 2, HDA_INPUT))) < 0) | ||
8493 | return err; | ||
8494 | } | ||
8495 | } | ||
8496 | return 0; | ||
8497 | } | ||
8498 | |||
8499 | /* add playback controls for speaker and HP outputs */ | ||
8500 | /* Based on ALC880 version. But ALC861VD has separate, | ||
8501 | * different NIDs for mute/unmute switch and volume control */ | ||
8502 | static int alc861vd_auto_create_extra_out(struct alc_spec *spec, | ||
8503 | hda_nid_t pin, const char *pfx) | ||
8504 | { | ||
8505 | hda_nid_t nid_v, nid_s; | ||
8506 | int err; | ||
8507 | char name[32]; | ||
8508 | |||
8509 | if (! pin) | ||
8510 | return 0; | ||
8511 | |||
8512 | if (alc880_is_fixed_pin(pin)) { | ||
8513 | nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | ||
8514 | /* specify the DAC as the extra output */ | ||
8515 | if (! spec->multiout.hp_nid) | ||
8516 | spec->multiout.hp_nid = nid_v; | ||
8517 | else | ||
8518 | spec->multiout.extra_out_nid[0] = nid_v; | ||
8519 | /* control HP volume/switch on the output mixer amp */ | ||
8520 | nid_v = alc861vd_idx_to_mixer_vol( | ||
8521 | alc880_fixed_pin_idx(pin)); | ||
8522 | nid_s = alc861vd_idx_to_mixer_switch( | ||
8523 | alc880_fixed_pin_idx(pin)); | ||
8524 | |||
8525 | sprintf(name, "%s Playback Volume", pfx); | ||
8526 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
8527 | HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, | ||
8528 | HDA_OUTPUT))) < 0) | ||
8529 | return err; | ||
8530 | sprintf(name, "%s Playback Switch", pfx); | ||
8531 | if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, | ||
8532 | HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, | ||
8533 | HDA_INPUT))) < 0) | ||
8534 | return err; | ||
8535 | } else if (alc880_is_multi_pin(pin)) { | ||
8536 | /* set manual connection */ | ||
8537 | /* we have only a switch on HP-out PIN */ | ||
8538 | sprintf(name, "%s Playback Switch", pfx); | ||
8539 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
8540 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, | ||
8541 | HDA_OUTPUT))) < 0) | ||
8542 | return err; | ||
8543 | } | ||
8544 | return 0; | ||
8545 | } | ||
8546 | |||
8547 | /* parse the BIOS configuration and set up the alc_spec | ||
8548 | * return 1 if successful, 0 if the proper config is not found, | ||
8549 | * or a negative error code | ||
8550 | * Based on ALC880 version - had to change it to override | ||
8551 | * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ | ||
8552 | static int alc861vd_parse_auto_config(struct hda_codec *codec) | ||
8553 | { | ||
8554 | struct alc_spec *spec = codec->spec; | ||
8555 | int err; | ||
8556 | static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; | ||
8557 | |||
8558 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | ||
8559 | alc861vd_ignore)) < 0) | ||
8560 | return err; | ||
8561 | if (! spec->autocfg.line_outs) | ||
8562 | return 0; /* can't find valid BIOS pin config */ | ||
8563 | |||
8564 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | ||
8565 | (err = alc861vd_auto_create_multi_out_ctls(spec, | ||
8566 | &spec->autocfg)) < 0 || | ||
8567 | (err = alc861vd_auto_create_extra_out(spec, | ||
8568 | spec->autocfg.speaker_pins[0], "Speaker")) < 0 || | ||
8569 | (err = alc861vd_auto_create_extra_out(spec, | ||
8570 | spec->autocfg.hp_pins[0], "Headphone")) < 0 || | ||
8571 | (err = alc880_auto_create_analog_input_ctls(spec, | ||
8572 | &spec->autocfg)) < 0) | ||
8573 | return err; | ||
8574 | |||
8575 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
8576 | |||
8577 | if (spec->autocfg.dig_out_pin) | ||
8578 | spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; | ||
8579 | |||
8580 | if (spec->kctl_alloc) | ||
8581 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | ||
8582 | |||
8583 | spec->init_verbs[spec->num_init_verbs++] | ||
8584 | = alc861vd_volume_init_verbs; | ||
8585 | |||
8586 | spec->num_mux_defs = 1; | ||
8587 | spec->input_mux = &spec->private_imux; | ||
8588 | |||
8589 | return 1; | ||
8590 | } | ||
8591 | |||
8592 | /* additional initialization for auto-configuration model */ | ||
8593 | static void alc861vd_auto_init(struct hda_codec *codec) | ||
8594 | { | ||
8595 | alc861vd_auto_init_multi_out(codec); | ||
8596 | alc861vd_auto_init_hp_out(codec); | ||
8597 | alc861vd_auto_init_analog_input(codec); | ||
8598 | } | ||
8599 | |||
8600 | static int patch_alc861vd(struct hda_codec *codec) | ||
8601 | { | ||
8602 | struct alc_spec *spec; | ||
8603 | int err, board_config; | ||
8604 | |||
8605 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
8606 | if (spec == NULL) | ||
8607 | return -ENOMEM; | ||
8608 | |||
8609 | codec->spec = spec; | ||
8610 | |||
8611 | board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, | ||
8612 | alc861vd_models, | ||
8613 | alc861vd_cfg_tbl); | ||
8614 | |||
8615 | if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { | ||
8616 | printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" | ||
8617 | "ALC861VD, trying auto-probe from BIOS...\n"); | ||
8618 | board_config = ALC861VD_AUTO; | ||
8619 | } | ||
8620 | |||
8621 | if (board_config == ALC861VD_AUTO) { | ||
8622 | /* automatic parse from the BIOS config */ | ||
8623 | err = alc861vd_parse_auto_config(codec); | ||
8624 | if (err < 0) { | ||
8625 | alc_free(codec); | ||
8626 | return err; | ||
8627 | } else if (! err) { | ||
8628 | printk(KERN_INFO | ||
8629 | "hda_codec: Cannot set up configuration " | ||
8630 | "from BIOS. Using base mode...\n"); | ||
8631 | board_config = ALC861VD_3ST; | ||
8632 | } | ||
8633 | } | ||
8634 | |||
8635 | if (board_config != ALC861VD_AUTO) | ||
8636 | setup_preset(spec, &alc861vd_presets[board_config]); | ||
8637 | |||
8638 | spec->stream_name_analog = "ALC861VD Analog"; | ||
8639 | spec->stream_analog_playback = &alc861vd_pcm_analog_playback; | ||
8640 | spec->stream_analog_capture = &alc861vd_pcm_analog_capture; | ||
8641 | |||
8642 | spec->stream_name_digital = "ALC861VD Digital"; | ||
8643 | spec->stream_digital_playback = &alc861vd_pcm_digital_playback; | ||
8644 | spec->stream_digital_capture = &alc861vd_pcm_digital_capture; | ||
8645 | |||
8646 | spec->adc_nids = alc861vd_adc_nids; | ||
8647 | spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); | ||
8648 | |||
8649 | spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; | ||
8650 | spec->num_mixers++; | ||
8651 | |||
8652 | codec->patch_ops = alc_patch_ops; | ||
8653 | |||
8654 | if (board_config == ALC861VD_AUTO) | ||
8655 | spec->init_hook = alc861vd_auto_init; | ||
8656 | |||
8657 | return 0; | ||
8658 | } | ||
8659 | |||
8660 | /* | ||
6849 | * patch entries | 8661 | * patch entries |
6850 | */ | 8662 | */ |
6851 | struct hda_codec_preset snd_hda_preset_realtek[] = { | 8663 | struct hda_codec_preset snd_hda_preset_realtek[] = { |
6852 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, | 8664 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
6853 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 8665 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
6854 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 8666 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
8667 | .patch = patch_alc861 }, | ||
8668 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | ||
8669 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | ||
8670 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, | ||
8671 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | ||
6855 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 8672 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
6856 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, | 8673 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, |
6857 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, | 8674 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
6858 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, | 8675 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, |
6859 | { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861", | ||
6860 | .patch = patch_alc861 }, | ||
6861 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | ||
6862 | .patch = patch_alc861 }, | ||
6863 | {} /* terminator */ | 8676 | {} /* terminator */ |
6864 | }; | 8677 | }; |