From: Niranjan H Y <niranjan.hy@ti.com>
To: <alsa-devel@alsa-project.org>
Cc: <linux-sound@vger.kernel.org>, <lgirdwood@gmail.com>,
<broonie@kernel.org>, <ckeepax@opensource.cirrus.com>,
<yung-chuan.liao@linux.intel.com>,
<ranjani.sridharan@linux.intel.com>, <perex@perex.cz>,
<tiwai@suse.com>, <cezary.rojewski@intel.com>,
<peter.ujfalusi@linux.intel.com>, <kai.vehmanen@linux.intel.com>,
<pierre-louis.bossart@linux.dev>, <navada@ti.com>,
<shenghao-ding@ti.com>, <v-hampiholi@ti.com>, <baojun.xu@ti.com>,
<dan.carpenter@linaro.org>, Niranjan H Y <niranjan.hy@ti.com>
Subject: [PATCH v1 2/8] ASoC: tas2783A: use custom firmware
Date: Thu, 20 Nov 2025 14:50:44 +0530 [thread overview]
Message-ID: <20251120092050.1218-2-niranjan.hy@ti.com> (raw)
In-Reply-To: <20251120092050.1218-1-niranjan.hy@ti.com>
Use the firmware version same as in Windows
projects. The firmware contains algorithm
parameters and some device configuration
writes which are part of the same firmware file.
Signed-off-by: Niranjan H Y <niranjan.hy@ti.com>
---
sound/soc/codecs/tas2783-sdw.c | 147 +++++++++++++++++++--------------
sound/soc/codecs/tas2783.h | 1 +
2 files changed, 85 insertions(+), 63 deletions(-)
diff --git a/sound/soc/codecs/tas2783-sdw.c b/sound/soc/codecs/tas2783-sdw.c
index 43b779873..6a0644670 100644
--- a/sound/soc/codecs/tas2783-sdw.c
+++ b/sound/soc/codecs/tas2783-sdw.c
@@ -35,8 +35,8 @@
#include "tas2783.h"
#define TIMEOUT_FW_DL_MS (3000)
-#define FW_DL_OFFSET 36
-#define FW_FL_HDR 12
+#define FW_DL_OFFSET 84 /* binary file information */
+#define FW_FL_HDR 20 /* minimum number of bytes in one chunk */
#define TAS2783_PROBE_TIMEOUT 5000
#define TAS2783_CALI_GUID EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc, \
0x09, 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92)
@@ -49,11 +49,22 @@ static const u32 tas2783_cali_reg[] = {
TAS2783_CAL_TLIM,
};
-struct bin_header_t {
- u16 vendor_id;
- u16 version;
+struct tas_fw_hdr {
+ u32 size;
+ u32 version_offset;
+ u32 plt_id;
+ u32 ppc3_ver;
+ u32 timestamp;
+ u8 ddc_name[64];
+};
+
+struct tas_fw_file {
+ u32 vendor_id;
u32 file_id;
+ u32 version;
u32 length;
+ u32 dest_addr;
+ u8 *fw_data;
};
struct calibration_data {
@@ -735,13 +746,28 @@ static s32 tas2783_update_calibdata(struct tas2783_prv *tas_dev)
return ret;
}
-static s32 read_header(const u8 *data, struct bin_header_t *hdr)
+static s32 tas_fw_read_hdr(const u8 *data, struct tas_fw_hdr *hdr)
+{
+ hdr->size = get_unaligned_le32(data);
+ hdr->version_offset = get_unaligned_le32(&data[4]);
+ hdr->plt_id = get_unaligned_le32(&data[8]);
+ hdr->ppc3_ver = get_unaligned_le32(&data[12]);
+ memcpy(hdr->ddc_name, &data[16], 64);
+ hdr->timestamp = get_unaligned_le32(&data[80]);
+
+ return 84;
+}
+
+static s32 tas_fw_get_next_file(const u8 *data, struct tas_fw_file *file)
{
- hdr->vendor_id = get_unaligned_le16(&data[0]);
- hdr->file_id = get_unaligned_le32(&data[2]);
- hdr->version = get_unaligned_le16(&data[6]);
- hdr->length = get_unaligned_le32(&data[8]);
- return 12;
+ file->vendor_id = get_unaligned_le32(&data[0]);
+ file->file_id = get_unaligned_le32(&data[4]);
+ file->version = get_unaligned_le32(&data[8]);
+ file->length = get_unaligned_le32(&data[12]);
+ file->dest_addr = get_unaligned_le32(&data[16]);
+ file->fw_data = (u8 *)&data[20];
+
+ return file->length + sizeof(u32) * 5;
}
static void tas2783_fw_ready(const struct firmware *fmw, void *context)
@@ -749,13 +775,20 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
struct tas2783_prv *tas_dev =
(struct tas2783_prv *)context;
const u8 *buf = NULL;
- s32 offset = 0, img_sz, file_blk_size, ret;
- struct bin_header_t hdr;
+ s32 img_sz, ret = 0, cur_file = 0;
+ s32 offset = 0;
+
+ struct tas_fw_hdr *hdr __free(kfree) = kzalloc(sizeof(*hdr), GFP_KERNEL);
+ struct tas_fw_file *file __free(kfree) = kzalloc(sizeof(*file), GFP_KERNEL);
+ if (!file || !hdr) {
+ ret = -ENOMEM;
+ goto out;
+ }
if (!fmw || !fmw->data) {
- /* No firmware binary, devices will work in ROM mode. */
+ /* firmware binary not found*/
dev_err(tas_dev->dev,
- "Failed to read %s, no side-effect on driver running\n",
+ "Failed to read fw binary %s\n",
tas_dev->rca_binaryname);
ret = -EINVAL;
goto out;
@@ -763,67 +796,47 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
img_sz = fmw->size;
buf = fmw->data;
- offset += FW_DL_OFFSET;
- if (offset >= (img_sz - FW_FL_HDR)) {
- dev_err(tas_dev->dev,
- "firmware is too small");
+ offset += tas_fw_read_hdr(buf, hdr);
+ if (hdr->size != img_sz) {
ret = -EINVAL;
+ dev_err(tas_dev->dev, "firmware size mismatch with header");
+ goto out;
+ }
+
+ if (img_sz < FW_DL_OFFSET) {
+ ret = -EINVAL;
+ dev_err(tas_dev->dev, "unexpected size, size is too small");
goto out;
}
mutex_lock(&tas_dev->pde_lock);
while (offset < (img_sz - FW_FL_HDR)) {
- memset(&hdr, 0, sizeof(hdr));
- offset += read_header(&buf[offset], &hdr);
+ offset += tas_fw_get_next_file(&buf[offset], file);
dev_dbg(tas_dev->dev,
- "vndr=%d, file=%d, version=%d, len=%d, off=%d\n",
- hdr.vendor_id, hdr.file_id, hdr.version,
- hdr.length, offset);
- /* size also includes the header */
- file_blk_size = hdr.length - FW_FL_HDR;
-
- /* make sure that enough data is there */
- if (offset + file_blk_size > img_sz) {
- ret = -EINVAL;
+ "v=%d, fid=%d, ver=%d, len=%d, daddr=0x%x, fw=%p",
+ file->vendor_id, file->file_id,
+ file->version, file->length,
+ file->dest_addr, file->fw_data);
+
+ ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral,
+ file->dest_addr,
+ file->length,
+ file->fw_data);
+ if (ret < 0) {
dev_err(tas_dev->dev,
- "corrupt firmware file");
+ "FW download failed: %d", ret);
break;
}
-
- switch (hdr.file_id) {
- case 0:
- ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral,
- PRAM_ADDR_START, file_blk_size,
- &buf[offset]);
- if (ret < 0)
- dev_err(tas_dev->dev,
- "PRAM update failed: %d", ret);
- break;
-
- case 1:
- ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral,
- YRAM_ADDR_START, file_blk_size,
- &buf[offset]);
- if (ret < 0)
- dev_err(tas_dev->dev,
- "YRAM update failed: %d", ret);
-
- break;
-
- default:
- ret = -EINVAL;
- dev_err(tas_dev->dev, "Unsupported file");
- break;
- }
-
- if (ret == 0)
- offset += file_blk_size;
- else
- break;
+ cur_file++;
}
mutex_unlock(&tas_dev->pde_lock);
- if (!ret)
+
+ if (cur_file == 0) {
+ dev_err(tas_dev->dev, "fw with no files");
+ ret = -EINVAL;
+ } else {
tas2783_update_calibdata(tas_dev);
+ }
out:
if (!ret)
@@ -1211,6 +1224,14 @@ static s32 tas_io_init(struct device *dev, struct sdw_slave *slave)
tas_dev->fw_dl_task_done = false;
tas_dev->fw_dl_success = false;
+
+ ret = regmap_write(tas_dev->regmap, TAS2783_SW_RESET, 0x1);
+ if (ret) {
+ dev_err(dev, "sw reset failed, err=%d", ret);
+ return ret;
+ }
+ usleep_range(2000, 2200);
+
scnprintf(tas_dev->rca_binaryname, sizeof(tas_dev->rca_binaryname),
"tas2783-%01x.bin", unique_id);
diff --git a/sound/soc/codecs/tas2783.h b/sound/soc/codecs/tas2783.h
index 794333e0a..bf34319c9 100644
--- a/sound/soc/codecs/tas2783.h
+++ b/sound/soc/codecs/tas2783.h
@@ -28,6 +28,7 @@
#define TASDEV_REG_SDW(book, page, reg) (((book) * 256 * 128) + \
0x800000 + ((page) * 128) + (reg))
+#define TAS2783_SW_RESET TASDEV_REG_SDW(0x0, 0x00, 0x01)
/* Volume control */
#define TAS2783_DVC_LVL TASDEV_REG_SDW(0x0, 0x00, 0x1A)
#define TAS2783_AMP_LEVEL TASDEV_REG_SDW(0x0, 0x00, 0x03)
--
2.25.1
next prev parent reply other threads:[~2025-11-20 16:52 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-20 9:20 [PATCH v1 1/8] ASoC: tas2783A: sdw_utils: support ch 3 & 4 Niranjan H Y
2025-11-20 9:20 ` Niranjan H Y [this message]
2025-11-20 9:20 ` [PATCH v1 3/8] ASoC: tas2783A: update default init writes Niranjan H Y
2025-11-20 9:20 ` [PATCH v1 4/8] ASoC: tas2783A: fix error log for calibration data Niranjan H Y
2025-11-20 9:20 ` [PATCH v1 5/8] ASoc: tas2783A: fw name based on system details Niranjan H Y
2025-11-20 9:20 ` [PATCH v1 6/8] ASoc: tas2783A: acpi match for 4 channel for mtl Niranjan H Y
2025-11-20 9:20 ` [PATCH v1 7/8] ASoC: tas2783A: use acpi initialisation table Niranjan H Y
2025-11-20 10:16 ` Charles Keepax
2025-11-20 9:20 ` [PATCH v1 8/8] ASoC: tas2783A: read slave properties from acpi table Niranjan H Y
2025-11-20 10:16 ` Charles Keepax
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251120092050.1218-2-niranjan.hy@ti.com \
--to=niranjan.hy@ti.com \
--cc=alsa-devel@alsa-project.org \
--cc=baojun.xu@ti.com \
--cc=broonie@kernel.org \
--cc=cezary.rojewski@intel.com \
--cc=ckeepax@opensource.cirrus.com \
--cc=dan.carpenter@linaro.org \
--cc=kai.vehmanen@linux.intel.com \
--cc=lgirdwood@gmail.com \
--cc=linux-sound@vger.kernel.org \
--cc=navada@ti.com \
--cc=perex@perex.cz \
--cc=peter.ujfalusi@linux.intel.com \
--cc=pierre-louis.bossart@linux.dev \
--cc=ranjani.sridharan@linux.intel.com \
--cc=shenghao-ding@ti.com \
--cc=tiwai@suse.com \
--cc=v-hampiholi@ti.com \
--cc=yung-chuan.liao@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).