[PATCH v1] ALSA: hda/tas2781: Fix device-0 reset issue and handle -EXDEV in block data processing

From: Baojun Xu

Date: Tue Jun 09 2026 - 07:04:17 EST


Fix reset for device-0:‌ In older projects (e.g., Merino), the hardware
reset pin for the first SPI device (device-0) is ineffective, causing
initialization failures. Added a software reset sequence for device-0
to ensure proper initialization.

‌Handle -EXDEV correctly:‌ When processing block data, if the data does
not belong to the current SPI device, the driver returned -EXDEV.
This error code is now ignored to allow the driver to continue iterating
through the block data and correctly calculate the total block size.

Signed-off-by: Baojun Xu <baojun.xu@xxxxxx>
---
sound/hda/codecs/side-codecs/tas2781_hda_spi.c | 16 ++++++++--------
sound/soc/codecs/tas2781-fmwlib.c | 7 ++++---
2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_spi.c b/sound/hda/codecs/side-codecs/tas2781_hda_spi.c
index 0efc476abe8e..3978d58ad020 100644
--- a/sound/hda/codecs/side-codecs/tas2781_hda_spi.c
+++ b/sound/hda/codecs/side-codecs/tas2781_hda_spi.c
@@ -190,15 +190,15 @@ static void tas2781_spi_reset(struct tasdevice_priv *tas_dev)
gpiod_set_value_cansleep(tas_dev->reset, 0);
fsleep(800);
gpiod_set_value_cansleep(tas_dev->reset, 1);
- } else {
- ret = tasdevice_dev_write(tas_dev, tas_dev->index,
- TASDEVICE_REG_SWRESET, TASDEVICE_REG_SWRESET_RESET);
- if (ret < 0) {
- dev_err(tas_dev->dev, "dev sw-reset fail, %d\n", ret);
- return;
- }
- fsleep(1000);
}
+
+ ret = tasdevice_dev_write(tas_dev, tas_dev->index,
+ TASDEVICE_REG_SWRESET, TASDEVICE_REG_SWRESET_RESET);
+ if (ret < 0) {
+ dev_err(tas_dev->dev, "dev sw-reset fail, %d\n", ret);
+ return;
+ }
+ fsleep(1000);
}

static int tascodec_spi_init(struct tasdevice_priv *tas_priv,
diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c
index 885e0b6fed00..bd16d5326a23 100644
--- a/sound/soc/codecs/tas2781-fmwlib.c
+++ b/sound/soc/codecs/tas2781-fmwlib.c
@@ -921,7 +921,8 @@ static int tasdevice_process_block(void *context, unsigned char *data,
data[subblk_offset + 1],
data[subblk_offset + 2]),
data[subblk_offset + 3]);
- if (rc < 0) {
+ if (rc < 0 &&
+ !(tas_priv->isspi && rc == -EXDEV)) {
is_err = true;
dev_err(tas_priv->dev,
"process_block: single write error\n");
@@ -953,7 +954,7 @@ static int tasdevice_process_block(void *context, unsigned char *data,
data[subblk_offset + 1],
data[subblk_offset + 2]),
&(data[subblk_offset + 4]), len);
- if (rc < 0) {
+ if (rc < 0 && !(tas_priv->isspi && rc == -EXDEV)) {
is_err = true;
dev_err(tas_priv->dev,
"%s: bulk_write error = %d\n",
@@ -991,7 +992,7 @@ static int tasdevice_process_block(void *context, unsigned char *data,
data[subblk_offset + 4]),
data[subblk_offset + 1],
data[subblk_offset + 5]);
- if (rc < 0) {
+ if (rc < 0 && !(tas_priv->isspi && rc == -EXDEV)) {
is_err = true;
dev_err(tas_priv->dev,
"%s: update_bits error = %d\n",
--
2.25.1