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
} }
}
})
}
}
@phptek
Copy link

phptek commented Jul 21, 2023

@phamdangtrung Thanks. I was afraid I'd need to do this. Long time Linux user, first-time compiling a new kernel. What are the dangers of doing this, if any?

Thank you :-)

@phamdangtrung
Copy link

@phamdangtrung Thanks. I was afraid I'd need to do this. Long time Linux user, first-time compiling a new kernel. What are the dangers of doing this, if any?

Thank you :-)

Nothing actually, but I do recommend backing up your important files first. I got some issue with initramfs after booting up with the new kernel so I used the old kernel and ran the following command
sudo make modules_install INSTALL_MOD_STRIP=1

@phptek
Copy link

phptek commented Jul 21, 2023

I got an initramfs issue too while it waited for my encrypted drive. Couldn't get passed that point. Had to revert to old kernel. sudo make modules_install produces a make error. No matter, I'll keep on with it and post back my findings.

@thierry-carron
Copy link

thank you very much, works fine for me :)
I will report solution onto asus forum.

@badger-ua
Copy link

badger-ua commented Jul 24, 2023

@lamperez @Moooebie
Hello, tried the following patch:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00001000)
{

    External (_SB_.PC00.SPI0, DeviceObj)
    External (_SB_.PC00.SPI0.SPK1, DeviceObj)

    Scope (_SB.PC00.SPI0.SPK1)
    {
        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 } },
                    }
                }) /* \_SB_.PC00.SPI0.SPK1._DSD */
        }
    }

    Scope (_SB.PC00.SPI0)
    {
        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
                        } }
                    }
                }) /* \_SB_.PC00.SPI0.SPK1._DSD */
        }
    }
}

sudo dmesg | grep SSDT output is seems to be correct I have the line with patch:
[ 0.015531] ACPI: SSDT 0x0000000047E01D76 0001A7 (v01 CUSTOM CSC3551 00001000 INTL 20200925)
but the outpu of: sudo journalctl -b -g CSC3551 still is:

Jul 24 12:43:53 zenbook-pop-os kernel: ACPI: SSDT 0x0000000047E01D76 0001A7 (v01 CUSTOM CSC3551  00001000 INTL 20200925)
Jul 24 12:43:53 zenbook-pop-os kernel: Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
Jul 24 12:43:54 zenbook-pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Error: ACPI _DSD Properties are missing for HID CSC3551.
Jul 24 12:43:54 zenbook-pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: error -EINVAL: Platform not supported
Jul 24 12:43:54 zenbook-pop-os kernel: cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.0 failed with error -22
Jul 24 12:43:54 zenbook-pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Error: ACPI _DSD Properties are missing for HID CSC3551.
Jul 24 12:43:54 zenbook-pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: error -EINVAL: Platform not supported
Jul 24 12:43:54 zenbook-pop-os kernel: cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.1 failed with error -22

I also tried to extract dsdt.dat by your guide: https://gist.github.com/lamperez/d5b385bc0c0c04928211e297a69f32d7 and dsdt.dsl has nothing CSC3551 related in that file

Device: asus_zenbook_s13_ux5304va
My kernel is: 6.2.6-76060206-generic
Dual Boot: No
Secure Boot: Disabled
Fastboot: Disabled
BIOS Version: 304

I'm assuming I need to modify the patch itself somehow?

P.S: Begging for help 😸

@thor2002ro
Copy link

It won't work on a different models kernel it needs to be adapted and also you have to look it the kernel is patched for you model the quirk is applied based on sound card id

@badger-ua
Copy link

badger-ua commented Jul 24, 2023

It won't work on a different models kernel it needs to be adapted and also you have to look it the kernel is patched for you model the quirk is applied based on sound card id

got it, I'll try to build kernel from sources then with my model included as @Moooebie wrote in his guide, s13 and 14 zenbooks are pretty much the same I had a hope that it will work without kernel patches, I created a working dsl patch (by modifiing depackaged dsdt.dat) via: https://gist.github.com/lamperez/d5b385bc0c0c04928211e297a69f32d7

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

    Scope (\_SB.PC00.SPI1)
    {
        Device (SPK1)
        {
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "104316D3")  // _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.SPI1",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    SpiSerialBusV2 (0x0001, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x003D0900, ClockPolarityLow,
                        ClockPhaseFirst, "\\_SB.PC00.SPI1",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0017
                        }
                    GpioIo (Exclusive, PullDown, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0131
                        }
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012E
                        }
                    GpioIo (Shared, PullUp, 0x0064, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012F
                        }
                    GpioInt (Edge, ActiveBoth, Shared, PullUp, 0x0064,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012F
                        }
                })
                Return (SBUF) /* \_SB_.PC00.SPI1.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 } },
                        }
                    }) /* \_SB_.PC00.SPI0.SPK1._DSD */
            }
        }

        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
                        } }
                    }
                }) /* \_SB_.PC00.SPI0.SPK1._DSD */
        }
    }
}

