* [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers @ 2026-01-21 13:12 Damien 2026-01-23 16:35 ` Takashi Iwai 0 siblings, 1 reply; 4+ messages in thread From: Damien @ 2026-01-21 13:12 UTC (permalink / raw) To: tiwai, perex; +Cc: linux-sound, alsa-devel [-- Attachment #1.1: Type: text/plain, Size: 585 bytes --] Hi, The LG Gram Style 14 (14Z90RS-G.AD77F, SSID 1854:0490) with Realtek ALC298 shows normal routing and volume changes, but internal speakers remain silent unless a userland HDA-verb workaround is applied. This patch adds a dedicated quirk for the LG Gram Style 14 that programs the codec coefficient sequence used by the known workaround and enables the speaker amps only during playback. Tested-by: Dams <damien.dagorn29@gmail.com> Tested: speaker-test -D hw:0 -c 2 -t wav -l 1 (front left/right OK) Please find the patch series attached. Thanks, Damien [-- Attachment #1.2: Type: text/html, Size: 720 bytes --] [-- Attachment #2: 0000-cover-letter.patch --] [-- Type: text/x-patch, Size: 899 bytes --] From 113b13ace8671a18c8f3820b007d5757df43dd36 Mon Sep 17 00:00:00 2001 From: Dams <damien.dagorn29@gmail.com> Date: Wed, 21 Jan 2026 14:06:38 +0100 Subject: [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers The LG Gram Style 14 (14Z90RS-G.AD77F, SSID 1854:0490) with Realtek ALC298 shows normal routing and volume changes, but internal speakers stay silent unless a userland HDA-verb workaround is applied. This patch adds a dedicated quirk for the LG Gram Style 14 that programs the codec coefficient sequence used by the known workaround and enables the speaker amps only during playback. Tested-by: Dams <damien.dagorn29@gmail.com> Tested: speaker-test -D hw:0 -c 2 -t wav -l 1 (front left/right OK) Dams (1): ALSA: hda/realtek: add LG Gram Style 14 amp init sound/hda/codecs/realtek/alc269.c | 168 ++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) -- 2.51.0 [-- Attachment #3: 0001-ALSA-hda-realtek-add-LG-Gram-Style-14-amp-init.patch --] [-- Type: text/x-patch, Size: 8448 bytes --] From 113b13ace8671a18c8f3820b007d5757df43dd36 Mon Sep 17 00:00:00 2001 From: Dams <damien.dagorn29@gmail.com> Date: Wed, 21 Jan 2026 14:06:30 +0100 Subject: [PATCH 1/1] ALSA: hda/realtek: add LG Gram Style 14 amp init --- sound/hda/codecs/realtek/alc269.c | 168 ++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index f267437..acbe818 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -1814,6 +1814,161 @@ static void alc298_samsung_v2_init_amps(struct hda_codec *codec, spec->gen.pcm_playback_hook = alc298_samsung_v2_playback_hook; } +struct alc298_lg_gram_style_seq { + unsigned short verb; + unsigned short idx; + unsigned short val; +}; + +static void alc298_lg_gram_style_coef_write(struct hda_codec *codec, + unsigned int verb, + unsigned int idx, + unsigned int val) +{ + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x23); + snd_hda_codec_write(codec, 0x20, 0, verb, idx); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0x00); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, val); + snd_hda_codec_write(codec, 0x20, 0, 0x4b0, 0x11); +} + +static void alc298_lg_gram_style_run_seq(struct hda_codec *codec, + const struct alc298_lg_gram_style_seq *seq, + int seq_size) +{ + int i; + + for (i = 0; i < seq_size; i++) + alc298_lg_gram_style_coef_write(codec, seq[i].verb, + seq[i].idx, seq[i].val); +} + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_preinit_seq[] = { + { 0x420, 0x00, 0x01 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_disable_seq[] = { + { 0x423, 0xff, 0x00 }, + { 0x420, 0x3a, 0x80 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_enable_seq[] = { + { 0x420, 0x3a, 0x81 }, + { 0x423, 0xff, 0x01 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_38[] = { + { 0x423, 0xe1, 0x00 }, { 0x420, 0x12, 0x6f }, { 0x420, 0x14, 0x00 }, + { 0x420, 0x1b, 0x01 }, { 0x420, 0x1d, 0x01 }, { 0x420, 0x1f, 0xfe }, + { 0x420, 0x21, 0x00 }, { 0x420, 0x22, 0x10 }, { 0x420, 0x3d, 0x05 }, + { 0x420, 0x3f, 0x03 }, { 0x420, 0x50, 0x2c }, { 0x420, 0x76, 0x0e }, + { 0x420, 0x7c, 0x4a }, { 0x420, 0x81, 0x03 }, { 0x423, 0x99, 0x03 }, + { 0x423, 0xa4, 0xb5 }, { 0x423, 0xa5, 0x01 }, { 0x423, 0xba, 0x94 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_39[] = { + { 0x423, 0xe1, 0x00 }, { 0x420, 0x12, 0x6f }, { 0x420, 0x14, 0x00 }, + { 0x420, 0x1b, 0x02 }, { 0x420, 0x1d, 0x02 }, { 0x420, 0x1f, 0xfd }, + { 0x420, 0x21, 0x01 }, { 0x420, 0x22, 0x10 }, { 0x420, 0x3d, 0x05 }, + { 0x420, 0x3f, 0x03 }, { 0x420, 0x50, 0x2c }, { 0x420, 0x76, 0x0e }, + { 0x420, 0x7c, 0x4a }, { 0x420, 0x81, 0x03 }, { 0x423, 0x99, 0x03 }, + { 0x423, 0xa4, 0xb5 }, { 0x423, 0xa5, 0x01 }, { 0x423, 0xba, 0x94 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_3c[] = { + { 0x423, 0xe1, 0x00 }, { 0x420, 0x12, 0x6f }, { 0x420, 0x14, 0x00 }, + { 0x420, 0x1b, 0x01 }, { 0x420, 0x1d, 0x01 }, { 0x420, 0x1f, 0xfe }, + { 0x420, 0x21, 0x00 }, { 0x420, 0x22, 0x10 }, { 0x420, 0x3d, 0x05 }, + { 0x420, 0x3f, 0x03 }, { 0x420, 0x50, 0x2c }, { 0x420, 0x76, 0x0e }, + { 0x420, 0x7c, 0x4a }, { 0x420, 0x81, 0x03 }, { 0x423, 0xba, 0x8d }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_3d[] = { + { 0x423, 0xe1, 0x00 }, { 0x420, 0x12, 0x6f }, { 0x420, 0x14, 0x00 }, + { 0x420, 0x1b, 0x02 }, { 0x420, 0x1d, 0x02 }, { 0x420, 0x1f, 0xfd }, + { 0x420, 0x21, 0x01 }, { 0x420, 0x22, 0x10 }, { 0x420, 0x3d, 0x05 }, + { 0x420, 0x3f, 0x03 }, { 0x420, 0x50, 0x2c }, { 0x420, 0x76, 0x0e }, + { 0x420, 0x7c, 0x4a }, { 0x420, 0x81, 0x03 }, { 0x423, 0xba, 0x8d }, +}; + +struct alc298_lg_gram_style_amp_desc { + unsigned char nid; + const struct alc298_lg_gram_style_seq *init_seq; + int init_seq_size; +}; + +static const struct alc298_lg_gram_style_amp_desc alc298_lg_gram_style_amps[] = { + { 0x38, alc298_lg_gram_style_init_seq_38, + ARRAY_SIZE(alc298_lg_gram_style_init_seq_38) }, + { 0x39, alc298_lg_gram_style_init_seq_39, + ARRAY_SIZE(alc298_lg_gram_style_init_seq_39) }, + { 0x3c, alc298_lg_gram_style_init_seq_3c, + ARRAY_SIZE(alc298_lg_gram_style_init_seq_3c) }, + { 0x3d, alc298_lg_gram_style_init_seq_3d, + ARRAY_SIZE(alc298_lg_gram_style_init_seq_3d) }, +}; + +static void alc298_lg_gram_style_enable_amps(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->num_speaker_amps; i++) { + alc_write_coef_idx(codec, 0x22, alc298_lg_gram_style_amps[i].nid); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_enable_seq, + ARRAY_SIZE(alc298_lg_gram_style_enable_seq)); + } +} + +static void alc298_lg_gram_style_disable_amps(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->num_speaker_amps; i++) { + alc_write_coef_idx(codec, 0x22, alc298_lg_gram_style_amps[i].nid); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_disable_seq, + ARRAY_SIZE(alc298_lg_gram_style_disable_seq)); + } +} + +static void alc298_lg_gram_style_playback_hook(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream, + int action) +{ + if (action == HDA_GEN_PCM_ACT_OPEN) + alc298_lg_gram_style_enable_amps(codec); + if (action == HDA_GEN_PCM_ACT_CLOSE) + alc298_lg_gram_style_disable_amps(codec); +} + +static void alc298_lg_gram_style_init_amps(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + spec->num_speaker_amps = ARRAY_SIZE(alc298_lg_gram_style_amps); + + for (i = 0; i < spec->num_speaker_amps; i++) { + alc_write_coef_idx(codec, 0x22, alc298_lg_gram_style_amps[i].nid); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_preinit_seq, + ARRAY_SIZE(alc298_lg_gram_style_preinit_seq)); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_disable_seq, + ARRAY_SIZE(alc298_lg_gram_style_disable_seq)); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_amps[i].init_seq, + alc298_lg_gram_style_amps[i].init_seq_size); + alc_write_coef_idx(codec, 0x89, 0x0); + } + + spec->gen.pcm_playback_hook = alc298_lg_gram_style_playback_hook; +} + static void alc298_fixup_samsung_amp_v2_2_amps(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -1828,6 +1983,13 @@ static void alc298_fixup_samsung_amp_v2_4_amps(struct hda_codec *codec, alc298_samsung_v2_init_amps(codec, 4); } +static void alc298_fixup_lg_gram_style_14(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PROBE) + alc298_lg_gram_style_init_amps(codec); +} + static void gpio2_mic_hotkey_event(struct hda_codec *codec, struct hda_jack_callback *event) { @@ -3630,6 +3792,7 @@ enum { ALC298_FIXUP_SAMSUNG_AMP, ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS, ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS, + ALC298_FIXUP_LG_GRAM_STYLE_14, ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, @@ -5294,6 +5457,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc298_fixup_samsung_amp_v2_4_amps }, + [ALC298_FIXUP_LG_GRAM_STYLE_14] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc298_fixup_lg_gram_style_14 + }, [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { @@ -7135,6 +7302,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1854, 0x0488, "LG gram 16 (16Z90R)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x1854, 0x0489, "LG gram 16 (16Z90R-A)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x1854, 0x048a, "LG gram 17 (17ZD90R)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), + SND_PCI_QUIRK(0x1854, 0x0490, "LG Gram Style 14 (14Z90RS)", ALC298_FIXUP_LG_GRAM_STYLE_14), 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(0x19e5, 0x3212, "Huawei KLV-WX9 ", ALC256_FIXUP_ACER_HEADSET_MIC), -- 2.51.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers 2026-01-21 13:12 [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers Damien @ 2026-01-23 16:35 ` Takashi Iwai 2026-01-23 17:20 ` Damien 0 siblings, 1 reply; 4+ messages in thread From: Takashi Iwai @ 2026-01-23 16:35 UTC (permalink / raw) To: Damien; +Cc: perex, linux-sound, alsa-devel On Wed, 21 Jan 2026 14:12:09 +0100, Damien wrote: > > > Hi, > > The LG Gram Style 14 (14Z90RS-G.AD77F, SSID 1854:0490) with Realtek ALC298 > shows normal routing and volume changes, but internal speakers remain silent > unless a userland HDA-verb workaround is applied. > > This patch adds a dedicated quirk for the LG Gram Style 14 that programs > the codec coefficient sequence used by the known workaround and enables > the speaker amps only during playback. > > Tested-by: Dams <damien.dagorn29@gmail.com> > Tested: speaker-test -D hw:0 -c 2 -t wav -l 1 (front left/right OK) > > Please find the patch series attached. > > Thanks, > Damien Thanks for the patch. Unfortunately, the patch looks created somehow in a not ideal way. First of all, the useful information like: > > From 113b13ace8671a18c8f3820b007d5757df43dd36 Mon Sep 17 00:00:00 2001 > From: Dams <damien.dagorn29@gmail.com> > Date: Wed, 21 Jan 2026 14:06:38 +0100 > Subject: [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers > > The LG Gram Style 14 (14Z90RS-G.AD77F, SSID 1854:0490) with Realtek ALC298 > shows normal routing and volume changes, but internal speakers stay silent > unless a userland HDA-verb workaround is applied. > > This patch adds a dedicated quirk for the LG Gram Style 14 that programs > the codec coefficient sequence used by the known workaround and enables > the speaker amps only during playback. > > Tested-by: Dams <damien.dagorn29@gmail.com> > Tested: speaker-test -D hw:0 -c 2 -t wav -l 1 (front left/right OK) ... those should be put rather in the description of the patch itself. You've put it in 0/1, that is a cover letter, which won't be included in the git commit. (And in general, there is no need for splitting to a cover letter if it's only a single patch; describe it right in the patch itself or not.) Secondly, a valid Signed-off-by tag is mandatory for upstreaming. It's a legal requirement. And for the Signed-off-by tag (also the From line as the author), you should provide a full real name. Now about the code changes: > --- a/sound/hda/codecs/realtek/alc269.c > +++ b/sound/hda/codecs/realtek/alc269.c > @@ -1814,6 +1814,161 @@ static void alc298_samsung_v2_init_amps(struct hda_codec *codec, > spec->gen.pcm_playback_hook = alc298_samsung_v2_playback_hook; > } > Maybe it'd be better to have some comments about the quirk. It's no trivial code, hence it's worth for explanation. > +struct alc298_lg_gram_style_seq { > + unsigned short verb; > + unsigned short idx; > + unsigned short val; > +}; > + > +static void alc298_lg_gram_style_coef_write(struct hda_codec *codec, > + unsigned int verb, > + unsigned int idx, > + unsigned int val) > +{ > + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x23); > + snd_hda_codec_write(codec, 0x20, 0, verb, idx); > + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0x00); > + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, val); > + snd_hda_codec_write(codec, 0x20, 0, 0x4b0, 0x11); Use AC_VERB_SET_PROC_COEF for 0x400. It's equivalent with snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb011); Could you try to resubmit with the corrections above? thanks, Takashi ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers 2026-01-23 16:35 ` Takashi Iwai @ 2026-01-23 17:20 ` Damien 2026-01-24 10:21 ` Takashi Iwai 0 siblings, 1 reply; 4+ messages in thread From: Damien @ 2026-01-23 17:20 UTC (permalink / raw) To: Takashi Iwai; +Cc: perex, linux-sound, alsa-devel [-- Attachment #1.1: Type: text/plain, Size: 4170 bytes --] Hi Takashi, Thanks for the feedback. I’ve reworked the patch as requested: - single patch (no cover letter), with the full description in the commit message - proper Signed-off-by with my full name - added comments for the quirk - use AC_VERB_SET_PROC_COEF for 0x400 and 0xb011 instead of 0x4b0 I hope this rework matches your request Please find the updated patch attached. Thanks, Damien Le ven. 23 janv. 2026 à 17:35, Takashi Iwai <tiwai@suse.de> a écrit : > On Wed, 21 Jan 2026 14:12:09 +0100, > Damien wrote: > > > > > > Hi, > > > > The LG Gram Style 14 (14Z90RS-G.AD77F, SSID 1854:0490) with Realtek > ALC298 > > shows normal routing and volume changes, but internal speakers remain > silent > > unless a userland HDA-verb workaround is applied. > > > > This patch adds a dedicated quirk for the LG Gram Style 14 that > programs > > the codec coefficient sequence used by the known workaround and enables > > the speaker amps only during playback. > > > > Tested-by: Dams <damien.dagorn29@gmail.com> > > Tested: speaker-test -D hw:0 -c 2 -t wav -l 1 (front left/right OK) > > > > Please find the patch series attached. > > > > Thanks, > > Damien > > Thanks for the patch. Unfortunately, the patch looks created somehow > in a not ideal way. First of all, the useful information like: > > > > From 113b13ace8671a18c8f3820b007d5757df43dd36 Mon Sep 17 00:00:00 2001 > > From: Dams <damien.dagorn29@gmail.com> > > Date: Wed, 21 Jan 2026 14:06:38 +0100 > > Subject: [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers > > > > The LG Gram Style 14 (14Z90RS-G.AD77F, SSID 1854:0490) with Realtek > ALC298 > > shows normal routing and volume changes, but internal speakers stay > silent > > unless a userland HDA-verb workaround is applied. > > > > This patch adds a dedicated quirk for the LG Gram Style 14 that programs > > the codec coefficient sequence used by the known workaround and enables > > the speaker amps only during playback. > > > > Tested-by: Dams <damien.dagorn29@gmail.com> > > Tested: speaker-test -D hw:0 -c 2 -t wav -l 1 (front left/right OK) > > ... those should be put rather in the description of the patch itself. > You've put it in 0/1, that is a cover letter, which won't be included > in the git commit. > (And in general, there is no need for splitting to a cover letter if > it's only a single patch; describe it right in the patch itself or > not.) > > Secondly, a valid Signed-off-by tag is mandatory for upstreaming. > It's a legal requirement. And for the Signed-off-by tag (also the > From line as the author), you should provide a full real name. > > Now about the code changes: > > > --- a/sound/hda/codecs/realtek/alc269.c > > +++ b/sound/hda/codecs/realtek/alc269.c > > @@ -1814,6 +1814,161 @@ static void alc298_samsung_v2_init_amps(struct > hda_codec *codec, > > spec->gen.pcm_playback_hook = alc298_samsung_v2_playback_hook; > > } > > > > Maybe it'd be better to have some comments about the quirk. > It's no trivial code, hence it's worth for explanation. > > > +struct alc298_lg_gram_style_seq { > > + unsigned short verb; > > + unsigned short idx; > > + unsigned short val; > > +}; > > + > > +static void alc298_lg_gram_style_coef_write(struct hda_codec *codec, > > + unsigned int verb, > > + unsigned int idx, > > + unsigned int val) > > +{ > > + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x23); > > + snd_hda_codec_write(codec, 0x20, 0, verb, idx); > > + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0x00); > > + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, val); > > + snd_hda_codec_write(codec, 0x20, 0, 0x4b0, 0x11); > > Use AC_VERB_SET_PROC_COEF for 0x400. It's equivalent with > snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb011); > > Could you try to resubmit with the corrections above? > > > thanks, > > Takashi > [-- Attachment #1.2: Type: text/html, Size: 5208 bytes --] [-- Attachment #2: 0001-ALSA-hda-realtek-fix-LG-Gram-Style-14-speakers.patch --] [-- Type: text/x-patch, Size: 9112 bytes --] From 82a7855e66194e1882c18409345bf41324ba6874 Mon Sep 17 00:00:00 2001 From: Damien Dagorn <damien.dagorn29@gmail.com> Date: Fri, 23 Jan 2026 18:14:52 +0100 Subject: [PATCH] ALSA: hda/realtek: fix LG Gram Style 14 speakers The LG Gram Style 14 (14Z90RS-G.AD77F, SSID 1854:0490) with Realtek ALC298 shows normal routing and volume changes, but internal speakers stay silent unless a userland HDA-verb workaround is applied. Add a dedicated quirk for the LG Gram Style 14 that programs the codec coefficient sequence used by the known workaround and enables the speaker amps only during playback. Tested-by: Damien Dagorn <damien.dagorn29@gmail.com> Signed-off-by: Damien Dagorn <damien.dagorn29@gmail.com> --- sound/hda/codecs/realtek/alc269.c | 170 ++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index f267437..c2bba85 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -1814,6 +1814,163 @@ static void alc298_samsung_v2_init_amps(struct hda_codec *codec, spec->gen.pcm_playback_hook = alc298_samsung_v2_playback_hook; } +/* LG Gram Style 14: program vendor coef sequence used by HDA-verb workaround */ +struct alc298_lg_gram_style_seq { + unsigned short verb; + unsigned short idx; + unsigned short val; +}; + +static void alc298_lg_gram_style_coef_write(struct hda_codec *codec, + unsigned int verb, + unsigned int idx, + unsigned int val) +{ + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x23); + snd_hda_codec_write(codec, 0x20, 0, verb, idx); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0x00); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, val); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 0xb011); +} + +static void alc298_lg_gram_style_run_seq(struct hda_codec *codec, + const struct alc298_lg_gram_style_seq *seq, + int seq_size) +{ + int i; + + for (i = 0; i < seq_size; i++) + alc298_lg_gram_style_coef_write(codec, seq[i].verb, + seq[i].idx, seq[i].val); +} + +/* Coef sequences derived from the HDA-verb workaround for this model. */ +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_preinit_seq[] = { + { 0x420, 0x00, 0x01 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_disable_seq[] = { + { 0x423, 0xff, 0x00 }, + { 0x420, 0x3a, 0x80 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_enable_seq[] = { + { 0x420, 0x3a, 0x81 }, + { 0x423, 0xff, 0x01 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_38[] = { + { 0x423, 0xe1, 0x00 }, { 0x420, 0x12, 0x6f }, { 0x420, 0x14, 0x00 }, + { 0x420, 0x1b, 0x01 }, { 0x420, 0x1d, 0x01 }, { 0x420, 0x1f, 0xfe }, + { 0x420, 0x21, 0x00 }, { 0x420, 0x22, 0x10 }, { 0x420, 0x3d, 0x05 }, + { 0x420, 0x3f, 0x03 }, { 0x420, 0x50, 0x2c }, { 0x420, 0x76, 0x0e }, + { 0x420, 0x7c, 0x4a }, { 0x420, 0x81, 0x03 }, { 0x423, 0x99, 0x03 }, + { 0x423, 0xa4, 0xb5 }, { 0x423, 0xa5, 0x01 }, { 0x423, 0xba, 0x94 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_39[] = { + { 0x423, 0xe1, 0x00 }, { 0x420, 0x12, 0x6f }, { 0x420, 0x14, 0x00 }, + { 0x420, 0x1b, 0x02 }, { 0x420, 0x1d, 0x02 }, { 0x420, 0x1f, 0xfd }, + { 0x420, 0x21, 0x01 }, { 0x420, 0x22, 0x10 }, { 0x420, 0x3d, 0x05 }, + { 0x420, 0x3f, 0x03 }, { 0x420, 0x50, 0x2c }, { 0x420, 0x76, 0x0e }, + { 0x420, 0x7c, 0x4a }, { 0x420, 0x81, 0x03 }, { 0x423, 0x99, 0x03 }, + { 0x423, 0xa4, 0xb5 }, { 0x423, 0xa5, 0x01 }, { 0x423, 0xba, 0x94 }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_3c[] = { + { 0x423, 0xe1, 0x00 }, { 0x420, 0x12, 0x6f }, { 0x420, 0x14, 0x00 }, + { 0x420, 0x1b, 0x01 }, { 0x420, 0x1d, 0x01 }, { 0x420, 0x1f, 0xfe }, + { 0x420, 0x21, 0x00 }, { 0x420, 0x22, 0x10 }, { 0x420, 0x3d, 0x05 }, + { 0x420, 0x3f, 0x03 }, { 0x420, 0x50, 0x2c }, { 0x420, 0x76, 0x0e }, + { 0x420, 0x7c, 0x4a }, { 0x420, 0x81, 0x03 }, { 0x423, 0xba, 0x8d }, +}; + +static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_3d[] = { + { 0x423, 0xe1, 0x00 }, { 0x420, 0x12, 0x6f }, { 0x420, 0x14, 0x00 }, + { 0x420, 0x1b, 0x02 }, { 0x420, 0x1d, 0x02 }, { 0x420, 0x1f, 0xfd }, + { 0x420, 0x21, 0x01 }, { 0x420, 0x22, 0x10 }, { 0x420, 0x3d, 0x05 }, + { 0x420, 0x3f, 0x03 }, { 0x420, 0x50, 0x2c }, { 0x420, 0x76, 0x0e }, + { 0x420, 0x7c, 0x4a }, { 0x420, 0x81, 0x03 }, { 0x423, 0xba, 0x8d }, +}; + +struct alc298_lg_gram_style_amp_desc { + unsigned char nid; + const struct alc298_lg_gram_style_seq *init_seq; + int init_seq_size; +}; + +static const struct alc298_lg_gram_style_amp_desc alc298_lg_gram_style_amps[] = { + { 0x38, alc298_lg_gram_style_init_seq_38, + ARRAY_SIZE(alc298_lg_gram_style_init_seq_38) }, + { 0x39, alc298_lg_gram_style_init_seq_39, + ARRAY_SIZE(alc298_lg_gram_style_init_seq_39) }, + { 0x3c, alc298_lg_gram_style_init_seq_3c, + ARRAY_SIZE(alc298_lg_gram_style_init_seq_3c) }, + { 0x3d, alc298_lg_gram_style_init_seq_3d, + ARRAY_SIZE(alc298_lg_gram_style_init_seq_3d) }, +}; + +static void alc298_lg_gram_style_enable_amps(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->num_speaker_amps; i++) { + alc_write_coef_idx(codec, 0x22, alc298_lg_gram_style_amps[i].nid); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_enable_seq, + ARRAY_SIZE(alc298_lg_gram_style_enable_seq)); + } +} + +static void alc298_lg_gram_style_disable_amps(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->num_speaker_amps; i++) { + alc_write_coef_idx(codec, 0x22, alc298_lg_gram_style_amps[i].nid); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_disable_seq, + ARRAY_SIZE(alc298_lg_gram_style_disable_seq)); + } +} + +static void alc298_lg_gram_style_playback_hook(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream, + int action) +{ + if (action == HDA_GEN_PCM_ACT_OPEN) + alc298_lg_gram_style_enable_amps(codec); + if (action == HDA_GEN_PCM_ACT_CLOSE) + alc298_lg_gram_style_disable_amps(codec); +} + +static void alc298_lg_gram_style_init_amps(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + spec->num_speaker_amps = ARRAY_SIZE(alc298_lg_gram_style_amps); + + for (i = 0; i < spec->num_speaker_amps; i++) { + alc_write_coef_idx(codec, 0x22, alc298_lg_gram_style_amps[i].nid); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_preinit_seq, + ARRAY_SIZE(alc298_lg_gram_style_preinit_seq)); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_disable_seq, + ARRAY_SIZE(alc298_lg_gram_style_disable_seq)); + alc298_lg_gram_style_run_seq(codec, + alc298_lg_gram_style_amps[i].init_seq, + alc298_lg_gram_style_amps[i].init_seq_size); + alc_write_coef_idx(codec, 0x89, 0x0); + } + + spec->gen.pcm_playback_hook = alc298_lg_gram_style_playback_hook; +} + static void alc298_fixup_samsung_amp_v2_2_amps(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -1828,6 +1985,13 @@ static void alc298_fixup_samsung_amp_v2_4_amps(struct hda_codec *codec, alc298_samsung_v2_init_amps(codec, 4); } +static void alc298_fixup_lg_gram_style_14(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PROBE) + alc298_lg_gram_style_init_amps(codec); +} + static void gpio2_mic_hotkey_event(struct hda_codec *codec, struct hda_jack_callback *event) { @@ -3630,6 +3794,7 @@ enum { ALC298_FIXUP_SAMSUNG_AMP, ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS, ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS, + ALC298_FIXUP_LG_GRAM_STYLE_14, ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, @@ -5294,6 +5459,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc298_fixup_samsung_amp_v2_4_amps }, + [ALC298_FIXUP_LG_GRAM_STYLE_14] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc298_fixup_lg_gram_style_14 + }, [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { @@ -7135,6 +7304,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1854, 0x0488, "LG gram 16 (16Z90R)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x1854, 0x0489, "LG gram 16 (16Z90R-A)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x1854, 0x048a, "LG gram 17 (17ZD90R)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), + SND_PCI_QUIRK(0x1854, 0x0490, "LG Gram Style 14 (14Z90RS)", ALC298_FIXUP_LG_GRAM_STYLE_14), 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(0x19e5, 0x3212, "Huawei KLV-WX9 ", ALC256_FIXUP_ACER_HEADSET_MIC), -- 2.51.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers 2026-01-23 17:20 ` Damien @ 2026-01-24 10:21 ` Takashi Iwai 0 siblings, 0 replies; 4+ messages in thread From: Takashi Iwai @ 2026-01-24 10:21 UTC (permalink / raw) To: Damien; +Cc: perex, linux-sound, alsa-devel On Fri, 23 Jan 2026 18:20:44 +0100, Damien wrote: > > > Hi Takashi, > > Thanks for the feedback. I’ve reworked the patch as requested: > - single patch (no cover letter), with the full description in the commit > message > - proper Signed-off-by with my full name > - added comments for the quirk > - use AC_VERB_SET_PROC_COEF for 0x400 and 0xb011 instead of 0x4b0 > > I hope this rework matches your request > > Please find the updated patch attached. > > Thanks, > Damien Thanks, I applied now to for-next branch. At the next time, please try to submit via git-fixes directly without attachments. An attachment is rather a last-resort when no direct submission is possible by some reasons. Takashi ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-01-24 10:21 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-21 13:12 [PATCH 0/1] ALSA: hda/realtek: fix LG Gram Style 14 speakers Damien 2026-01-23 16:35 ` Takashi Iwai 2026-01-23 17:20 ` Damien 2026-01-24 10:21 ` Takashi Iwai
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox