No sound in 2023

🔗Update: 23/08/2023

Before proceeding, see if you are running a kernel that includes the following two patches:

From 7eab52145bd662736ed4975b97cbe3f1a4ec90e1 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev>
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 <jlobue10@gmail.com>
Signed-off-by: Jonathan LoBue <jlobue10@gmail.com>
Co-developed-by: Luke D. Jones <luke@ljones.dev>
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
 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

these patches combined will fix the Cirrus amp, but still require the actual enabling of the amp. See the Kernel Patch section below for details on which laptops have the patches merged upstream or what work you may need to do. The laptops listed in the patch have had their alsa patches merged upstream.

If the above criteria is met you will still require the latest linux-firmware git, commit or later.

Finally, if your amp is SPI connected, you will need to proceed with getting the ACPI dump to find the SPI number, see the section below. You will then need the chipselect DSD patch only which will look like the following:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
    External (_SB_.PC00.SPI3, DeviceObj)
    External (_SB_.PC00.SPI3.SPK1, DeviceObj)
    Scope (_SB.PC00.SPI3)
    {
        Name (_DSD, Package ()
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cs-gpios", Package () { Zero, SPK1, Zero, Zero, Zero } }
            }
        })
    }
}

you must ensure that SPI3 is changed to match your SPI<number>, and that SPK1 is changed to match your speaker ID. Create and install the DSD patch with only the content as above using the instructions from the original guide.

If you use the above patches please report about your experience in the discord server or in the gitlab for asusctl.

Original article follows...

🔗The issue

Most of the 2023 ASUS laptops appear to have a Cirrus CS35L41 amp inside to driver the bass/mid-range speakers. Unfortunately the driver for it won't use it as it is missing a series of properties stored in the _DSD of the ACPI.

You will know if this is the case for you if you look in dmesg with dmesg |grep _DSD and see similar to:

Jun 28 20:02:56: cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Error: ACPI _DSD Properties are missing for HID CSC3551.
Jun 28 20:02:56: cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: error -EINVAL: Platform not supported
Jun 28 20:02:56: cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.0 failed with error -22
Jun 28 20:02:56: iwlwifi 0000:00:14.3: firmware: failed to load iwl-debug-yoyo.bin (-2)
Jun 28 20:02:56: iwlwifi 0000:00:14.3: firmware: failed to load iwl-debug-yoyo.bin (-2)
Jun 28 20:02:56: iwlwifi 0000:00:14.3: loaded firmware version 72.a764baac.0 so-a0-gf-a0-72.ucode op_mode iwlmvm
Jun 28 20:02:56: cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Error: ACPI _DSD Properties are missing for HID CSC3551.
Jun 28 20:02:56: cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: error -EINVAL: Platform not supported
Jun 28 20:02:56: cs35l41-hda: probe of spi0-CSC3551:00-cs35l41-hda.1 failed with error -22

This means you need:

  1. An ssdt patch to add the missing _DSD (device specific data) containing the Cirrus amplifier properties
  2. The firmware
  3. A kernel patch to add the required quirk to enable either the I2C connected amp, or an SPI connected amp

🔗Dump ACPI

The first thing to do is dump the ACPI tables so we can find information required.

mkdir cirrus && cd cirrus
sudo cat /sys/firmware/acpi/tables/DSDT > dsdt.dat
iasl -d dsdt.dat

If you want to get full ACPI:

sudo acpidump > acpi.log
acpixtract acpi.log
iasl -d *.dat

🔗Find the CSC3551 device in _DSD

This will show if your device amp is I2C or SPI connected, and what will be required for the ssdt patch you will write. Open the dumped dsdt.dsl and search for CSC3551.

Example SPI connected

    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,
                        )

Notice that this is Scope (_SB.PC00.SPI3), this means the amp is on SPI3.

