Skip to content

Instantly share code, notes, and snippets.

@lamperez
Last active November 14, 2024 16:20
Show Gist options
  • Save lamperez/d5b385bc0c0c04928211e297a69f32d7 to your computer and use it in GitHub Desktop.
Save lamperez/d5b385bc0c0c04928211e297a69f32d7 to your computer and use it in GitHub Desktop.
Load custom ACPI tables

ACPI DSDT/SSDT patching

These instructions are meant for a system with EFI, systemd-boot and deb based packages. Adjust them to your needs.

Reference: https://www.kernel.org/doc/Documentation/acpi/initrd_table_override.txt

See also https://github.com/lbschenkel/acer-sf314_43-acpi-patch

ACPICA tools: https://acpica.org/downloads

sudo apt install acpica-tools

Option 1: DSDT, extract and modify the tables

Extract the acpi tables

mkdir acpi && cd acpi
sudo acpidump -b

Disassemble the tables

iasl -d dsdt.dat

Modify or patch the tables

vim dsdt.dsl

Assemble the custom tables

iasl -sa dsdt.dsl

Generate the cpio file for initrd

cd ..
mkdir -p kernel/firmware/acpi
cp acpi/dsdt.aml kernel/firmware/acpi/
find kernel | cpio -H newc --create > patched_acpi_tables.cpio

Grub does not require a cpio file, you can directly provide the dsl file.

Option 2: SSDT, create the tables

SSDT tables add missing features to the existing ACPI, without requiring disassembling. They are created using the same tools and procedure.

Assemble the custom tables

iasl -sa ssdt.dsl

Generate the cpio file for initrd

cd ..
mkdir -p kernel/firmware/acpi
cp acpi/ssdt.aml kernel/firmware/acpi/
find kernel | cpio -H newc --create > patched_acpi_tables.cpio

Install the tables (systemd-boot)

Copy the cpio file with the custom tables where it can be addressed by the EFI boot

sudo mkdir /boot/efi/EFI/acpi
sudo cp patched_acpi_tables.cpio /boot/efi/EFI/acpi/

Edit the entry sudo vim /boot/efi/loader/entries/Pop_OS-current.conf

linux /EFI/...
initrd /EFI/acpi/patched_acpi_tables.cpio
initrd /EFI/Pop_OS-.../initrd.img
options ...
@fermino
Copy link

fermino commented Apr 4, 2023

To use it with grub, it is enough to copy acpi/dsdtl.aml to /boot/. Then I used a slightly modified version of this script to generate the grub configuration (https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1045690).

$ diff /boot/grub/grub.cfg.old /boot/grub/grub.cfg
88a89,95
> ### BEGIN /etc/grub.d/01_acpi ###
>  insmod part_gpt
>  insmod fat
>  search --no-floppy --fs-uuid --set=root 9FCD-44E3
> acpi ($root)/dsdt.aml
> ### END /etc/grub.d/01_acpi ###
> 

@pizFunk
Copy link

pizFunk commented Apr 6, 2023

@lamperez Thanks for your contribution here. Wondering your thoughts on whether this type of fix would work for my ASUS Zenbook Pro 16X OLED (UX7602ZM) with similar issues.

This output is what leads me to believe my system is using the same hardware as your UX3402:

[    6.135962] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Error: ACPI _DSD Properties are missing for HID CSC3551.
[    6.139570] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: error -EINVAL: Platform not supported
[    6.143034] iwlwifi 0000:00:14.3: api flags index 2 larger than supported by driver
[    6.143611] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.0 failed with error -22
[    6.143625] iwlwifi 0000:00:14.3: TLV_FW_FSEQ_VERSION: FSEQ Version: 0.0.2.36
[    6.144123] iwlwifi 0000:00:14.3: loaded firmware version 72.daa05125.0 so-a0-gf-a0-72.ucode op_mode iwlmvm
[    6.144729] input: USB2.0 FHD UVC WebCam: USB2.0 F as /devices/pci0000:00/0000:00:14.0/usb2/2-9/2-9:1.0/input/input22
[    6.147914] asus_wmi: ASUS WMI generic driver loaded
[    6.149212] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Error: ACPI _DSD Properties are missing for HID CSC3551.
[    6.153703] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: error -EINVAL: Platform not supported
[    6.154381] snd_hda_intel 0000:01:00.1: bound 0000:01:00.0 (ops nv50_audio_component_bind_ops [nouveau])
[    6.158331] cs35l41-hda: probe of spi1-CSC3551:00-cs35l41-hda.1 failed with error -22
[    6.158373] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.

However, when following your steps for modifying my ACPI tables, I find that my dsdt.dsl file doesn't contain any references to "SPK1" as yours must. Thus, I don't know how to proceed since I have never attempted something like this.

I am also aware that the changes to linux/sound/pci/hda/patch_realtek.c now included in the latest kernel versions do not include my model number presumably because this issue has primarily been with regards to the UX/UM3402. Specifically these lines:

SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),

