diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-02-20 11:20:48 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-02-20 11:30:49 -0500 |
commit | 817de92f1b52358f28534bb0b0c373f75e4b4baa (patch) | |
tree | d1a7f6267290207b7769bd99c5a0781639a1424a /sound/pci | |
parent | 7833c7e8b41d4c778e18481d7115dafa4bfaee0a (diff) |
ALSA: hda/realtek - Rewrite ALC880 model=uniwill with auto-parser
The model=uniwill would work almost as is, but a couple of adjustments
are needed to make the mutli-io working correctly. The headphone and
speaker pins have to be marked properly in pin configs.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/alc880_quirks.c | 118 | ||||
-rw-r--r-- | sound/pci/hda/alc_quirks.c | 12 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 12 |
3 files changed, 12 insertions, 130 deletions
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c index 2a00271e0651..c40f2446fcc4 100644 --- a/sound/pci/hda/alc880_quirks.c +++ b/sound/pci/hda/alc880_quirks.c | |||
@@ -18,7 +18,6 @@ enum { | |||
18 | ALC880_ASUS_W1V, | 18 | ALC880_ASUS_W1V, |
19 | ALC880_ASUS_DIG2, | 19 | ALC880_ASUS_DIG2, |
20 | ALC880_UNIWILL_DIG, | 20 | ALC880_UNIWILL_DIG, |
21 | ALC880_UNIWILL, | ||
22 | #ifdef CONFIG_SND_DEBUG | 21 | #ifdef CONFIG_SND_DEBUG |
23 | ALC880_TEST, | 22 | ALC880_TEST, |
24 | #endif | 23 | #endif |
@@ -306,34 +305,6 @@ static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { | |||
306 | { } /* end */ | 305 | { } /* end */ |
307 | }; | 306 | }; |
308 | 307 | ||
309 | /* Uniwill */ | ||
310 | static const struct snd_kcontrol_new alc880_uniwill_mixer[] = { | ||
311 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
312 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | ||
313 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
314 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
315 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
316 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
317 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
318 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
319 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
320 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
321 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
322 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
323 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
324 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
325 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
326 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
327 | { | ||
328 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
329 | .name = "Channel Mode", | ||
330 | .info = alc_ch_mode_info, | ||
331 | .get = alc_ch_mode_get, | ||
332 | .put = alc_ch_mode_put, | ||
333 | }, | ||
334 | { } /* end */ | ||
335 | }; | ||
336 | |||
337 | /* | 308 | /* |
338 | * initialize the codec volumes, etc | 309 | * initialize the codec volumes, etc |
339 | */ | 310 | */ |
@@ -518,83 +489,11 @@ static const struct hda_verb alc880_pin_6stack_init_verbs[] = { | |||
518 | { } | 489 | { } |
519 | }; | 490 | }; |
520 | 491 | ||
521 | /* | ||
522 | * Uniwill pin configuration: | ||
523 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, | ||
524 | * line = 0x1a | ||
525 | */ | ||
526 | static const struct hda_verb alc880_uniwill_init_verbs[] = { | ||
527 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
528 | |||
529 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
530 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
531 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
532 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
533 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
534 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
535 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
536 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
537 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
538 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
539 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
540 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
541 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
542 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
543 | |||
544 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
545 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
546 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
547 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
548 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
549 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
550 | /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ | ||
551 | /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ | ||
552 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
553 | |||
554 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
555 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
556 | |||
557 | { } | ||
558 | }; | ||
559 | |||
560 | static const struct hda_verb alc880_beep_init_verbs[] = { | 492 | static const struct hda_verb alc880_beep_init_verbs[] = { |
561 | { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, | 493 | { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, |
562 | { } | 494 | { } |
563 | }; | 495 | }; |
564 | 496 | ||
565 | static void alc880_uniwill_setup(struct hda_codec *codec) | ||
566 | { | ||
567 | struct alc_spec *spec = codec->spec; | ||
568 | |||
569 | spec->autocfg.hp_pins[0] = 0x14; | ||
570 | spec->autocfg.speaker_pins[0] = 0x15; | ||
571 | spec->autocfg.speaker_pins[0] = 0x16; | ||
572 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); | ||
573 | } | ||
574 | |||
575 | static void alc880_uniwill_init_hook(struct hda_codec *codec) | ||
576 | { | ||
577 | alc_hp_automute(codec); | ||
578 | alc88x_simple_mic_automute(codec); | ||
579 | } | ||
580 | |||
581 | static void alc880_uniwill_unsol_event(struct hda_codec *codec, | ||
582 | unsigned int res) | ||
583 | { | ||
584 | /* Looks like the unsol event is incompatible with the standard | ||
585 | * definition. 4bit tag is placed at 28 bit! | ||
586 | */ | ||
587 | res >>= 28; | ||
588 | switch (res) { | ||
589 | case ALC_MIC_EVENT: | ||
590 | alc88x_simple_mic_automute(codec); | ||
591 | break; | ||
592 | default: | ||
593 | alc_exec_unsol_event(codec, res); | ||
594 | break; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | /* | 497 | /* |
599 | * ASUS pin configuration: | 498 | * ASUS pin configuration: |
600 | * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a | 499 | * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a |
@@ -911,7 +810,6 @@ static const char * const alc880_models[ALC880_MODEL_LAST] = { | |||
911 | [ALC880_ASUS_W1V] = "asus-w1v", | 810 | [ALC880_ASUS_W1V] = "asus-w1v", |
912 | [ALC880_ASUS_DIG] = "asus-dig", | 811 | [ALC880_ASUS_DIG] = "asus-dig", |
913 | [ALC880_ASUS_DIG2] = "asus-dig2", | 812 | [ALC880_ASUS_DIG2] = "asus-dig2", |
914 | [ALC880_UNIWILL_DIG] = "uniwill", | ||
915 | #ifdef CONFIG_SND_DEBUG | 813 | #ifdef CONFIG_SND_DEBUG |
916 | [ALC880_TEST] = "test", | 814 | [ALC880_TEST] = "test", |
917 | #endif | 815 | #endif |
@@ -955,7 +853,6 @@ static const struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
955 | SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), | 853 | SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), |
956 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), | 854 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), |
957 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), | 855 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), |
958 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), | ||
959 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), | 856 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), |
960 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), | 857 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), |
961 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ | 858 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ |
@@ -1123,21 +1020,6 @@ static const struct alc_config_preset alc880_presets[] = { | |||
1123 | .need_dac_fix = 1, | 1020 | .need_dac_fix = 1, |
1124 | .input_mux = &alc880_capture_source, | 1021 | .input_mux = &alc880_capture_source, |
1125 | }, | 1022 | }, |
1126 | [ALC880_UNIWILL] = { | ||
1127 | .mixers = { alc880_uniwill_mixer }, | ||
1128 | .init_verbs = { alc880_volume_init_verbs, | ||
1129 | alc880_uniwill_init_verbs }, | ||
1130 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
1131 | .dac_nids = alc880_asus_dac_nids, | ||
1132 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1133 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
1134 | .channel_mode = alc880_threestack_modes, | ||
1135 | .need_dac_fix = 1, | ||
1136 | .input_mux = &alc880_capture_source, | ||
1137 | .unsol_event = alc880_uniwill_unsol_event, | ||
1138 | .setup = alc880_uniwill_setup, | ||
1139 | .init_hook = alc880_uniwill_init_hook, | ||
1140 | }, | ||
1141 | #ifdef CONFIG_SND_DEBUG | 1023 | #ifdef CONFIG_SND_DEBUG |
1142 | [ALC880_TEST] = { | 1024 | [ALC880_TEST] = { |
1143 | .mixers = { alc880_test_mixer }, | 1025 | .mixers = { alc880_test_mixer }, |
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c index b344603ac06d..a63a517780d6 100644 --- a/sound/pci/hda/alc_quirks.c +++ b/sound/pci/hda/alc_quirks.c | |||
@@ -165,15 +165,3 @@ static void alc_simple_setup_automute(struct alc_spec *spec, int mode) | |||
165 | spec->automute_lo = spec->automute_lo_possible = !!lo_pin; | 165 | spec->automute_lo = spec->automute_lo_possible = !!lo_pin; |
166 | spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0]; | 166 | spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0]; |
167 | } | 167 | } |
168 | |||
169 | /* auto-toggle front mic */ | ||
170 | static void alc88x_simple_mic_automute(struct hda_codec *codec) | ||
171 | { | ||
172 | unsigned int present; | ||
173 | unsigned char bits; | ||
174 | |||
175 | present = snd_hda_jack_detect(codec, 0x18); | ||
176 | bits = present ? HDA_AMP_MUTE : 0; | ||
177 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); | ||
178 | } | ||
179 | |||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3c0a46ed9ca9..ff4410cf75a6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4447,6 +4447,7 @@ enum { | |||
4447 | ALC880_FIXUP_VOL_KNOB, | 4447 | ALC880_FIXUP_VOL_KNOB, |
4448 | ALC880_FIXUP_FUJITSU, | 4448 | ALC880_FIXUP_FUJITSU, |
4449 | ALC880_FIXUP_F1734, | 4449 | ALC880_FIXUP_F1734, |
4450 | ALC880_FIXUP_UNIWILL, | ||
4450 | }; | 4451 | }; |
4451 | 4452 | ||
4452 | /* enable the volume-knob widget support on NID 0x21 */ | 4453 | /* enable the volume-knob widget support on NID 0x21 */ |
@@ -4556,12 +4557,23 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4556 | .chained = true, | 4557 | .chained = true, |
4557 | .chain_id = ALC880_FIXUP_VOL_KNOB, | 4558 | .chain_id = ALC880_FIXUP_VOL_KNOB, |
4558 | }, | 4559 | }, |
4560 | [ALC880_FIXUP_UNIWILL] = { | ||
4561 | /* need to fix HP and speaker pins to be parsed correctly */ | ||
4562 | .type = ALC_FIXUP_PINS, | ||
4563 | .v.pins = (const struct alc_pincfg[]) { | ||
4564 | { 0x14, 0x0121411f }, /* HP */ | ||
4565 | { 0x15, 0x99030120 }, /* speaker */ | ||
4566 | { 0x16, 0x99030130 }, /* bass speaker */ | ||
4567 | { } | ||
4568 | }, | ||
4569 | }, | ||
4559 | }; | 4570 | }; |
4560 | 4571 | ||
4561 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { | 4572 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { |
4562 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), | 4573 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), |
4563 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), | 4574 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), |
4564 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), | 4575 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), |
4576 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL), | ||
4565 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), | 4577 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), |
4566 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), | 4578 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), |
4567 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), | 4579 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), |