aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt1
-rw-r--r--sound/pci/hda/patch_realtek.c93
2 files changed, 94 insertions, 0 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 1def6049784c..baf18c6afdd6 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -701,6 +701,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
701 uniwill 3-jack 701 uniwill 3-jack
702 F1734 2-jack 702 F1734 2-jack
703 lg LG laptop (m1 express dual) 703 lg LG laptop (m1 express dual)
704 lg-lw LG LW20 laptop
704 test for testing/debugging purpose, almost all controls can be 705 test for testing/debugging purpose, almost all controls can be
705 adjusted. Appearing only when compiled with 706 adjusted. Appearing only when compiled with
706 $CONFIG_SND_DEBUG=y 707 $CONFIG_SND_DEBUG=y
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4c6c9ec8ea5b..6b45635b3ea3 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -52,6 +52,7 @@ enum {
52 ALC880_CLEVO, 52 ALC880_CLEVO,
53 ALC880_TCL_S700, 53 ALC880_TCL_S700,
54 ALC880_LG, 54 ALC880_LG,
55 ALC880_LG_LW,
55#ifdef CONFIG_SND_DEBUG 56#ifdef CONFIG_SND_DEBUG
56 ALC880_TEST, 57 ALC880_TEST,
57#endif 58#endif
@@ -1427,6 +1428,82 @@ static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1427} 1428}
1428 1429
1429/* 1430/*
1431 * LG LW20
1432 *
1433 * Pin assignment:
1434 * Speaker-out: 0x14
1435 * Mic-In: 0x18
1436 * Built-in Mic-In: 0x19 (?)
1437 * HP-Out: 0x1b
1438 * SPDIF-Out: 0x1e
1439 */
1440
1441/* seems analog CD is not working */
1442static struct hda_input_mux alc880_lg_lw_capture_source = {
1443 .num_items = 2,
1444 .items = {
1445 { "Mic", 0x0 },
1446 { "Internal Mic", 0x1 },
1447 },
1448};
1449
1450static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1451 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1452 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1455 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1456 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1457 { } /* end */
1458};
1459
1460static struct hda_verb alc880_lg_lw_init_verbs[] = {
1461 /* set capture source to mic-in */
1462 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1463 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1464 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1465 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1466 /* speaker-out */
1467 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1468 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1469 /* HP-out */
1470 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1471 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1472 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1473 /* mic-in to input */
1474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1475 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1476 /* built-in mic */
1477 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1478 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1479 /* jack sense */
1480 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1481 { }
1482};
1483
1484/* toggle speaker-output according to the hp-jack state */
1485static void alc880_lg_lw_automute(struct hda_codec *codec)
1486{
1487 unsigned int present;
1488
1489 present = snd_hda_codec_read(codec, 0x1b, 0,
1490 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1491 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1492 0x80, present ? 0x80 : 0);
1493 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1494 0x80, present ? 0x80 : 0);
1495}
1496
1497static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1498{
1499 /* Looks like the unsol event is incompatible with the standard
1500 * definition. 4bit tag is placed at 28 bit!
1501 */
1502 if ((res >> 28) == 0x01)
1503 alc880_lg_lw_automute(codec);
1504}
1505
1506/*
1430 * Common callbacks 1507 * Common callbacks
1431 */ 1508 */
1432 1509
@@ -2078,6 +2155,9 @@ static struct hda_board_config alc880_cfg_tbl[] = {
2078 { .modelname = "lg", .config = ALC880_LG }, 2155 { .modelname = "lg", .config = ALC880_LG },
2079 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, 2156 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
2080 2157
2158 { .modelname = "lg-lw", .config = ALC880_LG_LW },
2159 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
2160
2081#ifdef CONFIG_SND_DEBUG 2161#ifdef CONFIG_SND_DEBUG
2082 { .modelname = "test", .config = ALC880_TEST }, 2162 { .modelname = "test", .config = ALC880_TEST },
2083#endif 2163#endif
@@ -2268,6 +2348,19 @@ static struct alc_config_preset alc880_presets[] = {
2268 .unsol_event = alc880_lg_unsol_event, 2348 .unsol_event = alc880_lg_unsol_event,
2269 .init_hook = alc880_lg_automute, 2349 .init_hook = alc880_lg_automute,
2270 }, 2350 },
2351 [ALC880_LG_LW] = {
2352 .mixers = { alc880_lg_lw_mixer },
2353 .init_verbs = { alc880_volume_init_verbs,
2354 alc880_lg_lw_init_verbs },
2355 .num_dacs = 1,
2356 .dac_nids = alc880_dac_nids,
2357 .dig_out_nid = ALC880_DIGOUT_NID,
2358 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2359 .channel_mode = alc880_2_jack_modes,
2360 .input_mux = &alc880_lg_lw_capture_source,
2361 .unsol_event = alc880_lg_lw_unsol_event,
2362 .init_hook = alc880_lg_lw_automute,
2363 },
2271#ifdef CONFIG_SND_DEBUG 2364#ifdef CONFIG_SND_DEBUG
2272 [ALC880_TEST] = { 2365 [ALC880_TEST] = {
2273 .mixers = { alc880_test_mixer }, 2366 .mixers = { alc880_test_mixer },