diff options
Diffstat (limited to 'SOURCES/steamdeck-oled-audio.patch')
-rw-r--r-- | SOURCES/steamdeck-oled-audio.patch | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/SOURCES/steamdeck-oled-audio.patch b/SOURCES/steamdeck-oled-audio.patch new file mode 100644 index 0000000..978e76a --- /dev/null +++ b/SOURCES/steamdeck-oled-audio.patch @@ -0,0 +1,437 @@ +From ba5fcc25b726559cb36d61196c58c865190a8a7b Mon Sep 17 00:00:00 2001 +From c0c65da7ca4b0a4f93272f5e932dd7eed90703c8 Mon Sep 17 00:00:00 2001 +From: Ethan Geller <ethang@valvesoftware.com> +Date: Thu, 16 Nov 2023 21:31:48 +0000 +Subject: [PATCH] Fix for Max98388 issue where speakers would not be powered on + when we resume from S3. + +The issue was that when we flush the regmap to the amp on resume, we were also flushing a value of 1 to the SW_RESET pin. + +Theoretically, this is fixed by marking the SW_RESET register volatile. However, we did not observe a fix after marking the register volatile, so we opted for a more complete fix of ensuring SW_RESET is zero in our regmap after we have waited for the reset loop to be complete. +--- + sound/soc/codecs/max98388.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/max98388.c b/sound/soc/codecs/max98388.c +index 293ec172e0a71..4c495e0e33f90 100644 +--- a/sound/soc/codecs/max98388.c ++++ b/sound/soc/codecs/max98388.c +@@ -391,27 +391,43 @@ void max98388_reset(struct max98388_priv *max98388, struct device *dev) + { + int ret, reg, count; + ++ + /* Software Reset */ + ret = regmap_update_bits(max98388->regmap, + MAX98388_R2000_SW_RESET, + MAX98388_SOFT_RESET, + MAX98388_SOFT_RESET); +- if (ret) ++ ++ if (ret) { + dev_err(dev, "Reset command failed. (ret:%d)\n", ret); ++ goto exit; ++ } ++ + + count = 0; + while (count < 3) { + usleep_range(10000, 11000); ++ + /* Software Reset Verification */ + ret = regmap_read(max98388->regmap, + MAX98388_R22FF_REV_ID, ®); ++ + if (!ret) { + dev_info(dev, "Reset completed (retry:%d)\n", count); +- return; ++ goto exit; + } + count++; + } ++ + dev_err(dev, "Reset failed. (ret:%d)\n", ret); ++ ++ ++exit: ++ regcache_cache_only(max98388->regmap, true); ++ ret = regmap_update_bits(max98388->regmap, ++ MAX98388_R2000_SW_RESET, ++ MAX98388_SOFT_RESET, 0); ++ regcache_cache_only(max98388->regmap, false); + } + + static int max98388_probe(struct snd_soc_component *component) +@@ -420,6 +436,7 @@ static int max98388_probe(struct snd_soc_component *component) + + /* Software Reset */ + max98388_reset(max98388, component->dev); ++ usleep_range(400, 1000); + + /* General channel source configuration */ + regmap_write(max98388->regmap, +@@ -812,6 +829,7 @@ static bool max98388_readable_register(struct device *dev, + case MAX98388_R210E_AUTO_RESTART: + case MAX98388_R210F_GLOBAL_EN: + case MAX98388_R22FF_REV_ID: ++ case MAX98388_R2000_SW_RESET: + return true; + default: + return false; +@@ -824,6 +842,7 @@ static bool max98388_volatile_reg(struct device *dev, unsigned int reg) + case MAX98388_R2001_INT_RAW1 ... MAX98388_R2005_INT_STATE2: + case MAX98388_R210F_GLOBAL_EN: + case MAX98388_R22FF_REV_ID: ++ case MAX98388_R2000_SW_RESET: + return true; + default: + return false; +@@ -868,6 +887,7 @@ static int max98388_resume(struct device *dev) + + regcache_cache_only(max98388->regmap, false); + max98388_reset(max98388, dev); ++ usleep_range(400, 1000); + regcache_sync(max98388->regmap); + + return 0; +-- +GitLab + +From 39ecb253ecf7ed12e3019b72d7a226f0525dfaa3 Mon Sep 17 00:00:00 2001 +From: Venkata Prasad Potturu <venkataprasad.potturu@amd.com> +Date: Fri, 20 Oct 2023 15:14:52 +0530 +Subject: [PATCH] ASoC: amd: Add new dmi entries and add condition check for + acp config flag + +Signed-off-by: Venkata Prasad Potturu <venkataprasad.potturu@amd.com> +(cherry picked from commit 50f20ef9bcf6fdf6e6cc64a031be26fb9cb54849) +--- + sound/soc/amd/acp-config.c | 14 ++++++++++++++ + sound/soc/amd/vangogh/pci-acp5x.c | 3 ++- + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c +index f27c27580009..73d29a344e70 100644 +--- a/sound/soc/amd/acp-config.c ++++ b/sound/soc/amd/acp-config.c +@@ -47,6 +47,20 @@ static const struct config_entry config_table[] = { + {} + }, + }, ++ { ++ .flags = FLAG_AMD_LEGACY, ++ .device = ACP_PCI_DEV_ID, ++ .dmi_table = (const struct dmi_system_id []) { ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Valve"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Jupiter"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "Aerith"), ++ }, ++ }, ++ {} ++ }, ++ }, + { + .flags = FLAG_AMD_SOF, + .device = ACP_PCI_DEV_ID, +diff --git a/sound/soc/amd/vangogh/pci-acp5x.c b/sound/soc/amd/vangogh/pci-acp5x.c +index c4634a8a17cd..e29c4cc10e0f 100644 +--- a/sound/soc/amd/vangogh/pci-acp5x.c ++++ b/sound/soc/amd/vangogh/pci-acp5x.c +@@ -13,6 +13,7 @@ + #include <linux/pm_runtime.h> + + #include "acp5x.h" ++#include "../mach-config.h" + + struct acp5x_dev_data { + void __iomem *acp5x_base; +@@ -131,7 +132,7 @@ static int snd_acp5x_probe(struct pci_dev *pci, + + /* Return if acp config flag is defined */ + flag = snd_amd_acp_find_config(pci); +- if (flag) ++ if (flag != FLAG_AMD_LEGACY) + return -ENODEV; + + irqflags = IRQF_SHARED; +-- +GitLab + +From 4855323691ea7dd2288c51cd11f00561f9ba22df Mon Sep 17 00:00:00 2001 +From: Thomas Crider <gloriouseggroll@gmail.com> +Date: Tue, 5 Dec 2023 05:13:41 -0500 +Subject: [PATCH] cs35l41 fixup + +--- + sound/soc/amd/acp/acp-mach-common.c | 107 ++++++++++++++++++++++++++++ + sound/soc/amd/acp/acp-mach.h | 4 ++ + sound/soc/amd/acp/acp-sof-mach.c | 2 + + sound/soc/sof/ipc3-topology.c | 11 +-- + sound/soc/sof/topology.c | 3 +- + 5 files changed, 122 insertions(+), 5 deletions(-) + +diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c +index a06af82b8..ae32748a5 100644 +--- a/sound/soc/amd/acp/acp-mach-common.c ++++ b/sound/soc/amd/acp/acp-mach-common.c +@@ -26,6 +26,8 @@ + #include "../../codecs/rt5682s.h" + #include "../../codecs/nau8825.h" + #include "../../codecs/nau8821.h" ++#include "../../codecs/cs35l41.h" ++ + #include "acp-mach.h" + + #define PCO_PLAT_CLK 48000000 +@@ -1243,6 +1245,78 @@ SND_SOC_DAILINK_DEF(nau8821, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00", + "nau8821-hifi"))); + ++static int acp_cs35l41_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ return 0; ++} ++ ++static int acp_cs35l41_startup(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ ++ runtime->hw.channels_max = DUAL_CHANNEL; ++ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, ++ &constraints_channels); ++ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, ++ &constraints_rates); ++ return 0; ++} ++ ++static int acp_cs35l41_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); ++ struct snd_soc_card *card = rtd->card; ++ struct snd_soc_dai *codec_dai; ++ int ret, i; ++ unsigned int num_codecs = rtd->dai_link->num_codecs; ++ unsigned int bclk_val; ++ ++ ret = 0; ++ for (i = 0; i < num_codecs; i++) { ++ codec_dai = asoc_rtd_to_codec(rtd, i); ++ if (strcmp(codec_dai->name, "cs35l41-pcm") == 0) { ++ switch (params_rate(params)) { ++ case 48000: ++ bclk_val = 1536000; ++ break; ++ default: ++ dev_err(card->dev, "Invalid Samplerate:0x%x\n", ++ params_rate(params)); ++ return -EINVAL; ++ } ++ ret = snd_soc_component_set_sysclk(codec_dai->component, ++ 0, 0, bclk_val, SND_SOC_CLOCK_IN); ++ if (ret < 0) { ++ dev_err(card->dev, "failed to set sysclk for CS35l41 dai\n"); ++ return ret; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++static struct snd_soc_codec_conf cs35l41_conf[] = { ++ { ++ .dlc = COMP_CODEC_CONF("spi-VLV1776:00"), ++ .name_prefix = "Left", ++ }, ++ { ++ .dlc = COMP_CODEC_CONF("spi-VLV1776:01"), ++ .name_prefix = "Right", ++ }, ++}; ++ ++static const struct snd_soc_ops acp_cs35l41_ops = { ++ .startup = acp_cs35l41_startup, ++ .hw_params = acp_cs35l41_hw_params, ++}; ++ ++SND_SOC_DAILINK_DEF(cs35l41, ++ DAILINK_COMP_ARRAY(COMP_CODEC("spi-VLV1776:00", "cs35l41-pcm"), ++ COMP_CODEC("spi-VLV1776:01", "cs35l41-pcm"))); ++ + /* Declare DMIC codec components */ + SND_SOC_DAILINK_DEF(dmic_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); +@@ -1278,6 +1352,8 @@ SND_SOC_DAILINK_DEF(sof_hs, + DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs"))); + SND_SOC_DAILINK_DEF(sof_hs_virtual, + DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual"))); ++SND_SOC_DAILINK_DEF(sof_bt, ++ DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-bt"))); + SND_SOC_DAILINK_DEF(sof_dmic, + DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic"))); + SND_SOC_DAILINK_DEF(pdm_dmic, +@@ -1336,6 +1412,8 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) + + if (drv_data->hs_cpu_id) + num_links++; ++ if (drv_data->bt_cpu_id) ++ num_links++; + if (drv_data->amp_cpu_id) + num_links++; + if (drv_data->dmic_cpu_id) +@@ -1421,6 +1499,7 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) + links[i].platforms = sof_component; + links[i].num_platforms = ARRAY_SIZE(sof_component); + links[i].dpcm_playback = 1; ++ links[i].dpcm_capture = 1; + links[i].nonatomic = true; + links[i].no_pcm = 1; + if (!drv_data->amp_codec_id) { +@@ -1453,6 +1532,7 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) + links[i].platforms = sof_component; + links[i].num_platforms = ARRAY_SIZE(sof_component); + links[i].dpcm_playback = 1; ++ links[i].dpcm_capture = 1; + links[i].nonatomic = true; + links[i].no_pcm = 1; + if (!drv_data->amp_codec_id) { +@@ -1482,6 +1562,33 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) + card->codec_conf = rt1019_conf; + card->num_configs = ARRAY_SIZE(rt1019_conf); + } ++ if (drv_data->amp_codec_id == CS35L41) { ++ links[i].codecs = cs35l41; ++ links[i].num_codecs = ARRAY_SIZE(cs35l41); ++ links[i].init = acp_cs35l41_init; ++ card->codec_conf = cs35l41_conf; ++ card->num_configs = ARRAY_SIZE(cs35l41_conf); ++ links[i].ops = &acp_cs35l41_ops; ++ } ++ i++; ++ } ++ ++ if (drv_data->bt_cpu_id == I2S_BT) { ++ links[i].name = "acp-bt-codec"; ++ links[i].id = BT_BE_ID; ++ links[i].cpus = sof_bt; ++ links[i].num_cpus = ARRAY_SIZE(sof_bt); ++ links[i].platforms = sof_component; ++ links[i].num_platforms = ARRAY_SIZE(sof_component); ++ links[i].dpcm_playback = 1; ++ links[i].dpcm_capture = 1; ++ links[i].nonatomic = true; ++ links[i].no_pcm = 1; ++ if (!drv_data->bt_codec_id) { ++ /* Use dummy codec if codec id not specified */ ++ links[i].codecs = &asoc_dummy_dlc; ++ links[i].num_codecs = 1; ++ } + i++; + } + +diff --git a/sound/soc/amd/acp/acp-mach.h b/sound/soc/amd/acp/acp-mach.h +index 2b3ec6594..6feef5a93 100644 +--- a/sound/soc/amd/acp/acp-mach.h ++++ b/sound/soc/amd/acp/acp-mach.h +@@ -23,6 +23,7 @@ + enum be_id { + HEADSET_BE_ID = 0, + AMP_BE_ID, ++ BT_BE_ID, + DMIC_BE_ID, + }; + +@@ -41,6 +42,7 @@ enum codec_endpoints { + MAX98360A, + RT5682S, + NAU8825, ++ CS35L41, + NAU8821, + MAX98388, + }; +@@ -53,9 +55,11 @@ enum platform_end_point { + struct acp_card_drvdata { + unsigned int hs_cpu_id; + unsigned int amp_cpu_id; ++ unsigned int bt_cpu_id; + unsigned int dmic_cpu_id; + unsigned int hs_codec_id; + unsigned int amp_codec_id; ++ unsigned int bt_codec_id; + unsigned int dmic_codec_id; + unsigned int dai_fmt; + unsigned int platform; +diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c +index 5223033a1..45d4ce17c 100644 +--- a/sound/soc/amd/acp/acp-sof-mach.c ++++ b/sound/soc/amd/acp/acp-sof-mach.c +@@ -86,9 +86,11 @@ static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = { + static struct acp_card_drvdata sof_nau8821_max98388_data = { + .hs_cpu_id = I2S_SP, + .amp_cpu_id = I2S_HS, ++ .bt_cpu_id = I2S_BT, + .dmic_cpu_id = NONE, + .hs_codec_id = NAU8821, + .amp_codec_id = MAX98388, ++ .bt_codec_id = NONE, + .dmic_codec_id = NONE, + .soc_mclk = true, + .tdm_mode = false, +diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c +index ba4ef290b..2f070f907 100644 +--- a/sound/soc/sof/ipc3-topology.c ++++ b/sound/soc/sof/ipc3-topology.c +@@ -1174,6 +1174,7 @@ static int sof_link_acp_bt_load(struct snd_soc_component *scomp, struct snd_sof_ + struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs; + struct sof_dai_private_data *private = dai->private; + u32 size = sizeof(*config); ++ int ret; + + /* handle master/slave and inverted clocks */ + sof_dai_set_format(hw_config, config); +@@ -1182,12 +1183,14 @@ static int sof_link_acp_bt_load(struct snd_soc_component *scomp, struct snd_sof_ + memset(&config->acpbt, 0, sizeof(config->acpbt)); + config->hdr.size = size; + +- config->acpbt.fsync_rate = le32_to_cpu(hw_config->fsync_rate); +- config->acpbt.tdm_slots = le32_to_cpu(hw_config->tdm_slots); ++ ret = sof_update_ipc_object(scomp, &config->acpbt, SOF_ACPI2S_TOKENS, slink->tuples, ++ slink->num_tuples, size, slink->num_hw_configs); ++ if (ret < 0) ++ return ret; + +- dev_info(scomp->dev, "ACP_BT config ACP%d channel %d rate %d\n", ++ dev_info(scomp->dev, "ACP_BT config ACP%d channel %d rate %d tdm_mode %d\n", + config->dai_index, config->acpbt.tdm_slots, +- config->acpbt.fsync_rate); ++ config->acpbt.fsync_rate, config->acpbt.tdm_mode); + + dai->number_configs = 1; + dai->current_config = 0; +diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c +index a3a3af252..a634ae05f 100644 +--- a/sound/soc/sof/topology.c ++++ b/sound/soc/sof/topology.c +@@ -289,7 +289,7 @@ static const struct sof_dai_types sof_dais[] = { + {"ALH", SOF_DAI_INTEL_ALH}, + {"SAI", SOF_DAI_IMX_SAI}, + {"ESAI", SOF_DAI_IMX_ESAI}, +- {"ACP", SOF_DAI_AMD_BT}, ++ {"ACPBT", SOF_DAI_AMD_BT}, + {"ACPSP", SOF_DAI_AMD_SP}, + {"ACPDMIC", SOF_DAI_AMD_DMIC}, + {"ACPHS", SOF_DAI_AMD_HS}, +@@ -1953,6 +1953,7 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_ + token_id = SOF_ACPDMIC_TOKENS; + num_tuples += token_list[SOF_ACPDMIC_TOKENS].count; + break; ++ case SOF_DAI_AMD_BT: + case SOF_DAI_AMD_SP: + case SOF_DAI_AMD_HS: + case SOF_DAI_AMD_SP_VIRTUAL: +-- +2.43.0 + |