The latest BIOS is version 303 "UM3402YAR.303" (Release Date: 09/05/2023). All items posted here will be specific to the model number and BIOS version described here (BIOS 300, 302 were known working). Some things might be specific to Arch Linux but should be generic and portable to other distributions. There are no guarantees and should you wish to try any of this out it is assumed to be at your own risk.
The sound does not work out of the box (at least not on Arch but I am guessing for most Distros as well).
The patch 0001-ALSA-hda-realtek-Add-quirk-for-ASUS-UM3402YAR-using-.patch is required to be applied to kernels older than v6.4 to ensure that the Realtek sound device is properly bound to the Cirrus amplifiers. If you are using kernel v6.4 or newer this patch is not needed.
The ssdt_csc3551.dsl file can be used per the instructions found in the file header. No need to patch the DSDT, this is a stand-alone SSDT that is easily used via GRUB. It can also be used as an EFI var and the efivar_ssdt= kernel command line option. The values are prelimary as I review the Windows oem50.inf and oem37.inf files from Windows in order to extract the proper values.
The firmware files are missing from the linux-firmware on Arch Linux (and most likely other distros as well, until someone submits them for merge). Originally I was using direct copies of firmware files for the similar "10431e12" device that were present in /lib/firmware/cirrus. At the time these appeared to be identical. Updating the Windows OS recently and looking again shows that there are differences. So I am now copying the firmware files from Windows and running the "compress-rename.sh" script to prepare them on Linux.
To start grab the full contents of c:\windows\system32\csaudio
from Windows. Once you have these files on Linux you should have something like
$ ls -l
total 1080
-rw-r--r-- 1 mark mark 5532 Nov 24 14:16 10431E12_220304_V0_A0.bin
-rw-r--r-- 1 mark mark 2012 Nov 24 14:16 10431E12_220304_V0_A0_cal.bin
-rw-r--r-- 1 mark mark 5532 Nov 24 14:16 10431E12_220304_V0_A1.bin
-rw-r--r-- 1 mark mark 2012 Nov 24 14:16 10431E12_220304_V0_A1_cal.bin
-rw-r--r-- 1 mark mark 5532 Nov 24 14:16 10431E12_220304_V1_A0.bin
-rw-r--r-- 1 mark mark 2012 Nov 24 14:16 10431E12_220304_V1_A0_cal.bin
-rw-r--r-- 1 mark mark 5532 Nov 24 14:16 10431E12_220304_V1_A1.bin
-rw-r--r-- 1 mark mark 2012 Nov 24 14:16 10431E12_220304_V1_A1_cal.bin
-rw-r--r-- 1 mark mark 2600 Nov 24 14:16 Calibration_and_Diagnostics_CS35L41B_48000_29.63.1_left_cal.bin
-rw-r--r-- 1 mark mark 1548 Nov 24 14:16 Calibration_CS35L41B_48000_29.63.1_left_cal.bin
-rw-r--r-- 1 mark mark 11556 Nov 24 14:38 csaudio.cat
-rw-r--r-- 1 mark mark 100255 Nov 24 14:38 csaudioext.cat
-rw-r--r-- 1 mark mark 110868 Nov 24 14:35 csaudioext.inf
-rw-r--r-- 1 mark mark 6392 Nov 24 14:35 csaudio.inf
-rw-r--r-- 1 mark mark 350632 Nov 24 14:37 csaudio.sys
-rw-r--r-- 1 mark mark 5208 Nov 24 14:16 Enhance_Protect_Lite_Mono_CS35L41B_48000_29.63.1_left.bin
-rw-r--r-- 1 mark mark 33456 Nov 24 14:16 halo_cspl_RAM_diag_revB2_29.63.1.wmfw
-rw-r--r-- 1 mark mark 34068 Nov 24 14:16 halo_cspl_RAM_revB2_29.63.1.wmfw
-rw-r--r-- 1 mark mark 6392 Nov 24 14:31 oem37.inf
-rw-r--r-- 1 mark mark 9812 Nov 24 14:31 oem37.PNF
-rw-r--r-- 1 mark mark 110868 Nov 24 14:31 oem50.inf
-rw-r--r-- 1 mark mark 91068 Nov 24 14:31 oem50.PNF
-rw-r--r-- 1 mark mark 136610 Nov 24 14:32 oem82.inf
-rw-r--r-- 1 mark mark 3920 Nov 24 14:16 Protect_Lite_CS35L41B_48000_29.63.1_left.bin
-rw-r--r-- 1 mark mark 760 Nov 24 14:16 top_passthrough_CS35L41B_48000_29.63.1_full.bin
From this directory run the $ bash compress-rename.sh
script to generate the firmware files. You should now have
$ ls -l *zst
-rw-r--r-- 1 mark mark 1148 Nov 24 14:16 cs35l41-dsp1-spk-cali-10431683-spkid0-l0.bin.zst
-rw-r--r-- 1 mark mark 1144 Nov 24 14:16 cs35l41-dsp1-spk-cali-10431683-spkid0-r0.bin.zst
-rw-r--r-- 1 mark mark 1145 Nov 24 14:16 cs35l41-dsp1-spk-cali-10431683-spkid1-l0.bin.zst
-rw-r--r-- 1 mark mark 1147 Nov 24 14:16 cs35l41-dsp1-spk-cali-10431683-spkid1-r0.bin.zst
-rw-r--r-- 1 mark mark 18852 Nov 24 16:39 cs35l41-dsp1-spk-cali-10431683.wmfw.zst
-rw-r--r-- 1 mark mark 3122 Nov 24 14:16 cs35l41-dsp1-spk-prot-10431683-spkid0-l0.bin.zst
-rw-r--r-- 1 mark mark 3117 Nov 24 14:16 cs35l41-dsp1-spk-prot-10431683-spkid0-r0.bin.zst
-rw-r--r-- 1 mark mark 3146 Nov 24 14:16 cs35l41-dsp1-spk-prot-10431683-spkid1-l0.bin.zst
-rw-r--r-- 1 mark mark 3127 Nov 24 14:16 cs35l41-dsp1-spk-prot-10431683-spkid1-r0.bin.zst
-rw-r--r-- 1 mark mark 18852 Nov 24 16:39 cs35l41-dsp1-spk-prot-10431683.wmfw.zst
Copy all of these files to /lib/firmware/cirrus.
Elements are described in the kernel documentation found here
- "cirrus,dev-index": Confirmed by: Simple printk() was used to determine the values of the two AMPs. These are used to determine the index used ('0' or '1') when retrieving values from other elements in the _DSD
- "reset-gpios": Confirmed by: The driver issues a reset after reading the ACPI data and waits for the reset to complete by polling IRQ status for CS35L41_OTP_BOOT_DONE. If this is not set correctly then the reset would fail and a OTP_BOOT_DONE waiting message would be printed.
- "spk-id-gpios": Mostly confirmed by: There are 4 GPIOs listed in the 'shipped' ACPI DSDT. Index 0 is the reset-gpios Indicies 0x02 and 0x03 share a pin and are "shared". So by processes of elimination GPIO at index 'One' remains. The 0th element is definitely SPKR the 2nd and 3rd elements are best guess.
- "cirrus,speaker-position": Confirmed by: Simple left and right position in driver code & left and right are properly outputting sound in sound settings with isolated output
- "cirrus,gpio1-func": Confirmed by: the comment in the oem50.inf for "CONF_0330.NT"
- "cirrus,gpio2-func": Mostly confirmed by: the speakers working. Also a "Amp short error" interrupt was received while this work was being done.
- "cirrus,boost-type": Confirmed by: the comment in the oem50.inf for "CONF_0330.NT"
- "cirrus,gpio1-output-enable": Confirmed by: with GPIO1 being VSPK_SWITCH then GPIO1 needs to be an output
- "cirrus,gpio1-src-select": Confirmed by: with GPIO1 being used as a GPIO output, then this is the only thing that makes sense
The patch and the SSDT are the only changes required to get sound working. Again, use of items posted here is use-at-your-own-risk.
Not working
With kernel 6.7, a patch (https://lore.kernel.org/all/20231218151221.388745-1-sbinding@opensource.cirrus.com/ )is added for cs35l41 which fixes sound on many Asus laptops. Unfortunately this device (UM3402YAR) has
PCI_SUBSYS_ID=1043:1683
(result ofudevadm info /sys/bus/pci/devices/0000:00:00.0 | grep PCI_SUBSYS_ID
) and it does not appear here. https://github.com/torvalds/linux/blob/master/sound/pci/hda/cs35l41_hda_property.cAdding correct values to that table might fix speakers. But I don't know what are the correct values for
reset_gpio_index, spkid_gpio_index, cs_gpio_index, boost_ind_nanohenry, boost_peak_milliam, boost_cap_microfarad
. Last three are probably not needed as this device uses external boost.