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.c87
1 files changed, 64 insertions, 23 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 0db1dc49382b..1358987c49d8 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;
@@ -4358,6 +4374,7 @@ enum {
4358 ALC882_FIXUP_ACER_ASPIRE_8930G, 4374 ALC882_FIXUP_ACER_ASPIRE_8930G,
4359 ALC882_FIXUP_ASPIRE_8930G_VERBS, 4375 ALC882_FIXUP_ASPIRE_8930G_VERBS,
4360 ALC885_FIXUP_MACPRO_GPIO, 4376 ALC885_FIXUP_MACPRO_GPIO,
4377 ALC889_FIXUP_DAC_ROUTE,
4361}; 4378};
4362 4379
4363static void alc889_fixup_coef(struct hda_codec *codec, 4380static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4411,6 +4428,23 @@ static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
4411 alc882_gpio_mute(codec, 1, 0); 4428 alc882_gpio_mute(codec, 1, 0);
4412} 4429}
4413 4430
4431/* Fix the connection of some pins for ALC889:
4432 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
4433 * work correctly (bko#42740)
4434 */
4435static void alc889_fixup_dac_route(struct hda_codec *codec,
4436 const struct alc_fixup *fix, int action)
4437{
4438 if (action == ALC_FIXUP_ACT_PRE_PROBE) {
4439 hda_nid_t conn1[2] = { 0x0c, 0x0d };
4440 hda_nid_t conn2[2] = { 0x0e, 0x0f };
4441 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
4442 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
4443 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
4444 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
4445 }
4446}
4447
4414static const struct alc_fixup alc882_fixups[] = { 4448static const struct alc_fixup alc882_fixups[] = {
4415 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 4449 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
4416 .type = ALC_FIXUP_PINS, 4450 .type = ALC_FIXUP_PINS,
@@ -4558,6 +4592,10 @@ static const struct alc_fixup alc882_fixups[] = {
4558 .type = ALC_FIXUP_FUNC, 4592 .type = ALC_FIXUP_FUNC,
4559 .v.func = alc885_fixup_macpro_gpio, 4593 .v.func = alc885_fixup_macpro_gpio,
4560 }, 4594 },
4595 [ALC889_FIXUP_DAC_ROUTE] = {
4596 .type = ALC_FIXUP_FUNC,
4597 .v.func = alc889_fixup_dac_route,
4598 },
4561}; 4599};
4562 4600
4563static const struct snd_pci_quirk alc882_fixup_tbl[] = { 4601static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4582,6 +4620,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
4582 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 4620 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
4583 ALC882_FIXUP_ACER_ASPIRE_4930G), 4621 ALC882_FIXUP_ACER_ASPIRE_4930G),
4584 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), 4622 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
4623 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
4585 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), 4624 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
4586 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), 4625 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
4587 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), 4626 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
@@ -4735,7 +4774,6 @@ enum {
4735 ALC262_FIXUP_FSC_H270, 4774 ALC262_FIXUP_FSC_H270,
4736 ALC262_FIXUP_HP_Z200, 4775 ALC262_FIXUP_HP_Z200,
4737 ALC262_FIXUP_TYAN, 4776 ALC262_FIXUP_TYAN,
4738 ALC262_FIXUP_TOSHIBA_RX1,
4739 ALC262_FIXUP_LENOVO_3000, 4777 ALC262_FIXUP_LENOVO_3000,
4740 ALC262_FIXUP_BENQ, 4778 ALC262_FIXUP_BENQ,
4741 ALC262_FIXUP_BENQ_T31, 4779 ALC262_FIXUP_BENQ_T31,
@@ -4765,16 +4803,6 @@ static const struct alc_fixup alc262_fixups[] = {
4765 { } 4803 { }
4766 } 4804 }
4767 }, 4805 },
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] = { 4806 [ALC262_FIXUP_LENOVO_3000] = {
4779 .type = ALC_FIXUP_VERBS, 4807 .type = ALC_FIXUP_VERBS,
4780 .v.verbs = (const struct hda_verb[]) { 4808 .v.verbs = (const struct hda_verb[]) {
@@ -4807,8 +4835,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4807 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), 4835 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ),
4808 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), 4836 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
4809 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), 4837 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), 4838 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
4813 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), 4839 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
4814 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), 4840 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
@@ -5377,7 +5403,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5377 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 5403 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5378 ALC269_FIXUP_AMIC), 5404 ALC269_FIXUP_AMIC),
5379 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), 5405 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), 5406 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5382 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), 5407 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5383 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), 5408 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
@@ -5589,6 +5614,25 @@ enum {
5589 PINFIX_ASUS_A6RP, 5614 PINFIX_ASUS_A6RP,
5590}; 5615};
5591 5616
5617/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
5618static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
5619 const struct alc_fixup *fix, int action)
5620{
5621 struct alc_spec *spec = codec->spec;
5622 unsigned int val;
5623
5624 if (action != ALC_FIXUP_ACT_INIT)
5625 return;
5626 val = snd_hda_codec_read(codec, 0x0f, 0,
5627 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5628 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
5629 val |= AC_PINCTL_IN_EN;
5630 val |= AC_PINCTL_VREF_50;
5631 snd_hda_codec_write(codec, 0x0f, 0,
5632 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5633 spec->keep_vref_in_automute = 1;
5634}
5635
5592static const struct alc_fixup alc861_fixups[] = { 5636static const struct alc_fixup alc861_fixups[] = {
5593 [PINFIX_FSC_AMILO_PI1505] = { 5637 [PINFIX_FSC_AMILO_PI1505] = {
5594 .type = ALC_FIXUP_PINS, 5638 .type = ALC_FIXUP_PINS,
@@ -5599,17 +5643,14 @@ static const struct alc_fixup alc861_fixups[] = {
5599 } 5643 }
5600 }, 5644 },
5601 [PINFIX_ASUS_A6RP] = { 5645 [PINFIX_ASUS_A6RP] = {
5602 .type = ALC_FIXUP_VERBS, 5646 .type = ALC_FIXUP_FUNC,
5603 .v.verbs = (const struct hda_verb[]) { 5647 .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 }, 5648 },
5609}; 5649};
5610 5650
5611static const struct snd_pci_quirk alc861_fixup_tbl[] = { 5651static const struct snd_pci_quirk alc861_fixup_tbl[] = {
5612 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP), 5652 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP),
5653 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP),
5613 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), 5654 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
5614 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 5655 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
5615 {} 5656 {}