mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
ALSA: hda/tas2781: clear cali_data.total_sz when calibration read fails
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> Link: https://patch.msgid.link/20260720-tas2781-calfix-v1-1-3a5fa6ad90bc@outlook.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
740b3c6780
commit
b6016332b8
|
|
@ -354,6 +354,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;
|
||||
}
|
||||
/*
|
||||
|
|
@ -371,6 +372,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]);
|
||||
|
|
@ -382,6 +384,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user