Skip to content

Instantly share code, notes, and snippets.

@lamperez
Last active November 11, 2024 11:16
Show Gist options
  • Save lamperez/862763881c0e1c812392b5574727f6ff to your computer and use it in GitHub Desktop.
Save lamperez/862763881c0e1c812392b5574727f6ff to your computer and use it in GitHub Desktop.
CS35L41 amplifiers in an ASUS Zenbook on linux

Asus Zenbook UX3402 speakers on Linux

Important

THIS IS NOW OBSOLETE WITH KERNEL VERSIONS ≥ 6.7.0

A recent announcement in the kernel mail list by Cirrus developers will solve the problem described here. Therefore, the proposed solutions will be soon obsolete. See this comment (thanks, @flukejones, for the tip).

I got the speakers working on my Asus Zenbook 14 OLED UX3402, the one with Intel CPU and the two CS35L41 audio amplifiers connected over SPI (not the UM3402YA, with AMD and I²C). The amplifiers are supported by the snd_hda_scodec_cs35l41 module in recent kernel versions, but they require some model-specific configuration paramaters, that should be provided by the BIOS, via ACPI. Of course, they are missing. It seems that the Windows drivers have those parameters somehow hardcoded, instead of using ACPI (bad idea, but who am I to criticise). Since Asus has been nasty and refused/was not able to update the BIOS with the missing data, I have patched the ACPI tables myself.

Warning

As stated by Cirrus developers, if you try this there is a non-zero (low, I hope) possibility of blowing your speakers. Take into account that this procedure is not just configuring your box, it is hardware-level hacking with very scarce information about the hardware (thank you, ASUS, and thank you, Cirrus, for not publishing the CS35L41 datasheet and making it only available by request). Additionally, You should know how to work with DSDT or SSDT files (I have a brief guide here) and how to recover from a non booting system. You are on your own. You have been warned.

Note

I have used the patch for some months, and everything seems OK. As you can see, the most recent versions do not require electrical parameters to be specified, just providing the functions of several GPIO pins, that are already present in the original BIOS, and the behavior associated to them. I am almost sure that the patch is totally safe.

My BIOS is the most recent one (version 310). I have added two _DSD objects in the SSDT file (ssdt_csc3551.dsl, or its already assembled version, ssdt_csc3551.aml):

  • One inside the SPK1 device, providing the missing "cirrus,dev-index" and other properties, just like the I2C models. You can also provide these properties by patching the kernel module (the linux/sound/pci/hda/cs35l41_hda.c file).

  • Another one, after the SPK1 device, with the chip select GPIOs, "cs-gpios", required by the SPI bus (the somehow simpler I²C bus does not use chip select pins, but addresses). Without this _DSD object, only one amplifier can be addressed and activated. In this case, the driver refuses to load even for this single working amplifier.

Obsolete: DSDT patch

Instead of applying a SSDT file, you may patch the full DSDT dissassembled DSDT file (dsdt.dsl). This was my original solution (thanks to @thor2002ro for pointing to the simpler, nicer SSDT solution, see the comment, especially if you use grub). The patch is available for reference, just apply the SSDT file.

Obsolete: internal boost

I keep the old, original patch, that produced AMP short error messages when the volume was high enough, for reference. Please try first the simpler patch with external boost, that seems to work without flaws (thanks to @bdandy, see the comment).

Boot log

Output from journalctl -b -g CSC3551 --output short-monotonic after the old patch:

[5.358062] zenbook kernel: Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[5.643640] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[5.680302] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2
[5.996217] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Falling back to default firmware.
[5.996608] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: Firmware version: 3
[5.996611] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: cirrus/cs35l41-dsp1-spk-prot.wmfw: Fri 24 Jun 2022 14:55:56 GMT Daylight Time
[6.069598] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: Firmware: 400a4 vendor: 0x2 v0.58.0, 2 algorithms
[6.070173] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: 0: ID cd v29.78.0 XM@94 YM@e
[6.070185] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: 1: ID f20b v0.1.0 XM@17c YM@0
[6.070192] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: spk-prot: e:\workspace\workspace\tibranch_release_playback_6.76_2\ormis\staging\default_tunings\internal\CS35L53\Fixed_Attenuation_Mono_48000_29.78.0\full\Fixed_Attenuation_Mono_48000_29.78.0_full.bin
[6.083485] zenbook kernel: snd_hda_codec_realtek ehdaudio0D0: bound spi1-CSC3551:00-cs35l41-hda.0 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])
[6.083899] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Falling back to default firmware.
[6.083962] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: Firmware version: 3
[6.083966] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: cirrus/cs35l41-dsp1-spk-prot.wmfw: Fri 24 Jun 2022 14:55:56 GMT Daylight Time
[6.145224] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: Firmware: 400a4 vendor: 0x2 v0.58.0, 2 algorithms
[6.145817] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: 0: ID cd v29.78.0 XM@94 YM@e
[6.145828] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: 1: ID f20b v0.1.0 XM@17c YM@0
[6.145834] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: spk-prot: e:\workspace\workspace\tibranch_release_playback_6.76_2\ormis\staging\default_tunings\internal\CS35L53\Fixed_Attenuation_Mono_48000_29.78.0\full\Fixed_Attenuation_Mono_48000_29.78.0_full.bin
[6.161484] zenbook kernel: snd_hda_codec_realtek ehdaudio0D0: bound spi1-CSC3551:00-cs35l41-hda.1 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])

The "Falling back to default firmware" disappears if spk-id-gpios are provided (the block is commented in the patch). As a result, a different firmware is loaded, resulting in very low volume and strong distortion. If the new patch is used, that uses external boost, the sound is correct, and the log is