**Example I2C connected

    Scope (_SB.I2CD)
    {
        Device (ASPK)
        {
            Name (_HID, "CSC3551")  // _HID: Hardware ID
            Name (_SUB, "10431433")  // _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,
                        )

Notice that this is Scope (_SB.I2CD), this means the amp is on I2C. The I2C connected device also requires the addresses of each amp, in this example they are 0x0040 and 0x0041 as seen in I2cSerialBusV2 (0x0040, and I2cSerialBusV2 (0x0041,.

In both examples, also note the _SUB: Subsystem ID, such as 10431CAF and 10431433. These are required to match the kernel quirk.

Lastly, you should also notice that SPK1 and ASPK are the names of the device for each, this is important to get right.

🔗Create the SSDT patch

Starting off with a template:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
    External (<EXTERNAL>, DeviceObj)
    External (<EXTERNAL>.<SPK>, DeviceObj)

    Scope (<SCOPE>.<SPK>)
    {
        Name (_DSD, Package ()   // _DSD: Device-Specific Data
        {
            ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package ()
            {
                Package () { "cirrus,dev-index", Package () { <ADDRESS_PAIR> }},
                Package () { "reset-gpios", Package () {
					<SPK>, Zero, Zero, Zero,
					<SPK>, Zero, Zero, Zero,
                } },
                Package () { "spk-id-gpios", Package () {
					<SPK>, 0x02, Zero, Zero,
					<SPK>, 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 } },
            },
        })
    }
}

Save the file as something like cirrus_ssdt_patch.dsl

  1. <EXTERNAL> will be either _SB_.I2CD, or the SPI address such as _SB_.PC00.SPI3. Note the _SB_, also note that SPI3 may be numbered differently.
  2. <SPK> will be the name of the device, such as ASPK
  3. <SCOPE> will be similar to step 1, minus the trailing _ such as _SB.I2CD
  4. <ADDRESS_PAIR> will be either 0x0040, 0x0041 for I2C, or Zero, One for SPI

The two other items you may need to configure will be "reset-gpios" and "cirrus,gpio1-func", we will get to these later.

🔗Install the SSDT patch

Perform the following steps:

iasl -tc ssdt_csc3551.dsl
mkdir -p kernel/firmware/acpi
cp ssdt_csc3551.aml kernel/firmware/acpi
find kernel | cpio -H newc --create > patched_cirrus_acpi.cpio
sudo cp patched_cirrus_acpi.cpio /boot/patched_cirrus_acpi.cpio

🔗grub

If you use grub for booting, update your /etc/default/grub to add the line:

GRUB_EARLY_INITRD_LINUX_CUSTOM="patched_cirrus_acpi.cpio"

and update grub with sudo grub2-mkconfig -o /etc/grub2-efi.cfg (this command is for fedora, your distro may be different).

🔗systemd-boot

If you use systemd-boot for booting, the process can be a little different depending on how you use it.

🔗mkinitcpio

You may have one or more /etc/mkinitcpio.d/linux.preset files depending on your kernel setup/name, such as /etc/mkinitcpio.d/linux-rog.preset for my custom kernel. In each of these you will need to edit the line: ALL_microcode=(/boot/*-ucode.img) in to ALL_microcode=(/boot/*-ucode.img /boot/patched_cirrus_acpi.cpio) You will of course need to adjust paths depending on your own config, then run the appropriate command such as sudo mkinitcpio -P.

🔗systemd-boot loader

If you are using something like /boot/efi/loader/entries/ to configure boot you will need to add a line above the existing initrd lines like:

initrd  /boot/boot/patched_cirrus_acpi.cpio
initrd  /boot/intel-ucode.img
initrd  /boot/initramfs-linux.img

🔗Firmware

You will need the firmware from https://gitlab.com/asus-linux/firmware, fetch this and search in the cirrus dir for files matching the Subsystem ID you noted earlier. The files are lowercased.

UPDATE: linux-firmware git has almost all firmwares as of this commit

ls /lib/firmware/cirrus/ |grep 10431caf
cs35l41-dsp1-spk-cali-10431caf-spkid0-l0.bin
cs35l41-dsp1-spk-cali-10431caf-spkid0-r0.bin
cs35l41-dsp1-spk-cali-10431caf-spkid1-l0.bin
cs35l41-dsp1-spk-cali-10431caf-spkid1-r0.bin
cs35l41-dsp1-spk-cali-10431caf.wmfw -> cs35l41/v6.61.1/halo_cspl_RAM_revB2_29.63.1.wmfw
cs35l41-dsp1-spk-prot-10431caf-spkid0-l0.bin
cs35l41-dsp1-spk-prot-10431caf-spkid0-r0.bin
cs35l41-dsp1-spk-prot-10431caf-spkid1-l0.bin
cs35l41-dsp1-spk-prot-10431caf-spkid1-r0.bin
cs35l41-dsp1-spk-prot-10431caf.wmfw -> cs35l41/v6.61.1/halo_cspl_RAM_revB2_29.63.1.wmfw

you may have more or less than shown. If you have matches then cp -r cirrus /lib/firmware/.

If you don't have anything matching then you will need to search in your c:\windows\system*\ for files matching the subsystem ID. The path may look like csaudioext.inf_amd64_bc8b7c0798187cc2/tunings/ASUS_G634_10431CAF_221125 containing:

10431CAF_221125_V0_A0.bin      10431CAF_221125_V1_A0.bin
10431CAF_221125_V0_A0_cal.bin  10431CAF_221125_V1_A0_cal.bin
10431CAF_221125_V0_A1.bin      10431CAF_221125_V1_A1.bin
10431CAF_221125_V0_A1_cal.bin  10431CAF_221125_V1_A1_cal.bin

In the dir of these files run:

#!/bin/sh
# Make correct files from dir of 10431CAF_221125_V0_A0.bin etc

if ! command -v tr &> /dev/null
then
    echo "The tool `tr` could not be found"
    exit 1
fi

pattern="*.bin"
files=( $pattern )
filename=${files[0]}
SUBU=$(printf '%s\n' "${filename//_*}")
SUBL=$(echo $SUBU |tr '[:upper:]' '[:lower:]')

cp ${SUBU}_*_V0_A0.bin cs35l41-dsp1-spk-prot-${SUBL}-spkid0-l0.bin 2> /dev/null
cp ${SUBU}_*_V0_A1.bin cs35l41-dsp1-spk-prot-${SUBL}-spkid0-r0.bin 2> /dev/null
cp ${SUBU}_*_V0_A0_cal.bin cs35l41-dsp1-spk-cali-${SUBL}-spkid0-l0.bin 2> /dev/null
cp ${SUBU}_*_V0_A1_cal.bin cs35l41-dsp1-spk-cali-${SUBL}-spkid0-r0.bin 2> /dev/null

cp ${SUBU}_*_V1_A0.bin cs35l41-dsp1-spk-prot-${SUBL}-spkid1-l0.bin 2> /dev/null
cp ${SUBU}_*_V1_A1.bin cs35l41-dsp1-spk-prot-${SUBL}-spkid1-r0.bin 2> /dev/null
cp ${SUBU}_*_V1_A0_cal.bin cs35l41-dsp1-spk-cali-${SUBL}-spkid1-l0.bin 2> /dev/null
cp ${SUBU}_*_V1_A1_cal.bin cs35l41-dsp1-spk-cali-${SUBL}-spkid1-r0.bin 2> /dev/null

cp ${SUBU}_*_V01_A0.bin cs35l41-dsp1-spk-prot-${SUBL}-spkid1-l0.bin 2> /dev/null
cp ${SUBU}_*_V01_A1.bin cs35l41-dsp1-spk-prot-${SUBL}-spkid1-r0.bin 2> /dev/null
cp ${SUBU}_*_V01_A0_cal.bin cs35l41-dsp1-spk-cali-${SUBL}-spkid1-l0.bin 2> /dev/null
cp ${SUBU}_*_V01_A1_cal.bin cs35l41-dsp1-spk-cali-${SUBL}-spkid1-r0.bin 2> /dev/null

ln -s cs35l41/v6.61.1/halo_cspl_RAM_revB2_29.63.1.wmfw cs35l41-dsp1-spk-cali-${SUBL}.wmfw
ln -s cs35l41/v6.61.1/halo_cspl_RAM_revB2_29.63.1.wmfw cs35l41-dsp1-spk-prot-${SUBL}.wmfw

# mv cs35l41* /home/luke/firmware/
printf "\nDone! copy or move the files: 'mv cs35l41* /lib/firmware/cirrus'\n"

it would also be appreciated if the resulting renamed files could be submitted to the repo.

🔗Kernel patch

Patches for these subsystems/laptops are merged upstream and will be in stable releases (as of 22/08/23) and 6.5-rc7+:

  • SPI_2
    • 0x1043, 0x1473, "ASUS GU604V"
    • 0x1043, 0x1483, "ASUS GU603V"
    • 0x1043, 0x1493, "ASUS GV601V"
    • 0x1043, 0x1573, "ASUS GZ301V"
    • 0x1043, 0x1c9f, "ASUS G614JI"
  • SPI_4
    • 0x1043, 0x1caf, "ASUS G634JYR/JZR"
  • I2C_2
    • 0x1043, 0x1d1f, "ASUS ROG Strix G17
    • 0x1043, 0x1463, "Asus GA402X"
    • 0x1043, 0x1433, "ASUS GX650P"

There is also work progressing on a patch to remove the requirement of the DSD table patching listed above. The initial patch is athttps://lore.kernel.org/all/20230815161033.3519-1-sbinding@opensource.cirrus.com/ and this will require adding entries for our laptops.

Note: if you are using the 6.5 kernel, or a patched kernel, you do not need to do the following.

At the time of writing this, if you have kernel 6.3.10+ and SPI amp with quad speakers, then you can quickly test things with an alsa fw patch. Create or edit /etc/modprobe.d/alsa-base.conf and add:

options snd-hda-intel model=1043:1caf

and reboot. Change 1caf to 1c9f for dual speaker systems.

This option changes the subsystem ID to match a device with an already added quirk chain. So far most of the ROG range seem to require the exact same quirk chain (variations for SPI vs I2C taken in to account).

If you have an I2C connected amp you may try matching against the ROG Ally:

options snd-hda-intel model=1043:17f3

or try 1433 in place of 17f3 if you are using a kernel with the latest patches linked above.

If the above worked for you please drop us a line with your actual subsystem ID and laptop model number, and the correct quirk will be added to the Linux kernel.

Manually patching the kernel is a little out of scope of this article for now, and should be unrequired as long as you are running a 6.3.10+ kernel where the two subsystem quirks above have been added.

🔗How do I know it worked?

First, you'll have sound. But also you will want to check the dmesg output for something similar to the following:

dmesg |grep CSC3551
[    0.017487] ACPI: Table Upgrade: install [SSDT-CUSTOM- CSC3551]
[    0.017488] ACPI: SSDT 0x000000003959B000 0001A0 (v01 CUSTOM CSC3551  00000001 INTL 20220331)
[    6.458328] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.
[    6.585069] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Reset line busy, assuming shared reset
[    6.619422] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[    6.619635] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[    6.643196] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2
[    6.846341] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: DSP1: Firmware version: 3
[    6.846343] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: DSP1: cirrus/cs35l41-dsp1-spk-prot-10431caf.wmfw: Fri 27 Aug 2021 14:58:19 W. Europe Daylight Time
[    6.999610] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: DSP1: Firmware: 400a4 vendor: 0x2 v0.43.1, 2 algorithms
[    7.000479] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: DSP1: 0: ID cd v29.63.1 XM@94 YM@e
[    7.000483] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: DSP1: 1: ID f20b v0.1.0 XM@176 YM@0
[    7.000485] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: DSP1: spk-prot: C:\Users\dchunyi\Documents\Asus_ROG\Project\G6_Strix16\Tuning\20220930\G634\10431CAF_220930_V1_A0.bin
[    7.036740] snd_hda_codec_realtek hdaudioC0D0: bound spi0-CSC3551:00-cs35l41-hda.0 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])
[    7.037472] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: DSP1: Firmware version: 3
[    7.037474] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: DSP1: cirrus/cs35l41-dsp1-spk-prot-10431caf.wmfw: Fri 27 Aug 2021 14:58:19 W. Europe Daylight Time
[    7.178782] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: DSP1: Firmware: 400a4 vendor: 0x2 v0.43.1, 2 algorithms
[    7.179824] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: DSP1: 0: ID cd v29.63.1 XM@94 YM@e
[    7.179827] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: DSP1: 1: ID f20b v0.1.0 XM@176 YM@0
[    7.179829] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: DSP1: spk-prot: C:\Users\dchunyi\Documents\Asus_ROG\Project\G6_Strix16\Tuning\20220930\G634\10431CAF_220930_V1_A1.bin
[    7.218481] snd_hda_codec_realtek hdaudioC0D0: bound spi0-CSC3551:00-cs35l41-hda.1 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])

the line:

[    7.000485] cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: DSP1: spk-prot: C:\Users\dchunyi\Documents\Asus_ROG\Project\G6_Strix16\Tuning\20220930\G634\10431CAF_220930_V1_A0.bin

shows that the proper tuned firmware was loaded, matching my laptop name, and model number of G634.

If you have a message about "falling back to default firmware" or similar then the ssdt patch made need checking. If the patch looks correct check the following section.

🔗Additional info

Are you still having problems?

Try modifying "reset-gpios" to be:

<SPK>, One, Zero, Zero,
<SPK>, One, Zero, Zero,

or try modifying "cirrus,gpio1-func" to be:

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

don't forget to update the patched_cirrus_acpi.cpio using the provided instructions.

The SPI version may also need:

    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
                } }
            }
        })
    }

added inside the:

DefinitionBlock ("", "SSDT", 1, "CUSTOM", "CSC3551", 0x00000001)
{
...
<add to end before closing brace>
}

🔗Example ssdt for I2C

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

    Scope (_SB.I2CD.ASPK)
    {
        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 () {
                    ASPK, Zero, Zero, Zero,
                    ASPK, Zero, Zero, Zero,
                } },
                Package () { "spk-id-gpios", Package () {
                    ASPK, 0x02, Zero, Zero,
                    ASPK, 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 } },
            },
        })
    }
}

🔗Example ssdt for SPI

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
                } }
            }
        })
    }
}

🔗Credits

This article was enabled by many sources around the internet. The goal of this article was to provide an easily accessible guide for people to work from.

Sources:

Has this guide helped you set up your machine?

If this site helps you and you want to contribute we welcome you to help with development, search for issues, join the discord, and add to this website.

You can also donate

Your support on Pateron helps us buy ASUS devices for development to support new features and drivers.