at least the sudo journalctl -b -g CSC3551 outputs no errors but still no sound, going after kernel then, if that will be successful I'll upload a source code for my model to git, but the question that comes in mind, that to make users life easier just by appling patch without kernel modification as you mentioned my device SND_PCI_QUIRK(0x1043, 0x16d3, "ASUS UX5304VA", ALC245_FIXUP_CS35L41_SPI_2), should be included in kernel, I've never done the kernel modification before, if I'm modifying ubuntus kernel I have to find the kernel sources on ubuntu git and submit a pr?

@badger-ua
Copy link

I have a good news and bad news, good one is that patching kernel done the job, I've got the sound thatnks a lot for guides @lamperez @Moooebie @thor2002ro but with custom kernel wifi module is missing now 😸

@badger-ua
Copy link

wifi is working, just installation of kernel went wrong.
2 new issues I'm trying to solve will keep everyone here updated:

  1. When laptop goes to sleep, speakers doesn't work after wake up
  2. Since speakers are harman kardon branded sound on linux is complete crap comparing to windows, trying to bring some quality back with Easy Effects package but so far no luck.

@fermino
Copy link

fermino commented Jul 24, 2023

@badger-lviv-ua the first problem could be related to your sound server, does the 3.5mm output work after suspending and waking it up?

@badger-ua
Copy link

@badger-lviv-ua the first problem could be related to your sound server, does the 3.5mm output work after suspending and waking it up?

@fermino actually yes 3.5mm works, actually very strange behavior scenarious:

  • if laptop suspend with no sound playing, after laptop awake - speakers sound works
  • if laptop suspend with music playing, after laptop awake - speakers sound doesn't work, but if I inject 3.5mm headphones and unplug them sound is back from speakers

@badger-ua
Copy link

badger-ua commented Jul 24, 2023

Uploaded a patch for asus_zenbook_ux5304va

Special thanks

Author Description
lamperez For ACPI DSDT/SSDT patching guides and tools
Moooebie For ACPI DSDT/SSDT patching guide
thor2002ro For GRUB patch for similar laptop

Warning: patch doesnt work without kernel modification (described in repo readme)

@thor2002ro
Copy link

thor2002ro commented Jul 24, 2023

Try to disable the sound card realtek power saving on my model it tries to save power very aggressively and after a while all audio sounds werid like all highes and not mids and lows this seams to fix it not sure if it's placebo yet.... It's probably related to the fact that the speakers are separate from the card and are on the spi bus

@badger-ua
Copy link

Thanks for the hint @thor2002ro will try that 🤝

@psxpaul
Copy link

psxpaul commented Jul 28, 2023

I have a Dell XPS 15 9530 that seems to have the same CS35L41 amplifier and resulting ACPI _DSD Properties are missing for HID CSC3551 dmesg error. I've tried everything suggested here and this wiki, but it looks like the kernel module is attempting to load more firmware files than the Dell drivers provide. I figured out that if I omit spk-id-gpios from the ssdt patch, it attempts to load the correct firmware files, but it takes several minutes and the sounds doesn't seem improved.

Can someone tell me what some of these properties in the ssdt patch do, or how I can determine the correct values for my hardware?

@talentlessguy
Copy link

talentlessguy commented Jul 28, 2023

I uninstalled the patch since it was for another model, and tried to follow this guide to patch it myself.

dsdt.dsl values are:


    Scope (_SB.PC00.SPI0)
    {
        Device (SPK1)
        {
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "10431483")  // _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.SPI0",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    SpiSerialBusV2 (0x0001, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x003D0900, ClockPolarityLow,
                        ClockPhaseFirst, "\\_SB.PC00.SPI0",
                        0x00, ResourceConsumer, , Exclusive,
                        )
// ...

Mine 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 ()   // _DSD: Device-Specific Data
        {
            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 } },
                // 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 } },
            },
        })
    }
}

and I'm still having sound issues and this is what I have in dmesg:

[    0.008832] ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.008833] ACPI: SSDT 0x000000003652F000 000158 (v01 CUSTOM CSC3551  00000001 INTL 20221020)
[    5.220022] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Failed waiting for OTP_BOOT_DONE: -110
[    5.230196] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.0 failed with error -110
[    5.335631] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Failed waiting for OTP_BOOT_DONE: -110
[    5.346835] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.1 failed with error -110
[    5.346854] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.

Kernel: 6.4.6-arch1-1-g14
BIOS Version: 301
Laptop: ROG Zephyrus G16 GU603VV_GU603VV

@psxpaul
Copy link

psxpaul commented Jul 30, 2023

I think the OTP_BOOT_DONE error is from not having the cs-gpios for SPI devices

@pczekalski
Copy link

pczekalski commented Aug 5, 2023

Hi Guys, I'm just with a new machine (ASUS ROG Flow Z13 model GZ301VU) trying to make sound working. Obviously, as in the other cases it works with 3.5jack but speakers are silent.
I'm on Ubuntu 23.04, GRUB.
Once installed kernel 6.4.6 and modified: /etc/modprobe.d/alsa-base.conf as described here: look for "Kernel Patch" section + disabling post BIOS sound (during ROG logo), I made it to enables speakers, but they work only with tweeters. Sound is very shallow, so I believe amps are not working. There are still errors in the dmesg, it acknowledges, it does not work as expected:

[    2.104866] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
.....
[    2.193187] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Error: ACPI _DSD Properties are missing for HID CSC3551.
[    2.193211] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: error -EINVAL: Platform not supported
[    2.193226] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.0 failed with error -22
[    2.198675] Intel(R) Wireless WiFi driver for Linux
[    2.198789] iwlwifi 0000:00:14.3: enabling device (0000 -> 0002)
[    2.204499] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Error: ACPI _DSD Properties are missing for HID CSC3551.
[    2.204517] asus-nb-wmi asus-nb-wmi: Using throttle_thermal_policy for platform_profile support
[    2.204519] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: error -EINVAL: Platform not supported
[    2.204532] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.1 failed with error -22

Once dumping all ACPI I found CSC3551 in ssdt16.dsl:

/*
 * Intel ACPI Component Architecture
 * AML/ASL+ Disassembler version 20200925 (64-bit version)
 * Copyright (c) 2000 - 2020 Intel Corporation
 * 
 * Disassembling to symbolic ASL+ operators
 *
 * Disassembly of ssdt16.dat, Fri Aug  4 20:43:15 2023
 *
 * Original Table Header:
 *     Signature        "SSDT"
 *     Length           0x000001A4 (420)
 *     Revision         0x01
 *     Checksum         0x0C
 *     OEM ID           "_ASUS_"
 *     OEM Table ID     "SPKRAMPS"
 *     OEM Revision     0x00000002 (2)
 *     Compiler ID      "INTL"
 *     Compiler Version 0x20200717 (538969879)
 */
DefinitionBlock ("", "SSDT", 1, "_ASUS_", "SPKRAMPS", 0x00000002)
{
    External (_SB_.GPI0, DeviceObj)
    External (_SB_.PC00.SPI1, DeviceObj)

    Scope (\_SB.PC00.SPI1)
    {
        Device (SPK1)
        {
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "10431573")  // _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.SPI1",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    SpiSerialBusV2 (0x0001, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x003D0900, ClockPolarityLow,
                        ClockPhaseFirst, "\\_SB.PC00.SPI1",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0017
                        }
                    GpioIo (Exclusive, PullDown, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0131
                        }
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012E
                        }
                    GpioIo (Shared, PullUp, 0x0064, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012F
                        }
                    GpioInt (Edge, ActiveBoth, Shared, PullUp, 0x0064,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012F
                        }
                })
                Return (SBUF) /* \_SB_.PC00.SPI1.SPK1._CRS.SBUF */
            }

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

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

I understand then, my Cirrus amps are driven by SPI1?

Is there any ready patch for this config?

Thanks for any help,

P.

@wrighterase
Copy link

Uploaded a patch for asus_zenbook_ux5304va

Special thanks

Author Description
lamperez For ACPI DSDT/SSDT patching guides and tools
Moooebie For ACPI DSDT/SSDT patching guide
thor2002ro For GRUB patch for similar laptop

Warning: patch doesnt work without kernel modification (described in repo readme)

i had similar success on a 2023 Asus Zenbook Pro 14 UX6404VV. it required kernel patching as well as a patched dsl, but the sound is so terrible the effort doesnt even feel worth it.
when it comes to step 2 in this patch repo for the ux3504va the entry is as follows:
SND_PCI_QUIRK(0x1043, 0x1863, "ASUS UX6404VV", ALC245_FIXUP_CS35L41_SPI_2)

i've had very mixed results with this particular model and things working, but Ubuntu 23.04 seems to be the best starting point and manually compiling the iwlwifi driver instead of using apt

i'll clone this repo and modify it for the UX6404VV in the next day or so.

@wrighterase
Copy link

Hi Guys, I'm just with a new machine (ASUS ROG Flow Z13 model GZ301VU) trying to make sound working. Obviously, as in the other cases it works with 3.5jack but speakers are silent. I'm on Ubuntu 23.04, GRUB. Once installed kernel 6.4.6 and modified: /etc/modprobe.d/alsa-base.conf as described here: look for "Kernel Patch" section + disabling post BIOS sound (during ROG logo), I made it to enables speakers, but they work only with tweeters. Sound is very shallow, so I believe amps are not working. There are still errors in the dmesg, it acknowledges, it does not work as expected:

[    2.104866] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
.....
[    2.193187] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Error: ACPI _DSD Properties are missing for HID CSC3551.
[    2.193211] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: error -EINVAL: Platform not supported
[    2.193226] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.0 failed with error -22
[    2.198675] Intel(R) Wireless WiFi driver for Linux
[    2.198789] iwlwifi 0000:00:14.3: enabling device (0000 -> 0002)
[    2.204499] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Error: ACPI _DSD Properties are missing for HID CSC3551.
[    2.204517] asus-nb-wmi asus-nb-wmi: Using throttle_thermal_policy for platform_profile support
[    2.204519] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: error -EINVAL: Platform not supported
[    2.204532] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.1 failed with error -22

Once dumping all ACPI I found CSC3551 in ssdt16.dsl:

/*
 * Intel ACPI Component Architecture
 * AML/ASL+ Disassembler version 20200925 (64-bit version)
 * Copyright (c) 2000 - 2020 Intel Corporation
 * 
 * Disassembling to symbolic ASL+ operators
 *
 * Disassembly of ssdt16.dat, Fri Aug  4 20:43:15 2023
 *
 * Original Table Header:
 *     Signature        "SSDT"
 *     Length           0x000001A4 (420)
 *     Revision         0x01
 *     Checksum         0x0C
 *     OEM ID           "_ASUS_"
 *     OEM Table ID     "SPKRAMPS"
 *     OEM Revision     0x00000002 (2)
 *     Compiler ID      "INTL"
 *     Compiler Version 0x20200717 (538969879)
 */
DefinitionBlock ("", "SSDT", 1, "_ASUS_", "SPKRAMPS", 0x00000002)
{
    External (_SB_.GPI0, DeviceObj)
    External (_SB_.PC00.SPI1, DeviceObj)

    Scope (\_SB.PC00.SPI1)
    {
        Device (SPK1)
        {
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "10431573")  // _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.SPI1",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    SpiSerialBusV2 (0x0001, PolarityLow, FourWireMode, 0x08,
                        ControllerInitiated, 0x003D0900, ClockPolarityLow,
                        ClockPhaseFirst, "\\_SB.PC00.SPI1",
                        0x00, ResourceConsumer, , Exclusive,
                        )
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0017
                        }
                    GpioIo (Exclusive, PullDown, 0x0000, 0x0000, IoRestrictionOutputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x0131
                        }
                    GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012E
                        }
                    GpioIo (Shared, PullUp, 0x0064, 0x0000, IoRestrictionInputOnly,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012F
                        }
                    GpioInt (Edge, ActiveBoth, Shared, PullUp, 0x0064,
                        "\\_SB.GPI0", 0x00, ResourceConsumer, ,
                        )
                        {   // Pin list
                            0x012F
                        }
                })
                Return (SBUF) /* \_SB_.PC00.SPI1.SPK1._CRS.SBUF */
            }

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

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

I understand then, my Cirrus amps are driven by SPI1?

Is there any ready patch for this config?

Thanks for any help,

P.

you'll need to include the _DSD section. example and also patch the kernel.

in my last test case the dsl example i used was this: https://gist.github.com/lamperez/862763881c0e1c812392b5574727f6ff?permalink_comment_id=4600010#file-ssdt_csc3551-dsl

this guide helps understand whats happening: https://asus-linux.org/wiki/cirrus-amps/

@pczekalski
Copy link

pczekalski commented Aug 5, 2023

@wrighterase
Thanks for your support.
I made following steps:

  1. Created DSD patch as follows:
DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000002)
{
    External (_SB_.PC00.SPI1, DeviceObj)
    External (_SB_.PC00.SPI1.SPK1, DeviceObj)

    Scope (_SB.PC00.SPI1.SPK1)
    {
        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 } },
            },
        })
    }
    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
                } }
            }
        })
    }
}
  1. Assembled, injected cpio via GRUB,
  2. Copied firmware as instructed in https://gitlab.com/asus-linux/firmware
  3. Rebooted

Now all dmesg errors are gone but there are no DSP sections as other users reported:

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

There is also no report on loading firmware.

Now there is no sound at all :(

Did I miss any steps?

@tejassp919
Copy link

tejassp919 commented Aug 5, 2023

The new SSDT patch has made sound better for my asus m16 G604, but its still not up to the mark as system is using default cirrus firmware. Am using latest provided SSDT patch and appropriate cirrus firmware for my laptop as per asus-linux blog on this

journalctl -b -g CSC3551 --output short-monotonic
[    0.009924] pop-os kernel: ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.009926] pop-os kernel: ACPI: SSDT 0x0000000036AD6000 0001A0 (v01 CUSTOM CSC3551  00000001 INTL 20200925)
[    3.601585] pop-os kernel: Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[    3.914772] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[    3.915223] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[    3.946798] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2
[    3.951124] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Falling back to default firmware.
[    3.951519] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: Firmware version: 3
[    3.951521] pop-os 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
[    4.012307] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: Firmware: 400a4 vendor: 0x2 v0.58.0, 2 algorithms
[    4.012871] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: 0: ID cd v29.78.0 XM@94 YM@e
[    4.012876] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: 1: ID f20b v0.1.0 XM@17c YM@0
[    4.012880] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: DSP1: spk-prot: e:\workspace\workspace\tibranch_release_playback_6.76_2\ormis\staging\default_>
[    4.025695] pop-os kernel: snd_hda_codec_realtek hdaudioC0D0: bound spi1-CSC3551:00-cs35l41-hda.0 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])
[    4.025844] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Falling back to default firmware.
[    4.025978] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: Firmware version: 3
[    4.025979] pop-os 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
[    4.087102] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: Firmware: 400a4 vendor: 0x2 v0.58.0, 2 algorithms
[    4.087757] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: 0: ID cd v29.78.0 XM@94 YM@e
[    4.087764] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: 1: ID f20b v0.1.0 XM@17c YM@0
[    4.087769] pop-os kernel: cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: DSP1: spk-prot: e:\workspace\workspace\tibranch_release_playback_6.76_2\ormis\staging\default_>
[    4.105604] pop-os kernel: snd_hda_codec_realtek hdaudioC0D0: bound spi1-CSC3551:00-cs35l41-hda.1 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])
cat dsdt.dsl | grep -A 1 "CSC3551"
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "10431473")  // _SUB: Subsystem ID

ls /lib/firmware/cirrus/ | grep 10431473
cs35l41-dsp1-spk-cali-10431473-spkid0-l0.bin
cs35l41-dsp1-spk-cali-10431473-spkid0-r0.bin
cs35l41-dsp1-spk-prot-10431473-spkid0-l0.bin
cs35l41-dsp1-spk-prot-10431473-spkid0-r0.bin

@wrighterase
Copy link

@wrighterase Thanks for your support. I made following steps:

  1. Created DSD patch as follows:
DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000002)
{
    External (_SB_.PC00.SPI1, DeviceObj)
    External (_SB_.PC00.SPI1.SPK1, DeviceObj)

    Scope (_SB.PC00.SPI1.SPK1)
    {
        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 } },
            },
        })
    }
    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
                } }
            }
        })
    }
}
  1. Assembled, injected cpio via GRUB,
  2. Copied firmware as instructed in https://gitlab.com/asus-linux/firmware
  3. Rebooted

Now all dmesg errors are gone but there are no DSP sections as other users reported:

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

There is also no report on loading firmware.

