Skip to content

Instantly share code, notes, and snippets.

@masselstine
Last active September 18, 2024 16:10
Show Gist options
  • Save masselstine/8fe9634b4c31cef07b8dfab089e4eb38 to your computer and use it in GitHub Desktop.
Save masselstine/8fe9634b4c31cef07b8dfab089e4eb38 to your computer and use it in GitHub Desktop.
Linux on the Zenbook 14 OLED refresh (UM3402YAR)

Linux on the Zenbook 14 OLED (refresh) - Model UM3402YAR

BIOS

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.

Sound

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.

SPKR _DSD validation

Elements are described in the kernel documentation found here

100% Confirmed

  • "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.

Fingerprint

Not working

From f309c07e244945b9b3b3c473d5e8394cce132ddf Mon Sep 17 00:00:00 2001
From: Mark Asselstine <[email protected]>
Date: Sat, 29 Apr 2023 11:21:55 -0400
Subject: [PATCH] ALSA: hda/realtek: Add quirk for ASUS UM3402YAR using CS35L41
This Asus Zenbook laptop use Realtek HDA codec combined with
2xCS35L41 Amplifiers using I2C with External Boost.
Signed-off-by: Mark Asselstine <[email protected]>
---
sound/pci/hda/patch_realtek.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index f70d6a33421d..905acd66ea01 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -9500,6 +9500,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
+ SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
--
2.40.1
#!/usr/bin/bash
#
# Create the needed Linux firmware files from a copy of the firmware
# files from Windows (c:\windows\system32\csaudio)
#
zstd halo_cspl_RAM_revB2_29.63.1.wmfw -o halo_cspl_RAM_revB2_29.63.1.wmfw.zst
for t in cali prot
do
for i in 0 1
do
for side in l r
do
j=0
if [ $side == "r" ]; then
j=1
fi
deco=""
if [ $t == "cali" ]; then
deco="_cal"
fi
ofile=10431E12_220304_V${i}_A${j}${deco}.bin
zstd ${ofile} -o ${ofile}.zstd
mv ${ofile}.zstd cs35l41-dsp1-spk-${t}-10431683-spkid${i}-${side}0.bin.zst
done
done
cp halo_cspl_RAM_revB2_29.63.1.wmfw.zst cs35l41-dsp1-spk-${t}-10431683.wmfw.zst
done
rm halo_cspl_RAM_revB2_29.63.1.wmfw.zst
# dmesg | grep cs3
[ 12.582998] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[ 12.591327] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[ 12.636874] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2
[ 12.758779] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: DSP1: Firmware version: 3
[ 12.762457] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: DSP1: cirrus/cs35l41-dsp1-spk-prot-10431683.wmfw: Fri 27 Aug 2021 14:58:19 W. Europe Daylight Time
[ 13.262629] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: DSP1: Firmware: 400a4 vendor: 0x2 v0.43.1, 2 algorithms
[ 13.266856] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: DSP1: 0: ID cd v29.63.1 XM@94 YM@e
[ 13.270159] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: DSP1: 1: ID f20b v0.1.0 XM@176 YM@0
[ 13.274041] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: DSP1: spk-prot: C:\Users\tyang\Desktop\Product Setting\SmartAMP\ASUS\ASUS_Zenbook\UM3402\Tuning_Release\220304\ASUS_UM3402_L_tuning_IDHX_ReDC_Finish_PICL_RTL_0304.bin
[ 13.379459] snd_hda_codec_realtek hdaudioC1D0: bound i2c-CSC3551:00-cs35l41-hda.0 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])
[ 13.393246] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: DSP1: Firmware version: 3
[ 13.397723] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: DSP1: cirrus/cs35l41-dsp1-spk-prot-10431683.wmfw: Fri 27 Aug 2021 14:58:19 W. Europe Daylight Time
[ 13.898417] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: DSP1: Firmware: 400a4 vendor: 0x2 v0.43.1, 2 algorithms
[ 13.903515] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: DSP1: 0: ID cd v29.63.1 XM@94 YM@e
[ 13.907164] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: DSP1: 1: ID f20b v0.1.0 XM@176 YM@0
[ 13.909854] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: DSP1: spk-prot: C:\Users\tyang\Desktop\Product Setting\SmartAMP\ASUS\ASUS_Zenbook\UM3402\Tuning_Release\220304\ASUS_UM3402_R_tuning_IDHX_ReDC_Finish_PICL_RTL_0304.bin
[ 14.014944] snd_hda_codec_realtek hdaudioC1D0: bound i2c-CSC3551:00-cs35l41-hda.1 (ops cs35l41_hda_comp_ops [snd_hda_scodec_cs35l41])
...
;; ASUSTEK Zenbook notebook (see FC-2054)
%CirrusSpeakerAmp% = CONF_0322, ACPI\VEN_CSC&DEV_3551&SUBSYS_104316A3 ; UX3402VA [FC-1831] [FC-1905]
%CirrusSpeakerAmp% = CONF_0451, ACPI\VEN_CSC&DEV_3551&SUBSYS_104316D3 ; UX5304VA [FC-2056]
%CirrusSpeakerAmp% = CONF_0450, ACPI\VEN_CSC&DEV_3551&SUBSYS_104316F3 ; UX7602VZ [FC-1836]
%CirrusSpeakerAmp% = CONF_0460, ACPI\VEN_CSC&DEV_3551&SUBSYS_10431F1F ; H7604JV/HU/W7604J3D [FC-2033]
%CirrusSpeakerAmp% = CONF_0470, ACPI\VEN_CSC&DEV_3551&SUBSYS_10431863 ; UX6404VA/VU [FC-2015]
%CirrusSpeakerAmp% = CONF_0330, ACPI\VEN_CSC&DEV_3551&SUBSYS_10431683 ; UM3402YAR [FC-1827] (UM3402_refresh)
%CirrusSpeakerAmp% = CONF_0430, ACPI\VEN_CSC&DEV_3551&SUBSYS_104318D3 ; UM3504DA [FC-2054]
...
;; 2-ch I2C, ext. VSPK, SPKR_ID
[CONF_0330.NT]
AddReg=CONF_0320.Settings.AddReg, CONF_0330.Config.AddReg, L51_2_VSPK.Init.AddReg
AddReg=PB6.61.1.Firmware.AddReg, PB6.61.1.Tunings.AddReg, CONF_0330.Tunings.AddReg, 2_SPK_2_VEN_DefaultGain.AddReg
CopyFiles=PB6.61.1.Firmware.CopyFiles, PB6.61.1.Tunings.CopyFiles, CONF_0330.Tunings.CopyFiles
//
// Build
// # iasl -tc ssdt_csc3551.dsl
// Create the proper directory structure and copy .aml file
// # mkdir -p kernel/firmware/acpi
// # cp ssdt_csc3551.aml kernel/firmware/acpi/ssdt_csc3551.aml
// Package into a format loadable by grub
// # find kernel | cpio -H newc --create > acpi_override
// Copy to /boot
// # cp acpi_override /boot/.
// Load via grub
// initrd /acpi_override /amd-ucode.img /initramfs-linux.img
// Supporting docs
// https://www.kernel.org/doc/Documentation/devicetree/bindings/sound/cirrus%2Ccs35l41.yaml
//
DefinitionBlock ("", "SSDT", 2, "CUSTOM", "CSC3551", 0x00000003)
{
External (_SB_.I2CD, DeviceObj)
External (_SB_.I2CD.SPKR, DeviceObj)
Scope (\_SB.I2CD.SPKR)
{
Name(_DSD, Package ()
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package () { "cirrus,dev-index", Package () { 0x40, 0x41 }},
// reset-gpios: 2nd elem is GPIO index: Zero, One, 0x02 or 0x03
Package () { "reset-gpios", Package () {
SPKR, Zero, Zero, Zero,
SPKR, Zero, Zero, Zero
} },
// spk-id-gpios: 2nd elem is GPIO index: Zero, One, 0x02 or 0x03
Package () { "spk-id-gpios", Package () {
SPKR, One, Zero, Zero,
SPKR, One, Zero, Zero
} },
Package () { "cirrus,speaker-position", Package () { Zero, One } },
// gpioX-func: 0 not used, 1 VSPK_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 } },
// gpio1-output-enable: true, false (default: false, ie: input)
Package () { "cirrus,gpio1-output-enable", Package () { One, One } },
// gpio1-src-select: 0 High Impedance (default), 1 GPIO, 2 Sync, 3 MCLK input
Package () { "cirrus,gpio1-src-select", Package () { One, One } }
}
})
}
}
@nullptroma
Copy link

