* [PATCH 1/4] ASoC: mediatek: common: Keep codec references until the card is bound
2026-10-03 19:44 [PATCH 0/4] ASoC: Fixes for the MT8188 sound card Michał Kopeć
@ 2026-10-03 19:44 ` Michał Kopeć
2026-10-03 19:44 ` [PATCH 2/4] ASoC: mediatek: Don't keep a freed topology name in the static card Michał Kopeć
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Michał Kopeć @ 2026-10-03 19:44 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Jaroslav Kysela, Takashi Iwai, Matthias Brugger,
AngeloGioacchino Del Regno, Alexandre Mergnat, Kuninori Morimoto,
Peter Ujfalusi, Trevor Wu, linux-sound, linux-mediatek,
linux-arm-kernel, linux-kernel, Michał Kopeć
mtk_soundcard_common_probe() drops the codec references parsed from the
devicetree right after devm_snd_soc_register_card() returns. When a
component is still missing, snd_soc_bind_card() queues the card for a
later rebind and registration still returns success, so the card is not
instantiated yet. The rebind reuses the same dai_link array, but with the
codec references released both the codec name and of_node are unset, so
it fails the dai link sanity check and the sound card never appears.
Release the references right away only when the card was instantiated
or registration failed. Otherwise keep them for the rebind and release
them when the device is unbound.
Fixes: bce93a162505 ("ASoC: mediatek: Add common machine soundcard driver probe mechanism")
Signed-off-by: Michał Kopeć <michal@nozomi.space>
---
.../mediatek/common/mtk-soundcard-driver.c | 23 +++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.c b/sound/soc/mediatek/common/mtk-soundcard-driver.c
index 2d39ff23f8540..4bb98412feb11 100644
--- a/sound/soc/mediatek/common/mtk-soundcard-driver.c
+++ b/sound/soc/mediatek/common/mtk-soundcard-driver.c
@@ -129,6 +129,11 @@ void clean_card_reference(struct snd_soc_card *card)
}
EXPORT_SYMBOL_GPL(clean_card_reference);
+static void mtk_soundcard_put_card_reference(void *data)
+{
+ clean_card_reference(data);
+}
+
int mtk_soundcard_startup(struct snd_pcm_substream *substream,
enum mtk_pcm_constraint_type ctype)
{
@@ -325,8 +330,22 @@ int mtk_soundcard_common_probe(struct platform_device *pdev)
ret = devm_snd_soc_register_card(&pdev->dev, card);
- if (!needs_legacy_probe)
- clean_card_reference(card);
+ /*
+ * When a component is still missing, snd_soc_bind_card() queues the
+ * card for a later rebind and returns success, so the card is not
+ * instantiated yet. That rebind reuses this same dai_link array, so
+ * the codec references parsed from the devicetree must be kept until
+ * the device is unbound: dropping them leaves both name and of_node
+ * unset and the rebind fails the dai link sanity check instead.
+ */
+ if (!needs_legacy_probe) {
+ if (ret || snd_soc_card_is_instantiated(card))
+ clean_card_reference(card);
+ else
+ ret = devm_add_action_or_reset(&pdev->dev,
+ mtk_soundcard_put_card_reference,
+ card);
+ }
if (ret) {
dev_err_probe(&pdev->dev, ret, "Cannot register card\n");
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/4] ASoC: mediatek: Don't keep a freed topology name in the static card
2026-10-03 19:44 [PATCH 0/4] ASoC: Fixes for the MT8188 sound card Michał Kopeć
2026-10-03 19:44 ` [PATCH 1/4] ASoC: mediatek: common: Keep codec references until the card is bound Michał Kopeć
@ 2026-10-03 19:44 ` Michał Kopeć
2026-10-08 8:20 ` Mark Brown
2026-10-03 19:45 ` [PATCH 3/4] ASoC: mediatek: mt8188: Constrain UL8 FE to its back end's capabilities Michał Kopeć
2026-10-03 19:45 ` [PATCH 4/4] ASoC: hdmi-codec: Don't parse an empty ELD on startup Michał Kopeć
3 siblings, 1 reply; 6+ messages in thread
From: Michał Kopeć @ 2026-10-03 19:44 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Jaroslav Kysela, Takashi Iwai, Matthias Brugger,
AngeloGioacchino Del Regno, Alexandre Mergnat, Kuninori Morimoto,
Peter Ujfalusi, Trevor Wu, linux-sound, linux-mediatek,
linux-arm-kernel, linux-kernel, Michał Kopeć
The machine drivers pass a static snd_soc_card, which outlives any one
probe. With SOF, mtk_soundcard_common_probe() calls
snd_soc_card_set_topology_name(), which devm-allocates "sof-<name>",
stores it in card->topology_shortname and points card->name at it.
If the probe then fails or defers, devm frees the string, but the static
card keeps both pointers. The next probe does not allocate a new name,
because topology_shortname is already set, so the card registers with
whatever now occupies that memory:
input: \xc0cr\xc2 DP Jack as /devices/platform/sound/sound/card0/input10
UCM matches profiles by card name, so userspace then finds no profile and
the card is unusable until the next boot.
Save the original name before setting the topology name, and restore it
from a devm action that runs before the string is freed.
Fixes: ec4489c43efe ("ASoC: soc-card: add snd_soc_card_set_topology_name()")
Signed-off-by: Michał Kopeć <michal@nozomi.space>
---
.../mediatek/common/mtk-soundcard-driver.c | 44 ++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.c b/sound/soc/mediatek/common/mtk-soundcard-driver.c
index 4bb98412feb11..a84f4ab4488b7 100644
--- a/sound/soc/mediatek/common/mtk-soundcard-driver.c
+++ b/sound/soc/mediatek/common/mtk-soundcard-driver.c
@@ -185,6 +185,43 @@ const struct snd_soc_ops mtk_soundcard_common_capture_ops = {
};
EXPORT_SYMBOL_GPL(mtk_soundcard_common_capture_ops);
+struct mtk_soundcard_name {
+ struct snd_soc_card *card;
+ const char *name;
+};
+
+static void mtk_soundcard_restore_name(void *data)
+{
+ struct mtk_soundcard_name *saved = data;
+
+ saved->card->name = saved->name;
+ saved->card->topology_shortname = NULL;
+}
+
+/*
+ * The card is static and outlives this probe, but the topology name is
+ * devm-allocated. Restore the original name when the probe's resources are
+ * released, so that a deferred or failed probe does not leave the card name
+ * pointing to freed memory for the next one.
+ */
+static int mtk_soundcard_set_topology_name(struct device *dev,
+ struct snd_soc_card *card)
+{
+ struct mtk_soundcard_name *saved;
+
+ saved = devm_kzalloc(dev, sizeof(*saved), GFP_KERNEL);
+ if (!saved)
+ return -ENOMEM;
+
+ saved->card = card;
+ saved->name = card->name;
+ card->topology_shortname = NULL;
+
+ snd_soc_card_set_topology_name(card, "sof");
+
+ return devm_add_action_or_reset(dev, mtk_soundcard_restore_name, saved);
+}
+
int mtk_soundcard_common_probe(struct platform_device *pdev)
{
struct device_node *platform_node, *adsp_node, *accdet_node;
@@ -292,7 +329,12 @@ int mtk_soundcard_common_probe(struct platform_device *pdev)
card->probe = mtk_sof_card_probe;
card->late_probe = mtk_sof_card_late_probe;
- snd_soc_card_set_topology_name(card, "sof");
+ ret = mtk_soundcard_set_topology_name(&pdev->dev, card);
+ if (ret) {
+ of_node_put(adsp_node);
+ of_node_put(platform_node);
+ return ret;
+ }
}
/*
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 2/4] ASoC: mediatek: Don't keep a freed topology name in the static card
2026-10-03 19:44 ` [PATCH 2/4] ASoC: mediatek: Don't keep a freed topology name in the static card Michał Kopeć
@ 2026-10-08 8:20 ` Mark Brown
0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2026-10-08 8:20 UTC (permalink / raw)
To: Michał Kopeć
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Matthias Brugger,
AngeloGioacchino Del Regno, Alexandre Mergnat, Kuninori Morimoto,
Peter Ujfalusi, Trevor Wu, linux-sound, linux-mediatek,
linux-arm-kernel, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 601 bytes --]
On Sat, Oct 03, 2026 at 09:44:59PM +0200, Michał Kopeć wrote:
> The machine drivers pass a static snd_soc_card, which outlives any one
> probe. With SOF, mtk_soundcard_common_probe() calls
> snd_soc_card_set_topology_name(), which devm-allocates "sof-<name>",
> stores it in card->topology_shortname and points card->name at it.
...
> Save the original name before setting the topology name, and restore it
> from a devm action that runs before the string is freed.
This is valid, but it doesn't feel like this is Mediatek specific - we
should probably move this into the core code.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/4] ASoC: mediatek: mt8188: Constrain UL8 FE to its back end's capabilities
2026-10-03 19:44 [PATCH 0/4] ASoC: Fixes for the MT8188 sound card Michał Kopeć
2026-10-03 19:44 ` [PATCH 1/4] ASoC: mediatek: common: Keep codec references until the card is bound Michał Kopeć
2026-10-03 19:44 ` [PATCH 2/4] ASoC: mediatek: Don't keep a freed topology name in the static card Michał Kopeć
@ 2026-10-03 19:45 ` Michał Kopeć
2026-10-03 19:45 ` [PATCH 4/4] ASoC: hdmi-codec: Don't parse an empty ELD on startup Michał Kopeć
3 siblings, 0 replies; 6+ messages in thread
From: Michał Kopeć @ 2026-10-03 19:45 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Jaroslav Kysela, Takashi Iwai, Matthias Brugger,
AngeloGioacchino Del Regno, Alexandre Mergnat, Kuninori Morimoto,
Peter Ujfalusi, Trevor Wu, linux-sound, linux-mediatek,
linux-arm-kernel, linux-kernel, Michał Kopeć
UL8 advertises up to 24 channels, but its only back end, ETDM1_IN,
supports at most 16, and its bit clock is limited to 24.576 MHz.
Without merged constraints, userspace can open UL8 with 48 kHz, 24
channels and 32-bit slots, which then fails in hw_params:
mtk_dai_etdm_configure bck rate 36864000 not support
ASoC error (-22): at snd_soc_dai_hw_params() on ETDM1_IN
Set dpcm_merged_chan/rate/format, as the DL front ends already do, so
the FE only offers configurations the back end can accept.
Fixes: 96035d46d4b4 ("ASoC: mediatek: mt8188: add machine driver with mt6359")
Signed-off-by: Michał Kopeć <michal@nozomi.space>
---
sound/soc/mediatek/mt8188/mt8188-mt6359.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
index 75c90d1d165f7..f07aeb6371083 100644
--- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c
+++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
@@ -1142,6 +1142,9 @@ static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {
},
.dynamic = 1,
.capture_only = 1,
+ .dpcm_merged_chan = 1,
+ .dpcm_merged_rate = 1,
+ .dpcm_merged_format = 1,
SND_SOC_DAILINK_REG(capture8),
},
[DAI_LINK_UL9_FE] = {
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 4/4] ASoC: hdmi-codec: Don't parse an empty ELD on startup
2026-10-03 19:44 [PATCH 0/4] ASoC: Fixes for the MT8188 sound card Michał Kopeć
` (2 preceding siblings ...)
2026-10-03 19:45 ` [PATCH 3/4] ASoC: mediatek: mt8188: Constrain UL8 FE to its back end's capabilities Michał Kopeć
@ 2026-10-03 19:45 ` Michał Kopeć
3 siblings, 0 replies; 6+ messages in thread
From: Michał Kopeć @ 2026-10-03 19:45 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood
Cc: Jaroslav Kysela, Takashi Iwai, Matthias Brugger,
AngeloGioacchino Del Regno, Alexandre Mergnat, Kuninori Morimoto,
Peter Ujfalusi, Trevor Wu, linux-sound, linux-mediatek,
linux-arm-kernel, linux-kernel, Michał Kopeć
A bridge's get_eld() returns an all-zero ELD when no sink is connected.
hdmi_codec_startup() parses it unconditionally, so every open of a
disconnected HDMI/DP PCM logs:
hdmi-audio-codec: HDMI: Unknown ELD version 0
Skip parsing when the ELD is empty and clear the previously parsed
copy instead. The ELD hw constraint already falls back to basic stereo
rates for an empty ELD, so stream setup is unchanged. plugged_cb()
likewise treats a parse failure as debug-only.
Signed-off-by: Michał Kopeć <michal@nozomi.space>
---
sound/soc/codecs/hdmi-codec.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 7aa50c5bd3df8..0e1e532dfc634 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -475,8 +475,12 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
if (ret)
return ret;
- snd_parse_eld(dai->dev, &hcp->eld_parsed,
- hcp->eld, sizeof(hcp->eld));
+ /* An empty ELD means no sink is connected; nothing to parse. */
+ if (hcp->eld[0])
+ snd_parse_eld(dai->dev, &hcp->eld_parsed,
+ hcp->eld, sizeof(hcp->eld));
+ else
+ memset(&hcp->eld_parsed, 0, sizeof(hcp->eld_parsed));
ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld);
if (ret)
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread