Unverified Commit b0f6f4ac authored by Guilherme G. Piccoli's avatar Guilherme G. Piccoli Committed by Mark Brown
Browse files

ASoC: amd: acp: Add DMI quirk for Valve Steam Deck OLED

Commit 671dd2ff ("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: 671dd2ff ("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/ [1]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=218677

 [2]
Reviewed-by: default avatarCristian Ciocaltea <cristian.ciocaltea@collabora.com>
Reviewed-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Tested-by: default avatarMelissa Wen <mwen@igalia.com>
Signed-off-by: default avatarGuilherme G. Piccoli <gpiccoli@igalia.com>
Link: https://patch.msgid.link/20260423183505.116445-1-gpiccoli@igalia.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 254f4963
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+19 −3
Original line number Diff line number Diff line
@@ -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"
@@ -37,15 +38,21 @@
#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;
+4 −0
Original line number Diff line number Diff line
@@ -26,6 +26,10 @@

#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,
+1 −1
Original line number Diff line number Diff line
@@ -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;