On HP laptops (and potentially ASUS) with Intel Lunar Lake processors using dual
Cirrus Logic CS35L56 amplifiers over SPI, only the first amplifier (CS0) works.
The second amplifier (CS1) fails with HALO_STATE=0x0 (firmware boot timeout).
Speakers work correctly in Windows.
Affected bugs:
- https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/2131138
- https://bugzilla.kernel.org/show_bug.cgi?id=221064
- thesofproject/linux#5621
The ACPI DSDT has two bugs that combine to prevent the second amplifier from working:
The SPI controller's _DSD declares:
"cs-gpios", Package (0x01) { Zero }
This only declares CS0 (native). The entry for CS1 is missing entirely. The
ACPI GSPK device does define a GpioIo resource for the CS1 GPIO pin, and
both SpiSerialBusV2 resources correctly specify DeviceSelection 0 and 1, but
the SPI controller doesn't know about the GPIO for CS1.
Even when serial-multi-instantiate correctly acquires the GPIO and calls
spi_set_csgpiod() on the SPI device, the kernel's __spi_add_device() function
unconditionally overwrites spi->cs_gpiod[] from ctlr->cs_gpiods[cs]:
if (ctlr->cs_gpiods) {
for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
cs = spi_get_chipselect(spi, idx);
if (is_valid_cs(cs))
spi_set_csgpiod(spi, idx, ctlr->cs_gpiods[cs]);
}
}Since ctlr->cs_gpiods was allocated with only 1 entry (from the broken
cs-gpios), accessing ctlr->cs_gpiods[1] reads NULL, wiping out the GPIO
descriptor. The SPI framework then never toggles the GPIO chip select, and on
Intel LPSS controllers with dynamic clock gating (cs_clk_stays_gated=true),
the SPI clock doesn't run because no native CS is asserted.
Two patches are required:
Instead of setting the GPIO on the SPI device (which gets overwritten), set it
on the controller's cs_gpiods array. This requires reallocating the array
to accommodate the additional chip select. The SPI_CONTROLLER_GPIO_SS flag is
set so the framework calls both the GPIO toggle and the controller's set_cs
callback.
File: drivers/platform/x86/serial-multi-instantiate.c
On Intel LPSS SPI controllers (Cannon Lake and later) with cs_clk_stays_gated,
the SPI clock is gated when no native CS is asserted. When using GPIO chip
select, the native CS register must still be programmed to "asserted" state, and
the clock gate must be forced on. On deassert, restore both.
File: drivers/spi/spi-pxa2xx.c
- HP EliteBook 8 G1i (HP 8E2C)
- Intel Core Ultra 7 258V (Lunar Lake-M)
- PCI SPI Controller: 8086:a827 (LPSS_CNL_SSP via tgl_spi_info)
- 2x Cirrus Logic CS35L56 Rev B0 OTP3 fw:3.4.4
- ACPI HID: CSC3556
- Kernel: 6.17.0-14-generic (Ubuntu)
Both amplifiers now probe successfully, load calibration data, and produce audio.
@khalilst
Thank you for your hard work. I look forward to this patch flowing into the kernel distribution so my Elitebook 8 G1i will have sound from the speakers.