]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: hda/realtek: fix the hp playback volume issue for LG machines
authorHui Wang <hui.wang@canonical.com>
Mon, 18 Mar 2024 01:11:28 +0000 (09:11 +0800)
committerTakashi Iwai <tiwai@suse.de>
Mon, 18 Mar 2024 15:13:25 +0000 (16:13 +0100)
Recently we tested the headphone playback on 2 LG machines, if we set
the volume to the max value or near to the max value, the sound is too
loud, it could even bring harm to listeners.

A workaround is to decrease the max volume to a reasonable value for
the headphone's amplifier, then the users couldn't set the volume
bigger than that value from the userspace.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
Message-ID: <20240318011128.156023-1-hui.wang@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/patch_realtek.c

index e904f62e195267faab2a1ed67dcab4fa75f2d8f8..d463d416fc23a7a0957e2f2167d809bf6c22a8b9 100644 (file)
@@ -6964,6 +6964,25 @@ static void alc256_fixup_mic_no_presence_and_resume(struct hda_codec *codec,
        }
 }
 
+static void alc256_decrease_headphone_amp_val(struct hda_codec *codec,
+                                             const struct hda_fixup *fix, int action)
+{
+       u32 caps;
+       u8 nsteps, offs;
+
+       if (action != HDA_FIXUP_ACT_PRE_PROBE)
+               return;
+
+       caps = query_amp_caps(codec, 0x3, HDA_OUTPUT);
+       nsteps = ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) - 10;
+       offs = ((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT) - 10;
+       caps &= ~AC_AMPCAP_NUM_STEPS & ~AC_AMPCAP_OFFSET;
+       caps |= (nsteps << AC_AMPCAP_NUM_STEPS_SHIFT) | (offs << AC_AMPCAP_OFFSET_SHIFT);
+
+       if (snd_hda_override_amp_caps(codec, 0x3, HDA_OUTPUT, caps))
+               codec_warn(codec, "failed to override amp caps for NID 0x3\n");
+}
+
 static void alc_fixup_dell4_mic_no_presence_quiet(struct hda_codec *codec,
                                                  const struct hda_fixup *fix,
                                                  int action)
@@ -7382,6 +7401,7 @@ enum {
        ALC294_FIXUP_CS35L41_I2C_2,
        ALC245_FIXUP_CS35L56_SPI_4_HP_GPIO_LED,
        ALC256_FIXUP_ACER_SFG16_MICMUTE_LED,
+       ALC256_FIXUP_HEADPHONE_AMP_VOL,
 };
 
 /* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -9581,6 +9601,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc256_fixup_acer_sfg16_micmute_led,
        },
+       [ALC256_FIXUP_HEADPHONE_AMP_VOL] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc256_decrease_headphone_amp_val,
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -10319,6 +10343,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
        SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1854, 0x0440, "LG CQ6", ALC256_FIXUP_HEADPHONE_AMP_VOL),
+       SND_PCI_QUIRK(0x1854, 0x0441, "LG CQ6 AIO", ALC256_FIXUP_HEADPHONE_AMP_VOL),
        SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
        SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),