aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c2367
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 */
37enum { 41enum {
@@ -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 */
78enum { 85enum {
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 */
113enum {
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 */
99enum { 123enum {
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 */
1048static 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
1077static 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
1091static 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 */
1339static 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 */
1377static 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
1406static 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 */
1412static 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
1433static 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
1444static 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
1457static 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}
1475static 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
2128static struct hda_board_config alc880_cfg_tbl[] = { 2364static 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
2391static 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 */
3094static struct snd_kcontrol_new alc260_acer_mixer[] = { 3331static 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 */
3931static struct hda_board_config alc260_cfg_tbl[] = { 4174static 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
4186static 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 */
4564static 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
4575static 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};
4625static 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 */
4438static struct hda_board_config alc882_cfg_tbl[] = { 4779static 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*/ 4787static 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
5130static 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
5251static 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
5288static 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
5321static 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
4878static struct snd_kcontrol_new alc883_chmode_mixer[] = { 5346static 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
5434static 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 */
5454static 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
5467static 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 */
5060static struct hda_board_config alc883_cfg_tbl[] = { 5567static 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) */ 5581static 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
5931static 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
5358static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 5949static 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
5971static 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
5989static 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
6077static 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
6083static 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 */
6094static 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 */
6126static 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
6134static 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 */
6166static 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
6524static 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 */
5869static struct hda_board_config alc262_cfg_tbl[] = { 6675static 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 */ 6686static 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 */
6944static 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 */
6958static 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
6976static 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
6083static struct snd_kcontrol_new alc861_base_mixer[] = { 6983static 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
7059static 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
6158static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 7080static 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
7122static 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 */
7165static 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
7361static 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 */
7423static 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
7481static 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 */
7488static 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
7504static 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 */
6713static struct hda_board_config alc861_cfg_tbl[] = { 7787static 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 }, 7799static 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
6796static int patch_alc861(struct hda_codec *codec) 7920static 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
7983static 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 */
7995static hda_nid_t alc660vd_dac_nids[3] = {
7996 /* front, rear, clfe, rear_surr */
7997 0x02, 0x04, 0x03
7998};
7999
8000static 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 */
8007static 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
8020static 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 */
8049static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
8050 { 2, NULL }
8051};
8052
8053/*
8054 * 6ch mode
8055 */
8056static 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 */
8067static 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
8075static struct hda_channel_mode alc861vd_6stack_modes[2] = {
8076 { 6, alc861vd_6stack_ch6_init },
8077 { 8, alc861vd_6stack_ch8_init },
8078};
8079
8080static 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
8091static 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 */
8114static 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
8153static 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 */
8182static 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 */
8232static 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 */
8263static 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 */
8313static 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
8321static 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
8330static 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 */
8380static 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
8390static 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
8404static 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
8417static 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 */
8443static 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 */
8502static 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 */
8552static 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 */
8593static 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
8600static 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 */
6851struct hda_codec_preset snd_hda_preset_realtek[] = { 8663struct 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};