Linux Sound subsystem development
 help / color / mirror / Atom feed
* [PATCH] ALSA: hda/tas2781: clear cali_data.total_sz when calibration read fails
@ 2026-07-20  9:41 Philipp Oster via B4 Relay
  2026-07-20 18:49 ` Takashi Iwai
  0 siblings, 1 reply; 2+ messages in thread
From: Philipp Oster via B4 Relay @ 2026-07-20  9:41 UTC (permalink / raw)
  To: Shenghao Ding, Kevin Lu, Baojun Xu, Jaroslav Kysela, Takashi Iwai
  Cc: linux-sound, linux-kernel, Gergo Koteles, Philipp Oster

From: Philipp Oster <philippdev5396@outlook.de>

tas2563_save_calibration() assigns cali_data.total_sz before it reads the
per-device calibration data from EFI, but its error paths return without
clearing it again. cali_data.cali_reg_array is left all zero, because the
function returns before the register addresses are assigned.

On the first playback tasdev_load_calibrated_data() does

	if (!data || !cali_data->total_sz)
		return;

which passes, since total_sz is still non-zero. It then issues five
4-byte bulk writes to p->r0_reg, p->r0_low_reg, p->invr0_reg, p->pow_reg
and p->tlimit_reg, all of which are 0. Register 0 decodes to book 0 /
page 0 / register 0x00, so the auto-incrementing block write zeroes
registers 0x00 to 0x03. Register 0x03 is PB_CFG1, which holds AMP_LEVEL,
so the amplifier gain is set to its minimum and the speaker stays silent.

This is reproducible on a Lenovo Yoga 7 14ARB7 (two TAS2563 on I2C,
ACPI INT8866) whose factory calibration was never written to UEFI, so the
EFI read fails with EFI_NOT_FOUND. The two woofers driven by the
amplifiers are silent while the tweeters driven directly by the ALC287
play. Reading the amplifier registers over i2c shows PWR_CTL = 0x00
(active) and the TDM slots correctly programmed by the RCA profile, but
PB_CFG1 = 0x00. With this change PB_CFG1 keeps its power-on default of
0x20 and both woofers play.

tas2781_save_calibration() in tas2781_hda.c already clears total_sz on
failure; do the same for the TAS2563 variant.

Signed-off-by: Philipp Oster <philippdev5396@outlook.de>
---
Single patch - see the commit message for the full analysis and the
register-level evidence from the affected machine.
---
 sound/hda/codecs/side-codecs/tas2781_hda_i2c.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
index 67240ce18..b1c89cc35 100644
--- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
+++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
@@ -355,6 +355,7 @@ static int tas2563_save_calibration(struct tas2781_hda *h)
 			if (ret < 0 || ret >= sizeof(var8) - 1) {
 				dev_err(p->dev, "%s: Read %s failed\n",
 					__func__, var8);
+				cd->total_sz = 0;
 				return -EINVAL;
 			}
 			/*
@@ -372,6 +373,7 @@ static int tas2563_save_calibration(struct tas2781_hda *h)
 				dev_warn(p->dev,
 					"Dev %d: Caldat[%d] read failed %ld\n",
 					i, j, status);
+				cd->total_sz = 0;
 				return -EINVAL;
 			}
 			bedata = cpu_to_be32(*(uint32_t *)&data[offset]);
@@ -383,6 +385,7 @@ static int tas2563_save_calibration(struct tas2781_hda *h)
 	if (cd->total_sz != offset) {
 		dev_err(p->dev, "%s: tot_size(%lu) and offset(%u) mismatch\n",
 			__func__, cd->total_sz, offset);
+		cd->total_sz = 0;
 		return -EINVAL;
 	}
 

---
base-commit: 199c9959d3a9b53f346c221757fc7ac507fbac50
change-id: 20260720-tas2781-calfix-3a1d661ef44b

Best regards,
-- 
Philipp Oster <philippdev5396@outlook.de>



^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-20 18:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20  9:41 [PATCH] ALSA: hda/tas2781: clear cali_data.total_sz when calibration read fails Philipp Oster via B4 Relay
2026-07-20 18:49 ` Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox