]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: amd: acp: Add DMI quirk for Valve Steam Deck OLED
authorGuilherme G. Piccoli <gpiccoli@igalia.com>
Thu, 23 Apr 2026 18:30:58 +0000 (15:30 -0300)
committerMark Brown <broonie@kernel.org>
Sun, 26 Apr 2026 21:54:14 +0000 (06:54 +0900)
Commit 671dd2ffbd8b ("ASoC: amd: acp: Add new cpu dai and dailink creation for I2S BT instance")
introduced a change that "broke" Steam Deck's audio probe, in the OLED
model, as observed in the following dmesg snippet:

[...]
snd_sof_amd_vangogh 0000:04:00.5: Topology: ABI 3:26:0 Kernel ABI 3:23:1
sof_mach nau8821-max: ASoC: physical link acp-bt-codec (id 2) not exist
sof_mach nau8821-max: ASoC: topology: could not load header: -22
snd_sof_amd_vangogh 0000:04:00.5: tplg amd/sof-tplg/sof-vangogh-nau8821-max.tplg component load failed -22
snd_sof_amd_vangogh 0000:04:00.5: error: failed to load DSP topology -22
snd_sof_amd_vangogh 0000:04:00.5: ASoC error (-22): at snd_soc_component_probe() on 0000:04:00.5
sof_mach nau8821-max: ASoC: failed to instantiate card -22
sof_mach nau8821-max: error -EINVAL: Failed to register card(sof-nau8821-max)
sof_mach nau8821-max: probe with driver sof_mach failed with error -22
[...]

Notice the quotes in "broke": it's not really a bug in such commit,
but instead a problem with a topology file from Steam Deck OLED. This
was discussed to great extent in [1], and Cristian proposed a pretty
simple and functional change that resolved the issue for the Deck's
issue. That change, though, would break other devices, so it wasn't
accepted upstream. And the proper suggested solution (fix the topology)
was never implemented, so Valve's kernel (and anyone that wants to boot
the mainline on Steam Deck OLED) is carrying that fix downstream.

So, we propose hereby a different approach: a DMI quirk, as many already
present in the sound drivers, to address this issue solely on Steam Deck
OLED, not breaking other devices and as a bonus, allowing simple patch
up in case eventually the topology file gets fixed (we'd just need to
check against any DMI info reflecting that or the topology/FW versions).

The motivation of such upstream quirk is related to users that want
to test latest kernel trees on their devices and get no only non-working
sound device, but seems some games (like Ori and the Blind Forest)
can't properly work without a proper functional audio device.
Example of such report can be seen at [2].

Cc: Mark Brown <broonie@kernel.org>
Cc: Robert Beckett <bob.beckett@collabora.com>
Cc: Umang Jain <uajain@igalia.com>
Fixes: 671dd2ffbd8b ("ASoC: amd: acp: Add new cpu dai and dailink creation for I2S BT instance")
Link: https://lore.kernel.org/r/20231209205351.880797-11-cristian.ciocaltea@collabora.com/
Link: https://bugzilla.kernel.org/show_bug.cgi?id=218677
Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Tested-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
Link: https://patch.msgid.link/20260423183505.116445-1-gpiccoli@igalia.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/amd/acp/acp-legacy-mach.c
sound/soc/amd/acp/acp-mach-common.c
sound/soc/amd/acp/acp-mach.h
sound/soc/amd/acp/acp-sof-mach.c

index a7a551366a4097d7f1410c1980ecb3a8eea4e775..235d6cc83fa989bbfd16d0fb09e227f66b263542 100644 (file)
@@ -174,7 +174,7 @@ static int acp_asoc_probe(struct platform_device *pdev)
                acp_card_drvdata->acp_rev = mach->mach_params.subsystem_rev;
 
        dmi_id = dmi_first_match(acp_quirk_table);
