[PATCH] ASoC: tas2781: Add delay before block checksum retry to prevent deadlock
李则良 <[email protected]>
| Newsgroups | org.kernel.vger.linux-sound,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CANd6bg+B_fZUpy4wwU8HyQMeo9-GKMEx2FPBem=-e4yr4eU1uw@mail.gmail.com> |
From 3ee77f811a91350caa56783b76251cd8218e2263 Mon Sep 17 00:00:00 2001 From: Zeliang Li <[email protected]> Date: Sat, 15 Aug 2026 01:52:57 +0800 Subject: [PATCH] ASoC: tas2781: Add delay before block checksum retry to prevent deadlock During runtime resume from power-saving states, the tas2781 amplifier firmware block calibration checksum verification may occasionally fail due to transient instabilities on the I2C bus or the chip's internal power rails. When tasdev_block_chksum() detects a checksum mismatch, it correctly decrements block->nr_retry and returns -EAGAIN to trigger a re-transmission loop. However, because there is no delay introduced before repeating the loop, all available retry attempts are exhausted almost instantly (within microseconds) before the hardware can fully stabilize. This causes a permanent calibration failure, triggering "ERROR_PRAM_CRCCHK", and results in a silent speaker deadlock after pausing/resuming media on modern laptops. Fix this by adding a 2ms usleep_range() delay before initiating a checksum re-try loop, allowing the hardware sufficient time to stabilize. Signed-off-by: Zeliang Li <[email protected]> --- sound/soc/codecs/tas2781-fmwlib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index dcbeb9618195..09cbee7a55dc 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -1765,9 +1765,16 @@ static int tasdev_block_chksum(struct tasdevice_priv *tas_priv, ret = -EAGAIN; block->nr_retry--; - if (block->nr_retry <= 0) + if (block->nr_retry <= 0) { set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]); + + } else { + /* Give the chip and I2C bus time to stabilize before + * next re-transmission attempt. + */ + usleep_range(2000, 2500); + } } else tas_priv->tasdevice[chn].err_code &= ~ERROR_PRAM_CRCCHK; -- 2.53.0 -- KISS == Keep it simple,stupid~:-) http://lizeliang.org