After the release of 6.8, when everything works, will it be necessary to somehow remove the current fixes in the form of renamed drivers?

@zonkypop
Copy link

Upgraded the kernel to 6.8-rc5 and sound is working for the first time 🥳

@nullptroma
Copy link

Upgraded the kernel to 6.8-rc5 and sound is working for the first time 🥳

but the sound is quiet. Cisco .zst files are still needed, aren't they?

@kelna
Copy link

kelna commented Jul 6, 2024

After a full system upgrade (Arch) today, sound completely disappeared again from the internal speakers. Any similar experience or idea?

@pkuronen22
Copy link

I have been using this with Fedora 40 and it works perfectly and is very very snappy. Best laptop I ever had. Did not need any tricks, just install and go. I did not test the sound though since I use Jabra headphones for all online meets.

@kelna
Copy link

kelna commented Jul 29, 2024

After a full system upgrade (Arch) today, sound completely disappeared again from the internal speakers. Any similar experience or idea?

I have no idea why or how but muting and unmuting fixed the sound. (It was NOT muted originally, I swear, seriously.😅)

@masselstine
Copy link
Author

After a full system upgrade (Arch) today, sound completely disappeared again from the internal speakers. Any similar experience or idea?

I have no idea why or how but muting and unmuting fixed the sound. (It was NOT muted originally, I swear, seriously.😅)

Glad you were able to get sound working again. Thanks for posting the update to help others who might run into this.

@Zotyamester
Copy link

After a full system upgrade (Arch) today, sound completely disappeared again from the internal speakers. Any similar experience or idea?

I have no idea why or how but muting and unmuting fixed the sound. (It was NOT muted originally, I swear, seriously.😅)

Can confirm it. As crazy as it sounds, but it seems to be a good workaround. 👍

@sachinchaudhary1808
Copy link

what about battery life and cpu usage ? it seems high and low battery life ?

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