[0.004000] zenbook kernel: ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[0.004000] zenbook kernel: ACPI: SSDT 0x00000000368FD000 0001A0 (v01 CUSTOM CSC3551  00000001 INTL 20200925)
[5.607253] zenbook kernel: Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[5.906936] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[5.907354] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[5.938136] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2
[6.239406] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: Firmware version: 3
[6.239415] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: cirrus/cs35l41-dsp1-spk-prot-10431e02.wmfw: Fri 27 Aug 2021 14:58:19 W. Europe Daylight Time
[6.313109] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: Firmware: 400a4 vendor: 0x2 v0.43.1, 2 algorithms
[6.313524] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: 0: ID cd v29.63.1 XM@94 YM@e
[6.313530] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: 1: ID f20b v0.1.0 XM@176 YM@0
[6.313535] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: spk-prot: C:\Users\tyang\Desktop\Product Setting\SmartAMP\ASUS\ASUS_Zenbook\UX3402\Tuning Release\220304\ASUS_UX3402_L_tuning_IDYC_ReDc_PICL_RTL_0304.bin
[6.337211] zenbook kernel: snd_hda_codec_realtek ehdaudio0D0: bound spi1-CSC3551:00-cs35l41-hda.0 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])
[6.337534] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: Firmware version: 3
[6.337540] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: cirrus/cs35l41-dsp1-spk-prot-10431e02.wmfw: Fri 27 Aug 2021 14:58:19 W. Europe Daylight Time
[6.399070] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: Firmware: 400a4 vendor: 0x2 v0.43.1, 2 algorithms
[6.399612] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: 0: ID cd v29.63.1 XM@94 YM@e
[6.399623] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: 1: ID f20b v0.1.0 XM@176 YM@0
[6.399629] zenbook kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: spk-prot: C:\Users\tyang\Desktop\Product Setting\SmartAMP\ASUS\ASUS_Zenbook\UX3402\Tuning Release\220304\ASUS_UX3402_R_tuning_IDYC_ReDc_PICL_RTL_0304.bin
[6.427637] zenbook kernel: snd_hda_codec_realtek ehdaudio0D0: bound spi1-CSC3551:00-cs35l41-hda.1 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])
--- dsdt.dsl.old 2023-03-26 01:06:48.845795666 +0100
+++ dsdt.dsl 2023-03-26 12:00:45.643851841 +0200
@@ -18,7 +18,7 @@
* Compiler ID "INTL"
* Compiler Version 0x20200717 (538969879)
*/
-DefinitionBlock ("", "DSDT", 2, "_ASUS_", "Notebook", 0x01072009)
+DefinitionBlock ("", "DSDT", 2, "_ASUS_", "Notebook", 0x0107200A)
{
/*
* iASL Warning: There were 233 external control methods found during
@@ -90642,7 +90642,48 @@
Method (_DIS, 0, NotSerialized) // _DIS: Disable Device
{
}
+
+ Name (_DSD, Package () // _DSD: Device-Specific Data
+ {
+ ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package () { "cirrus,dev-index", Package () { Zero, One }},
+ Package () { "reset-gpios", Package () {
+ SPK1, One, Zero, Zero,
+ SPK1, One, Zero, Zero,
+ } },
+ // Package () { "spk-id-gpios", Package () {
+ // SPK1, 0x02, Zero, Zero,
+ // SPK1, 0x02, Zero, Zero,
+ // } },
+ Package () { "cirrus,speaker-position", Package () { Zero, One } },
+ Package () { "cirrus,gpio1-func", Package () { Zero, Zero } },
+ Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
+ // boost-type: 0 internal, 1 external
+ Package () { "cirrus,boost-type", Package () { Zero, Zero } },
+ // boost-peak-milliamp: 1600 to 4500, increments of 50 mA
+ Package () { "cirrus,boost-peak-milliamp", Package () { 4500, 4500 } },
+ // boost-ind-nanohenry: 1000 | 1200 | 1500 | 2200 nH
+ Package () { "cirrus,boost-ind-nanohenry", Package () { 1000, 1000 } },
+ // boost-cap-microfarad: rounded to the nearest integer
+ Package () { "cirrus,boost-cap-microfarad", Package () { 24, 24 } },
+ },
+ })
}
+
+ Name (_DSD, Package ()
+ {
+ ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package () { "cs-gpios", Package () {
+ Zero, // Native CS
+ SPK1, Zero, Zero, Zero // GPIO CS
+ } }
+ }
+ })
+
}
Scope (_SB.PC00.LPCB)
--- dsdt.dsl.old 2023-03-26 01:06:48.845795666 +0100
+++ dsdt.dsl 2023-03-26 12:00:45.643851841 +0200
@@ -18,7 +18,7 @@
* Compiler ID "INTL"
* Compiler Version 0x20200717 (538969879)
*/
-DefinitionBlock ("", "DSDT", 2, "_ASUS_", "Notebook", 0x01072009)
+DefinitionBlock ("", "DSDT", 2, "_ASUS_", "Notebook", 0x0107200A)
{
/*
* iASL Warning: There were 233 external control methods found during
@@ -90642,7 +90642,43 @@
Method (_DIS, 0, NotSerialized) // _DIS: Disable Device
{
}
+
+ Name (_DSD, Package () // _DSD: Device-Specific Data
+ {
+ ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package () { "cirrus,dev-index", Package () { Zero, One }},
+ Package () { "reset-gpios", Package () {
+ SPK1, One, Zero, Zero,
+ SPK1, One, Zero, Zero,
+ } },
+ Package () { "spk-id-gpios", Package () {
+ SPK1, 0x02, Zero, Zero,
+ SPK1, 0x02, Zero, Zero,
+ } },
+ Package () { "cirrus,speaker-position", Package () { Zero, One } },
+ // gpioX-func: 0 not used, 1 VPSK_SWITCH, 2: INTERRUPT, 3: SYNC
+ Package () { "cirrus,gpio1-func", Package () { One, One } },
+ Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
+ // boost-type: 0 internal, 1 external
+ Package () { "cirrus,boost-type", Package () { One, One } },
+ },
+ })
}
+
+ Name (_DSD, Package ()
+ {
+ ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package () { "cs-gpios", Package () {
+ Zero, // Native CS
+ SPK1, Zero, Zero, Zero // GPIO CS
+ } }
+ }
+ })
+
}
Scope (_SB.PC00.LPCB)
DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
External (_SB_.PC00.SPI0, DeviceObj)
External (_SB_.PC00.SPI0.SPK1, DeviceObj)
Scope (_SB.PC00.SPI0.SPK1)
{
Name (_DSD, Package ()
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package () { "cirrus,dev-index", Package () { Zero, One }},
Package () { "reset-gpios", Package () {
SPK1, One, Zero, Zero,
SPK1, One, Zero, Zero
} },
Package () { "spk-id-gpios", Package () {
SPK1, 0x02, Zero, Zero,
SPK1, 0x02, Zero, Zero
} },
Package () { "cirrus,speaker-position", Package () { Zero, One } },
// gpioX-func: 0 not used, 1 VPSK_SWITCH, 2: INTERRUPT, 3: SYNC
Package () { "cirrus,gpio1-func", Package () { One, One } },
Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
// boost-type: 0 internal, 1 external
Package () { "cirrus,boost-type", Package () { One, One } }
}
})
}
Scope (_SB.PC00.SPI0)
{
Name (_DSD, Package ()
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package () { "cs-gpios", Package () {
Zero, // Native CS
SPK1, Zero, Zero, Zero // GPIO CS
} }
}
})
}
}
@kureta
Copy link

kureta commented Sep 29, 2023

I have finally found the problem and it's working. Only the first lines were different. So I changed the patch to DefinitionBlock ("", "SSDT", 1, "_ASUS_", "SPKRAMPS", 0x00000003). Apparently the last number is OEM revision number and it should be incremented. now it works! Thank you everyone in this thread!

@isle9
Copy link

isle9 commented Sep 29, 2023

I solved my problem with https://github.com/badgers-ua/asus_zenbook_ux5304va_sound. Thank you all. But i have to do the whole process after each kernel update. I hope fedora team insert path in next version

Hey I get page not found when I try to open your link.

@kureta
Copy link

kureta commented Sep 29, 2023

@mypsik
Copy link

mypsik commented Oct 16, 2023

Working ssdt-csc3551.dsl for ASUS Zenbook UM3402Y (the speakers are connected to I2C, not SPI).
Follow the rest from https://github.com/badgers-ua/asus_zenbook_ux5304va_sound

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CS3551", 0x0000300A)
{

    External (_SB_.I2CD, DeviceObj)
    External (_SB_.I2CD.SPKR, DeviceObj)

    Scope (_SB.I2CD.SPKR)
    {
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cirrus,dev-index", Package () { 0x0040, 0x0041 }},
                        Package () { "reset-gpios", Package () {
                           SPKR, Zero, Zero, Zero,
                           SPKR, Zero, Zero, Zero
                        } },
                        Package () { "spk-id-gpios", Package () {
                             SPKR, 0x02, Zero, Zero,
                             SPKR, 0x02, Zero, Zero,
                        } },
                        Package () { "cirrus,speaker-position", Package () { Zero, One } },
                        Package () { "cirrus,gpio1-func", Package () { One, One } },
                        Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
                        // boost-type: 0 internal, 1 external
                        Package () { "cirrus,boost-type", Package () { One, One } },
                        // boost-peak-milliamp: 1600 to 4500, increments of 50 mA
                        //Package () { "cirrus,boost-peak-milliamp",  Package () { 3000, 3000 } },
                        // boost-ind-nanohenry: 1000 | 1200 | 1500 | 2200 nH
                        //Package () { "cirrus,boost-ind-nanohenry",  Package () { 1000, 1000 } },
                        // boost-cap-microfarad: rounded to the nearest integer
                        //Package () { "cirrus,boost-cap-microfarad", Package () { 15, 15 } },
                    }
                })
        }
    }

    Scope (_SB.I2CD)
    {
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cs-gpios", Package () { 
                            Zero,                    // Native CS
                            SPKR, Zero, Zero, Zero   // GPIO CS
                        } }
                    }
                })
        }
    }
}

@dabendji2000
Copy link

Working ssdt-csc3551.dsl for ASUS Zenbook UM3402Y (the speakers are connected to I2C, not SPI). Follow the rest from https://github.com/badgers-ua/asus_zenbook_ux5304va_sound

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CS3551", 0x0000300A)
{

    External (_SB_.I2CD, DeviceObj)
    External (_SB_.I2CD.SPKR, DeviceObj)

    Scope (_SB.I2CD.SPKR)
    {
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cirrus,dev-index", Package () { 0x0040, 0x0041 }},
                        Package () { "reset-gpios", Package () {
                           SPKR, Zero, Zero, Zero,
                           SPKR, Zero, Zero, Zero
                        } },
                        Package () { "spk-id-gpios", Package () {
                             SPKR, 0x02, Zero, Zero,
                             SPKR, 0x02, Zero, Zero,
                        } },
                        Package () { "cirrus,speaker-position", Package () { Zero, One } },
                        Package () { "cirrus,gpio1-func", Package () { One, One } },
                        Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
                        // boost-type: 0 internal, 1 external
                        Package () { "cirrus,boost-type", Package () { One, One } },
                        // boost-peak-milliamp: 1600 to 4500, increments of 50 mA
                        //Package () { "cirrus,boost-peak-milliamp",  Package () { 3000, 3000 } },
                        // boost-ind-nanohenry: 1000 | 1200 | 1500 | 2200 nH
                        //Package () { "cirrus,boost-ind-nanohenry",  Package () { 1000, 1000 } },
                        // boost-cap-microfarad: rounded to the nearest integer
                        //Package () { "cirrus,boost-cap-microfarad", Package () { 15, 15 } },
                    }
                })
        }
    }

    Scope (_SB.I2CD)
    {
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cs-gpios", Package () { 
                            Zero,                    // Native CS
                            SPKR, Zero, Zero, Zero   // GPIO CS
                        } }
                    }
                })
        }
    }
}

Hi, I have an Asus Zenbook UM3402YAR-UM3402YA laptop I've purchased a week ago. I have installed the Ubuntu 23.10 and have no sound from the speakers. I've been searching over the internet and have come across this community and this post dealing with the issuue. Unfortunately I have no practical experience on how to make a patch to the kernel that is required. Is there a chance that you help me somehow (maybe through a remote connection or similar)? Really appreciate all the help...

@alex-spataru
Copy link

For those with an ASUS UX7602ZM laptop, you can check the guide & SSDT patches here: https://github.com/alex-spataru/asus_zenbook_ux7602zm_sound.

Basically, getting sound to work boils down to two things:

  1. Modifying the patch_realtek.c file and add the following quirck SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2).
  2. Compiling and installing the SSDT patch in a very similar way that with the other Zenbook models.

Thanks everyone for helping me find a way to get the sound working with my laptop, happy hacking!

@abishekmuthian
Copy link

abishekmuthian commented Nov 6, 2023

Folks, Can anyone help me? After patching the SSDT for my G634JY on Fedora 38 with 6.6.0-61.rog.fc38.x86_64 I get the following in the dmesg; I have very low volume from rear-speakers and front speakers doesn't work.

[    0.019213] ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.019215] ACPI: SSDT 0x0000000039533000 0001A0 (v01 CUSTOM CSC3551  00000001 INTL 20220331)
[   16.010867] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[   16.134141] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Using extra _DSD properties, bypassing _DSD in ACPI
[   16.134143] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: error -ENOENT: Failed to get reset GPIO
[   16.158265] cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.0 failed with error -2
[   16.158384] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Using extra _DSD properties, bypassing _DSD in ACPI
[   16.158387] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: error -ENOENT: Failed to get reset GPIO
[   16.176295] cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.1 failed with error -2

This is my patch

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
    External (_SB_.PC00.SPI3, DeviceObj)
    External (_SB_.PC00.SPI3.SPK1, DeviceObj)

    Scope (_SB.PC00.SPI3.SPK1)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cirrus,dev-index", Package () { Zero, One }},
                Package () { "reset-gpios", Package () {
		            SPK1, Zero, Zero, Zero,
		            SPK1, Zero, Zero, Zero
                } },
                Package () { "spk-id-gpios", Package () {
                    SPK1, 0x02, Zero, Zero,
                    SPK1, 0x02, Zero, Zero
                } },
                Package () { "cirrus,speaker-position",		Package () { Zero, One } },
                Package () { "cirrus,gpio1-func",			Package () { One, One } },
                Package () { "cirrus,gpio2-func",			Package () { 0x02, 0x02 } },
                Package () { "cirrus,boost-type",			Package () { One, One } }
            }
        })
    }

    Scope (_SB.PC00.SPI3)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cs-gpios", Package () {
                    Zero,                    // Native CS
                    SPK1, Zero, Zero, Zero   // GPIO CS
                } }
            }
        })
    }
}

I tried,

SPK1, One, Zero, Zero,
SPK1, One, Zero, Zero,
Package () { "cirrus,gpio1-func",           Package () { Zero, Zero } },

And get the same result. Any help would be much appreciated.

@alex-spataru
Copy link

alex-spataru commented Nov 7, 2023

By the way, I also contacted ASUS, and their (rephrased & summarized) response was:

We're sorry for the limited Linux support and encourage you to reach out to the software manufacturer for more comprehensive assistance, as they often provide substantial online support.

I already asked for a contact from the "software manufacturer" they mentioned. I might be naive, but hopefully we can pressure them into fixing their ACPI tables...

@alex-spataru
Copy link

@abishekmuthian Could you please provide us with your original SSDT7 dump? In my case it was necessary to modify my SSDT dump and adding the _DST methods without modifying anything else, I also needed to modify the patch_realtek.c file in the Linux kernel.

@abishekmuthian
Copy link

abishekmuthian commented Nov 7, 2023

@alex-spataru Thank you for your reply and thank you for contacting Asus on behalf of us, I think if we all contact they'll feel the need to address the Linux support issues.

Here's my original SSDT7.dsl .

Here's my original DSDT SPI3 scope :

Scope (_SB.PC00.SPI3)
    {
        Device (SPK1)
        {
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "10431CAF")  // _SUB: Subsystem ID
            Name (_UID, One)  // _UID: Unique ID
            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
            {
                Name (SBUF, ResourceTemplate ()
                {
                    SpiSerialBusV2 (0x0000, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x003D0900, ClockPolarityLow,
                        ClockPhaseFirst, "\\_SB.PC00.SPI3",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    SpiSerialBusV2 (0x0001, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x003D0900, ClockPolarityLow,
                        ClockPhaseFirst, "\\_SB.PC00.SPI3",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x01D4
                        }
                    GpioIo (Exclusive, PullDown, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0140
                        }
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x00C0
                        }
                    GpioIo (Shared, PullUp, 0x0064, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0141
                        }
                    GpioInt (Edge, ActiveBoth, Shared, PullUp, 0x0064,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0141
                        }
                })
                Return (SBUF) /* \_SB_.PC00.SPI3.SPK1._CRS.SBUF */
            }

            Method (_STA, 0, NotSerialized)  // _STA: Status
            {
                Return (0x0F)
            }

            Method (_DIS, 0, NotSerialized)  // _DIS: Disable Device
            {
            }
        }
    }