I am thinking that even if I were able to patch my ACPI tables as you've been able to do, the lack of a quirk for my specific model would still require me to patch the kernel myself, which I would like to avoid.

I would appreciate any thoughts/help you might be willing to offer.

@lamperez
Copy link
Author

lamperez commented Apr 7, 2023

@pizFunk The log messages are just the same, so you can try: it requires no lengthy compilations, and just one reboot. In case it does not work, it is very easy to revert everything, just undo the changes in grub or systemd-boot.

The name of the block in the DSDT file is not important, SPK1 is just a variable. The block is the one that begins with Name (_HID, "CSC3551"), that should be present since your kernel is referencing it. Just search for CSC3551 in your disassembled file.

Once there, check that there is a _CRS block with two SpiSerialBusV2 devices, four GPioIo and one GpioInt, and maybe a _STA and a _DIS block (this one is empty). The patch should be inserted after that _DIS block.

Do not forget to increase the number in the DefinitionBlock ("", "DSDT", 2, "_ASUS_", "Notebook", 0x01072009), or similar, at the beginning (so it takes precedence over the original ACPI in the BIOS).

@pizFunk
Copy link

pizFunk commented Apr 7, 2023

@lamperez Thanks so much for your reply! So it turns out I was following slightly different instructions to get the dsdt.dat file and when i followed your instructions here more closely I realized I had 24 SSDT files that got dumped along with my dsdt.dat file. I was able to find the relevant Device (SPK1) block in the ssdt7.dsl file exactly as you described.

I will attempt to make progress from here. :)

Do you think I will still have problems if I get the ACPI modification working, but I won't have the sound quirk for my particular model?

@pizFunk
Copy link

pizFunk commented Apr 7, 2023

Update: After patching and creating cpio archive from just the single ssdt*.dsl -- the numbering of the ssdt files seem to change every acpidump -- file that contained the Device (SPK1) block, I was able to reboot and get this output in the log (no longer missing ACPI properties):

[6.117987] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[6.170875] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[6.182962] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2
[6.182991] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.

However, my sound still doesn't work properly and I'm assuming the extra log lines I'm missing when comparing to yours are due to the missing quirks for my laptop model in linux/sound/pci/hda/patch_realtek.c. Looks like I'll have to figure out how to make that modification after all. Do you have any knowledge as to where I find the values I will need to replace in this line that exists for the UX3402 (I think specifically just the 2nd parameter)?

SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2)

Thanks again!

EDIT: I believe I've figured out the answer to my question -- the parameters come from the SubVendor and SubDevice ids of my machine:

SubVendor: pci 0x1043 "ASUSTeK Computer Inc."
SubDevice: pci 0x1f62 

so the line I'll need to add should be something like:

SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602", ALC245_FIXUP_CS35L41_SPI_2)

@asaromi
Copy link

asaromi commented May 22, 2023

do you use Pop_OS 22.04 or another? @lamperez
I have tried this on Ubuntu 23.04 and openSUSE Tumbleweed but still get nothing. I will try other Linux distro until getting the audio works fine.

@lamperez
Copy link
Author

@asaromi Indeed, Pop_OS! 22.04. I am using a mainline kernel (6.3.3) but the sound also works with the stock one (6.2.x). I played a lot with the kernel modules when trying to make the sound run, but since I found the ACPI thing I use a anilla kernel. Also, the Cirrus Logic firmware files (linux-firmware package). The exact file that is required is

/lib/firmware/cirrus/cs35l41-dsp1-spk-prot-10431e02.wmfw

It is available in both the Pop_OS! and Ubuntu repos, I do not know for other distros.

@asaromiv2
Copy link

Sorry brother, just want to make sure. (I'm using the same device UX3402za but with i5 core)
So, if I use both Ubuntu and Pop_OS, I can execute the following steps (exactly, with nothing changes) anywhere I want, right?

But if that so, why I can't make the speaker work out? I want to try using Pop_OS for the next step.

@lamperez
Copy link
Author

I do not know. Always check the system log, for example journalctl -b -g CSC3551. If some lines on the top contain

cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Error: ACPI _DSD Properties are missing for HID CSC3551.

or something similar (twice, one for each amplifier) don't bother to try another distro: the problem is the ACPI, not the OS. Try to patch it, see the SSDT patch here.

@Moooebie
Copy link

Moooebie commented May 27, 2023

Update: After patching and creating cpio archive from just the single ssdt*.dsl -- the numbering of the ssdt files seem to change every acpidump -- file that contained the Device (SPK1) block, I was able to reboot and get this output in the log (no longer missing ACPI properties):

[6.117987] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Reset line busy, assuming shared reset
[6.170875] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[6.182962] cs35l41-hda spi1-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2
[6.182991] Serial bus multi instantiate pseudo device driver CSC3551:00: Instantiated 2 SPI devices.

However, my sound still doesn't work properly and I'm assuming the extra log lines I'm missing when comparing to yours are due to the missing quirks for my laptop model in linux/sound/pci/hda/patch_realtek.c. Looks like I'll have to figure out how to make that modification after all. Do you have any knowledge as to where I find the values I will need to replace in this line that exists for the UX3402 (I think specifically just the 2nd parameter)?

SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2)

