aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorKailang Yang <kailang@realtek.com.tw>2006-10-17 06:32:26 -0400
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:01:03 -0500
commitccc656ce5f6627032bd44e660071bb71e65a231a (patch)
tree97448e9fc35647867bae9640f955c6c582f7ba7b /sound/pci
parenta53d1aece388d940831846f642810e47526883e8 (diff)
[ALSA] hda-codec - Add new modesl for Realtek codecs
Changes from Realtek driver: - New models hippo and hippo_1 for ALC262 - New models tagra-dig and tagra-2ch-dig for ALC883 - New id for ALC660 codec chip Signed-off-by: Kailang Yang <kailang@realtek.com.tw> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_realtek.c536
1 files changed, 530 insertions, 6 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 62c75388457e..04749d2f7bdf 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 {
@@ -49,6 +53,8 @@ enum {
49 ALC880_ASUS_W1V, 53 ALC880_ASUS_W1V,
50 ALC880_ASUS_DIG2, 54 ALC880_ASUS_DIG2,
51 ALC880_UNIWILL_DIG, 55 ALC880_UNIWILL_DIG,
56 ALC880_UNIWILL,
57 ALC880_UNIWILL_P53,
52 ALC880_CLEVO, 58 ALC880_CLEVO,
53 ALC880_TCL_S700, 59 ALC880_TCL_S700,
54 ALC880_LG, 60 ALC880_LG,
@@ -77,6 +83,8 @@ enum {
77/* ALC262 models */ 83/* ALC262 models */
78enum { 84enum {
79 ALC262_BASIC, 85 ALC262_BASIC,
86 ALC262_HIPPO,
87 ALC262_HIPPO_1,
80 ALC262_FUJITSU, 88 ALC262_FUJITSU,
81 ALC262_HP_BPC, 89 ALC262_HP_BPC,
82 ALC262_BENQ_ED8, 90 ALC262_BENQ_ED8,
@@ -111,6 +119,8 @@ enum {
111 ALC883_3ST_6ch_DIG, 119 ALC883_3ST_6ch_DIG,
112 ALC883_3ST_6ch, 120 ALC883_3ST_6ch,
113 ALC883_6ST_DIG, 121 ALC883_6ST_DIG,
122 ALC883_TARGA_DIG,
123 ALC883_TARGA_2ch_DIG,
114 ALC888_DEMO_BOARD, 124 ALC888_DEMO_BOARD,
115 ALC883_ACER, 125 ALC883_ACER,
116 ALC883_MEDION, 126 ALC883_MEDION,
@@ -1017,6 +1027,46 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1017 { } /* end */ 1027 { } /* end */
1018}; 1028};
1019 1029
1030/* Uniwill */
1031static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1032 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1033 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1034 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1035 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1036 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1037 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1038 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1039 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1040 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1041 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1042 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1043 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1046 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1047 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1048 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1049 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1050 {
1051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1052 .name = "Channel Mode",
1053 .info = alc_ch_mode_info,
1054 .get = alc_ch_mode_get,
1055 .put = alc_ch_mode_put,
1056 },
1057 { } /* end */
1058};
1059
1060static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1061 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1062 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1063 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1064 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1067 { } /* end */
1068};
1069
1020/* 1070/*
1021 * build control elements 1071 * build control elements
1022 */ 1072 */
@@ -1250,6 +1300,154 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1250 { } 1300 { }
1251}; 1301};
1252 1302
1303/*
1304 * Uniwill pin configuration:
1305 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1306 * line = 0x1a
1307 */
1308static struct hda_verb alc880_uniwill_init_verbs[] = {
1309 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1310
1311 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1312 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1313 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1314 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1315 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1316 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1317 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1318 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1319 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1321 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1322 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1323 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1324 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1325
1326 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1327 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1328 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1329 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1330 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1331 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1332 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1333 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1334 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1335
1336 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1337 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1338
1339 { }
1340};
1341
1342/*
1343* Uniwill P53
1344* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1345 */
1346static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1347 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1348
1349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1350 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1352 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1353 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1354 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1357 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1358 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1359 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1360 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1361
1362 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1363 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1364 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1365 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1366 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1367 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1368
1369 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1370 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1371
1372 { }
1373};
1374
1375/* toggle speaker-output according to the hp-jack state */
1376static void alc880_uniwill_automute(struct hda_codec *codec)
1377{
1378 unsigned int present;
1379
1380 present = snd_hda_codec_read(codec, 0x14, 0,
1381 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1382 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1383 0x80, present ? 0x80 : 0);
1384 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1385 0x80, present ? 0x80 : 0);
1386 snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1387 0x80, present ? 0x80 : 0);
1388 snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1389 0x80, present ? 0x80 : 0);
1390
1391 present = snd_hda_codec_read(codec, 0x18, 0,
1392 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1393 snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1394 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
1395}
1396
1397static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1398 unsigned int res)
1399{
1400 /* Looks like the unsol event is incompatible with the standard
1401 * definition. 4bit tag is placed at 28 bit!
1402 */
1403 if ((res >> 28) == ALC880_HP_EVENT ||
1404 (res >> 28) == ALC880_MIC_EVENT)
1405 alc880_uniwill_automute(codec);
1406}
1407
1408static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1409{
1410 unsigned int present;
1411
1412 present = snd_hda_codec_read(codec, 0x14, 0,
1413 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1414
1415 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1416 0x80, present ? 0x80 : 0);
1417 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1418 0x80, present ? 0x80 : 0);
1419}
1420
1421static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1422{
1423 unsigned int present;
1424
1425 present = snd_hda_codec_read(codec, 0x21, 0,
1426 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1427
1428 snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1429 0x7f, present);
1430 snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1431 0x7f, present);
1432
1433 snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1434 0x7f, present);
1435 snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1436 0x7f, present);
1437
1438}
1439static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1440 unsigned int res)
1441{
1442 /* Looks like the unsol event is incompatible with the standard
1443 * definition. 4bit tag is placed at 28 bit!
1444 */
1445 if ((res >> 28) == ALC880_HP_EVENT)
1446 alc880_uniwill_p53_hp_automute(codec);
1447 if ((res >> 28) == ALC880_DCVOL_EVENT)
1448 alc880_uniwill_p53_dcvol_automute(codec);
1449}
1450
1253/* FIXME! */ 1451/* FIXME! */
1254/* 1452/*
1255 * F1734 pin configuration: 1453 * F1734 pin configuration:
@@ -2262,7 +2460,10 @@ static struct hda_board_config alc880_cfg_tbl[] = {
2262 { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, 2460 { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
2263 2461
2264 { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, 2462 { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
2265 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG }, 2463 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
2464 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9070, .config = ALC880_UNIWILL },
2465 { .pci_subvendor = 0x1734, .pci_subdevice = 0x10ac, .config = ALC880_UNIWILL },
2466 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9077, .config = ALC880_UNIWILL_P53 },
2266 2467
2267 { .modelname = "F1734", .config = ALC880_F1734 }, 2468 { .modelname = "F1734", .config = ALC880_F1734 },
2268 { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 }, 2469 { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
@@ -2440,7 +2641,8 @@ static struct alc_config_preset alc880_presets[] = {
2440 }, 2641 },
2441 [ALC880_UNIWILL_DIG] = { 2642 [ALC880_UNIWILL_DIG] = {
2442 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, 2643 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2443 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, 2644 .init_verbs = { alc880_volume_init_verbs,
2645 alc880_pin_asus_init_verbs },
2444 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2646 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2445 .dac_nids = alc880_asus_dac_nids, 2647 .dac_nids = alc880_asus_dac_nids,
2446 .dig_out_nid = ALC880_DIGOUT_NID, 2648 .dig_out_nid = ALC880_DIGOUT_NID,
@@ -2449,6 +2651,32 @@ static struct alc_config_preset alc880_presets[] = {
2449 .need_dac_fix = 1, 2651 .need_dac_fix = 1,
2450 .input_mux = &alc880_capture_source, 2652 .input_mux = &alc880_capture_source,
2451 }, 2653 },
2654 [ALC880_UNIWILL] = {
2655 .mixers = { alc880_uniwill_mixer },
2656 .init_verbs = { alc880_volume_init_verbs,
2657 alc880_uniwill_init_verbs },
2658 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2659 .dac_nids = alc880_asus_dac_nids,
2660 .dig_out_nid = ALC880_DIGOUT_NID,
2661 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2662 .channel_mode = alc880_threestack_modes,
2663 .need_dac_fix = 1,
2664 .input_mux = &alc880_capture_source,
2665 .unsol_event = alc880_uniwill_unsol_event,
2666 .init_hook = alc880_uniwill_automute,
2667 },
2668 [ALC880_UNIWILL_P53] = {
2669 .mixers = { alc880_uniwill_p53_mixer },
2670 .init_verbs = { alc880_volume_init_verbs,
2671 alc880_uniwill_p53_init_verbs },
2672 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2673 .dac_nids = alc880_asus_dac_nids,
2674 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2675 .channel_mode = alc880_w810_modes,
2676 .input_mux = &alc880_capture_source,
2677 .unsol_event = alc880_uniwill_p53_unsol_event,
2678 .init_hook = alc880_uniwill_p53_hp_automute,
2679 },
2452 [ALC880_CLEVO] = { 2680 [ALC880_CLEVO] = {
2453 .mixers = { alc880_three_stack_mixer }, 2681 .mixers = { alc880_three_stack_mixer },
2454 .init_verbs = { alc880_volume_init_verbs, 2682 .init_verbs = { alc880_volume_init_verbs,
@@ -4912,6 +5140,62 @@ static snd_kcontrol_new_t alc883_fivestack_mixer[] = {
4912 { } /* end */ 5140 { } /* end */
4913}; 5141};
4914 5142
5143static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5144 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5145 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5146 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5147 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5148 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5149 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5150 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5151 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5152 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5153 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5154 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5155 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5156 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5159 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5160 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5161 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5162 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5163 {
5164 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5165 /* .name = "Capture Source", */
5166 .name = "Input Source",
5167 .count = 2,
5168 .info = alc883_mux_enum_info,
5169 .get = alc883_mux_enum_get,
5170 .put = alc883_mux_enum_put,
5171 },
5172 { } /* end */
5173};
5174
5175static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5176 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5178 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5179 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5180 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5182 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5183 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5184 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5185 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5186 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5187 {
5188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5189 /* .name = "Capture Source", */
5190 .name = "Input Source",
5191 .count = 2,
5192 .info = alc883_mux_enum_info,
5193 .get = alc883_mux_enum_get,
5194 .put = alc883_mux_enum_put,
5195 },
5196 { } /* end */
5197};
5198
4915static struct snd_kcontrol_new alc883_chmode_mixer[] = { 5199static struct snd_kcontrol_new alc883_chmode_mixer[] = {
4916 { 5200 {
4917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -5000,6 +5284,45 @@ static struct hda_verb alc883_init_verbs[] = {
5000 { } 5284 { }
5001}; 5285};
5002 5286
5287static struct hda_verb alc883_tagra_verbs[] = {
5288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5290
5291 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5292 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5293
5294 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5295 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5296 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5297
5298 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5299 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5300 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5301 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5302
5303 { } /* end */
5304};
5305
5306/* toggle speaker-output according to the hp-jack state */
5307static void alc883_tagra_automute(struct hda_codec *codec)
5308{
5309 unsigned int present;
5310
5311 present = snd_hda_codec_read(codec, 0x14, 0,
5312 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5313 snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5314 0x80, present ? 0x80 : 0);
5315 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5316 0x80, present ? 0x80 : 0);
5317 snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5318}
5319
5320static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
5321{
5322 if ((res >> 26) == ALC880_HP_EVENT)
5323 alc883_tagra_automute(codec);
5324}
5325
5003/* 5326/*
5004 * generic initialization of ADC, input mixers and output mixers 5327 * generic initialization of ADC, input mixers and output mixers
5005 */ 5328 */
@@ -5101,9 +5424,9 @@ static struct hda_board_config alc883_cfg_tbl[] = {
5101 .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ 5424 .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/
5102 { .modelname = "3stack-6ch", .config = ALC883_3ST_6ch }, 5425 { .modelname = "3stack-6ch", .config = ALC883_3ST_6ch },
5103 { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, 5426 { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d,
5104 .config = ALC883_3ST_6ch }, 5427 .config = ALC883_3ST_6ch },
5105 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd601, 5428 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd601,
5106 .config = ALC883_3ST_6ch }, /* D102GGC */ 5429 .config = ALC883_3ST_6ch }, /* D102GGC */
5107 { .modelname = "6stack-dig", .config = ALC883_6ST_DIG }, 5430 { .modelname = "6stack-dig", .config = ALC883_6ST_DIG },
5108 { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, 5431 { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668,
5109 .config = ALC883_6ST_DIG }, /* MSI */ 5432 .config = ALC883_6ST_DIG }, /* MSI */
@@ -5111,6 +5434,32 @@ static struct hda_board_config alc883_cfg_tbl[] = {
5111 .config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */ 5434 .config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */
5112 { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, 5435 { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668,
5113 .config = ALC883_6ST_DIG }, /* Foxconn */ 5436 .config = ALC883_6ST_DIG }, /* Foxconn */
5437 { .pci_subvendor = 0x1462, .pci_subdevice = 0x7187,
5438 .config = ALC883_6ST_DIG }, /* MSI */
5439 { .modelname = "targa-dig", .config = ALC883_TARGA_DIG },
5440 { .pci_subvendor = 0x1462, .pci_subdevice = 0x4314,
5441 .config = ALC883_TARGA_DIG }, /* MSI */
5442 { .pci_subvendor = 0x1462, .pci_subdevice = 0x3fcc,
5443 .config = ALC883_TARGA_DIG }, /* MSI */
5444 { .pci_subvendor = 0x1462, .pci_subdevice = 0x3fc1,
5445 .config = ALC883_TARGA_DIG }, /* MSI */
5446 { .pci_subvendor = 0x1462, .pci_subdevice = 0x3fc3,
5447 .config = ALC883_TARGA_DIG }, /* MSI */
5448 { .pci_subvendor = 0x1462, .pci_subdevice = 0x4314,
5449 .config = ALC883_TARGA_DIG }, /* MSI */
5450 { .pci_subvendor = 0x1462, .pci_subdevice = 0x4319,
5451 .config = ALC883_TARGA_DIG }, /* MSI */
5452 { .pci_subvendor = 0x1462, .pci_subdevice = 0x3ef9,
5453 .config = ALC883_TARGA_DIG }, /* MSI */
5454 { .pci_subvendor = 0x1462, .pci_subdevice = 0x4324,
5455 .config = ALC883_TARGA_DIG }, /* MSI */
5456 { .modelname = "targa-2ch-dig", .config = ALC883_TARGA_2ch_DIG },
5457 { .pci_subvendor = 0x1462, .pci_subdevice = 0x0579,
5458 .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5459 { .pci_subvendor = 0x1462, .pci_subdevice = 0xa422,
5460 .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5461 { .pci_subvendor = 0x1462, .pci_subdevice = 0x3b7f,
5462 .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5114 { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, 5463 { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD },
5115 { .modelname = "acer", .config = ALC883_ACER }, 5464 { .modelname = "acer", .config = ALC883_ACER },
5116 { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/, 5465 { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/,
@@ -5178,6 +5527,35 @@ static struct alc_config_preset alc883_presets[] = {
5178 .channel_mode = alc883_sixstack_modes, 5527 .channel_mode = alc883_sixstack_modes,
5179 .input_mux = &alc883_capture_source, 5528 .input_mux = &alc883_capture_source,
5180 }, 5529 },
5530 [ALC883_TARGA_DIG] = {
5531 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
5532 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5533 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5534 .dac_nids = alc883_dac_nids,
5535 .dig_out_nid = ALC883_DIGOUT_NID,
5536 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5537 .adc_nids = alc883_adc_nids,
5538 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5539 .channel_mode = alc883_3ST_6ch_modes,
5540 .need_dac_fix = 1,
5541 .input_mux = &alc883_capture_source,
5542 .unsol_event = alc883_tagra_unsol_event,
5543 .init_hook = alc883_tagra_automute,
5544 },
5545 [ALC883_TARGA_2ch_DIG] = {
5546 .mixers = { alc883_tagra_2ch_mixer},
5547 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5548 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5549 .dac_nids = alc883_dac_nids,
5550 .dig_out_nid = ALC883_DIGOUT_NID,
5551 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5552 .adc_nids = alc883_adc_nids,
5553 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5554 .channel_mode = alc883_3ST_2ch_modes,
5555 .input_mux = &alc883_capture_source,
5556 .unsol_event = alc883_tagra_unsol_event,
5557 .init_hook = alc883_tagra_automute,
5558 },
5181 [ALC888_DEMO_BOARD] = { 5559 [ALC888_DEMO_BOARD] = {
5182 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 5560 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5183 .init_verbs = { alc883_init_verbs }, 5561 .init_verbs = { alc883_init_verbs },
@@ -5408,6 +5786,24 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
5408 { } /* end */ 5786 { } /* end */
5409}; 5787};
5410 5788
5789static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
5790 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5791 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5794 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5795 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5796 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5797 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5798 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5799 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5800 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5801 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
5802 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
5803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5804 { } /* end */
5805};
5806
5411static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 5807static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
5412 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5808 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5413 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5809 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -5512,6 +5908,103 @@ static struct hda_verb alc262_init_verbs[] = {
5512 { } 5908 { }
5513}; 5909};
5514 5910
5911static struct hda_verb alc262_hippo_unsol_verbs[] = {
5912 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5914 {}
5915};
5916
5917static struct hda_verb alc262_hippo1_unsol_verbs[] = {
5918 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5919 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5920 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5921
5922 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5923 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5924 {}
5925};
5926
5927/* mute/unmute internal speaker according to the hp jack and mute state */
5928static void alc262_hippo_automute(struct hda_codec *codec, int force)
5929{
5930 struct alc_spec *spec = codec->spec;
5931 unsigned int mute;
5932
5933 if (force || ! spec->sense_updated) {
5934 unsigned int present;
5935 /* need to execute and sync at first */
5936 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
5937 present = snd_hda_codec_read(codec, 0x15, 0,
5938 AC_VERB_GET_PIN_SENSE, 0);
5939 spec->jack_present = (present & 0x80000000) != 0;
5940 spec->sense_updated = 1;
5941 }
5942 if (spec->jack_present) {
5943 /* mute internal speaker */
5944 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5945 0x80, 0x80);
5946 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5947 0x80, 0x80);
5948 } else {
5949 /* unmute internal speaker if necessary */
5950 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
5951 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5952 0x80, mute & 0x80);
5953 mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
5954 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5955 0x80, mute & 0x80);
5956 }
5957}
5958
5959/* unsolicited event for HP jack sensing */
5960static void alc262_hippo_unsol_event(struct hda_codec *codec,
5961 unsigned int res)
5962{
5963 if ((res >> 26) != ALC880_HP_EVENT)
5964 return;
5965 alc262_hippo_automute(codec, 1);
5966}
5967
5968static void alc262_hippo1_automute(struct hda_codec *codec, int force)
5969{
5970 struct alc_spec *spec = codec->spec;
5971 unsigned int mute;
5972
5973 if (force || ! spec->sense_updated) {
5974 unsigned int present;
5975 /* need to execute and sync at first */
5976 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
5977 present = snd_hda_codec_read(codec, 0x1b, 0,
5978 AC_VERB_GET_PIN_SENSE, 0);
5979 spec->jack_present = (present & 0x80000000) != 0;
5980 spec->sense_updated = 1;
5981 }
5982 if (spec->jack_present) {
5983 /* mute internal speaker */
5984 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5985 0x80, 0x80);
5986 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5987 0x80, 0x80);
5988 } else {
5989 /* unmute internal speaker if necessary */
5990 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
5991 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5992 0x80, mute & 0x80);
5993 mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
5994 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5995 0x80, mute & 0x80);
5996 }
5997}
5998
5999/* unsolicited event for HP jack sensing */
6000static void alc262_hippo1_unsol_event(struct hda_codec *codec,
6001 unsigned int res)
6002{
6003 if ((res >> 26) != ALC880_HP_EVENT)
6004 return;
6005 alc262_hippo1_automute(codec, 1);
6006}
6007
5515/* 6008/*
5516 * fujitsu model 6009 * fujitsu model
5517 * 0x14 = headphone/spdif-out, 0x15 = internal speaker 6010 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
@@ -5921,6 +6414,12 @@ static void alc262_auto_init(struct hda_codec *codec)
5921 */ 6414 */
5922static struct hda_board_config alc262_cfg_tbl[] = { 6415static struct hda_board_config alc262_cfg_tbl[] = {
5923 { .modelname = "basic", .config = ALC262_BASIC }, 6416 { .modelname = "basic", .config = ALC262_BASIC },
6417 { .modelname = "hippo",
6418 .pci_subvendor =0x1002, .pci_subdevice = 0x437b,
6419 .config = ALC262_HIPPO},
6420 { .modelname = "hippo_1",
6421 .pci_subvendor =0x17ff, .pci_subdevice = 0x058f,
6422 .config = ALC262_HIPPO_1},
5924 { .modelname = "fujitsu", .config = ALC262_FUJITSU }, 6423 { .modelname = "fujitsu", .config = ALC262_FUJITSU },
5925 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, 6424 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397,
5926 .config = ALC262_FUJITSU }, 6425 .config = ALC262_FUJITSU },
@@ -5953,6 +6452,30 @@ static struct alc_config_preset alc262_presets[] = {
5953 .channel_mode = alc262_modes, 6452 .channel_mode = alc262_modes,
5954 .input_mux = &alc262_capture_source, 6453 .input_mux = &alc262_capture_source,
5955 }, 6454 },
6455 [ALC262_HIPPO] = {
6456 .mixers = { alc262_base_mixer },
6457 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
6458 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6459 .dac_nids = alc262_dac_nids,
6460 .hp_nid = 0x03,
6461 .dig_out_nid = ALC262_DIGOUT_NID,
6462 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6463 .channel_mode = alc262_modes,
6464 .input_mux = &alc262_capture_source,
6465 .unsol_event = alc262_hippo_unsol_event,
6466 },
6467 [ALC262_HIPPO_1] = {
6468 .mixers = { alc262_hippo1_mixer },
6469 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
6470 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6471 .dac_nids = alc262_dac_nids,
6472 .hp_nid = 0x02,
6473 .dig_out_nid = ALC262_DIGOUT_NID,
6474 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6475 .channel_mode = alc262_modes,
6476 .input_mux = &alc262_capture_source,
6477 .unsol_event = alc262_hippo1_unsol_event,
6478 },
5956 [ALC262_FUJITSU] = { 6479 [ALC262_FUJITSU] = {
5957 .mixers = { alc262_fujitsu_mixer }, 6480 .mixers = { alc262_fujitsu_mixer },
5958 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, 6481 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
@@ -6983,7 +7506,8 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
6983 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 7506 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
6984 { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861", 7507 { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861",
6985 .patch = patch_alc861 }, 7508 .patch = patch_alc861 },
6986 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 7509 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
6987 .patch = patch_alc861 }, 7510 .patch = patch_alc861 },
7511 { .id = 0x10ec0660, .name = "ALC660", .patch = patch_alc861 },
6988 {} /* terminator */ 7512 {} /* terminator */
6989}; 7513};