Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Matthew Schwartz <matthew.schwartz@linux.dev>
To: broonie@kernel.org
Cc: Matthew Schwartz <matthew.schwartz@linux.dev>,
	Shenghao Ding <shenghao-ding@ti.com>, Kevin Lu <kevin-lu@ti.com>,
	Baojun Xu <baojun.xu@ti.com>, Sen Wang <sen@ti.com>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
	linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 3/5] ASoC: tas2783-sdw: use the BIOS speaker ID in the firmware name
Date: Fri, 16 Oct 2026 16:24:13 -0700	[thread overview]
Message-ID: <20261016232416.2628603-4-matthew.schwartz@linux.dev> (raw)
In-Reply-To: <20261016232416.2628603-1-matthew.schwartz@linux.dev>

Some boards have TAS2783 firmware in linux-firmware named
SSID-SPKID-LINK-0xUID.bin, with a speaker ID ahead of the link ID (the
HP 8EA1 has its amps on link 0 and ships 8EA1-{0,1}-0-0x*.bin). The
driver only builds the three-field SSID-LINK-0xUID name, so these boards
never load firmware. On the ASUS ROG Xbox Ally X20 (SSID 1954) the BIOS
provides the speaker ID in a 4-byte SPEAKER_ID EFI variable, and only
the four-field 1954-*-*-0x*.bin files exist.

Read SPEAKER_ID once and request the four-field name first when it is
present. Boards without the variable keep the current names, and the
unprefixed three-field name is still tried if the four-field file is
missing.

Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
---
 sound/soc/codecs/tas2783-sdw.c | 42 +++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/sound/soc/codecs/tas2783-sdw.c b/sound/soc/codecs/tas2783-sdw.c
index a57230e01f755..db234c54aa2ac 100644
--- a/sound/soc/codecs/tas2783-sdw.c
+++ b/sound/soc/codecs/tas2783-sdw.c
@@ -46,6 +46,8 @@
 #define TAS2783_PROBE_TIMEOUT 5000
 #define TAS2783_CALI_GUID EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc, \
 				   0x09, 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92)
+#define TAS2783_SPKID_GUID EFI_GUID(0xaa61eaaf, 0x6e83, 0x7523, 0xb0, \
+				    0xd0, 0x7d, 0xf7, 0x4b, 0xb2, 0x4a, 0x81)
 
 static const u32 tas2783_cali_reg[] = {
 	TAS2783_CAL_R0,
@@ -104,6 +106,11 @@ struct tas2783_prv {
 	bool fw_dl_success;
 	/* use fallback fw name */
 	bool fw_use_fallback;
+#if IS_ENABLED(CONFIG_PCI)
+	/* UEFI speaker ID, read once */
+	int spk_id;
+	bool spk_id_read;
+#endif
 };
 
 static const struct reg_default tas2783_reg_default[] = {
@@ -1156,6 +1163,26 @@ static const struct dev_pm_ops tas2783_sdca_pm = {
 	RUNTIME_PM_OPS(tas2783_sdca_dev_suspend, tas2783_sdca_dev_resume, NULL)
 };
 
+#if IS_ENABLED(CONFIG_PCI)
+/* BIOS speaker ID that selects the SSID-SPKID-LINK-UID firmware name */
+static int tas2783_get_spk_id(void)
+{
+	efi_guid_t guid = TAS2783_SPKID_GUID;
+	unsigned long size = sizeof(u32);
+	efi_status_t status;
+	u32 spk_id = 0;
+
+	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
+		return -ENOENT;
+
+	status = efi.get_variable(L"SPEAKER_ID", &guid, NULL, &size, &spk_id);
+	if (status != EFI_SUCCESS)
+		return -ENOENT;
+
+	return spk_id;
+}
+#endif
+
 static void tas_generate_fw_name(struct sdw_slave *slave, char *name, size_t size)
 {
 	struct sdw_bus *bus = slave->bus;
@@ -1170,9 +1197,18 @@ static void tas_generate_fw_name(struct sdw_slave *slave, char *name, size_t siz
 	for (; dev; dev = dev->parent) {
 		if (dev->bus == &pci_bus_type) {
 			pci = to_pci_dev(dev);
-			scnprintf(name, size, "%04X-%1X-%s%1X.bin",
-				  pci->subsystem_device, bus->link_id,
-				  fw_uid_prefix, unique_id);
+			if (!tas_dev->spk_id_read) {
+				tas_dev->spk_id = tas2783_get_spk_id();
+				tas_dev->spk_id_read = true;
+			}
+			if (tas_dev->spk_id >= 0 && !tas_dev->fw_use_fallback)
+				scnprintf(name, size, "%04X-%X-%1X-0x%1X.bin",
+					  pci->subsystem_device, tas_dev->spk_id,
+					  bus->link_id, unique_id);
+			else
+				scnprintf(name, size, "%04X-%1X-%s%1X.bin",
+					  pci->subsystem_device, bus->link_id,
+					  fw_uid_prefix, unique_id);
 			pci_found = true;
 			break;
 		}
-- 
2.56.0


  parent reply	other threads:[~2026-10-16 23:24 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 23:24 [PATCH 0/5] ASoC: support the ASUS ROG Xbox Ally X20 audio Matthew Schwartz
2026-10-16 23:24 ` [PATCH 1/5] ASoC: amd: acp-config: force SoundWire probe on ASUS RC74XA Matthew Schwartz
2026-10-16 23:24 ` [PATCH 2/5] ASoC: amd: acp: add ACP70 SoundWire machine entry for " Matthew Schwartz
2026-10-16 23:24 ` Matthew Schwartz [this message]
2026-10-16 23:24 ` [PATCH 4/5] ASoC: sdw_utils: honor empty DisCo port lists when creating DAI links Matthew Schwartz
2026-10-16 23:24 ` [PATCH 5/5] ASoC: rt721-sdca: wait for PDEs to reach PS0 after powering them up Matthew Schwartz

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=20261016232416.2628603-4-matthew.schwartz@linux.dev \
    --to=matthew.schwartz@linux.dev \
    --cc=baojun.xu@ti.com \
    --cc=broonie@kernel.org \
    --cc=kevin-lu@ti.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=sen@ti.com \
    --cc=shenghao-ding@ti.com \
    --cc=tiwai@suse.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