]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ALSA: hda/realtek: Add quirk for Lenovo Yoga9 14IAP7
authorPhilipp Jungkamp <p.jungkamp@gmx.net>
Fri, 29 Jul 2022 16:21:03 +0000 (18:21 +0200)
committerTakashi Iwai <tiwai@suse.de>
Sat, 30 Jul 2022 07:05:22 +0000 (09:05 +0200)
The Lenovo Yoga 9 14IAP7 is set up similarly to the Thinkpad X1 7th and
8th Gen. It also has the speakers attached to NID 0x14 and the bass
speakers to NID 0x17, but here the codec misreports the NID 0x17 as
unconnected.

The pincfg and hda verbs connect and activate the bass speaker
amplifiers, but the generic driver will connect them to NID 0x06 which
has no volume control. Set connection list/preferred connections is
required to gain volume control.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208555
Signed-off-by: Philipp Jungkamp <p.jungkamp@gmx.net>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20220729162103.6062-1-p.jungkamp@gmx.net
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/patch_realtek.c

index e1fbda21597568e4666e6fe7e4eddaec5de49445..cca093cb643eed4a404813178a2d5b9ab6c64983 100644 (file)
@@ -6817,6 +6817,43 @@ static void alc_fixup_dell4_mic_no_presence_quiet(struct hda_codec *codec,
        }
 }
 
+static void alc287_fixup_yoga9_14iap7_bass_spk_pin(struct hda_codec *codec,
+                                         const struct hda_fixup *fix, int action)
+{
+       /*
+        * The Pin Complex 0x17 for the bass speakers is wrongly reported as
+        * unconnected.
+        */
+       static const struct hda_pintbl pincfgs[] = {
+               { 0x17, 0x90170121 },
+               { }
+       };
+       /*
+        * Avoid DAC 0x06 and 0x08, as they have no volume controls.
+        * DAC 0x02 and 0x03 would be fine.
+        */
+       static const hda_nid_t conn[] = { 0x02, 0x03 };
+       /*
+        * Prefer both speakerbar (0x14) and bass speakers (0x17) connected to DAC 0x02.
+        * Headphones (0x21) are connected to DAC 0x03.
+        */
+       static const hda_nid_t preferred_pairs[] = {
+               0x14, 0x02,
+               0x17, 0x02,
+               0x21, 0x03,
+               0
+       };
+       struct alc_spec *spec = codec->spec;
+
+       switch (action) {
+       case HDA_FIXUP_ACT_PRE_PROBE:
+               snd_hda_apply_pincfgs(codec, pincfgs);
+               snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
+               spec->gen.preferred_dacs = preferred_pairs;
+               break;
+       }
+}
+
 enum {
        ALC269_FIXUP_GPIO2,
        ALC269_FIXUP_SONY_VAIO,
@@ -7054,6 +7091,8 @@ enum {
        ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
        ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE,
        ALC287_FIXUP_LEGION_16ITHG6,
+       ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK,
+       ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN,
 };
 
 /* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -8900,6 +8939,74 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc287_fixup_legion_16ithg6_speakers,
        },
+       [ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       // enable left speaker
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x41 },
+
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xc },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x1a },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xf },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x42 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x10 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x40 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x2 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+                       // enable right speaker
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x46 },
+
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xc },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x2a },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xf },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x46 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x10 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x44 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x2 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+                       { },
+               },
+       },
+       [ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc287_fixup_yoga9_14iap7_bass_spk_pin,
+               .chained = true,
+               .chain_id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK,
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -9352,6 +9459,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x17aa, 0x31af, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340),
+       SND_PCI_QUIRK(0x17aa, 0x3801, "Lenovo Yoga9 14IAP7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
        SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
        SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
        SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7),
@@ -9598,6 +9706,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"},
        {.id = ALC285_FIXUP_HP_SPECTRE_X360_EB1, .name = "alc285-hp-spectre-x360-eb1"},
        {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"},
+       {.id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, .name = "alc287-yoga9-bass-spk-pin"},
        {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"},
        {.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"},
        {.id = ALC285_FIXUP_HP_GPIO_AMP_INIT, .name = "alc285-hp-amp-init"},