diff options
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 93 |
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 */ | ||
1442 | static 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 | |||
1450 | static 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 | |||
1460 | static 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 */ | ||
1485 | static 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 | |||
1497 | static 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 }, |