Commit cf5a22793cfa54c056655d374722dc5dfd496eca

Authored by Takashi Iwai
1 parent 589876e243

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),