@avasnik
Copy link

avasnik commented Nov 7, 2023

Users of ux3402va, I finally submitted a fix for our model to the kernel so that we don't need to use kernel patches! https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/commit/?id=07058dceb038a4b0dd49af07118b6b2a685bb4a6

Hello; do you have any idea of when the patch will be available? I'm running
uname -a  ✔ Linux andrey-zenbookux3402va 6.5.9-1-MANJARO #1 SMP PREEMPT_DYNAMIC Wed Oct 25 13:14:27 UTC 2023 x86_64 GNU/Linux
and have no sound at the moment.
Thanks a lot for your effort!

@alex-spataru
Copy link

alex-spataru commented Nov 7, 2023

@abishekmuthian

I believe your SSDT patch should be:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000002)
{
    External (_SB_.PC00.SPI3, DeviceObj)
    External (_SB_.PC00.SPI3.SPK1, DeviceObj)
    
    Scope (_SB.PC00.SPI3)
    {
        Device (SPK1)
        {
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "10431CAF")  // _SUB: Subsystem ID
            Name (_UID, One)  // _UID: Unique ID
            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
            {
                Name (SBUF, ResourceTemplate ()
                {
                    SpiSerialBusV2 (0x0000, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x003D0900, ClockPolarityLow,
                        ClockPhaseFirst, "\\_SB.PC00.SPI3",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    SpiSerialBusV2 (0x0001, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x003D0900, ClockPolarityLow,
                        ClockPhaseFirst, "\\_SB.PC00.SPI3",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x01D4
                        }
                    GpioIo (Exclusive, PullDown, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0140
                        }
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x00C0
                        }
                    GpioIo (Shared, PullUp, 0x0064, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0141
                        }
                    GpioInt (Edge, ActiveBoth, Shared, PullUp, 0x0064,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0141
                        }
                })
                Return (SBUF) /* \_SB_.PC00.SPI3.SPK1._CRS.SBUF */
            }

            Method (_STA, 0, NotSerialized)  // _STA: Status
            {
                Return (0x0F)
            }

            Method (_DIS, 0, NotSerialized)  // _DIS: Disable Device
            {
            }
            
            Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
            {
                Return (Package ()
                    {
                        ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                        Package ()
                        {
                            Package () { "cirrus,dev-index", Package () { Zero, One }},
                            Package () { "reset-gpios", Package () {
                            SPK1, One, Zero, Zero,
                            SPK1, One, Zero, Zero
                            } },
                            Package () { "spk-id-gpios", Package () {
                                SPK1, 0x02, Zero, Zero,
                                SPK1, 0x02, Zero, Zero,
                            } },
                            Package () { "cirrus,speaker-position", Package () { Zero, One } },
                            Package () { "cirrus,gpio1-func", Package () { One, One } },
                            Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
                            // boost-type: 0 internal, 1 external
                            Package () { "cirrus,boost-type", Package () { One, One } },
                            // boost-peak-milliamp: 1600 to 4500, increments of 50 mA
                            //Package () { "cirrus,boost-peak-milliamp",  Package () { 3000, 3000 } },
                            // boost-ind-nanohenry: 1000 | 1200 | 1500 | 2200 nH
                            //Package () { "cirrus,boost-ind-nanohenry",  Package () { 1000, 1000 } },
                            // boost-cap-microfarad: rounded to the nearest integer
                            //Package () { "cirrus,boost-cap-microfarad", Package () { 15, 15 } },
                        }
                    })
            }
        }
        
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cs-gpios", Package () { 
                            Zero,                    // Native CS
                            SPK1, Zero, Zero, Zero   // GPIO CS
                        } }
                    }
                })
        }
    }
}

