From d34d249de38aac03df4e1ef443ccab323e48f9f9 Mon Sep 17 00:00:00 2001 From: Kasey Prichard Date: Sat, 29 Aug 2026 17:04:05 -0500 Subject: [PATCH 1/2] ASoC: SDCA: fall back to SmartAmp function type for TI TAS2783 On the HP OmniBook Ultra 14 (board 8EB4, Panther Lake) the four TI TAS2783 SmartAmp peripherals declare the SDCA Function Topology control (0x05) with access mode 0x03 and no mipi-sdca-control-dc-value, so find_sdca_function() rejects them ("function type only supported as DisCo constant"). No SmartAmp function is created, no speaker DAI exists and the internal speakers are silent. The RT712 on link 3 does provide a DC value and is unaffected. The same firmware defect was reported for the HP EliteBook X in thesofproject/linux#5760, where the conclusion was that the BIOS should supply a DC value, and HP fixed that machine with a BIOS update. The newest BIOS for 8EB4 (F.06, 2026-06-25) still ships access mode 0x03 with no DC value for the amplifiers, so machines in the field need a fallback. Keep it minimal: a table of known peripherals (TAS2783, mfg 0x0102 part 0x0000, is always a SmartAmp) rather than reading the control from hardware, so functions can still be parsed before the device is available. Happy to drop this if HP commits to a BIOS fix for 8EB4. Link: https://github.com/thesofproject/linux/issues/5732 Link: https://github.com/thesofproject/linux/issues/5760 Assisted-by: Claude:claude-fable-5 Signed-off-by: Kasey Prichard --- sound/soc/sdca/sdca_functions.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index e01d91eb3cc812..113f6643d2d182 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -87,6 +87,26 @@ static const char *get_sdca_function_name(u32 function_type) } } +/* + * Some platform firmware declares the Function Topology control (0x05) + * with a read-only access mode and no DisCo constant, so the function + * type can only be learned by reading it from the hardware. Fall back to + * a table of known peripherals in that case. + * + * HP OmniBook Ultra 14 (board 8EB4) does this for its four TI TAS2783 + * amplifiers, while its RT712 provides a DC value. + */ +static int sdca_fallback_function_type(struct sdw_slave *slave, u32 *function_type) +{ + /* Texas Instruments TAS2783 smart amplifier */ + if (slave->id.mfg_id == 0x0102 && slave->id.part_id == 0x0000) { + *function_type = SDCA_FUNCTION_TYPE_SMART_AMP; + return 0; + } + + return -ENODEV; +} + static int find_sdca_function(struct acpi_device *adev, void *data) { struct fwnode_handle *function_node = acpi_fwnode_handle(adev); @@ -135,8 +155,11 @@ static int find_sdca_function(struct acpi_device *adev, void *data) fwnode_handle_put(control5); if (ret < 0) { - dev_err(dev, "function type only supported as DisCo constant\n"); - return ret; + if (sdca_fallback_function_type(slave, &function_type)) { + dev_err(dev, "function type only supported as DisCo constant\n"); + return ret; + } + dev_info(dev, "function type not a DisCo constant, using fallback for known peripheral\n"); } if (!sdca_device_quirk_match(slave, SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING)) { From 878e468403e1c66083721e7366ee28b54203e95c Mon Sep 17 00:00:00 2001 From: Kasey Prichard Date: Sat, 29 Aug 2026 17:04:05 -0500 Subject: [PATCH 2/2] soundwire: intel: override ACTMCTL DOAIS/DOAISE2 on HP OmniBook Ultra 14 The HP OmniBook Ultra 14 (board 8EB4, Panther Lake, BIOS F.06) has four TI TAS2783 SmartAmp peripherals, two each on SoundWire links 1 and 2. The static DSDT declares intel-sdw-doais = 1 and intel-sdw-doaise2 = 1 for every link, but SNDW._INI then runs DCFG() on each LNKn package and overwrites those entries from NVS bytes (DAIn, DAXn, ...), and the values the driver actually reads are doais = 3, doaise2 = 0. With that ACTMCTL timing only one of the four amplifiers survives enumeration: the other three attach, answer DEVID reads, then drop off the bus within a few hundred ms and never come back, so there is no speaker output on Linux. Windows drives all four amplifiers on the same firmware. Bisecting the ACTMCTL fields at runtime shows that DOAIS = 1 together with DOAISE2 = 1 is both necessary and sufficient: with that pair all four amplifiers attach, download firmware on the first attempt and stay attached with no parity errors, and all four speakers play. DODS, CLDS and CLDE make no difference. DOAISE2 gates whether DOAIS is honoured, so neither field alone helps. Add a DMI-keyed override for the ACTMCTL fields, applied after the _DSD properties are read, and use it to force DOAIS = 1 / DOAISE2 = 1 on links 1 and 2 of this board. Other links and other boards are untouched. Link: https://github.com/thesofproject/linux/issues/5732 Assisted-by: Claude:claude-fable-5 Signed-off-by: Kasey Prichard --- drivers/soundwire/intel_auxdevice.c | 60 +++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c index 3d1f9ce1eab734..ff2be403354f3f 100644 --- a/drivers/soundwire/intel_auxdevice.c +++ b/drivers/soundwire/intel_auxdevice.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -155,6 +156,62 @@ static void generic_new_peripheral_assigned(struct sdw_bus *bus, sdw->link_res->hw_ops->program_sdi(sdw, dev_num); } +/* + * Board-level overrides for the vendor-specific ACTMCTL timing fields. + * + * The _DSD values are patched in from NVS by the BIOS at _INI time and + * some boards ship values the attached peripherals cannot follow. On the + * HP OmniBook Ultra 14 (board 8EB4, BIOS F.06) the four TAS2783 amplifiers + * on links 1 and 2 only enumerate reliably with DOAIS=1 and DOAISE2=1; + * the BIOS provides DOAIS=3 and DOAISE2=0, with which three of the four + * amplifiers drop off the bus within a few hundred ms of attaching. + */ +struct sdw_intel_actmctl_quirk { + u8 link_mask; + u16 doais; + u16 doaise2; +}; + +static const struct sdw_intel_actmctl_quirk hp_omnibook_ultra_14_actmctl = { + .link_mask = BIT(1) | BIT(2), + .doais = 1, + .doaise2 = 1, +}; + +static const struct dmi_system_id sdw_intel_actmctl_quirk_table[] = { + { + /* HP OmniBook Ultra 14 (kd0xxx), 4x TAS2783 on links 1/2 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_BOARD_NAME, "8EB4"), + }, + .driver_data = (void *)&hp_omnibook_ultra_14_actmctl, + }, + {} +}; + +static void sdw_intel_apply_actmctl_quirk(struct sdw_bus *bus, + struct sdw_intel_prop *intel_prop) +{ + const struct sdw_intel_actmctl_quirk *quirk; + const struct dmi_system_id *id; + + id = dmi_first_match(sdw_intel_actmctl_quirk_table); + if (!id) + return; + + quirk = id->driver_data; + if (!(quirk->link_mask & BIT(bus->link_id))) + return; + + dev_info(bus->dev, "ACTMCTL quirk: doais %#x -> %#x, doaise2 %#x -> %#x\n", + intel_prop->doais, quirk->doais, + intel_prop->doaise2, quirk->doaise2); + + intel_prop->doais = quirk->doais; + intel_prop->doaise2 = quirk->doaise2; +} + static int sdw_master_read_intel_prop(struct sdw_bus *bus) { struct sdw_master_prop *prop = &bus->prop; @@ -238,6 +295,9 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus) fwnode_property_read_u16(link, "intel-sdw-dods", &intel_prop->dods); + + sdw_intel_apply_actmctl_quirk(bus, intel_prop); + bus->vendor_specific_prop = intel_prop; dev_dbg(bus->dev, "doaise %#x doais %#x dodse %#x dods %#x\n",