Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve SOF support for Steam Deck OLED

Merge series from Cristian Ciocaltea <cristian.ciocaltea@collabora.com>:

This patch series is a continuation of [1] to provide several fixes and
improvements to the SOF drivers targeting the Vangogh platform, as found on
Valve's Steam Deck OLED. The previous series only handled the legacy ACP
drivers.

Also note that, since v2, this patch series requires an updated SOF
topology to provide a correct DAI link ID for the BT codec. The binary
file should be located under:

/usr/lib/firmware/amd/sof-tplg/sof-vangogh-nau8821-max.tplg

Alternatively, as a temporary workaround, patch [2] can be used to adapt
the driver to the broken topology.

Another requirement to get this functional is patch [3] from v1, which has
been dropped from the series to be upstreamed via the SOF development
workflow.

[1]: https://lore.kernel.org/all/20231209203229.878730-1-cristian.ciocaltea@collabora.com/
[2]: https://lore.kernel.org/all/20231209205351.880797-11-cristian.ciocaltea@collabora.com/
[3]: https://lore.kernel.org/all/20231209205351.880797-12-cristian.ciocaltea@collabora.com/

+70 -44
+3 -3
sound/soc/amd/acp/acp-mach-common.c
··· 821 821 }; 822 822 823 823 SND_SOC_DAILINK_DEF(max98388, 824 - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", "max98388-aif1"), 825 - COMP_CODEC("i2c-ADS8388:01", "max98388-aif1"))); 824 + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", MAX98388_CODEC_DAI), 825 + COMP_CODEC("i2c-ADS8388:01", MAX98388_CODEC_DAI))); 826 826 827 827 static const struct snd_kcontrol_new max98388_controls[] = { 828 828 SOC_DAPM_PIN_SWITCH("Left Spk"), ··· 1273 1273 1274 1274 SND_SOC_DAILINK_DEF(nau8821, 1275 1275 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00", 1276 - "nau8821-hifi"))); 1276 + NAU8821_CODEC_DAI))); 1277 1277 1278 1278 /* Declare DMIC codec components */ 1279 1279 SND_SOC_DAILINK_DEF(dmic_codec,
+7 -19
sound/soc/amd/acp/acp-sof-mach.c
··· 28 28 .hs_codec_id = RT5682, 29 29 .amp_codec_id = RT1019, 30 30 .dmic_codec_id = DMIC, 31 - .tdm_mode = false, 32 31 }; 33 32 34 33 static struct acp_card_drvdata sof_rt5682_max_data = { ··· 37 38 .hs_codec_id = RT5682, 38 39 .amp_codec_id = MAX98360A, 39 40 .dmic_codec_id = DMIC, 40 - .tdm_mode = false, 41 41 }; 42 42 43 43 static struct acp_card_drvdata sof_rt5682s_rt1019_data = { ··· 46 48 .hs_codec_id = RT5682S, 47 49 .amp_codec_id = RT1019, 48 50 .dmic_codec_id = DMIC, 49 - .tdm_mode = false, 50 51 }; 51 52 52 53 static struct acp_card_drvdata sof_rt5682s_max_data = { ··· 55 58 .hs_codec_id = RT5682S, 56 59 .amp_codec_id = MAX98360A, 57 60 .dmic_codec_id = DMIC, 58 - .tdm_mode = false, 59 61 }; 60 62 61 63 static struct acp_card_drvdata sof_nau8825_data = { ··· 65 69 .amp_codec_id = MAX98360A, 66 70 .dmic_codec_id = DMIC, 67 71 .soc_mclk = true, 68 - .tdm_mode = false, 69 72 }; 70 73 71 74 static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = { ··· 75 80 .amp_codec_id = RT1019, 76 81 .dmic_codec_id = DMIC, 77 82 .soc_mclk = true, 78 - .tdm_mode = false, 79 83 }; 80 84 81 85 static struct acp_card_drvdata sof_nau8821_max98388_data = { 82 86 .hs_cpu_id = I2S_SP, 83 87 .amp_cpu_id = I2S_HS, 84 88 .bt_cpu_id = I2S_BT, 85 - .dmic_cpu_id = NONE, 86 89 .hs_codec_id = NAU8821, 87 90 .amp_codec_id = MAX98388, 88 - .bt_codec_id = NONE, 89 - .dmic_codec_id = NONE, 90 91 .soc_mclk = true, 91 - .tdm_mode = false, 92 92 }; 93 93 94 94 static int acp_sof_probe(struct platform_device *pdev) ··· 112 122 if (dmi_id && dmi_id->driver_data) 113 123 acp_card_drvdata->tdm_mode = dmi_id->driver_data; 114 124 115 - acp_sofdsp_dai_links_create(card); 125 + ret = acp_sofdsp_dai_links_create(card); 126 + if (ret) 127 + return dev_err_probe(&pdev->dev, ret, "Failed to create DAI links\n"); 116 128 117 129 ret = devm_snd_soc_register_card(&pdev->dev, card); 118 - if (ret) { 119 - dev_err(&pdev->dev, 120 - "devm_snd_soc_register_card(%s) failed: %d\n", 121 - card->name, ret); 122 - return ret; 123 - } 124 - 130 + if (ret) 131 + return dev_err_probe(&pdev->dev, ret, 132 + "Failed to register card(%s)\n", card->name); 125 133 return 0; 126 134 } 127 135 ··· 166 178 module_platform_driver(acp_asoc_audio); 167 179 168 180 MODULE_IMPORT_NS(SND_SOC_AMD_MACH); 169 - MODULE_DESCRIPTION("ACP chrome SOF audio support"); 181 + MODULE_DESCRIPTION("ACP SOF Machine Driver"); 170 182 MODULE_ALIAS("platform:rt5682-rt1019"); 171 183 MODULE_ALIAS("platform:rt5682-max"); 172 184 MODULE_ALIAS("platform:rt5682s-max");
+27 -7
sound/soc/sof/amd/acp-loader.c
··· 267 267 { 268 268 struct snd_sof_pdata *plat_data = sdev->pdata; 269 269 struct acp_dev_data *adata = plat_data->hw_pdata; 270 + const char *fw_filename; 270 271 int ret; 271 272 272 - ret = request_firmware(&sdev->basefw.fw, adata->fw_code_bin, sdev->dev); 273 + fw_filename = kasprintf(GFP_KERNEL, "%s/%s", 274 + plat_data->fw_filename_prefix, 275 + adata->fw_code_bin); 276 + if (!fw_filename) 277 + return -ENOMEM; 278 + 279 + ret = request_firmware(&sdev->basefw.fw, fw_filename, sdev->dev); 273 280 if (ret < 0) { 281 + kfree(fw_filename); 274 282 dev_err(sdev->dev, "sof signed firmware code bin is missing\n"); 275 283 return ret; 276 284 } else { 277 - dev_dbg(sdev->dev, "request_firmware %s successful\n", adata->fw_code_bin); 285 + dev_dbg(sdev->dev, "request_firmware %s successful\n", fw_filename); 278 286 } 279 - ret = snd_sof_dsp_block_write(sdev, SOF_FW_BLK_TYPE_IRAM, 0, 280 - (void *)sdev->basefw.fw->data, sdev->basefw.fw->size); 287 + kfree(fw_filename); 281 288 282 - ret = request_firmware(&adata->fw_dbin, adata->fw_data_bin, sdev->dev); 289 + ret = snd_sof_dsp_block_write(sdev, SOF_FW_BLK_TYPE_IRAM, 0, 290 + (void *)sdev->basefw.fw->data, 291 + sdev->basefw.fw->size); 292 + 293 + fw_filename = kasprintf(GFP_KERNEL, "%s/%s", 294 + plat_data->fw_filename_prefix, 295 + adata->fw_data_bin); 296 + if (!fw_filename) 297 + return -ENOMEM; 298 + 299 + ret = request_firmware(&adata->fw_dbin, fw_filename, sdev->dev); 283 300 if (ret < 0) { 301 + kfree(fw_filename); 284 302 dev_err(sdev->dev, "sof signed firmware data bin is missing\n"); 285 303 return ret; 286 304 287 305 } else { 288 - dev_dbg(sdev->dev, "request_firmware %s successful\n", adata->fw_data_bin); 306 + dev_dbg(sdev->dev, "request_firmware %s successful\n", fw_filename); 289 307 } 308 + kfree(fw_filename); 290 309 291 310 ret = snd_sof_dsp_block_write(sdev, SOF_FW_BLK_TYPE_DRAM, 0, 292 - (void *)adata->fw_dbin->data, adata->fw_dbin->size); 311 + (void *)adata->fw_dbin->data, 312 + adata->fw_dbin->size); 293 313 return ret; 294 314 } 295 315 EXPORT_SYMBOL_NS(acp_sof_load_signed_firmware, SND_SOC_SOF_AMD_COMMON);
+18 -12
sound/soc/sof/amd/acp.c
··· 28 28 29 29 const struct dmi_system_id acp_sof_quirk_table[] = { 30 30 { 31 - /* Valve Jupiter device */ 31 + /* Steam Deck OLED device */ 32 32 .matches = { 33 33 DMI_MATCH(DMI_SYS_VENDOR, "Valve"), 34 34 DMI_MATCH(DMI_PRODUCT_NAME, "Galileo"), 35 - DMI_MATCH(DMI_PRODUCT_FAMILY, "Sephiroth"), 36 35 }, 37 36 .driver_data = (void *)SECURED_FIRMWARE, 38 37 }, ··· 493 494 int amd_sof_acp_probe(struct snd_sof_dev *sdev) 494 495 { 495 496 struct pci_dev *pci = to_pci_dev(sdev->dev); 496 - struct snd_sof_pdata *plat_data = sdev->pdata; 497 497 struct acp_dev_data *adata; 498 498 const struct sof_amd_acp_desc *chip; 499 499 const struct dmi_system_id *dmi_id; ··· 559 561 adata->signed_fw_image = false; 560 562 dmi_id = dmi_first_match(acp_sof_quirk_table); 561 563 if (dmi_id && dmi_id->driver_data) { 562 - adata->fw_code_bin = kasprintf(GFP_KERNEL, "%s/sof-%s-code.bin", 563 - plat_data->fw_filename_prefix, 564 - chip->name); 565 - adata->fw_data_bin = kasprintf(GFP_KERNEL, "%s/sof-%s-data.bin", 566 - plat_data->fw_filename_prefix, 567 - chip->name); 568 - adata->signed_fw_image = dmi_id->driver_data; 564 + adata->fw_code_bin = devm_kasprintf(sdev->dev, GFP_KERNEL, 565 + "sof-%s-code.bin", 566 + chip->name); 567 + if (!adata->fw_code_bin) { 568 + ret = -ENOMEM; 569 + goto free_ipc_irq; 570 + } 569 571 570 - dev_dbg(sdev->dev, "fw_code_bin:%s, fw_data_bin:%s\n", adata->fw_code_bin, 571 - adata->fw_data_bin); 572 + adata->fw_data_bin = devm_kasprintf(sdev->dev, GFP_KERNEL, 573 + "sof-%s-data.bin", 574 + chip->name); 575 + if (!adata->fw_data_bin) { 576 + ret = -ENOMEM; 577 + goto free_ipc_irq; 578 + } 579 + 580 + adata->signed_fw_image = dmi_id->driver_data; 572 581 } 582 + 573 583 adata->enable_fw_debug = enable_fw_debug; 574 584 acp_memory_init(sdev); 575 585
+15 -3
sound/soc/sof/fw-file-profile.c
··· 89 89 return ret; 90 90 } 91 91 92 + static bool sof_platform_uses_generic_loader(struct snd_sof_dev *sdev) 93 + { 94 + return (sdev->pdata->desc->ops->load_firmware == snd_sof_load_firmware_raw || 95 + sdev->pdata->desc->ops->load_firmware == snd_sof_load_firmware_memcpy); 96 + } 97 + 92 98 static int 93 99 sof_file_profile_for_ipc_type(struct snd_sof_dev *sdev, 94 100 enum sof_ipc_type ipc_type, ··· 136 130 * For default path and firmware name do a verification before 137 131 * continuing further. 138 132 */ 139 - if (base_profile->fw_path || base_profile->fw_name) { 133 + if ((base_profile->fw_path || base_profile->fw_name) && 134 + sof_platform_uses_generic_loader(sdev)) { 140 135 ret = sof_test_firmware_file(dev, out_profile, &ipc_type); 141 136 if (ret) 142 137 return ret; ··· 188 181 out_profile->ipc_type = ipc_type; 189 182 190 183 /* Test only default firmware file */ 191 - if (!base_profile->fw_path && !base_profile->fw_name) 184 + if ((!base_profile->fw_path && !base_profile->fw_name) && 185 + sof_platform_uses_generic_loader(sdev)) 192 186 ret = sof_test_firmware_file(dev, out_profile, NULL); 193 187 194 188 if (!ret) ··· 275 267 276 268 dev_info(dev, "Firmware paths/files for ipc type %d:\n", profile->ipc_type); 277 269 278 - dev_info(dev, " Firmware file: %s/%s\n", profile->fw_path, profile->fw_name); 270 + /* The firmware path is only valid when generic loader is used */ 271 + if (sof_platform_uses_generic_loader(sdev)) 272 + dev_info(dev, " Firmware file: %s/%s\n", 273 + profile->fw_path, profile->fw_name); 274 + 279 275 if (profile->fw_lib_path) 280 276 dev_info(dev, " Firmware lib path: %s\n", profile->fw_lib_path); 281 277 dev_info(dev, " Topology file: %s/%s\n", profile->tplg_path, profile->tplg_name);