-       if (dmi_id && dmi_id->driver_data)
+       if (dmi_id && dmi_id->driver_data == (void *)QUIRK_TDM_MODE_ENABLE)
                acp_card_drvdata->tdm_mode = dmi_id->driver_data;
 
        ret = acp_legacy_dai_links_create(card);
index 09f6c9a2c04104b555a4657980e5f020fc23f202..ef784cca13f2b8e3967d3d756d23eecce2886582 100644 (file)
@@ -20,6 +20,7 @@
 #include <sound/soc.h>
 #include <linux/input.h>
 #include <linux/module.h>
+#include <linux/dmi.h>
 
 #include "../../codecs/rt5682.h"
 #include "../../codecs/rt1019.h"
 #define NAU8821_FREQ_OUT       12288000
 #define MAX98388_CODEC_DAI     "max98388-aif1"
 
-#define TDM_MODE_ENABLE 1
-
 const struct dmi_system_id acp_quirk_table[] = {
        {
                /* Google skyrim proto-0 */
                .matches = {
                        DMI_EXACT_MATCH(DMI_PRODUCT_FAMILY, "Google_Skyrim"),
                },
-               .driver_data = (void *)TDM_MODE_ENABLE,
+               .driver_data = (void *)QUIRK_TDM_MODE_ENABLE,
+       },
+       {
+               /* Valve Steam Deck OLED */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Valve"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Galileo"),
+               },
+               .driver_data = (void *)QUIRK_REMAP_DMIC_BT,
        },
        {}
 };
@@ -1401,6 +1408,7 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
        struct snd_soc_dai_link *links;
        struct device *dev = card->dev;
        struct acp_card_drvdata *drv_data = card->drvdata;
+       const struct dmi_system_id *dmi_id = dmi_first_match(acp_quirk_table);
        int i = 0, num_links = 0;
 
        if (drv_data->hs_cpu_id)
@@ -1572,6 +1580,9 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
                        links[i].codecs = &snd_soc_dummy_dlc;
                        links[i].num_codecs = 1;
                }
+
+               if (dmi_id && dmi_id->driver_data == (void *)QUIRK_REMAP_DMIC_BT)
+                       links[i].id = DMIC_BE_ID;
                i++;
        }
 
@@ -1587,6 +1598,11 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
                links[i].capture_only = 1;
                links[i].nonatomic = true;
                links[i].no_pcm = 1;
+
+               if (dmi_id && dmi_id->driver_data == (void *)QUIRK_REMAP_DMIC_BT) {
+                       links[i].id = BT_BE_ID;
+                       dev_dbg(dev, "quirk REMAP_DMIC_BT enabled\n");
+               }
        }
 
        card->dai_link = links;
index f94c30c20f20b6bfd7b00a0ec34ffb4de8996766..7177d3fd9619279d5710f2fd850b989d58e712d5 100644 (file)
 
 #define acp_get_drvdata(card) ((struct acp_card_drvdata *)(card)->drvdata)
 
+/* List of DMI quirks - check acp-mach-common.c for usage. */
+#define QUIRK_TDM_MODE_ENABLE 1
+#define QUIRK_REMAP_DMIC_BT 2
+
 enum be_id {
        HEADSET_BE_ID = 0,
        AMP_BE_ID,
index 6215e31eceddf8931ed55c29d8488629e23bcdd0..36ecef7013b9cb42e961c6d6f5be5e9ab22936a5 100644 (file)
@@ -110,7 +110,7 @@ static int acp_sof_probe(struct platform_device *pdev)
 
        acp_card_drvdata = card->drvdata;
        dmi_id = dmi_first_match(acp_quirk_table);
-       if (dmi_id && dmi_id->driver_data)
+       if (dmi_id && dmi_id->driver_data == (void *)QUIRK_TDM_MODE_ENABLE)
                acp_card_drvdata->tdm_mode = dmi_id->driver_data;
 
        acp_card_drvdata->acp_rev = mach->mach_params.subsystem_rev;