If after applying the SSDT patch your speakers still do not work, it might be necessary to modify and install a custom Linux kernel, to do so:

  1. Pull the kernel source code.

  2. Open kernel_source_root/sound/pci/hda/patch_realtek.c with your text editor and search for ALC245_FIXUP_CS35L41_SPI_2 until you find a list of definitions like this:

SND_PCI_QUIRK(0x1043, 0x3a50, "ASUS G834JYR/JZR", ALC245_FIXUP_CS35L41_SPI_2),
  1. Insert the configuration for your laptop:
SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JY", ALC245_FIXUP_CS35L41_SPI_2),

Edit: I just took a look at the kernel source code, it already has the following quirk for your laptop model:

SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JYR/JZR", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),

In that case, it might be only necessary to add the modified SSDT. I am not really sure if the ALC245_FIXUP_CS35L41_SPI_2 fixup is required for your model.

Please let me know if it works for you!

@abishekmuthian
Copy link

@alex-spataru Thank you so much for your effort, dmesg now shows Reset line busy, assuming shared reset which I don't think I had got before but the audio is still from rear speakers with very low volume.

[    0.018671] ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.018673] ACPI: SSDT 0x0000000039533000 0002DE (v01 CUSTOM CSC3551  00000002 INTL 20220331)
[   20.698885] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[   20.790197] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Using extra _DSD properties, bypassing _DSD in ACPI
[   20.790199] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Reset line busy, assuming shared reset
[   20.892699] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Failed waiting for OTP_BOOT_DONE: -110
[   20.905002] cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.0 failed with error -110
[   20.905231] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Using extra _DSD properties, bypassing _DSD in ACPI
[   20.905233] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[   21.007673] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Failed waiting for OTP_BOOT_DONE: -110
[   21.020006] cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.1 failed with error -110