Now there is no sound at all :(

Did I miss any steps?

thats partial success. when i got the same logs as you now have, i needed to then patch the kernel. you can use @badger-lviv-ua repo here to get that part done as it mostly outlines whats required.

you'll need to pull the kernel source with apt-get source (this link may help you: https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel) and then patch sound/pci/hda/patch_realtek.c with something like this: SND_PCI_QUIRK(0x1043, 0x1863, "ASUS UX6404VV", ALC245_FIXUP_CS35L41_SPI_2) where 0x1043 is the SubVendor id and 0x1863 is the SubDevice id. these can be found using lspci and then using the PCI device name with hwinfo to find them. in my case as an example...
lspci shows Multimedia audio controller
hwinfo | grep "Multimedia audio controller" -A 10

44: PCI 1f.3: 0401 Multimedia audio controller
  [Created at pci.386]
  Unique ID: nS1_.1h_x0r_Xh66
  SysFS ID: /devices/pci0000:00/0000:00:1f.3
  SysFS BusID: 0000:00:1f.3
  Hardware Class: sound
  Model: "Intel Multimedia audio controller"
  Vendor: pci 0x8086 "Intel Corporation"
  Device: pci 0x51ca 
  SubVendor: pci 0x1043 "ASUSTeK Computer Inc."
  SubDevice: pci 0x1863 
  Revision: 0x01
  Driver: "sof-audio-pci-intel-tgl"
  Driver Modules: "snd_sof_pci_intel_tgl"
  Memory Range: 0x622d1a0000-0x622d1a3fff (rw,non-prefetchable)
  Memory Range: 0x622d000000-0x622d0fffff (rw,non-prefetchable)
  IRQ: 189 (2426 events)

hope this helps.

@lal12
Copy link

lal12 commented Aug 6, 2023

For anyone having issues with the ASUS ROG STRIX G17 (2023) G713PV:

I've used the following dsl patch:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
    External (_SB_.I2CD, DeviceObj)
    External (_SB_.I2CD.SPKR, DeviceObj)

    Scope (_SB.I2CD.SPKR)
    {
        Name (_DSD, Package ()   // _DSD: Device-Specific Data
        {
            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 } },
                // 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 } },
            },
        })
    }
}

The following works with grub:
Compile it with: iasl -tc speaker_amplifier_fix_patch.dsl, copy the resulting speaker_amplifier_fix_patch.aml file file to the boot partition (mostly /boot). Then add the entry acpi speaker_amplifier_fix_patch.aml to the grub config, e.g. to the /etc/grub.d/40_custom file. Don't forget to regenerate your grub config (sudo grub-mkconfig -o /boot/grub/grub.cfg on Arch).

You also need the newest linux-firmware version (20230804) (on arch as of writing only available via AUR linux-firmware-git).
Also the newest kernel version (6.4.8) is necessary.

It is possible to get it working with older kernel by adding some modprobe options to snd-hda-intel, but I don't know which exactly.
Instead of using the newest linux-firmware you can also create links to all files in /lib/firmware/cirrus containing -10431503- by replacing it with -10431d1f-, e.g. cs35l41-dsp1-spk-prot-10431d1f-spkid0-l0.bin -> cs35l41-dsp1-spk-prot-10431503-spkid0-l0.bin

Thanks to this gist and the information in https://asus-linux.org/wiki/cirrus-amps/#create-the-ssdt-patch

@Lumi571
Copy link

Lumi571 commented Aug 13, 2023

Hi. 🙂

A friend of mine recently bought an Asus Zenbook 15 UM3504DA laptop (2023) and installed Fedora Workstation 38 (currently Linux kernel 6.4.8). Unfortunately, the system is unable to produce sound via the built-in speakers. However, speakers connected via jack or Bluetooth provide a functional audio output.

We followed the tutorial at https://asus-linux.org/wiki/cirrus-amps/. (Many thanks to its creators!)
We installed the following SSDT patch:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
    External (_SB_.I2CB, DeviceObj)
    External (_SB_.I2CB.SPKR, DeviceObj)

    Scope (_SB.I2CB.SPKR)
    {
        Name (_DSD, Package ()   // _DSD: Device-Specific Data
        {
            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 } },
                // 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 } },
            },
        })
    }
}

And we installed the 104318d3 firmwares from https://gitlab.com/asus-linux/firmware/-/tree/main/cirrus:

$ ls /lib/firmware/cirrus/ | grep 104318d3
cs35l41-dsp1-spk-cali-104318d3-spkid1-l0.bin
cs35l41-dsp1-spk-cali-104318d3-spkid1-r0.bin
cs35l41-dsp1-spk-prot-104318d3-spkid1-l0.bin
cs35l41-dsp1-spk-prot-104318d3-spkid1-r0.bin

This gave the system speaker recognition, as I understand it:

$ dmesg |grep CSC3551
[    0.003682] ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.003683] ACPI: SSDT 0x00000000B9BD5000 00014D (v01 CUSTOM CSC3551  00000001 INTL 20220331)
[   27.685077] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 I2C devices.
[   27.911686] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[   27.912587] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[   27.954205] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2

