[PATCH 0/1] ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Master after reboot from Windows
This patch addresses an issue where after rebooting from Windows into Linux there would be no audio output.
It turns out that the Realtek Audio driver on Windows changes some coeffs which are not being reset/reinitialized when rebooting the machine. As a result, there is no audio output until these coeffs are being reset to their initial state. This patch takes care of that by setting known-good (initial) values to the coeffs.
The coeffs were collected via alsa-info, see: broken: https://pastebin.com/4bRBSseH working: https://pastebin.com/WUTufvZB
I also created a script which fixes the audio at runtime.
#!/bin/sh hda-verb /dev/snd/hwC2D0 0x20 SET_COEF_INDEX 0x1a hda-verb /dev/snd/hwC2D0 0x20 SET_PROC_COEF 0x01c1 hda-verb /dev/snd/hwC2D0 0x20 SET_COEF_INDEX 0x1b hda-verb /dev/snd/hwC2D0 0x20 SET_PROC_COEF 0x0202 hda-verb /dev/snd/hwC2D0 0x20 SET_COEF_INDEX 0x43 hda-verb /dev/snd/hwC2D0 0x20 SET_PROC_COEF 0x3005 hda-verb /dev/snd/hwC2D0 0x20 SET_COEF_INDEX 0x58 hda-verb /dev/snd/hwC2D0 0x20 SET_PROC_COEF 0x8fd6 hda-verb /dev/snd/hwC2D0 0x20 SET_COEF_INDEX 0x5f hda-verb /dev/snd/hwC2D0 0x20 SET_PROC_COEF 0xa3c5 hda-verb /dev/snd/hwC2D0 0x20 SET_COEF_INDEX 0x6a hda-verb /dev/snd/hwC2D0 0x20 SET_PROC_COEF 0x0232
However, obviously, we can and should fix this in the kernel.
We initially relied upon alc1220_fixup_clevo_p950() to fix some pins in the connection list. However, it also sets coef 0x7 which does not need to be touched. Furthermore, to prevent mixing device-specific quirks I introduced a new alc1220_fixup_gb_x570() which is heavily based on alc1220_fixup_clevo_p950() but does not set coeff 0x7 and fixes the coeffs that are actually needed instead.
This new alc1220_fixup_gb_x570() is believed to also work for other boards, like the Gigabyte X570 Aorus Extreme and the newer Gigabyte Aorus X570S Master. However, as there is no way for me to test these I initially only enable this new behaviour for the mainboard I have which is the Gigabyte X570(non-S) Aorus Master.
I tested this patch on the 5.15 branch as well as on master and it is working well for me.
Christian Lachner (1): ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Master after reboot from Windows
sound/pci/hda/patch_realtek.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
This patch addresses an issue where after rebooting from Windows into Linux there would be no audio output.
It turns out that the Realtek Audio driver on Windows changes some coeffs which are not being reset/reinitialized when rebooting the machine. As a result, there is no audio output until these coeffs are being reset to their initial state. This patch takes care of that by setting known-good (initial) values to the coeffs.
We initially relied upon alc1220_fixup_clevo_p950() to fix some pins in the connection list. However, it also sets coef 0x7 which does not need to be touched. Furthermore, to prevent mixing device-specific quirks I introduced a new alc1220_fixup_gb_x570() which is heavily based on alc1220_fixup_clevo_p950() but does not set coeff 0x7 and fixes the coeffs that are actually needed instead.
This new alc1220_fixup_gb_x570() is believed to also work for other boards, like the Gigabyte X570 Aorus Extreme and the newer Gigabyte Aorus X570S Master. However, as there is no way for me to test these I initially only enable this new behaviour for the mainboard I have which is the Gigabyte X570(non-S) Aorus Master.
I tested this patch on the 5.15 branch as well as on master and it is working well for me.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205275 Signed-off-by: Christian Lachner gladiac@gmail.com --- sound/pci/hda/patch_realtek.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 28255e752c4a..1463d7d62465 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1924,6 +1924,7 @@ enum { ALC887_FIXUP_ASUS_BASS, ALC887_FIXUP_BASS_CHMAP, ALC1220_FIXUP_GB_DUAL_CODECS, + ALC1220_FIXUP_GB_X570, ALC1220_FIXUP_CLEVO_P950, ALC1220_FIXUP_CLEVO_PB51ED, ALC1220_FIXUP_CLEVO_PB51ED_PINS, @@ -2113,6 +2114,26 @@ static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec, } }
+static void alc1220_fixup_gb_x570(struct hda_codec *codec, + const struct hda_fixup *fix, + int action) +{ + static const hda_nid_t conn1[] = { 0x0c }; + + if (action != HDA_FIXUP_ACT_PRE_PROBE) + return; + + alc_write_coef_idx(codec, 0x1a, 0x01c1); + alc_write_coef_idx(codec, 0x1b, 0x0202); + alc_write_coef_idx(codec, 0x43, 0x3005); + alc_write_coef_idx(codec, 0x58, 0x8fd6); + alc_write_coef_idx(codec, 0x5f, 0xa3c5); + alc_write_coef_idx(codec, 0x6a, 0x0232); + + snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1); + snd_hda_override_conn_list(codec, 0x1b, ARRAY_SIZE(conn1), conn1); +} + static void alc1220_fixup_clevo_p950(struct hda_codec *codec, const struct hda_fixup *fix, int action) @@ -2415,6 +2436,10 @@ static const struct hda_fixup alc882_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc1220_fixup_gb_dual_codecs, }, + [ALC1220_FIXUP_GB_X570] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc1220_fixup_gb_x570, + }, [ALC1220_FIXUP_CLEVO_P950] = { .type = HDA_FIXUP_FUNC, .v.func = alc1220_fixup_clevo_p950, @@ -2517,7 +2542,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x13fe, 0x1009, "Advantech MIT-W101", ALC886_FIXUP_EAPD), SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), - SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950), + SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_GB_X570), SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1462, 0x11f7, "MSI-GE63", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
On Fri, 31 Dec 2021 11:21:38 +0100, Christian Lachner wrote:
+static void alc1220_fixup_gb_x570(struct hda_codec *codec,
const struct hda_fixup *fix,
int action)
+{
- static const hda_nid_t conn1[] = { 0x0c };
- if (action != HDA_FIXUP_ACT_PRE_PROBE)
return;
- alc_write_coef_idx(codec, 0x1a, 0x01c1);
- alc_write_coef_idx(codec, 0x1b, 0x0202);
- alc_write_coef_idx(codec, 0x43, 0x3005);
- alc_write_coef_idx(codec, 0x58, 0x8fd6);
- alc_write_coef_idx(codec, 0x5f, 0xa3c5);
- alc_write_coef_idx(codec, 0x6a, 0x0232);
Those could be better with struct coef_fw table to be processed via alc_process_coef_fw().
Also the coef update needs to be performed not only at PRE_INIT but also at each resume, so this should be better done for action == HDA_FIXUP_ACT_INIT, I suppose.
thanks,
Takashi
participants (2)
-
Christian Lachner
-
Takashi Iwai