aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-02-20 11:20:48 -0500
committerTakashi Iwai <tiwai@suse.de>2012-02-20 11:30:49 -0500
commit817de92f1b52358f28534bb0b0c373f75e4b4baa (patch)
treed1a7f6267290207b7769bd99c5a0781639a1424a /sound/pci
parent7833c7e8b41d4c778e18481d7115dafa4bfaee0a (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.c118
-rw-r--r--sound/pci/hda/alc_quirks.c12
-rw-r--r--sound/pci/hda/patch_realtek.c12
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 */
310static 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 */
526static 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
560static const struct hda_verb alc880_beep_init_verbs[] = { 492static 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
565static 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
575static void alc880_uniwill_init_hook(struct hda_codec *codec)
576{
577 alc_hp_automute(codec);
578 alc88x_simple_mic_automute(codec);
579}
580
581static 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 */
170static 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
4561static const struct snd_pci_quirk alc880_fixup_tbl[] = { 4572static 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),