However, the sound is still not working on his computer and it seems to me that some lines are missing in the command return above. Is it necessary to patch and compile the Linux kernel to enable sound to work, even on the latest versions of the Fedora kernel (6.4.8)? Or do we need to do other things to do this?

Thank you for taking the time to read my message. 🪷

@v-gu
Copy link

v-gu commented Aug 17, 2023

Hey guys, I have a G634JZ (Rog Strix Scar 16 2023), using following ssdt(dsdt shows SPI3 and SPK1):

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 ()   // _DSD: Device-Specific Data
        {
            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 } },
                // 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.SPI3)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cs-gpios", Package () {
                    Zero,                    // Native CS
                    SPK1, Zero, Zero, Zero   // GPIO CS
                } }
            }
        })
    }
}

The dmesg shows:

λ sudo dmesg|grep CSC3551
[    0.018409] ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.018410] ACPI: SSDT 0x0000000039A7D000 0001A0 (v01 CUSTOM CSC3551  00000001 INTL 20221020)
[    5.780873] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Reset line busy, assuming shared reset
[    5.884861] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Failed waiting for OTP_BOOT_DONE: -110
[    5.897583] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.0 failed with error -110
[    5.899702] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[    6.003547] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Failed waiting for OTP_BOOT_DONE: -110
[    6.024392] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.1 failed with error -110
[    6.024574] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.

The kernel patch of this device (1043:1caf) seems in the linux-g14 kernel patch code, which I'm using.

So anyone happened to fix the OTP_BOOT_DONE?

@pczekalski
Copy link

pczekalski commented Aug 22, 2023

Apologies for the delay in communication, I was away.
So I need to compile kernel, anyway?
I'm trying to follow the links you've shared (thanks @wrighterase) but I'm stuck with obtaining building dependencies for a kernel. To be clear, I've updated Ubuntu 22.04 kernel to the version 6.46 (using Mainline Kernels App):
$ sudo apt-get build-dep linux linux-image-$(uname -r) Reading package lists... Done E: Unable to find a source package for linux-image-6.4.6-060406-generic
--EDIT--
Meanwhile, I found sub-ids:

57: PCI 05.0: 0480 Multimedia controller
  [Created at pci.386]
  Unique ID: CvwD.Dtjiosnz0WC
  SysFS ID: /devices/pci0000:00/0000:00:05.0
  SysFS BusID: 0000:00:05.0
  Hardware Class: unknown
  Model: "Intel Multimedia controller"
  Vendor: pci 0x8086 "Intel Corporation"
  Device: pci 0xa75d 
  SubVendor: pci 0x1043 "ASUSTeK Computer Inc."
  SubDevice: pci 0x1573 
  Memory Range: 0x682e000000-0x682effffff (rw,non-prefetchable,disabled)
  IRQ: 255 (no events)
  Module Alias: "pci:v00008086d0000A75Dsv00001043sd00001573bc04sc80i00"
  Config Status: cfg=new, avail=yes, need=no, active=unknown

So, the correct patch in the sound/pci/hda/patch_realtek.c would be then:
SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301VU.306", ALC245_FIXUP_CS35L41_SPI_2),?
Just wonder, my soundcard seems to be on SPI1, not SPI2 (as in the patch, but there is no SPI1)...

Any help appreciated.

@flukejones
Copy link

flukejones commented Aug 23, 2023

For everyone ending up here through a boogle search, please see my guide (built from everything here) https://asus-linux.org/wiki/cirrus-amps/ for more info.

I have been pushing Cirrus devs to create proper solutions, and so far we have a patch merged by Taki, and I've submitted a new patch to finish enabling ASUS amps. The info is at the top of the article to be clear.

EDIT

I am now working on new patch

@flukejones
Copy link

flukejones commented Aug 23, 2023

Requires also https://lore.kernel.org/all/[email protected]/

From 7eab52145bd662736ed4975b97cbe3f1a4ec90e1 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <[email protected]>
Date: Wed, 23 Aug 2023 11:05:59 +1200
Subject: [PATCH] ALSA: hda: cs35l41: Support ASUS 2023 laptops with missing
 DSD

Support adding the missing DSD properties required  for ASUS ROG 2023
laptops and other ASUS laptops to properly utilise the cs35l41.

The currently added laptops are:
- ASUS GS650P,   i2c
- ASUS GA402X,   i2c
- ASUS GU604V,   spi
- ASUS GU603V,   spi
- ASUS GV601V,   spi
- ASUS GZ301V,   spi
- ASUS ROG ALLY, i2c
- ASUS G614J,    spi
- ASUS G634J,    spi
- ASUS G614JI,   spi
- ASUS G713P,    i2c
- ASUS H7604JV,  spi