In the asus linux discord channel, @v-gu has made an old post telling how he fixed OTP_BOOT_DONE error for his G634JZ ,

He states -

After some trial and error, I found that my version of the laptop requires reset-gpios to be on , One, Zero, Zero instead of , Zero, Zero, Zero. So I edited the second patch on the guide and add "10431CAF" to the if condition, with:

+    if (strcmp(cs35l41->acpi_subsystem_id, "10431473") == 0
+        || strcmp(cs35l41->acpi_subsystem_id, "10431483") == 0
+        || strcmp(cs35l41->acpi_subsystem_id, "10431493") == 0
+        || strcmp(cs35l41->acpi_subsystem_id, "10431CAF") == 0) {
+        cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 1, GPIOD_OUT_HIGH);
+    } else {
+        cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
+    }

Since I was running rog 6.6 kernel I thought I need not mess with the kernel, I guess now I have to attempt the above changes to the patch?
I

@phaserblast
Copy link

phaserblast commented Nov 8, 2023

UPDATE: Sound on the ASUS GV302XA is working! The reason the Cirrus firmware wasn't loading was I didn't add the laptop's subsystem ID in /sound/pci/hda/patch_realtek.c. Once I did that, it worked. I used the following line:

SND_PCI_QUIRK(0x1043, 0x1533, "ASUS GV302XA", ALC294_FIXUP_CS35L41_I2C_2),

It also works with ALC287_FIXUP_CS35L41_I2C_2 and ALC285_FIXUP_ASUS_I2C_HEADSET_MIC. I don't know if these are the best quirks to use, but ALC294_FIXUP_CS35L41_I2C_2 seems to work okay so far!
Quick side note: Sound actually works on this laptop without the ACPI patch (only the subsystem ID in the kernel is needed), but the sound will only be mono out of both speakers. To get stereo, you need the additional cpio loaded during boot.

Original Post:

Hey all, I picked up an ASUS ROG Flow X13 (2023) this week from Best Buy in the US. The model number is GLV302X (actually GV302XA) and it has the two Cirrus amps connected via I2C. The laptop uses an AMD Ryzen 9 7940HS CPU. The subsystem ID for this laptop is 1043:1533.

I'm running Debian trixie with a 6.5.0 kernel. Although I was able to apply the ACPI patch using systemd-boot and get no dmesg errors, the firmware is never loaded for the amps. I copied the entire 'cirrus' directory from the linux-firmware git to my system, but no firmware load is even attempted. I have not patched the kernel yet:

[    0.002898] ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.002900] ACPI: SSDT 0x00000000BB4CE000 00014D (v01 CUSTOM CSC3551  00000001 INTL 20230628)
[    9.601723] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 I2C devices.
[    9.719731] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[    9.719913] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[    9.774618] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2

That's all I get.

Here's the relevant section from the ACPI dump:

Scope (_SB.I2CD)
{
	Device (SPKR)
	{
		Name (_HID, "CSC3551")  // _HID: Hardware ID
		Name (_SUB, "10431533")  // _SUB: Subsystem ID
		Name (_UID, One)  // _UID: Unique ID
		Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
		{
			Name (RBUF, ResourceTemplate ()
			{
				I2cSerialBusV2 (0x0040, ControllerInitiated, 0x000F4240,
					AddressingMode7Bit, "\\_SB.I2CD",
					0x00, ResourceConsumer, , Exclusive,
					)
				I2cSerialBusV2 (0x0041, ControllerInitiated, 0x000F4240,
					AddressingMode7Bit, "\\_SB.I2CD",
					0x00, ResourceConsumer, , Exclusive,
					)
				GpioIo (Exclusive, PullDown, 0x0000, 0x0000, IoRestrictionOutputOnly,
					"\\_SB.GPIO", 0x00, ResourceConsumer, ,
					)
					{   // Pin list
						0x005A
					}
				GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionInputOnly,
					"\\_SB.GPIO", 0x00, ResourceConsumer, ,
					)
					{   // Pin list
						0x008E
					}
				GpioIo (Shared, PullUp, 0x0064, 0x0000, IoRestrictionInputOnly,
					"\\_SB.GPIO", 0x00, ResourceConsumer, ,
					)
					{   // Pin list
						0x0054
					}
				GpioInt (Edge, ActiveBoth, Shared, PullUp, 0x0064,
					"\\_SB.GPIO", 0x00, ResourceConsumer, ,
					)
					{   // Pin list
						0x0054
					}
			})
			Return (RBUF) /* \_SB_.I2CD.SPKR._CRS.RBUF */
		}

		Method (_STA, 0, NotSerialized)  // _STA: Status
		{
			Return (0x0F)
		}

		Method (_DIS, 0, NotSerialized)  // _DIS: Disable Device
		{
		}
	}
}

Has anyone else encountered this problem?

@Xishang7707
Copy link

Hello, G814JV has been processed according to the steps described by https://asus-linux.org/wiki/cirrus-amps/. Although there is sound, the models that have been tried have current sounds.What should I do?

@Peter-Ries
Copy link

Peter-Ries commented Nov 24, 2023

Hi everyone. Thanks to all for contributing and trying to get things work. I read this thread three times, asus-linux.org, and several other git pages. I'm lost now...

