Re: cs35l41-hda: PUP_DONE times out on ASUS UX3405CA (SSID 10431A63)
Luqman H <[email protected]>
| Newsgroups | gmane.linux.alsa.devel |
|---|---|
| Message-ID | <CA+Mr_5Udw+Q0aSVJpi=0r3x_g=KizPCkTc6WdfUL9hUUi0hyjA@mail.gmail.com> |
Subject: Re: cs35l41-hda: PUP_DONE times out on ASUS UX3405CA (SSID 10431A63) Please disregard this report - it is resolved by an ASUS BIOS update, and my diagnosis pointed in the wrong direction. Updating from BIOS UX3405CA.314 (2025-11-20) to UX3405CA.315 (2026-01-21) fixed it completely. The internal speakers work normally, and there have been zero PUP_DONE timeouts since, including across a suspend/resume cycle - which previously always resulted in the amps failing again: cs35l41-hda ...hda.0: Asserting Reset cs35l41-hda ...hda.0: Calibration applied: R0=10390 cs35l41-hda ...hda.1: Calibration applied: R0=10440 cs35l41-hda ...hda.0: Firmware Loaded - Type: spk-prot, Gain: 19 cs35l41-hda ...hda.1: Firmware Loaded - Type: spk-prot, Gain: 19 Two corrections to my original mail: 1. I stated that UX3405CA.314 was the latest BIOS available from ASUS. That was wrong - .315 existed and is what fixes this. Apologies for the misleading information. 2. I suggested raising the 100 ms PUP_DONE bound in cs35l41_global_enable(). Please do not act on that on my account. The cause was platform firmware, not the kernel timeout, and patching the timeout would have papered over an ASUS ACPI/firmware bug rather than fixing it. The observation that PUP_DONE was asserting after the timeout still stands as a description of what the old BIOS did, but it was a symptom, not the bug. For anyone else hitting this on a UX3405CA: update the BIOS to .315 or later before investigating anything on the kernel side. Sorry for the noise, and thanks for your time. Luqman On Wed, Aug 5, 2026 at 1:11 PM [email protected] <[email protected]> wrote: > Hi, > > Both CS35L41 amps driving the internal speakers on an ASUS Zenbook 14 > UX3405CA fail every power-up with: > > cs35l41-hda spi0-CSC3551:00-cs35l41-hda.0: Failed waiting for > CS35L41_PUP_DONE_MASK: -110 > cs35l41-hda spi0-CSC3551:00-cs35l41-hda.1: Failed waiting for > CS35L41_PUP_DONE_MASK: -110 > > The internal speakers are completely silent. HDMI and Bluetooth are > unaffected. > > Reading the amp registers during a failing playback shows that PUP_DONE > *does* eventually assert - the amps are not faulting, they are just > slower to bring up external boost than the 100 ms the driver allows. > Details and evidence below. > > > ROOT CAUSE EVIDENCE > =================== > > Registers captured during a failing playback. Playback started, the > PUP_DONE timeout was logged at 11:15:26, registers were read at > 11:15:28: > > Register amp .0 (L) amp .1 (R) > -------------------- ----------- ----------- > PWR_CTRL1 00000001 00000001 > IRQ1_STATUS1 01400001 01400000 > IRQ1_RAW_STATUS1 41406001 40406000 > IRQ1_MASK1 7ffd7e3f 7ffd7e3f > GPIO_STATUS1 00000001 00000000 > GPIO_PAD_CONTROL 02010000 02000000 > AMP_GAIN_CTRL 00000273 00000273 > AMP_ERR_VOL 00000000 00000000 > VPBR_STATUS 00000000 00000000 > VBBR_STATUS 00000000 00000000 > PROTECT_REL_ERR_IGN 00000000 00000000 > > IRQ1_STATUS1 has bit 24 set on both amps, and CS35L41_PUP_DONE_MASK is > 0x01000000 - bit 24. Power-up completed. > > That can only be a late assertion. In the CS35L41_EXT_BOOST branch of > cs35l41_global_enable() the failure path returns without clearing the > status; only the success path clears it: > > ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, > int_status, > int_status & CS35L41_PUP_DONE_MASK, > 1000, 100000); > if (ret) { > dev_err(dev, "Failed waiting for CS35L41_PUP_DONE_MASK: > %d\n", ret); > cs35l41_test_key_lock(dev, regmap); > return ret; /* <-- status not cleared */ > } > regmap_write(regmap, CS35L41_IRQ1_STATUS1, CS35L41_PUP_DONE_MASK); > > Every attempt on this machine takes the failure path, so nothing ever > clears bit 24. The only way it can be set is for the amp to have > asserted PUP_DONE some time after the 100 ms poll expired. > > No fault bit is set - not bit 6 (BST_OVP_ERR), 7 (BST_DCM_UVP_ERR), 8 > (BST_SHORT_ERR), 15 (TEMP_WARN), 17 (TEMP_ERR) or 31 (AMP_SHORT_ERR). > PWR_CTRL1 = 1 confirms GLOBAL_EN is set, and GPIO_STATUS1 = 1 on amp .0 > confirms the VSPK switch is actually being driven. > > I should be clear that this is an inference from the code path that > never clears the bit, not a direct observation of the bit changing. I > could not time the assertion: because the failure path never clears it, > it cannot be re-armed without rebooting for a clean baseline. > > > NO FAULT INTERRUPT HAS EVER FIRED > ================================= > > Consistent with the above, the amps have never raised an interrupt. > Setup is correct on both sides: all 12 handlers (6 per amp) are > registered, cs35l41_configure_interrupt() does not emit its "IRQ Config > Failed" warning, and IRQ1_MASK1 = 0x7ffd7e3f leaves all six fault > interrupts unmasked at the chip. The parent GPIO interrupt is > level-triggered on hwirq 207. > > Yet every counter is zero after hours of uptime: > > 177: 0 ... 0 intel-gpio 207 cs35l41 IRQ1 Controller, cs35l41 IRQ1 > Controller > 197: 0 ... 0 cs35l41 IRQ1 Controller 0 Boost Overvoltage Error > 198: 0 ... 0 cs35l41 IRQ1 Controller 1 Boost Undervoltage Error > 199: 0 ... 0 cs35l41 IRQ1 Controller 2 Boost Inductor Short > Error > 200: 0 ... 0 cs35l41 IRQ1 Controller 3 Temperature Warning > 201: 0 ... 0 cs35l41 IRQ1 Controller 4 Temperature Error > 202: 0 ... 0 cs35l41 IRQ1 Controller 5 Amp Short > (identical block for the second amp, 203-208) > > I initially read this as a misrouted interrupt line. I no longer think > so - the register evidence says the part simply does not consider > itself > faulted, so there is nothing for it to report. > > > HARDWARE > ======== > > Machine: ASUS Zenbook 14 UX3405CA (DMI board UX3405CA) > BIOS: UX3405CA.314, 11/20/2025 (latest from ASUS) > SoC: Intel Core Ultra 200H > HDA codec: Realtek ALC294 > Amps: 2x Cirrus Logic CS35L41 (35a40) Revision B2, on SPI > SSID: 10431A63 > ALSA components: HDA:8086281d,80860101,00100000 > HDA:10ec0294,10431a63,00100004 > cfg-dmics:2 iec61937-pcm:5,4,3 > > > SOFTWARE > ======== > > Distribution: Fedora 44 > Kernel: 7.1.5-201.fc44.x86_64 > linux-firmware: 20260622-1.fc44 > alsa-lib: 1.2.16.1 > PipeWire: 1.6.8 / WirePlumber 0.5.14 > Driver stack: snd_soc_skl_hda_dsp (SOF) + cs35l41-hda over SPI > > Earlier 7.1.x kernels showed a milder symptom (see HISTORY); I cannot > confirm whether the PUP_DONE error was present there. > > > REPRODUCES ON A CLEAN COLD BOOT > =============================== > > Firmware loads correctly and both amps bind, then power-up fails two > seconds later: > > 10:48:46 ...hda.0: Calibration applied: R0=10390 > 10:48:46 ...hda.0: Firmware Loaded - Type: spk-prot, Gain: 19 > 10:48:46 ...hda.0: CS35L41 Bound - SSID: 10431A63, BST: 1, VSPK: 1, > CH: L, FW EN: 1, SPKID: 1 > 10:48:46 ...hda.1: Calibration applied: R0=10440 > 10:48:46 ...hda.1: Firmware Loaded - Type: spk-prot, Gain: 19 > 10:48:46 ...hda.1: CS35L41 Bound - SSID: 10431A63, BST: 1, VSPK: 0, > CH: R, FW EN: 1, SPKID: 1 > 10:48:47 ...hda.0: Failed waiting for CS35L41_PUP_DONE_MASK: -110 > 10:48:47 ...hda.1: Failed waiting for CS35L41_PUP_DONE_MASK: -110 > > Fully reproducible and permanent from boot. On an earlier boot the > first > failure came 11 s after boot and the only suspend/resume cycle happened > four hours later, so suspend is not the trigger. > > > BEHAVIOUR WITH THE DSP FIRMWARE ABSENT > ====================================== > > At one point the amps ended up running with no DSP firmware (see the > secondary bug below). In that state the behaviour changed > informatively: > > - PUP_DONE no longer timed out at all, across ~20 minutes of repeated > playback. > - The speakers did produce sound, for roughly the first 4 seconds. > - After that they went silent and stayed silent, with playback still > running and no kernel message of any kind. > - Reproduced deliberately with six 2-second pink-noise bursts, 1 s > apart, at 100% volume: only the first two were audible. > > "Forced Mute Status" was polled every 2 s across a 20 s playback and > stayed off on both amps. > > > PLATFORM _DSD IS COMPLETE AND CORRECTLY APPLIED > =============================================== > > I dumped and decompiled the platform ACPI to check whether the _DSD was > at fault. It is not. Device (SPK1) in SSDT17 declares: > > Name (_HID, "CSC3551") > Name (_SUB, "10431A63") > > Name (_DSD, Package (0x02) > { > ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), > Package (0x06) > { > Package (0x02) { "cirrus,dev-index", Package (0x02) > { Zero, One } }, > Package (0x02) { "reset-gpios", Package (0x08) > { ^SPK1, , One, Zero, Zero, > > ^SPK1, , One, Zero, Zero } }, > Package (0x02) { "cirrus,speaker-position", Package (0x02) > { Zero, One } }, > Package (0x02) { "cirrus,boost-type", Package (0x02) > { One, One } }, > Package (0x02) { "cirrus,gpio1-func", Package (0x02) > { One, Zero } }, > Package (0x02) { "cirrus,gpio2-func", Package (0x02) > { 0x02, 0x02 } } > } > }) > > Every value matches the driver's bind messages and the chip registers: > > Property Value Meaning > Confirmed by > ----------------------- ------- ------------------------------- -- > -------------------- > cirrus,boost-type {1, 1} CS35L41_EXT_BOOST > BST: 1 in bind log > cirrus,gpio1-func {1, 0} CS35L41_GPIO1_GPIO / HIZ > VSPK: 1 / VSPK: 0 > cirrus,gpio2-func {2, 2} CS35L41_GPIO2_INT_OPEN_DRAIN > IRQ registered, level > cirrus,speaker-position {0, 1} Left / Right > CH: L / CH: R > reset-gpios idx 1 shared reset > "Reset line busy..." > > GPIO_PAD_CONTROL reads 0x02010000 on amp .0 (GP2 = 2, GP1 = 1) and > 0x02000000 on amp .1 (GP2 = 2, GP1 = 0), exactly as declared. > > So unlike 103C89C6 and 103C8B63 - where cs35l41_hda_property.c carries > comments about ACPI declaring the wrong boost type - there is no > evident > mis-declaration here to override. > > > NOTE ON THE DRIVER PROPERTY TABLE > ================================= > > In sound/hda/codecs/side-codecs/cs35l41_hda_property.c (formerly > sound/pci/hda/), the entry is: > > { "CSC3551", "10431A63", missing_speaker_id_gpio2 }, > > identical in v7.0, v7.1 and master. Of the 40 ASUS 1043* SSIDs in that > file, 10431A63 is the only one not handled by generic_dsd_config, and > the only one with no cs35l41_config_table entry. > > There is no cirrus,speaker-id-gpios in the platform _DSD, which is > presumably why the quirk exists - it supplies one from GPIO resource > index 2. Decoding the raw _CRS gives five GPIO resources: > > idx 0 GpioIo pin 72 > idx 1 GpioIo pin 208 reset line referenced by reset-gpios > idx 2 GpioIo pin 206 claimed by the quirk as speaker-id > idx 3 GpioIo pin 207 > idx 4 GpioInt pin 207 level-triggered; matches intel-gpio 207 > > Pin 207 appears twice, as a GpioIo at index 3 and as the GpioInt at > index 4. I cannot verify from here whether index 2 is the correct > speaker-id resource on the CA variant; given the quirk appears to have > been authored for the closely related UX3405MA, that may be worth > confirming. > > Also worth noting: "Using extra _DSD properties, bypassing _DSD in > ACPI" > is printed whenever cs35l41_add_dsd_properties() succeeds, but on the > missing_speaker_id_gpio2 path the platform _DSD is still parsed by > cs35l41_hda_parse_acpi(). The message overstates what happened and > initially misled my own diagnosis. > > > HISTORY > ======= > > This machine previously showed a milder form of the same problem: > playback cut out for a fraction of a second roughly every 1 s, and a > reboot restored clean audio for a while. No kernel error was logged at > all then. If the cause is a marginal boost ramp against a fixed 100 ms > bound, that earlier intermittent behaviour fits: sometimes boost made > the deadline, sometimes not. It has since degraded to failing every > time. > > > RULED OUT > ========= > > None of these changed the behaviour: > > - CPU governor (powersave -> performance) > - snd_hda_intel power_save = 0 > - PipeWire quantum locked to 1024/2048 > - WirePlumber node suspension disabled > - PipeWire RT scheduling (verified: SCHED_RR prio 60 via rtkit) > - SMI storms (0 per turbostat) > - Scheduler latency (no gaps > 30 ms over 15 s) > - CS35L41 runtime PM (forced power/control=on on both SPI devices) > - BIOS and linux-firmware both at latest available versions > > Mixer state during failure is correct throughout: ALSA Master 100% on, > Speaker 90% on, SOF Pre/Post Mixer Analog 100% at 0.00 dB, PipeWire > sink > routed to Speaker and unmuted. > > > SUGGESTED DIRECTION > =================== > > The 100 ms bound in cs35l41_global_enable() looks too short for this > platform's external boost. A longer timeout, or a per-platform bound, > would likely fix this machine. > > If you can supply a debug patch that timestamps the assertion - or > simply raises the timeout so I can report whether audio returns - I am > glad to build and test it. I can also read back further registers or > provide any other debug output on request. > > > SECONDARY BUG: FIRMWARE LOOKUP FAILS AFTER A PCI REBIND > ======================================================= > > Probably unrelated, but found along the way. Unbinding and rebinding > the > audio controller: > > echo 0000:00:1f.3 > /sys/bus/pci/drivers/sof-audio-pci-intel- > mtl/unbind > echo 0000:00:1f.3 > /sys/bus/pci/drivers/sof-audio-pci-intel-mtl/bind > > rebuilds the sound card successfully, but the amps then cannot find > their firmware: > > cs35l41-hda ...hda.0: Falling back to default firmware. > cs35l41-hda ...hda.0: Unable to find firmware and tuning > cs35l41-hda ...hda.0: Cannot Initialize Firmware. Error: -2 > > With firmware_loader dynamic debug enabled, the requested names are: > > fw-cirrus/cs35l41--spk-prot-10431a63-spkid1-r0.wmfw > fw-cirrus/cs35l41--spk-prot-10431a63-r0.wmfw > fw-cirrus/cs35l41--spk-prot-10431a63-spkid1.wmfw > fw-cirrus/cs35l41--spk-prot-10431a63.wmfw > fw-cirrus/cs35l41--spk-prot.wmfw > > Note the doubled hyphen. SSID (10431a63), speaker id (spkid1) and amp > name (r0) are all still correct - what is missing is dsp_name, i.e. > cs35l41->cs_dsp.name, which should be dsp1. It is empty after the > rebind, so cs35l41_request_firmware_file() builds cs35l41--spk-prot-... > instead of cs35l41-dsp1-spk-prot-..., and every candidate misses, > including the generic fallback (cirrus/cs35l41-dsp1-spk-prot.wmfw.xz is > present on disk). > > A runtime reload via the "L0/R0 DSP1 Firmware Load" ALSA controls fails > the same way, so the amps cannot recover their firmware without a > reboot. > > Separately, unbinding the HDA codec alone: > > echo ehdaudio0D0 > > /sys/bus/hdaudio/drivers/snd_hda_codec_alc269/unbind > > tears down the entire SOF card, and the subsequent bind fails with > "No such device". > > > Happy to provide the full regmap dumps, the decompiled SSDT, or > anything > else useful. > > Thanks, > Luqman > -- Luqman ~ Sent from the web