diff options
author | Kailang Yang <kailang@realtek.com.tw> | 2006-10-17 06:32:26 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:01:03 -0500 |
commit | ccc656ce5f6627032bd44e660071bb71e65a231a (patch) | |
tree | 97448e9fc35647867bae9640f955c6c582f7ba7b | |
parent | a53d1aece388d940831846f642810e47526883e8 (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>
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 536 |
2 files changed, 534 insertions, 6 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index a16dd34817d2..feb97bd711f9 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -801,6 +801,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
801 | fujitsu Fujitsu Laptop | 801 | fujitsu Fujitsu Laptop |
802 | hp-bpc HP xw4400/6400/8400/9400 laptops | 802 | hp-bpc HP xw4400/6400/8400/9400 laptops |
803 | benq Benq ED8 | 803 | benq Benq ED8 |
804 | hippo Hippo (ATI) with jack detection | ||
805 | hippo_1 Hippo (Benq) with jack detection | ||
804 | basic fixed pin assignment w/o SPDIF | 806 | basic fixed pin assignment w/o SPDIF |
805 | auto auto-config reading BIOS (default) | 807 | auto auto-config reading BIOS (default) |
806 | 808 | ||
@@ -818,6 +820,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
818 | 6stack-dig-demo 6-jack digital for Intel demo board | 820 | 6stack-dig-demo 6-jack digital for Intel demo board |
819 | acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) | 821 | acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) |
820 | medion Medion Laptops | 822 | medion Medion Laptops |
823 | targa-dig Targa/MSI | ||
824 | targa-2ch-dig Targs/MSI with 2-channel | ||
821 | auto auto-config reading BIOS (default) | 825 | auto auto-config reading BIOS (default) |
822 | 826 | ||
823 | ALC861/660 | 827 | ALC861/660 |
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 */ |
37 | enum { | 41 | enum { |
@@ -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 */ |
78 | enum { | 84 | enum { |
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 */ | ||
1031 | static 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 | |||
1060 | static 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 | */ | ||
1308 | static 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 | */ | ||
1346 | static 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 */ | ||
1376 | static 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 | |||
1397 | static 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 | |||
1408 | static 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 | |||
1421 | static 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 | } | ||
1439 | static 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 | ||
5143 | static 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 | |||
5175 | static 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 | |||
4915 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | 5199 | static 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 | ||
5287 | static 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 */ | ||
5307 | static 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 | |||
5320 | static 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 | ||
5789 | static 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 | |||
5411 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | 5807 | static 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 | ||
5911 | static 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 | |||
5917 | static 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 */ | ||
5928 | static 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 */ | ||
5960 | static 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 | |||
5968 | static 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 */ | ||
6000 | static 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 | */ |
5922 | static struct hda_board_config alc262_cfg_tbl[] = { | 6415 | static 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 | }; |