Sum up:

  • I have a fresh Asus Zenbook 14 OLED UX3402-VA model (german)
  • I updated to BIOS 302 (latest available from Asus website as of today)
  • Secure boot is off
  • Running an Ubuntu 23.10 with kernel 6.5.0-13-generic

What I did up to now...

  • with the output of dsdt.dsl grepping for 3551 I created/modified the ssdt-csc3551.dsl to the one at the end of this comment
  • I created the aml file from it and copied it to /boot
  • I copied and chmod +x the acpi_01 file to /etc/default/grub.d
  • sudo update-grub
  • reboot: sound not working yet

I don't know if the ubuntu kernel already has the patch for asus sound included nor how to find it out...

Do you have any hint how to get the laptop sound to work?

here's the dsl file:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
    External (_SB_.PC00.SPI0, DeviceObj)
    External (_SB_.PC00.SPI0.SPK1, DeviceObj)

    Scope (_SB.PC00.SPI0.SPK1)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cirrus,dev-index", Package () { Zero, One }},
                Package () { "reset-gpios", Package () {
                    SPK1, One, Zero, Zero,
                    SPK1, One, Zero, Zero
                } },
                Package () { "spk-id-gpios", Package () {
                    SPK1, 0x02, Zero, Zero,
                    SPK1, 0x02, Zero, Zero
                } },
                Package () { "cirrus,speaker-position", Package () { Zero, One } },
                // gpioX-func: 0 not used, 1 VPSK_SWITCH, 2: INTERRUPT, 3: SYNC
                Package () { "cirrus,gpio1-func", Package () { One, One } },
                Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
                // boost-type: 0 internal, 1 external
                Package () { "cirrus,boost-type", Package () { One, One } }
            }
        })
    }

    Scope (_SB.PC00.SPI0)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cs-gpios", Package () { 
                    Zero,                    // Native CS
                    SPK1, Zero, Zero, Zero   // GPIO CS
                } }
            }
        })
    }
}

here's the relevant grepped part searching for 3551:

Scope (_SB.PC00.SPI0)
    {
        Device (SPK1)
        {
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "104316A3")  // _SUB: Subsystem ID
            Name (_UID, One)  // _UID: Unique ID
            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
            {
...

@hmyzna
Copy link

hmyzna commented Nov 27, 2023

Thanks to you all I got sound working on UM3504DA (Asus Zenbook 15 OLED)!

My dsl file looks like this:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CS3551", 0x0000300A)
{

    External (_SB_.I2CB, DeviceObj)
    External (_SB_.I2CB.SPKR, DeviceObj)

    Scope (_SB.I2CB.SPKR)
    {
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cirrus,dev-index", Package () { 0x0040, 0x0041 }},
                        Package () { "reset-gpios", Package () {
                           SPKR, One, Zero, Zero,
                           SPKR, One, Zero, Zero
                        } },
                        Package () { "spk-id-gpios", Package () {
                             SPKR, 0x02, Zero, Zero,
                             SPKR, 0x02, Zero, Zero,
                        } },
                        Package () { "cirrus,speaker-position", Package () { Zero, One } },
                        Package () { "cirrus,gpio1-func", Package () { One, One } },
                        Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
                        // boost-type: 0 internal, 1 external
                        Package () { "cirrus,boost-type", Package () { One, One } },
                        // boost-peak-milliamp: 1600 to 4500, increments of 50 mA
                        //Package () { "cirrus,boost-peak-milliamp",  Package () { 3000, 3000 } },
                        // boost-ind-nanohenry: 1000 | 1200 | 1500 | 2200 nH
                        //Package () { "cirrus,boost-ind-nanohenry",  Package () { 1000, 1000 } },
                        // boost-cap-microfarad: rounded to the nearest integer
                        //Package () { "cirrus,boost-cap-microfarad", Package () { 15, 15 } },
                    }
                }) /* \_SB.I2CB.SPKR._DSD */
        }
    }

    Scope (_SB.I2CB)
    {
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cs-gpios", Package () { 
                            Zero,                    // Native CS
                            SPKR, Zero, Zero, Zero   // GPIO CS
                        } }
                    }
                }) /* \_SB.I2CB.SPKR._DSD */
        }
    }
}

I had to add SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC287_FIXUP_CS35L41_I2C_2), to static const struct snd_pci_quirk alc269_fixup_tbl at line 9500 in file sound/pci/hda/patch_realtek.c and compile linux 6.6.2 kernel (never did it before).

In 6.7 there's ALC294_FIXUP_CS35L41_I2C_2 which appears to do the same as ALC287_FIXUP_CS35L41_I2C_2. UM3504 has ALC294 by the way.

Is there anything I can do to make SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC294_FIXUP_CS35L41_I2C_2), appear in source code of the linux kernel so that I never have to compile it again?

@armeldemarsac92
Copy link

Thanks to you all I got sound working on UM3504DA (Asus Zenbook 15 OLED)!

My dsl file looks like this:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CS3551", 0x0000300A)
{

    External (_SB_.I2CB, DeviceObj)
    External (_SB_.I2CB.SPKR, DeviceObj)

    Scope (_SB.I2CB.SPKR)
    {
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cirrus,dev-index", Package () { 0x0040, 0x0041 }},
                        Package () { "reset-gpios", Package () {
                           SPKR, One, Zero, Zero,
                           SPKR, One, Zero, Zero
                        } },
                        Package () { "spk-id-gpios", Package () {
                             SPKR, 0x02, Zero, Zero,
                             SPKR, 0x02, Zero, Zero,
                        } },
                        Package () { "cirrus,speaker-position", Package () { Zero, One } },
                        Package () { "cirrus,gpio1-func", Package () { One, One } },
                        Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
                        // boost-type: 0 internal, 1 external
                        Package () { "cirrus,boost-type", Package () { One, One } },
                        // boost-peak-milliamp: 1600 to 4500, increments of 50 mA
                        //Package () { "cirrus,boost-peak-milliamp",  Package () { 3000, 3000 } },
                        // boost-ind-nanohenry: 1000 | 1200 | 1500 | 2200 nH
                        //Package () { "cirrus,boost-ind-nanohenry",  Package () { 1000, 1000 } },
                        // boost-cap-microfarad: rounded to the nearest integer
                        //Package () { "cirrus,boost-cap-microfarad", Package () { 15, 15 } },
                    }
                }) /* \_SB.I2CB.SPKR._DSD */
        }
    }

    Scope (_SB.I2CB)
    {
        Method (_DSD, 0, NotSerialized)  // _DSD: Device Specific Data
        {
            Return (Package ()
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
                    Package ()
                    {
                        Package () { "cs-gpios", Package () { 
                            Zero,                    // Native CS
                            SPKR, Zero, Zero, Zero   // GPIO CS
                        } }
                    }
                }) /* \_SB.I2CB.SPKR._DSD */
        }
    }
}

