Commit cf5a22793cfa54c056655d374722dc5dfd496eca
1 parent
589876e243
Exists in
master
and in
20 other branches
ALSA: hda/realtek - Rewrite ALC880 model=futjisu with auto-parser
Now adding the support for the volume-knob widget, we can move the static quirk for ALC880 model=fujitsu to the auto-parser completely. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 3 changed files with 74 additions and 36 deletions Side-by-side Diff
Documentation/sound/alsa/HD-Audio-Models.txt
... | ... | @@ -14,7 +14,6 @@ |
14 | 14 | asus-dig ASUS with SPDIF out |
15 | 15 | asus-dig2 ASUS with SPDIF out (using GPIO2) |
16 | 16 | uniwill 3-jack |
17 | - fujitsu Fujitsu Laptops (Pi1536) | |
18 | 17 | F1734 2-jack |
19 | 18 | test for testing/debugging purpose, almost all controls can be |
20 | 19 | adjusted. Appearing only when compiled with |
sound/pci/hda/alc880_quirks.c
... | ... | @@ -18,7 +18,6 @@ |
18 | 18 | ALC880_ASUS_DIG, |
19 | 19 | ALC880_ASUS_W1V, |
20 | 20 | ALC880_ASUS_DIG2, |
21 | - ALC880_FUJITSU, | |
22 | 21 | ALC880_UNIWILL_DIG, |
23 | 22 | ALC880_UNIWILL, |
24 | 23 | ALC880_UNIWILL_P53, |
... | ... | @@ -371,20 +370,6 @@ |
371 | 370 | { } /* end */ |
372 | 371 | }; |
373 | 372 | |
374 | -static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = { | |
375 | - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | |
376 | - HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | |
377 | - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | |
378 | - HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | |
379 | - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | |
380 | - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | |
381 | - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | |
382 | - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | |
383 | - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | |
384 | - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | |
385 | - { } /* end */ | |
386 | -}; | |
387 | - | |
388 | 373 | static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { |
389 | 374 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
390 | 375 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
... | ... | @@ -1074,7 +1059,6 @@ |
1074 | 1059 | [ALC880_ASUS_DIG2] = "asus-dig2", |
1075 | 1060 | [ALC880_UNIWILL_DIG] = "uniwill", |
1076 | 1061 | [ALC880_UNIWILL_P53] = "uniwill-p53", |
1077 | - [ALC880_FUJITSU] = "fujitsu", | |
1078 | 1062 | [ALC880_F1734] = "F1734", |
1079 | 1063 | #ifdef CONFIG_SND_DEBUG |
1080 | 1064 | [ALC880_TEST] = "test", |
1081 | 1065 | |
... | ... | @@ -1125,9 +1109,7 @@ |
1125 | 1109 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), |
1126 | 1110 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), |
1127 | 1111 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), |
1128 | - SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), | |
1129 | 1112 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), |
1130 | - SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), | |
1131 | 1113 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ |
1132 | 1114 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), |
1133 | 1115 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), |
... | ... | @@ -1330,21 +1312,6 @@ |
1330 | 1312 | .dac_nids = alc880_asus_dac_nids, |
1331 | 1313 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), |
1332 | 1314 | .channel_mode = alc880_threestack_modes, |
1333 | - .input_mux = &alc880_capture_source, | |
1334 | - .unsol_event = alc880_uniwill_p53_unsol_event, | |
1335 | - .setup = alc880_uniwill_p53_setup, | |
1336 | - .init_hook = alc_hp_automute, | |
1337 | - }, | |
1338 | - [ALC880_FUJITSU] = { | |
1339 | - .mixers = { alc880_fujitsu_mixer }, | |
1340 | - .init_verbs = { alc880_volume_init_verbs, | |
1341 | - alc880_uniwill_p53_init_verbs, | |
1342 | - alc880_beep_init_verbs }, | |
1343 | - .num_dacs = ARRAY_SIZE(alc880_dac_nids), | |
1344 | - .dac_nids = alc880_dac_nids, | |
1345 | - .dig_out_nid = ALC880_DIGOUT_NID, | |
1346 | - .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | |
1347 | - .channel_mode = alc880_2_jack_modes, | |
1348 | 1315 | .input_mux = &alc880_capture_source, |
1349 | 1316 | .unsol_event = alc880_uniwill_p53_unsol_event, |
1350 | 1317 | .setup = alc880_uniwill_p53_setup, |
sound/pci/hda/patch_realtek.c
... | ... | @@ -651,15 +651,51 @@ |
651 | 651 | snd_hda_jack_report_sync(codec); |
652 | 652 | } |
653 | 653 | |
654 | +/* update the master volume per volume-knob's unsol event */ | |
655 | +static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid) | |
656 | +{ | |
657 | + unsigned int val; | |
658 | + struct snd_kcontrol *kctl; | |
659 | + struct snd_ctl_elem_value *uctl; | |
660 | + | |
661 | + kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); | |
662 | + if (!kctl) | |
663 | + return; | |
664 | + uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); | |
665 | + if (!uctl) | |
666 | + return; | |
667 | + val = snd_hda_codec_read(codec, nid, 0, | |
668 | + AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); | |
669 | + val &= HDA_AMP_VOLMASK; | |
670 | + uctl->value.integer.value[0] = val; | |
671 | + uctl->value.integer.value[1] = val; | |
672 | + kctl->put(kctl, uctl); | |
673 | + kfree(uctl); | |
674 | +} | |
675 | + | |
654 | 676 | /* unsolicited event for HP jack sensing */ |
655 | 677 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) |
656 | 678 | { |
679 | + int action; | |
680 | + | |
657 | 681 | if (codec->vendor_id == 0x10ec0880) |
658 | 682 | res >>= 28; |
659 | 683 | else |
660 | 684 | res >>= 26; |
661 | - res = snd_hda_jack_get_action(codec, res); | |
662 | - alc_exec_unsol_event(codec, res); | |
685 | + action = snd_hda_jack_get_action(codec, res); | |
686 | + if (res == ALC_DCVOL_EVENT) { | |
687 | + /* Execute the dc-vol event here as it requires the NID | |
688 | + * but we don't pass NID to alc_exec_unsol_event(). | |
689 | + * Once when we convert all static quirks to the auto-parser, | |
690 | + * this can be integerated into there. | |
691 | + */ | |
692 | + struct hda_jack_tbl *jack; | |
693 | + jack = snd_hda_jack_tbl_get_from_tag(codec, res); | |
694 | + if (jack) | |
695 | + alc_update_knob_master(codec, jack->nid); | |
696 | + return; | |
697 | + } | |
698 | + alc_exec_unsol_event(codec, action); | |
663 | 699 | } |
664 | 700 | |
665 | 701 | /* call init functions of standard auto-mute helpers */ |
666 | 702 | |
... | ... | @@ -4408,8 +4444,18 @@ |
4408 | 4444 | ALC880_FIXUP_W810, |
4409 | 4445 | ALC880_FIXUP_EAPD_COEF, |
4410 | 4446 | ALC880_FIXUP_TCL_S700, |
4447 | + ALC880_FIXUP_VOL_KNOB, | |
4448 | + ALC880_FIXUP_FUJITSU, | |
4411 | 4449 | }; |
4412 | 4450 | |
4451 | +/* enable the volume-knob widget support on NID 0x21 */ | |
4452 | +static void alc880_fixup_vol_knob(struct hda_codec *codec, | |
4453 | + const struct alc_fixup *fix, int action) | |
4454 | +{ | |
4455 | + if (action == ALC_FIXUP_ACT_PROBE) | |
4456 | + snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT); | |
4457 | +} | |
4458 | + | |
4413 | 4459 | static const struct alc_fixup alc880_fixups[] = { |
4414 | 4460 | [ALC880_FIXUP_GPIO2] = { |
4415 | 4461 | .type = ALC_FIXUP_VERBS, |
... | ... | @@ -4465,6 +4511,30 @@ |
4465 | 4511 | .chained = true, |
4466 | 4512 | .chain_id = ALC880_FIXUP_GPIO2, |
4467 | 4513 | }, |
4514 | + [ALC880_FIXUP_VOL_KNOB] = { | |
4515 | + .type = ALC_FIXUP_FUNC, | |
4516 | + .v.func = alc880_fixup_vol_knob, | |
4517 | + }, | |
4518 | + [ALC880_FIXUP_FUJITSU] = { | |
4519 | + /* override all pins as BIOS on old Amilo is broken */ | |
4520 | + .type = ALC_FIXUP_PINS, | |
4521 | + .v.pins = (const struct alc_pincfg[]) { | |
4522 | + { 0x14, 0x0121411f }, /* HP */ | |
4523 | + { 0x15, 0x99030120 }, /* speaker */ | |
4524 | + { 0x16, 0x99030130 }, /* bass speaker */ | |
4525 | + { 0x17, 0x411111f0 }, /* N/A */ | |
4526 | + { 0x18, 0x411111f0 }, /* N/A */ | |
4527 | + { 0x19, 0x01a19950 }, /* mic-in */ | |
4528 | + { 0x1a, 0x411111f0 }, /* N/A */ | |
4529 | + { 0x1b, 0x411111f0 }, /* N/A */ | |
4530 | + { 0x1c, 0x411111f0 }, /* N/A */ | |
4531 | + { 0x1d, 0x411111f0 }, /* N/A */ | |
4532 | + { 0x1e, 0x01454140 }, /* SPDIF out */ | |
4533 | + { } | |
4534 | + }, | |
4535 | + .chained = true, | |
4536 | + .chain_id = ALC880_FIXUP_VOL_KNOB, | |
4537 | + }, | |
4468 | 4538 | }; |
4469 | 4539 | |
4470 | 4540 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { |
... | ... | @@ -4472,6 +4542,8 @@ |
4472 | 4542 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), |
4473 | 4543 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), |
4474 | 4544 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), |
4545 | + SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), | |
4546 | + SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU), | |
4475 | 4547 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), |
4476 | 4548 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), |
4477 | 4549 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), |