Thanks again!

EDIT: I believe I've figured out the answer to my question -- the parameters come from the SubVendor and SubDevice ids of my machine:

SubVendor: pci 0x1043 "ASUSTeK Computer Inc."
SubDevice: pci 0x1f62 

so the line I'll need to add should be something like:

SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602", ALC245_FIXUP_CS35L41_SPI_2)

Hello. Sorry for bothering, I am having the same issue (reset line busy...), just wondering how did you find the SubVendor and SubDevice information of the device?

EDIT: found using alsa-info.sh

@sieskei
Copy link

sieskei commented Jun 5, 2023

@lamperez, thank you!
It works great this way!
Do you have any idea how to automate it so when GRUB create new entries (install new kernel), it automatically adds cpio.
Thank you in advance!

@lamperez
Copy link
Author

lamperez commented Jun 5, 2023

Sorry, I do not know. I use grub in other machines, but not in the Zenbook. I suppose that it will be something in /etc/grub.d, but I cannot tell for sure.

@fermino
Copy link

fermino commented Jun 5, 2023

@sieskei maybe this could serve as a basis, it's for an .aml file but it should be easy to modify!
https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1045690

@Moooebie
Copy link

Moooebie commented Jun 5, 2023

@sieskei

Find your distro's grub config script in /ect/grub.d, I use Manjaro and the script related to adding boot options was 10_linux. There I found a series of complex process to detect kernels and add relevant boot options.
A block of code there was

  initrd=
  if test -n "${initrd_early}" || test -n "${initrd_real}"; then
    initrd="${initrd_early} ${initrd_real}"

    initrd_display=
    for i in ${initrd}; do
      initrd_display="${initrd_display} ${dirname}/${i}"
    done
    gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
  fi

My poor understanding to shell scripting is enough to recognize that part is responsible for adding the initrd command. Since it first only adds the file name and later adds the /boot/ prefix, I changed the third line to:

initrd="${initrd_early} patched_dsdt.cpio ${initrd_real}"

So after running grub update command it correctly added the /boot/patched_dsdt.cpio between the Intel ucode and kernel initrd images.

This is likely not a great solution, though. The better way is to write your own script there to parch the options, and give it a larger prefix so it runs after the original boot options adding scripts.

@sieskei
Copy link

sieskei commented Jun 7, 2023

Hello @fermino, @Moooebie
thank you for your assistance.

In the end, I managed to do it very easily by edit /etc/default/grub.
I added GRUB_EARLY_INITRD_LINUX_CUSTOM = "patched_acpi_tables.cpio" and move file to /boot.

@Elysion-tcfa
Copy link

Elysion-tcfa commented Aug 30, 2023

To use it with grub, it is enough to copy acpi/dsdtl.aml to /boot/. Then I used a slightly modified version of this script to generate the grub configuration (https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1045690).

$ diff /boot/grub/grub.cfg.old /boot/grub/grub.cfg
88a89,95
> ### BEGIN /etc/grub.d/01_acpi ###
>  insmod part_gpt
>  insmod fat
>  search --no-floppy --fs-uuid --set=root 9FCD-44E3
> acpi ($root)/dsdt.aml
> ### END /etc/grub.d/01_acpi ###
> 

@fermino I have the same CSC3551 issue coming with my ASUS ROG Zephyrus G14 GA402XV as this one, and your way of applying a SSDT patch did make Linux correctly detect the woofer speakers. Unfortunately, after that, due to some unknown reason, the laptop started becoming hot and noisy even when idling. The battery started to drain very quickly after being unplugged, and battery life dropped from ~10hrs to 2-3hrs. Even when the laptop was under sleep the battery continued draining.

After some attempts it looks like this way of patching is indeed the culprit. The correct way instead is to copy the cpio file to /boot and add this file in the initrd line, such like this:
initrd /patched_acpi_tables.cpio /initramfs-linux.img
Now the battery life goes back to normal while the woofer speakers are still detected and working.

@pizFunk
Copy link

pizFunk commented Oct 28, 2023

Anyone having done this patch notice that when the system volume is low the sound is more bass than treble and the reverse when the volume is high? Somewhere around 75% sounds pretty good. Wondering if it's just an issue on my end.

@mrnossiom
Copy link

Let's go. My sound works perfectly.
For NixOS people, I made a module that is very easy to integrate into your NixOS configuration :
https://github.com/mrnossiom/dotfiles/blob/nixos/modules/nixos/asus-zenbook-ux3402za-sound.nix

@Ben9986
Copy link

Ben9986 commented May 5, 2024

Let's go. My sound works perfectly. For NixOS people, I made a module that is very easy to integrate into your NixOS configuration : https://github.com/mrnossiom/dotfiles/blob/nixos/modules/nixos/asus-zenbook-ux3402za-sound.nix

THANK YOU! I couldn't figure out how to nixify the instructions to work with systemd-boot, but your config just worked!

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