I had to add SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC287_FIXUP_CS35L41_I2C_2), to static const struct snd_pci_quirk alc269_fixup_tbl at line 9500 in file sound/pci/hda/patch_realtek.c and compile linux 6.6.2 kernel (never did it before).

In 6.7 there's ALC294_FIXUP_CS35L41_I2C_2 which appears to do the same as ALC287_FIXUP_CS35L41_I2C_2. UM3504 has ALC294 by the way.

Is there anything I can do to make SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC294_FIXUP_CS35L41_I2C_2), appear in source code of the linux kernel so that I never have to compile it again?

awesome ! could you please elaborate a bit on the kernel part ? where you downloaded it and how you edited it ? it would be very nice of you, i have the same model and the sound issue is driving me mad.

@hmyzna
Copy link

hmyzna commented Nov 27, 2023

awesome ! could you please elaborate a bit on the kernel part ? where you downloaded it and how you edited it ? it would be very nice of you, i have the same model and the sound issue is driving me mad.

I downloaded tarball with wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.2.tar.xz, extracted it, copied default arch linux configuration with sudo zcat /proc/config.gz > .config and added a single line SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC287_FIXUP_CS35L41_I2C_2), to file patch_realtek.c, 9876 on screenshot
image
then built it with the help of this 3 y.o. youtube video.

I barely know what I'm doing so there's probably better way to handle "custom" kernels.

@lamentary
Copy link

Is there anything I can do to make SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC294_FIXUP_CS35L41_I2C_2), appear in source code of the linux kernel so that I never have to compile it again?

Great work! I'll have to give it a try, as I have the same model. FWIW, if you want to submit it as a kernel patch (as your question seems to indicate), here are the instructions: https://docs.kernel.org/process/submitting-patches.html

@Peter-Ries
Copy link

Finally got it working on ASUS Zenbook 14 OLED Model UX3402VA.

Using Ubuntu 23.10.

Working dsl file looks like this:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
    External (_SB_.PC00.SPI0, DeviceObj)
    External (_SB_.PC00.SPI0.SPK1, DeviceObj)

    Scope (_SB.PC00.SPI0.SPK1)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cirrus,dev-index", Package () { Zero, One }},
                Package () { "reset-gpios", Package () {
                    SPK1, One, Zero, Zero,
                    SPK1, One, Zero, Zero
                } },
                Package () { "spk-id-gpios", Package () {
                    SPK1, 0x02, Zero, Zero,
                    SPK1, 0x02, Zero, Zero
                } },
                Package () { "cirrus,speaker-position", Package () { Zero, One } },
                // gpioX-func: 0 not used, 1 VPSK_SWITCH, 2: INTERRUPT, 3: SYNC
                Package () { "cirrus,gpio1-func", Package () { One, One } },
                Package () { "cirrus,gpio2-func", Package () { 0x02, 0x02 } },
                // boost-type: 0 internal, 1 external
                Package () { "cirrus,boost-type", Package () { One, One } }
            }
        })
    }

    Scope (_SB.PC00.SPI0)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cs-gpios", Package () { 
                    Zero,                    // Native CS
                    SPK1, Zero, Zero, Zero   // GPIO CS
                } }
            }
        })
    }
}

Using the commands provided here for Ubuntu/Debain it worked. My mistake was to copy the 01_acpi file into /etc/default/grub.d instead of /etc/grub.d

Furthermore I found out that the Kernel patch to distinguish betweek UX3402ZA and UX3402VA has been added starting with Kernel 6.5.6 so you need a Kernel >= 6.5.6

For Ubuntu 23.10 shipping 6.5.0-xxx at this time I use a mainline kernel for this. Please google for mainline ppa ubuntu. three lines of code then you can use a mainline-gtk interface to easily install a suitable kernel.

So as of thor2002ro git page:

  • create the aml file from my dsl file
  • copy aml file to /boot
  • copy acpi_01 fiel to /etc/grub.d and make it executable
  • get a mainline kernel 6.5.6+
  • sudo update-grub
  • reboot & select kernel
  • have sound :)

Thanks community.

@staropram
Copy link

staropram commented Dec 1, 2023

I'm trying to get sound working on Zenbook UP6502ZD_UP6502ZD. I've tried various dsl variants, but the best I can get is this:

[    0.012272] ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.012274] ACPI: SSDT 0x00000000546E6000 0001A0 (v01 CUSTOM CSC3551  00000001 INTL 20200925)
[   11.234682] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[   11.811372] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Reset line busy, assuming shared reset
[   11.914416] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Failed waiting for OTP_BOOT_DONE: -110
[   11.927120] cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.0 failed with error -110
[   11.927667] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[   12.032348] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Failed waiting for OTP_BOOT_DONE: -110
[   12.043625] cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.1 failed with error -110

I'm a bit confused about what I can expect to see depending on the absence/presence of the factors.

What is needed to initialise the SPI amplifiers? Just the correct _DSD or do you need that, the firmware, and the kernel patched?

If I get the _DSD correct should I then expect to see non-erroneous output in dmesg or would I also need to have firmware and kernel to see non-erroneous output?

How are people figuring out the correct parameters for the dsl file? (besides the SPI address and SPK name which we get from disassembling the acpidump)

Are people just using random trial and error for things like the reset-gpios parameters? Or is there some logic here? Its a shame we can't just look at the technical spec of the amplifier...

@lamperez
Copy link
Author

lamperez commented Dec 4, 2023

@staropram You should see:

ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
ACPI: SSDT 0x00000000368FC000 0001A0 (v01 CUSTOM CSC3551  00000001 INTL 20200925)
Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2

This means that both amplifiers have been detected and reset, that is, both cs-gpios and reset-gpios are good. Notice that the reset GPIO is the same for both amplifiers, and therefore the message Reset line busy, assuming shared reset. Also for SPI, the first chip select GPIO (cs-gpios) is Zero, meaning the default pin provided by the SPI bus, while the other is another GPIO, specified in the ACPI dump. As a result, typically only one amplifier is reset, but this is not your case.

After this, the next log lines should be about loading the correct firmware files, that must be available (package provided by your distro). If only one amplifier is reset, the kernel refuses to load the firmware and nothing works.

And yes, trial and error was the name of the game to get the first working patch. That, and reading a lot of kernel code and specifications of the SPI bus.

@staropram
Copy link

@lamperez thanks for that! I've got a bit of an odd situation now where I have patched the kernel as the top of https://asus-linux.org/wiki/cirrus-amps/ and then I just defined a _DSD for the cs-gpios section:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
    External (_SB_.PC00.SPI1, DeviceObj)
    External (_SB_.PC00.SPI1.SPK1, DeviceObj)

   Scope (_SB.PC00.SPI1)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cs-gpios", Package () {
                    Zero,                    // Native CS
                    SPK1, Zero, Zero, Zero   // GPIO CS
                } }
            }
        })
    }
}