The SPI connected amps may be required to use an external DSD patch
to fix or add the "cs-gpios" property.

Co-developed-by: Jonathan LoBue <[email protected]>
Signed-off-by: Jonathan LoBue <[email protected]>
Co-developed-by: Luke D. Jones <[email protected]>
Signed-off-by: Luke D. Jones <[email protected]>
---
 sound/pci/hda/cs35l41_hda_property.c | 47 ++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index 673f23257a09..b39f9443e1d6 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -43,6 +43,41 @@ static int lenovo_legion_no_acpi(struct cs35l41_hda *cs35l41, struct device *phy
 	return 0;
 }
 
+/*
+ * The CSC3551 is used in almost the entire ASUS ROG laptop range in 2023, this is likely to
+ * also include many non ROG labelled laptops. It is also used with either I2C connection or
+ * SPI connection. The SPI connected versions may be missing a chip select GPIO and require
+ * an DSD table patch.
+ */
+static int asus_rog_2023_spkr_id2(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
+				const char *hid)
+{
+	struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
+
+	/* check SPI or I2C address to assign the index */
+	cs35l41->index = (id == 0 || id == 0x40) ? 0 : 1;
+	cs35l41->channel_index = 0;
+	cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
+	hw_cfg->spk_pos = cs35l41->index;
+	hw_cfg->bst_type = CS35L41_EXT_BOOST;
+	hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
+	hw_cfg->gpio1.valid = true;
+	hw_cfg->gpio2.func = CS35L41_INTERRUPT;
+	hw_cfg->gpio2.valid = true;
+
+	if (strcmp(cs35l41->acpi_subsystem_id, "10431473") == 0
+		|| strcmp(cs35l41->acpi_subsystem_id, "10431483") == 0
+		|| strcmp(cs35l41->acpi_subsystem_id, "10431493") == 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);
+	}
+
+	hw_cfg->valid = true;
+
+	return 0;
+}
+
 struct cs35l41_prop_model {
 	const char *hid;
 	const char *ssid;
@@ -53,6 +88,18 @@ struct cs35l41_prop_model {
 const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
 	{ "CLSA0100", NULL, lenovo_legion_no_acpi },
 	{ "CLSA0101", NULL, lenovo_legion_no_acpi },
+	{ "CSC3551", "10431433", asus_rog_2023_spkr_id2 }, // ASUS GS650P - i2c
+	{ "CSC3551", "10431463", asus_rog_2023_spkr_id2 }, // ASUS GA402X/N - i2c
+	{ "CSC3551", "10431473", asus_rog_2023_spkr_id2 }, // ASUS GU604V - spi, reset gpio 1
+	{ "CSC3551", "10431483", asus_rog_2023_spkr_id2 }, // ASUS GU603V - spi, reset gpio 1
+	{ "CSC3551", "10431493", asus_rog_2023_spkr_id2 }, // ASUS GV601V - spi, reset gpio 1
+	{ "CSC3551", "10431573", asus_rog_2023_spkr_id2 }, // ASUS GZ301V - spi, reset gpio 0
+	{ "CSC3551", "104317F3", asus_rog_2023_spkr_id2 }, // ASUS ROG ALLY - i2c
+	{ "CSC3551", "10431B93", asus_rog_2023_spkr_id2 }, // ASUS G614J - spi, reset gpio 0
+	{ "CSC3551", "10431CAF", asus_rog_2023_spkr_id2 }, // ASUS G634J - spi, reset gpio 0
+	{ "CSC3551", "10431C9F", asus_rog_2023_spkr_id2 }, // ASUS G614JI -spi, reset gpio 0
+	{ "CSC3551", "10431D1F", asus_rog_2023_spkr_id2 }, // ASUS G713P - i2c
+	{ "CSC3551", "10431F1F", asus_rog_2023_spkr_id2 }, // ASUS H7604JV - spi, reset gpio 0
 	{}
 };
 
-- 
2.41.0

This will be submitted after I get some additional testing

@pczekalski
Copy link

For everyone ending up here through a boogle search, please see my guide (built from everything here) https://asus-linux.org/wiki/cirrus-amps/ for more info.

I have been pushing Cirrus devs to create proper solutions, and so far we have a patch merged by Taki, and I've submitted a new patch to finish enabling ASUS amps. The info is at the top of the article to be clear.

EDIT

I am now working on new patch

@flukejones Thanks for your effort, really appreciate that.

I have GZ301V so let me know how / if I can be in help for testing.

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