diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-02-20 10:31:07 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-02-20 10:31:07 -0500 |
commit | cf5a22793cfa54c056655d374722dc5dfd496eca (patch) | |
tree | 879a8976cc8b9f8f0221560d6f52b90355c8370f /sound/pci | |
parent | 589876e243bb14343d09d9fd7f9ddf79f1d80158 (diff) |
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>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/alc880_quirks.c | 33 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 76 |
2 files changed, 74 insertions, 35 deletions
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c index 56f8fa1e3460..f062eaae6b1e 100644 --- a/sound/pci/hda/alc880_quirks.c +++ b/sound/pci/hda/alc880_quirks.c | |||
@@ -18,7 +18,6 @@ enum { | |||
18 | ALC880_ASUS_DIG, | 18 | ALC880_ASUS_DIG, |
19 | ALC880_ASUS_W1V, | 19 | ALC880_ASUS_W1V, |
20 | ALC880_ASUS_DIG2, | 20 | ALC880_ASUS_DIG2, |
21 | ALC880_FUJITSU, | ||
22 | ALC880_UNIWILL_DIG, | 21 | ALC880_UNIWILL_DIG, |
23 | ALC880_UNIWILL, | 22 | ALC880_UNIWILL, |
24 | ALC880_UNIWILL_P53, | 23 | ALC880_UNIWILL_P53, |
@@ -371,20 +370,6 @@ static const struct snd_kcontrol_new alc880_uniwill_mixer[] = { | |||
371 | { } /* end */ | 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 | static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { | 373 | static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { |
389 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 374 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
390 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 375 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -1074,7 +1059,6 @@ static const char * const alc880_models[ALC880_MODEL_LAST] = { | |||
1074 | [ALC880_ASUS_DIG2] = "asus-dig2", | 1059 | [ALC880_ASUS_DIG2] = "asus-dig2", |
1075 | [ALC880_UNIWILL_DIG] = "uniwill", | 1060 | [ALC880_UNIWILL_DIG] = "uniwill", |
1076 | [ALC880_UNIWILL_P53] = "uniwill-p53", | 1061 | [ALC880_UNIWILL_P53] = "uniwill-p53", |
1077 | [ALC880_FUJITSU] = "fujitsu", | ||
1078 | [ALC880_F1734] = "F1734", | 1062 | [ALC880_F1734] = "F1734", |
1079 | #ifdef CONFIG_SND_DEBUG | 1063 | #ifdef CONFIG_SND_DEBUG |
1080 | [ALC880_TEST] = "test", | 1064 | [ALC880_TEST] = "test", |
@@ -1125,9 +1109,7 @@ static const struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
1125 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), | 1109 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), |
1126 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), | 1110 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), |
1127 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), | 1111 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), |
1128 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), | ||
1129 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), | 1112 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), |
1130 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), | ||
1131 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ | 1113 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ |
1132 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), | 1114 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), |
1133 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), | 1115 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), |
@@ -1335,21 +1317,6 @@ static const struct alc_config_preset alc880_presets[] = { | |||
1335 | .setup = alc880_uniwill_p53_setup, | 1317 | .setup = alc880_uniwill_p53_setup, |
1336 | .init_hook = alc_hp_automute, | 1318 | .init_hook = alc_hp_automute, |
1337 | }, | 1319 | }, |
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 | .input_mux = &alc880_capture_source, | ||
1349 | .unsol_event = alc880_uniwill_p53_unsol_event, | ||
1350 | .setup = alc880_uniwill_p53_setup, | ||
1351 | .init_hook = alc_hp_automute, | ||
1352 | }, | ||
1353 | #ifdef CONFIG_SND_DEBUG | 1320 | #ifdef CONFIG_SND_DEBUG |
1354 | [ALC880_TEST] = { | 1321 | [ALC880_TEST] = { |
1355 | .mixers = { alc880_test_mixer }, | 1322 | .mixers = { alc880_test_mixer }, |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 895113ee3857..6a6436a54f07 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -651,15 +651,51 @@ static void alc_exec_unsol_event(struct hda_codec *codec, int action) | |||
651 | snd_hda_jack_report_sync(codec); | 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 | /* unsolicited event for HP jack sensing */ | 676 | /* unsolicited event for HP jack sensing */ |
655 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 677 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) |
656 | { | 678 | { |
679 | int action; | ||
680 | |||
657 | if (codec->vendor_id == 0x10ec0880) | 681 | if (codec->vendor_id == 0x10ec0880) |
658 | res >>= 28; | 682 | res >>= 28; |
659 | else | 683 | else |
660 | res >>= 26; | 684 | res >>= 26; |
661 | res = snd_hda_jack_get_action(codec, res); | 685 | action = snd_hda_jack_get_action(codec, res); |
662 | alc_exec_unsol_event(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 | /* call init functions of standard auto-mute helpers */ | 701 | /* call init functions of standard auto-mute helpers */ |
@@ -4408,8 +4444,18 @@ enum { | |||
4408 | ALC880_FIXUP_W810, | 4444 | ALC880_FIXUP_W810, |
4409 | ALC880_FIXUP_EAPD_COEF, | 4445 | ALC880_FIXUP_EAPD_COEF, |
4410 | ALC880_FIXUP_TCL_S700, | 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 | static const struct alc_fixup alc880_fixups[] = { | 4459 | static const struct alc_fixup alc880_fixups[] = { |
4414 | [ALC880_FIXUP_GPIO2] = { | 4460 | [ALC880_FIXUP_GPIO2] = { |
4415 | .type = ALC_FIXUP_VERBS, | 4461 | .type = ALC_FIXUP_VERBS, |
@@ -4465,6 +4511,30 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4465 | .chained = true, | 4511 | .chained = true, |
4466 | .chain_id = ALC880_FIXUP_GPIO2, | 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 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { | 4540 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { |
@@ -4472,6 +4542,8 @@ static const struct snd_pci_quirk alc880_fixup_tbl[] = { | |||
4472 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), | 4542 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), |
4473 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), | 4543 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), |
4474 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), | 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 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), | 4547 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), |
4476 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), | 4548 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), |
4477 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), | 4549 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), |