aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 0db1dc49382b..9350f3c3bdf8 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,
@@ -1843,6 +1855,8 @@ static const char * const alc_slave_vols[] = {
1843 "Speaker Playback Volume", 1855 "Speaker Playback Volume",
1844 "Mono Playback Volume", 1856 "Mono Playback Volume",
1845 "Line-Out Playback Volume", 1857 "Line-Out Playback Volume",
1858 "CLFE Playback Volume",
1859 "Bass Speaker Playback Volume",
1846 "PCM Playback Volume", 1860 "PCM Playback Volume",
1847 NULL, 1861 NULL,
1848}; 1862};
@@ -1858,6 +1872,8 @@ static const char * const alc_slave_sws[] = {
1858 "Mono Playback Switch", 1872 "Mono Playback Switch",
1859 "IEC958 Playback Switch", 1873 "IEC958 Playback Switch",
1860 "Line-Out Playback Switch", 1874 "Line-Out Playback Switch",
1875 "CLFE Playback Switch",
1876 "Bass Speaker Playback Switch",
1861 "PCM Playback Switch", 1877 "PCM Playback Switch",
1862 NULL, 1878 NULL,
1863}; 1879};
@@ -2306,7 +2322,7 @@ static int alc_build_pcms(struct hda_codec *codec)
2306 "%s Analog", codec->chip_name); 2322 "%s Analog", codec->chip_name);
2307 info->name = spec->stream_name_analog; 2323 info->name = spec->stream_name_analog;
2308 2324
2309 if (spec->multiout.dac_nids > 0) { 2325 if (spec->multiout.num_dacs > 0) {
2310 p = spec->stream_analog_playback; 2326 p = spec->stream_analog_playback;
2311 if (!p) 2327 if (!p)
2312 p = &alc_pcm_analog_playback; 2328 p = &alc_pcm_analog_playback;
@@ -4735,7 +4751,6 @@ enum {
4735 ALC262_FIXUP_FSC_H270, 4751 ALC262_FIXUP_FSC_H270,
4736 ALC262_FIXUP_HP_Z200, 4752 ALC262_FIXUP_HP_Z200,
4737 ALC262_FIXUP_TYAN, 4753 ALC262_FIXUP_TYAN,
4738 ALC262_FIXUP_TOSHIBA_RX1,
4739 ALC262_FIXUP_LENOVO_3000, 4754 ALC262_FIXUP_LENOVO_3000,
4740 ALC262_FIXUP_BENQ, 4755 ALC262_FIXUP_BENQ,
4741 ALC262_FIXUP_BENQ_T31, 4756 ALC262_FIXUP_BENQ_T31,
@@ -4765,16 +4780,6 @@ static const struct alc_fixup alc262_fixups[] = {
4765 { } 4780 { }
4766 } 4781 }
4767 }, 4782 },
4768 [ALC262_FIXUP_TOSHIBA_RX1] = {
4769 .type = ALC_FIXUP_PINS,
4770 .v.pins = (const struct alc_pincfg[]) {
4771 { 0x14, 0x90170110 }, /* speaker */
4772 { 0x15, 0x0421101f }, /* HP */
4773 { 0x1a, 0x40f000f0 }, /* N/A */
4774 { 0x1b, 0x40f000f0 }, /* N/A */
4775 { 0x1e, 0x40f000f0 }, /* N/A */
4776 }
4777 },
4778 [ALC262_FIXUP_LENOVO_3000] = { 4783 [ALC262_FIXUP_LENOVO_3000] = {
4779 .type = ALC_FIXUP_VERBS, 4784 .type = ALC_FIXUP_VERBS,
4780 .v.verbs = (const struct hda_verb[]) { 4785 .v.verbs = (const struct hda_verb[]) {
@@ -4807,8 +4812,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4807 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), 4812 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ),
4808 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), 4813 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
4809 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), 4814 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
4810 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
4811 ALC262_FIXUP_TOSHIBA_RX1),
4812 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), 4815 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
4813 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), 4816 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
4814 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), 4817 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
@@ -5377,7 +5380,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5377 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 5380 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5378 ALC269_FIXUP_AMIC), 5381 ALC269_FIXUP_AMIC),
5379 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), 5382 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
5380 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC),
5381 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), 5383 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5382 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), 5384 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5383 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), 5385 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
@@ -5589,6 +5591,25 @@ enum {
5589 PINFIX_ASUS_A6RP, 5591 PINFIX_ASUS_A6RP,
5590}; 5592};
5591 5593
5594/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
5595static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
5596 const struct alc_fixup *fix, int action)
5597{
5598 struct alc_spec *spec = codec->spec;
5599 unsigned int val;
5600
5601 if (action != ALC_FIXUP_ACT_INIT)
5602 return;
5603 val = snd_hda_codec_read(codec, 0x0f, 0,
5604 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5605 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
5606 val |= AC_PINCTL_IN_EN;
5607 val |= AC_PINCTL_VREF_50;
5608 snd_hda_codec_write(codec, 0x0f, 0,
5609 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5610 spec->keep_vref_in_automute = 1;
5611}
5612
5592static const struct alc_fixup alc861_fixups[] = { 5613static const struct alc_fixup alc861_fixups[] = {
5593 [PINFIX_FSC_AMILO_PI1505] = { 5614 [PINFIX_FSC_AMILO_PI1505] = {
5594 .type = ALC_FIXUP_PINS, 5615 .type = ALC_FIXUP_PINS,
@@ -5599,17 +5620,14 @@ static const struct alc_fixup alc861_fixups[] = {
5599 } 5620 }
5600 }, 5621 },
5601 [PINFIX_ASUS_A6RP] = { 5622 [PINFIX_ASUS_A6RP] = {
5602 .type = ALC_FIXUP_VERBS, 5623 .type = ALC_FIXUP_FUNC,
5603 .v.verbs = (const struct hda_verb[]) { 5624 .v.func = alc861_fixup_asus_amp_vref_0f,
5604 /* node 0x0f VREF seems controlling the master output */
5605 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
5606 { }
5607 },
5608 }, 5625 },
5609}; 5626};
5610 5627
5611static const struct snd_pci_quirk alc861_fixup_tbl[] = { 5628static const struct snd_pci_quirk alc861_fixup_tbl[] = {
5612 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP), 5629 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP),
5630 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP),
5613 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), 5631 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
5614 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 5632 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
5615 {} 5633 {}