[PATCH 3/8] ASoC: aw88399: add per-instance BSTS status bypass flag
From: Marco Giunta
Date: Fri Jul 17 2026 - 09:30:25 EST
Add a bsts_unreliable flag to struct aw88399 that, when set, causes
the startup status check (aw_dev_check_sysst) to skip the BSTS
(boost startup finished) requirement.
On some hardware, the BSTS bit in the SYSST register (0x01, bit 9)
does not reliably assert even during normal audio playback. Register
inspection on affected Lenovo Legion hardware shows both amplifiers
reporting BSTS=0 on both channels despite clean audio output.
Per the AW88399 datasheet, BSTS indicates boost startup completion.
If BSTS never reliably sets to 1, the chip is never allowed to start
by aw_dev_check_sysst, regardless of whether the boot failure is genuine.
The new flag defaults to false via kzalloc, preserving the original check
behavior for all existing users. No existing code path sets this flag;
it will be set by the forthcoming HDA side codec property driver for
affected hardware.
Tested-by: Nadim Kobeissi <nadim@symbolic.software>
Tested-by: Xia Yun'an <imitoy@xxxxxxxxxx>
Tested-by: Munzir Taha <munzirtaha@xxxxxxxxx>
Signed-off-by: Marco Giunta <marco_giunta@xxxxxxxxxx>
---
include/sound/aw88399.h | 1 +
sound/soc/codecs/aw88399-lib.c | 13 +++++++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/include/sound/aw88399.h b/include/sound/aw88399.h
index 3a2153f0ee92..dee91b540b81 100644
--- a/include/sound/aw88399.h
+++ b/include/sound/aw88399.h
@@ -598,6 +598,7 @@ struct aw88399 {
unsigned int crc_init_val;
unsigned int vcalb_init_val;
unsigned int dither_st;
+ bool bsts_unreliable;
};
int aw_dev_check_syspll(struct aw_device *aw_dev);
diff --git a/sound/soc/codecs/aw88399-lib.c b/sound/soc/codecs/aw88399-lib.c
index b525695c96d1..2045c4171be0 100644
--- a/sound/soc/codecs/aw88399-lib.c
+++ b/sound/soc/codecs/aw88399-lib.c
@@ -167,8 +167,9 @@ int aw_dev_check_syspll(struct aw_device *aw_dev)
}
EXPORT_SYMBOL_GPL(aw_dev_check_syspll);
-static int aw_dev_check_sysst(struct aw_device *aw_dev)
+static int aw_dev_check_sysst(struct aw88399 *aw88399)
{
+ struct aw_device *aw_dev = aw88399->aw_pa;
unsigned int check_val;
unsigned int reg_val;
int ret, i;
@@ -182,6 +183,14 @@ static int aw_dev_check_sysst(struct aw_device *aw_dev)
else
check_val = AW88399_BIT_SYSST_SWS_CHECK;
+ /*
+ * On some hardware the BSTS (boost-finished) status bit does not
+ * reliably assert even when audio output is working normally.
+ * Allow per-instance bypass when flagged by the side-codec driver.
+ */
+ if (aw88399->bsts_unreliable)
+ check_val &= ~AW88399_BSTS_FINISHED_VALUE;
+
for (i = 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) {
ret = regmap_read(aw_dev->regmap, AW88399_SYSST_REG, ®_val);
if (ret)
@@ -710,7 +719,7 @@ static int aw88399_dev_start(struct aw88399 *aw88399)
usleep_range(AW88399_1000_US, AW88399_1000_US + 50);
/* check i2s status */
- ret = aw_dev_check_sysst(aw_dev);
+ ret = aw_dev_check_sysst(aw88399);
if (ret) {
dev_err(aw_dev->dev, "sysst check failed");
goto sysst_check_fail;
--
2.55.0