Now I get something a little bid odd from the dmesg output:

$ sudo dmesg | grep CSC
[   11.706278] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[   12.412121] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Using extra _DSD properties, bypassing _DSD in ACPI
[   12.461060] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[   12.484874] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Using extra _DSD properties, bypassing _DSD in ACPI
[   12.484901] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[   12.587890] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Failed waiting for OTP_BOOT_DONE: -110
[   12.599850] cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.1 failed with error -110

So now it looks like progress was made but that only the first amplifier has been detected? reset?

It's quite hard to understand if they are both detected and not reset or if only one is detected, and whether I have a problem with the reset-gpios in the patch or the cs-gpios in the _DSD.

What do you think?

@alexVinarskis
Copy link

Dell laptop here, XPS 9530 with SPI connected CS35L41, making some progress thanks to this thread, but there are weird SPI issues - takes ~3 minutes to load the firmware, then it all works. I suspect there are misconfiguration in Dell's ACPI tables wrt to SPI configuration. Anyone by chance had a similar problem?

@Peter-Ries I see that you also have SPI connected amp, and managed to make it work - is there a chance you could share ACPI dumps from your machine? Complete one via sudo acpidump > acpi.log , that would really help. Thanks in advance :)

@AlexeyPashnin1
Copy link

Hey guys! Sorry for asking but I'm ubuntu newbee. I've downloaded the files, what should I do next? Except for killing myself with my new laptop of course

@staropram
Copy link

staropram commented Dec 6, 2023

Hey guys! Sorry for asking but I'm ubuntu newbee. I've downloaded the files, what should I do next? Except for killing myself with my new laptop of course

what laptop do you have: can you share the output of

inxi -MA

This should give us the model and the audio system. You might get lucky and have a laptop that already has bleeding edge kernel integration.

Also:

sudo dmesg | grep CSC

@AlexeyPashnin1
Copy link

Hi @staropram :) Here's the outputs

inxi -MA

Machine:
Type: Laptop System: ASUSTeK product: Zenbook UX3402VA_UX3402VA v: 1.0
serial:
Mobo: ASUSTeK model: UX3402VA v: 1.0 serial:
UEFI: American Megatrends LLC. v: UX3402VA.302 date: 05/23/2023
Audio:
Device-1: Intel Raptor Lake-P/U/H cAVS driver: sof-audio-pci-intel-tgl
API: ALSA v: k6.5.0-13-generic status: kernel-api
Server-1: PipeWire v: 0.3.79 status: active

sudo dmesg | grep CSC

[ 2.103571] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[ 2.345764] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[ 2.346390] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[ 2.381187] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2

Is there a chance to fix it? Thank you!

@staropram
Copy link

staropram commented Dec 7, 2023

@AlexeyPashnin1

You're lucky, it isn't an issue with the CSC3551 in your case as both CS35l41 ppear to be instantiated, and by the looks of it a quirk was added recently for your machine: see this mailing list entry

Was that all the output from dmesg relating to CSC? There should also be some lines about firmware?

In anycase, you can try applying that kernel patch. Follow this tutorial to compile the linux kernel: don't worry the old kernel will still be an option in the boot menu if something goes wrong (make sure you edit /etc/default/grub and comment out the GRUB_TIMEOUT_STYLE=hidden option and then add GRUB_TIMEOUT=10 otherwise you'll never see the boot menu if something was going wrong, then run sudo update-grub to make sure this change is applied).

The patch looks like it is already in the current stable version 6.6.4 if you look here: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/sound/pci/hda/patch_realtek.c?h=v6.6.4#n9892

So it hopefully is as straightforward as compiling and installing the 6.6.4 kernel and it should work.

What kernel are you currently running btw? run uname -a pls

@AlexeyPashnin1
Copy link

@staropram

Was that all the output from dmesg relating to CSC?

Yeah, that's it. I've grepped this now, too
sudo dmesg | grep 'firmware'

[ 1.869087] systemd[1]: systemd-pcrmachine.service - TPM2 PCR Machine ID Measurement was skipped because of an unmet condition check (ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f).
[ 2.330088] iwlwifi 0000:00:14.3: loaded firmware version 83.e8f84e98.0 so-a0-gf-a0-83.ucode op_mode iwlmvm
[ 2.707903] i915 0000:00:02.0: [drm] Finished loading DMC firmware i915/adlp_dmc.bin (v2.20)
[ 2.729786] i915 0000:00:02.0: [drm] GT0: GuC firmware i915/adlp_guc_70.bin version 70.5.1
[ 2.729797] i915 0000:00:02.0: [drm] GT0: HuC firmware i915/tgl_huc.bin version 7.9.3
[ 2.829317] Bluetooth: hci0: Minimum firmware build 1 week 10 2014
[ 2.839905] Bluetooth: hci0: Found device firmware: intel/ibt-0040-0041.sfi
[ 4.363514] Bluetooth: hci0: Waiting for firmware download to complete
[ 4.405729] iwlwifi 0000:00:14.3: Loaded firmware version: 83.e8f84e98.0 so-a0-gf-a0-83.ucode
[26973.001094] i915 0000:00:02.0: [drm] GT0: GuC firmware i915/adlp_guc_70.bin version 70.5.1
[26973.001098] i915 0000:00:02.0: [drm] GT0: HuC firmware i915/tgl_huc.bin version 7.9.3
[26973.594981] audit: type=1400 audit(1701948974.855:188): apparmor="DENIED" operation="open" class="file" profile="snap.firmware-updater.firmware-notifier" name="/proc/sys/vm/max_map_count" pid=4008 comm="firmware-notifi" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0

Follow this tutorial to compile the linux kernel

I've run the command for Debian users (because Ubuntu is Debian-based, if I get it right)
sudo apt install bc binutils bison dwarves flex gcc git gnupg2 gzip libelf-dev libncurses5-dev libssl-dev make openssl pahole perl-base rsync tar xz-utils

downloaded the patch,

then unxz --keep linux-*.tar.xz

then gpg2 --locate-keys [email protected] [email protected] (got the same output as in the manual)

but stuck on the next step gpg2 --verify linux-*.tar.sign with this output

gpg: can't open 'linux-*.tar.sign': No such file or directory
gpg: verify signatures failed: No such file or directory

I was in the Downloads folder. Also tried cd to .gnupg and run the command there - no luck. God, its so embarrassing

Could you please point out to me where I failed?

What kernel are you currently running btw

I've found that previously, sorry that didn't specify it
6.5.0-13-generic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment