diff options
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a7f17becbd7c..42b6a01e17db 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -177,6 +177,7 @@ struct alc_spec { | |||
177 | unsigned int detect_lo:1; /* Line-out detection enabled */ | 177 | unsigned int detect_lo:1; /* Line-out detection enabled */ |
178 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ | 178 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ |
179 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ | 179 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ |
180 | unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ | ||
180 | 181 | ||
181 | /* other flags */ | 182 | /* other flags */ |
182 | unsigned int no_analog :1; /* digital I/O only */ | 183 | unsigned int no_analog :1; /* digital I/O only */ |
@@ -495,13 +496,24 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
495 | 496 | ||
496 | for (i = 0; i < num_pins; i++) { | 497 | for (i = 0; i < num_pins; i++) { |
497 | hda_nid_t nid = pins[i]; | 498 | hda_nid_t nid = pins[i]; |
499 | unsigned int val; | ||
498 | if (!nid) | 500 | if (!nid) |
499 | break; | 501 | break; |
500 | switch (spec->automute_mode) { | 502 | switch (spec->automute_mode) { |
501 | case ALC_AUTOMUTE_PIN: | 503 | case ALC_AUTOMUTE_PIN: |
504 | /* don't reset VREF value in case it's controlling | ||
505 | * the amp (see alc861_fixup_asus_amp_vref_0f()) | ||
506 | */ | ||
507 | if (spec->keep_vref_in_automute) { | ||
508 | val = snd_hda_codec_read(codec, nid, 0, | ||
509 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
510 | val &= ~PIN_HP; | ||
511 | } else | ||
512 | val = 0; | ||
513 | val |= pin_bits; | ||
502 | snd_hda_codec_write(codec, nid, 0, | 514 | snd_hda_codec_write(codec, nid, 0, |
503 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 515 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
504 | pin_bits); | 516 | val); |
505 | break; | 517 | break; |
506 | case ALC_AUTOMUTE_AMP: | 518 | case ALC_AUTOMUTE_AMP: |
507 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | 519 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
@@ -5588,6 +5600,25 @@ enum { | |||
5588 | PINFIX_ASUS_A6RP, | 5600 | PINFIX_ASUS_A6RP, |
5589 | }; | 5601 | }; |
5590 | 5602 | ||
5603 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | ||
5604 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | ||
5605 | const struct alc_fixup *fix, int action) | ||
5606 | { | ||
5607 | struct alc_spec *spec = codec->spec; | ||
5608 | unsigned int val; | ||
5609 | |||
5610 | if (action != ALC_FIXUP_ACT_INIT) | ||
5611 | return; | ||
5612 | val = snd_hda_codec_read(codec, 0x0f, 0, | ||
5613 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5614 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) | ||
5615 | val |= AC_PINCTL_IN_EN; | ||
5616 | val |= AC_PINCTL_VREF_50; | ||
5617 | snd_hda_codec_write(codec, 0x0f, 0, | ||
5618 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); | ||
5619 | spec->keep_vref_in_automute = 1; | ||
5620 | } | ||
5621 | |||
5591 | static const struct alc_fixup alc861_fixups[] = { | 5622 | static const struct alc_fixup alc861_fixups[] = { |
5592 | [PINFIX_FSC_AMILO_PI1505] = { | 5623 | [PINFIX_FSC_AMILO_PI1505] = { |
5593 | .type = ALC_FIXUP_PINS, | 5624 | .type = ALC_FIXUP_PINS, |
@@ -5598,17 +5629,13 @@ static const struct alc_fixup alc861_fixups[] = { | |||
5598 | } | 5629 | } |
5599 | }, | 5630 | }, |
5600 | [PINFIX_ASUS_A6RP] = { | 5631 | [PINFIX_ASUS_A6RP] = { |
5601 | .type = ALC_FIXUP_VERBS, | 5632 | .type = ALC_FIXUP_FUNC, |
5602 | .v.verbs = (const struct hda_verb[]) { | 5633 | .v.func = alc861_fixup_asus_amp_vref_0f, |
5603 | /* node 0x0f VREF seems controlling the master output */ | ||
5604 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, | ||
5605 | { } | ||
5606 | }, | ||
5607 | }, | 5634 | }, |
5608 | }; | 5635 | }; |
5609 | 5636 | ||
5610 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { | 5637 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
5611 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP), | 5638 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), |
5612 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), | 5639 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), |
5613 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), | 5640 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), |
5614 | {} | 5641 | {} |