From: Sergey Lebedev <lsa.uz@pm.me>
To: Mark Brown <broonie@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>,
Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
Oder Chiou <oder_chiou@realtek.com>,
Bard Liao <yung-chuan.liao@linux.intel.com>,
Peter Ujfalusi <peter.ujfalusi@linux.intel.com>,
Kai Vehmanen <kai.vehmanen@linux.intel.com>,
Ranjani Sridharan <ranjani.sridharan@linux.intel.com>,
Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>,
Daniel Baluta <daniel.baluta@nxp.com>,
Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Cc: linux-sound@vger.kernel.org,
sound-open-firmware@alsa-project.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 2/3] ASoC: sdw_utils: skip endpoints of a peripheral that is not on the bus
Date: Tue, 04 Aug 2026 22:59:34 +0000 [thread overview]
Message-ID: <20260804225853.31585-3-lsa.uz@pm.me> (raw)
In-Reply-To: <20260804225853.31585-1-lsa.uz@pm.me>
asoc_sdw_parse_sdw_endpoints() builds DAI links for every endpoint of
every _ADR entry the firmware declares. If a declared peripheral never
enumerates, its links are still created and later fail to prepare, which
takes the whole link down rather than degrading it:
sof_sdw sof_sdw: ASoC: error at snd_soc_link_startup on
SDW0-Playback-SmartAmp: -61
The Microsoft Surface Pro 11 (Intel) declares one physical RT1320 twice,
as two _ADR entries on link 0 differing only in SDCA class id:
SWRA _ADR 0x000030025D132000 class 0
SWRB _ADR 0x000030025D132001 class 1
Same link, same manufacturer, part and version, same unique id 0. The
part reports class 1, so only SWRB enumerates. SWRA is a phantom and
stays UNATTACHED across every boot and every firmware version tested,
including the November 2025 bundle.
The existing is_sdca_endpoint_present() check cannot filter it out.
Setting aside that it is gated on a non-zero class id and the phantom is
the class-0 entry, the deeper problem is that the BIOS describes both
entries identically: each declares the same two SDCA functions, so the
check matches for either. Bus presence is what distinguishes them, so
test that.
The check is by nature a runtime one, and its correctness depends on the
peripheral having enumerated by the time the card probes. That holds
here: the real device is Attached and the phantom has no device number
at all whenever this runs. It is a weaker property than the surrounding
BIOS-driven checks, and a suggestion for something stronger would be
welcome, but the firmware offers nothing else to key on.
Signed-off-by: Sergey Lebedev <lsa.uz@pm.me>
---
sound/soc/sdw_utils/soc_sdw_utils.c | 46 +++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index d8db8fc53..12ca4bdd4 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -1909,6 +1909,46 @@ int asoc_sdw_get_dai_type(u32 type)
}
EXPORT_SYMBOL_NS(asoc_sdw_get_dai_type, "SND_SOC_SDW_UTILS");
+/*
+ * Some firmware describes one physical peripheral with two _ADR entries that
+ * differ only in SDCA class id, on the same link and with the same unique id.
+ * Only the entry whose class id matches the part ever enumerates; the other is
+ * a phantom. Building DAI links for it fails the whole link rather than
+ * degrading it, so the endpoints have to be skipped.
+ *
+ * This cannot be decided from the BIOS description: on the machine that
+ * prompted this, both entries declare an identical set of SDCA functions, so
+ * is_sdca_endpoint_present() below matches for either. Bus presence is the only
+ * thing that distinguishes them.
+ */
+static bool is_peripheral_attached(struct device *dev,
+ const struct snd_soc_acpi_link_adr *adr_link,
+ int adr_index)
+{
+ const char *sdw_codec_name;
+ struct device *sdw_dev;
+ struct sdw_slave *slave;
+ bool attached;
+
+ sdw_codec_name = _asoc_sdw_get_codec_name(dev, adr_link, adr_index);
+ if (!sdw_codec_name)
+ return true;
+
+ sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_codec_name);
+ if (!sdw_dev)
+ return true;
+
+ slave = dev_to_sdw_dev(sdw_dev);
+ attached = slave->status != SDW_SLAVE_UNATTACHED;
+ if (!attached)
+ dev_dbg(dev, "%s not present on the bus, skipping its endpoints\n",
+ sdw_codec_name);
+
+ put_device(sdw_dev);
+
+ return attached;
+}
+
/**
* is_sdca_endpoint_present - Check if an SDCA endpoint is present on the SDW peripheral
* @dev: Device pointer
@@ -2065,6 +2105,12 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
dai_info = &codec_info->dais[adr_end->num];
soc_dai = asoc_sdw_find_dailink(soc_dais, adr_end);
+ /* skip a peripheral that is not on the bus at all */
+ if (!is_peripheral_attached(dev, adr_link, i)) {
+ (*num_devs)--;
+ continue;
+ }
+
/*
* quirk should have higher priority than the sdca properties
* in the BIOS. We can't always check the DAI quirk because we
--
2.50.1 (Apple Git-155)
next prev parent reply other threads:[~2026-08-04 22:59 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 22:59 [PATCH 0/3] ASoC: fix audio on the Microsoft Surface Pro 11 (Intel) Sergey Lebedev
2026-08-04 22:59 ` [PATCH 1/3] ASoC: rt1320: run the initialisation preset on the first hardware init Sergey Lebedev
2026-08-04 22:59 ` Sergey Lebedev [this message]
2026-08-05 1:12 ` [PATCH 2/3] ASoC: sdw_utils: skip endpoints of a peripheral that is not on the bus Liao, Bard
2026-08-05 8:22 ` Pierre-Louis Bossart
2026-08-05 13:28 ` Liao, Bard
2026-08-04 22:59 ` [PATCH 3/3] ASoC: SOF: Intel: hda: duplicate _ADR entries share one amp index Sergey Lebedev
2026-08-05 1:21 ` Liao, Bard
2026-08-05 8:33 ` Pierre-Louis Bossart
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=20260804225853.31585-3-lsa.uz@pm.me \
--to=lsa.uz@pm.me \
--cc=Vijendar.Mukunda@amd.com \
--cc=broonie@kernel.org \
--cc=daniel.baluta@nxp.com \
--cc=kai.vehmanen@linux.intel.com \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=oder_chiou@realtek.com \
--cc=perex@perex.cz \
--cc=peter.ujfalusi@linux.intel.com \
--cc=pierre-louis.bossart@linux.dev \
--cc=ranjani.sridharan@linux.intel.com \
--cc=sound-open-firmware@alsa-project.org \
--cc=tiwai@suse.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