diff --git a/include/sound/sof.h b/include/sound/sof.h index 268d0ca0f69f2b..ecb43e76100190 100644 --- a/include/sound/sof.h +++ b/include/sound/sof.h @@ -57,6 +57,17 @@ enum sof_ipc_type { SOF_IPC_TYPE_COUNT }; +struct sof_loadable_file_profile { + enum sof_ipc_type ipc_type; + + const char *fw_path; + const char *fw_name; + const char *fw_lib_path; + const char *fw_path_postfix; + const char *tplg_path; + const char *tplg_name; +}; + /* * SOF Platform data. */ @@ -86,6 +97,9 @@ struct snd_sof_pdata { /* descriptor */ const struct sof_dev_desc *desc; + /* platform's preferred IPC type and path overrides */ + struct sof_loadable_file_profile ipc_file_profile_base; + /* firmware and topology filenames */ const char *fw_filename_prefix; const char *fw_filename; @@ -143,13 +157,9 @@ struct sof_dev_desc { /* The platform supports DSPless mode */ bool dspless_mode_supported; - /* defaults paths for firmware, library and topology files */ - const char *default_fw_path[SOF_IPC_TYPE_COUNT]; - const char *default_lib_path[SOF_IPC_TYPE_COUNT]; - const char *default_tplg_path[SOF_IPC_TYPE_COUNT]; - - /* default firmware name */ - const char *default_fw_filename[SOF_IPC_TYPE_COUNT]; + /* strings used for the firmware layout path/filename creation */ + const char *vendor; + const char *platform; struct snd_sof_dsp_ops *ops; int (*ops_init)(struct snd_sof_dev *sdev); diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig index a741ed96e78976..32ffd345e07fc4 100644 --- a/sound/soc/sof/Kconfig +++ b/sound/soc/sof/Kconfig @@ -126,6 +126,17 @@ config SND_SOC_SOF_STRICT_ABI_CHECKS If you are not involved in SOF releases and CI development, select "N". +config SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION + bool "SOF allow fallback to newer IPC version" + help + This option will allow the kernel to try to 'fallback' to a newer IPC + version if there are missing firmware files to satisfy the default IPC + version. + IPC version fallback to older versions is not affected by this option, + it is always available. + Say Y if you are involved in SOF development and need this option. + If not, select N. + config SND_SOC_SOF_DEBUG bool "SOF debugging features" help diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index ef6fd43d0b72d1..3624124575afdf 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -1,7 +1,8 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ - control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o + control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o\ + fw-file-profile.o # IPC implementations ifneq ($(CONFIG_SND_SOC_SOF_IPC3),) diff --git a/sound/soc/sof/amd/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c index 72e211b5f7a489..508c6259d82fe2 100644 --- a/sound/soc/sof/amd/pci-rmb.c +++ b/sound/soc/sof/amd/pci-rmb.c @@ -49,15 +49,8 @@ static const struct sof_dev_desc rembrandt_desc = { .chip_info = &rembrandt_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "amd/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "amd/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-rmb.ri", - }, + .vendor = "amd", + .platform = "rmb", .nocodec_tplg_filename = "sof-acp.tplg", .ops = &sof_rembrandt_ops, .ops_init = sof_rembrandt_ops_init, diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c index a0195e9b400c89..90a9edae57944b 100644 --- a/sound/soc/sof/amd/pci-rn.c +++ b/sound/soc/sof/amd/pci-rn.c @@ -49,15 +49,8 @@ static const struct sof_dev_desc renoir_desc = { .chip_info = &renoir_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "amd/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "amd/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-rn.ri", - }, + .vendor = "amd", + .platform = "rn", .nocodec_tplg_filename = "sof-acp.tplg", .ops = &sof_renoir_ops, .ops_init = sof_renoir_ops_init, diff --git a/sound/soc/sof/amd/pci-vangogh.c b/sound/soc/sof/amd/pci-vangogh.c index 5cd3ac84752fb8..a21674be337c7f 100644 --- a/sound/soc/sof/amd/pci-vangogh.c +++ b/sound/soc/sof/amd/pci-vangogh.c @@ -47,15 +47,8 @@ static const struct sof_dev_desc vangogh_desc = { .chip_info = &vangogh_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "amd/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "amd/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-vangogh.ri", - }, + .vendor = "amd", + .platform = "vangogh", .nocodec_tplg_filename = "sof-acp.tplg", .ops = &sof_vangogh_ops, .ops_init = sof_vangogh_ops_init, diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 2d1616b81485c5..1de72c8717f873 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -13,6 +13,7 @@ #include #include #include "sof-priv.h" +#include "sof-of-dev.h" #include "ops.h" #define CREATE_TRACE_POINTS @@ -143,6 +144,208 @@ void sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state) } EXPORT_SYMBOL(sof_set_fw_state); +/* SOF Driver enumeration */ +static int sof_machine_check(struct snd_sof_dev *sdev) +{ + struct snd_sof_pdata *sof_pdata = sdev->pdata; + const struct sof_dev_desc *desc = sof_pdata->desc; + struct snd_soc_acpi_mach *mach; + + if (!IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)) { + const struct snd_sof_of_mach *of_mach; + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + goto nocodec; + + /* find machine */ + mach = snd_sof_machine_select(sdev); + if (mach) { + sof_pdata->machine = mach; + + if (sof_pdata->subsystem_id_set) { + mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor; + mach->mach_params.subsystem_device = sof_pdata->subsystem_device; + mach->mach_params.subsystem_id_set = true; + } + + snd_sof_set_mach_params(mach, sdev); + return 0; + } + + of_mach = sof_of_machine_select(sdev); + if (of_mach) { + sof_pdata->of_machine = of_mach; + return 0; + } + + if (!IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)) { + dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n"); + return -ENODEV; + } + } else { + dev_warn(sdev->dev, "Force to use nocodec mode\n"); + } + +nocodec: + /* select nocodec mode */ + dev_warn(sdev->dev, "Using nocodec machine driver\n"); + mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL); + if (!mach) + return -ENOMEM; + + mach->drv_name = "sof-nocodec"; + if (!sof_pdata->tplg_filename) + sof_pdata->tplg_filename = desc->nocodec_tplg_filename; + + sof_pdata->machine = mach; + snd_sof_set_mach_params(mach, sdev); + + return 0; +} + +static int sof_select_ipc_and_paths(struct snd_sof_dev *sdev) +{ + struct snd_sof_pdata *plat_data = sdev->pdata; + struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; + struct sof_loadable_file_profile out_profile; + struct device *dev = sdev->dev; + int ret; + + if (base_profile->ipc_type != plat_data->desc->ipc_default) + dev_info(dev, + "Module parameter used, overriding default IPC %d to %d\n", + plat_data->desc->ipc_default, base_profile->ipc_type); + + if (base_profile->fw_path) + dev_dbg(dev, "Module parameter used, changed fw path to %s\n", + base_profile->fw_path); + else if (base_profile->fw_path_postfix) + dev_dbg(dev, "Path postfix appended to default fw path: %s\n", + base_profile->fw_path_postfix); + + if (base_profile->fw_lib_path) + dev_dbg(dev, "Module parameter used, changed fw_lib path to %s\n", + base_profile->fw_lib_path); + else if (base_profile->fw_path_postfix) + dev_dbg(dev, "Path postfix appended to default fw_lib path: %s\n", + base_profile->fw_path_postfix); + + if (base_profile->fw_name) + dev_dbg(dev, "Module parameter used, changed fw filename to %s\n", + base_profile->fw_name); + + if (base_profile->tplg_path) + dev_dbg(dev, "Module parameter used, changed tplg path to %s\n", + base_profile->tplg_path); + + if (base_profile->tplg_name) + dev_dbg(dev, "Module parameter used, changed tplg name to %s\n", + base_profile->tplg_name); + + ret = sof_create_ipc_file_profile(sdev, base_profile, &out_profile); + if (ret) + return ret; + + plat_data->ipc_type = out_profile.ipc_type; + plat_data->fw_filename = out_profile.fw_name; + plat_data->fw_filename_prefix = out_profile.fw_path; + plat_data->fw_lib_prefix = out_profile.fw_lib_path; + plat_data->tplg_filename_prefix = out_profile.tplg_path; + + return 0; +} + +static int validate_sof_ops(struct snd_sof_dev *sdev) +{ + int ret; + + /* init ops, if necessary */ + ret = sof_ops_init(sdev); + if (ret < 0) + return ret; + + /* check all mandatory ops */ + if (!sof_ops(sdev) || !sof_ops(sdev)->probe) { + dev_err(sdev->dev, "missing mandatory ops\n"); + sof_ops_free(sdev); + return -EINVAL; + } + + if (!sdev->dspless_mode_selected && + (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read || + !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg || + !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) { + dev_err(sdev->dev, "missing mandatory DSP ops\n"); + sof_ops_free(sdev); + return -EINVAL; + } + + return 0; +} + +static int sof_init_environment(struct snd_sof_dev *sdev) +{ + struct snd_sof_pdata *plat_data = sdev->pdata; + struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; + int ret; + + /* check IPC support */ + if (!(BIT(base_profile->ipc_type) & plat_data->desc->ipc_supported_mask)) { + dev_err(sdev->dev, + "ipc_type %d is not supported on this platform, mask is %#x\n", + base_profile->ipc_type, plat_data->desc->ipc_supported_mask); + return -EINVAL; + } + + /* + * Save the selected IPC type and a topology name override before + * selecting ops since platform code might need this information + */ + plat_data->ipc_type = base_profile->ipc_type; + plat_data->tplg_filename = base_profile->tplg_name; + + /* init ops, if necessary */ + ret = validate_sof_ops(sdev); + if (ret < 0) + return ret; + + /* probe the DSP hardware */ + ret = snd_sof_probe(sdev); + if (ret < 0) { + dev_err(sdev->dev, "failed to probe DSP %d\n", ret); + sof_ops_free(sdev); + return ret; + } + + /* check machine info */ + ret = sof_machine_check(sdev); + if (ret < 0) { + dev_err(sdev->dev, "failed to get machine info %d\n", ret); + goto err_machine_check; + } + + ret = sof_select_ipc_and_paths(sdev); + if (!ret && plat_data->ipc_type != base_profile->ipc_type) { + /* IPC type changed, re-initialize the ops */ + sof_ops_free(sdev); + + ret = validate_sof_ops(sdev); + if (ret < 0) { + snd_sof_remove(sdev); + return ret; + } + } + +err_machine_check: + if (ret) { + snd_sof_remove(sdev); + sof_ops_free(sdev); + } + + return ret; +} + /* * FW Boot State Transition Diagram * @@ -188,23 +391,13 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) struct snd_sof_pdata *plat_data = sdev->pdata; int ret; - /* probe the DSP hardware */ - ret = snd_sof_probe(sdev); - if (ret < 0) { - dev_err(sdev->dev, "error: failed to probe DSP %d\n", ret); - goto probe_err; - } + /* Initialize loadable file paths and check the environment validity */ + ret = sof_init_environment(sdev); + if (ret) + return ret; sof_set_fw_state(sdev, SOF_FW_BOOT_PREPARE); - /* check machine info */ - ret = sof_machine_check(sdev); - if (ret < 0) { - dev_err(sdev->dev, "error: failed to get machine info %d\n", - ret); - goto dsp_err; - } - /* set up platform component driver */ snd_sof_new_platform_drv(sdev); @@ -324,9 +517,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) ipc_err: dbg_err: snd_sof_free_debug(sdev); -dsp_err: snd_sof_remove(sdev); -probe_err: sof_ops_free(sdev); /* all resources freed, update state to match */ @@ -352,7 +543,6 @@ static void sof_probe_work(struct work_struct *work) int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) { struct snd_sof_dev *sdev; - int ret; sdev = devm_kzalloc(dev, sizeof(*sdev), GFP_KERNEL); if (!sdev) @@ -380,34 +570,6 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) } } - /* check IPC support */ - if (!(BIT(plat_data->ipc_type) & plat_data->desc->ipc_supported_mask)) { - dev_err(dev, "ipc_type %d is not supported on this platform, mask is %#x\n", - plat_data->ipc_type, plat_data->desc->ipc_supported_mask); - return -EINVAL; - } - - /* init ops, if necessary */ - ret = sof_ops_init(sdev); - if (ret < 0) - return ret; - - /* check all mandatory ops */ - if (!sof_ops(sdev) || !sof_ops(sdev)->probe) { - sof_ops_free(sdev); - dev_err(dev, "missing mandatory ops\n"); - return -EINVAL; - } - - if (!sdev->dspless_mode_selected && - (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read || - !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg || - !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) { - sof_ops_free(sdev); - dev_err(dev, "missing mandatory DSP ops\n"); - return -EINVAL; - } - INIT_LIST_HEAD(&sdev->pcm_list); INIT_LIST_HEAD(&sdev->kcontrol_list); INIT_LIST_HEAD(&sdev->widget_list); @@ -512,6 +674,40 @@ int snd_sof_device_shutdown(struct device *dev) } EXPORT_SYMBOL(snd_sof_device_shutdown); +/* Machine driver registering and unregistering */ +int sof_machine_register(struct snd_sof_dev *sdev, void *pdata) +{ + struct snd_sof_pdata *plat_data = pdata; + const char *drv_name; + const void *mach; + int size; + + drv_name = plat_data->machine->drv_name; + mach = plat_data->machine; + size = sizeof(*plat_data->machine); + + /* register machine driver, pass machine info as pdata */ + plat_data->pdev_mach = + platform_device_register_data(sdev->dev, drv_name, + PLATFORM_DEVID_NONE, mach, size); + if (IS_ERR(plat_data->pdev_mach)) + return PTR_ERR(plat_data->pdev_mach); + + dev_dbg(sdev->dev, "created machine %s\n", + dev_name(&plat_data->pdev_mach->dev)); + + return 0; +} +EXPORT_SYMBOL(sof_machine_register); + +void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata) +{ + struct snd_sof_pdata *plat_data = pdata; + + platform_device_unregister(plat_data->pdev_mach); +} +EXPORT_SYMBOL(sof_machine_unregister); + MODULE_AUTHOR("Liam Girdwood"); MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/sof/fw-file-profile.c b/sound/soc/sof/fw-file-profile.c new file mode 100644 index 00000000000000..154ba5e71cc9d4 --- /dev/null +++ b/sound/soc/sof/fw-file-profile.c @@ -0,0 +1,554 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// + +#include +#include +#include +#include "sof-priv.h" + +/** + * enum sof_fw_layout_type - pre-defined file-layout for loadable fw files + * @SOF_FW_LAYOUT_IPC3_SOF: + * firmware path: /sof + * firmware name: sof-.ri + * topology path: /sof-tplg/ + * @SOF_FW_LAYOUT_IPC4_SOF: + * firmware path: /sof-ipc4/ + * firmware name: sof-.ri + * firmware lib path: /sof-ipc4-lib/ + * topology path: /sof-ipc4-tplg/ + * @SOF_FW_LAYOUT_IPC4_INTEL_ACE: + * firmware path: intel/sof-ipc4/ + * firmware name: sof-.ri + * firmware lib path: intel/sof-ipc4-lib/ + * topology path: intel/sof-ace-tplg/ + * @SOF_FW_LAYOUT_IPC4_INTEL_AVS: + * firmware path: intel/avs/ + * firmware name: dsp_basefw.bin + * firmware lib path: intel/avs/ + * topology path: intel/avs-tplg/ + */ +enum sof_fw_layout_type { + SOF_FW_LAYOUT_IPC3_SOF, + SOF_FW_LAYOUT_IPC4_SOF, + SOF_FW_LAYOUT_IPC4_INTEL_ACE, + SOF_FW_LAYOUT_IPC4_INTEL_AVS, +}; + +struct sof_fw_layout_map { + enum sof_ipc_type ipc_type; + char *layout_name; +}; + +static const struct sof_fw_layout_map fw_layouts[] = { + { .ipc_type = SOF_IPC_TYPE_3, .layout_name = "SOF IPC3", }, + { .ipc_type = SOF_IPC_TYPE_4, .layout_name = "SOF IPC4", }, + { .ipc_type = SOF_IPC_TYPE_4, .layout_name = "SOF IPC4 for Intel ACE platforms", }, + { .ipc_type = SOF_IPC_TYPE_4, .layout_name = "Intel AVS IPC4", }, +}; + +static int sof_test_firmware_file(struct device *dev, + struct sof_loadable_file_profile *profile, + enum sof_ipc_type *ipc_type_to_adjust) +{ + enum sof_ipc_type fw_ipc_type; + const struct firmware *fw; + const char *fw_filename; + const u32 *magic; + int ret; + + fw_filename = kasprintf(GFP_KERNEL, "%s/%s", profile->fw_path, + profile->fw_name); + if (!fw_filename) + return -ENOMEM; + + ret = firmware_request_nowarn(&fw, fw_filename, dev); + if (ret < 0) { + dev_dbg(dev, "Failed to open firmware file: %s\n", fw_filename); + kfree(fw_filename); + return ret; + } + + /* firmware file exists, check the magic number */ + magic = (const u32 *)fw->data; + switch (*magic) { + case SOF_EXT_MAN_MAGIC_NUMBER: + fw_ipc_type = SOF_IPC_TYPE_3; + break; + case SOF_EXT_MAN4_MAGIC_NUMBER: + fw_ipc_type = SOF_IPC_TYPE_4; + break; + default: + dev_err(dev, "Invalid firmware magic: %#x\n", *magic); + ret = -EINVAL; + goto out; + } + + if (ipc_type_to_adjust) { + *ipc_type_to_adjust = fw_ipc_type; + } else if (fw_ipc_type != profile->ipc_type) { + dev_err(dev, + "ipc type mismatch between %s and expected: %d vs %d\n", + fw_filename, fw_ipc_type, profile->ipc_type); + ret = -EINVAL; + } +out: + release_firmware(fw); + kfree(fw_filename); + + return ret; +} + +static int sof_test_topology_file(struct device *dev, + struct sof_loadable_file_profile *profile) +{ + const struct firmware *fw; + const char *tplg_filename; + int ret; + + if (!profile->tplg_path || !profile->tplg_name) + return 0; + + tplg_filename = kasprintf(GFP_KERNEL, "%s/%s", profile->tplg_path, + profile->tplg_name); + if (!tplg_filename) + return -ENOMEM; + + ret = firmware_request_nowarn(&fw, tplg_filename, dev); + if (!ret) + release_firmware(fw); + else + dev_dbg(dev, "Failed to open topology file: %s\n", tplg_filename); + + kfree(tplg_filename); + + return ret; +} + +static int +sof_create_fw_profile(struct snd_sof_dev *sdev, const struct sof_dev_desc *desc, + struct sof_loadable_file_profile *default_profile, + struct sof_loadable_file_profile *base_profile, + struct sof_loadable_file_profile *out_profile) +{ + enum sof_ipc_type ipc_type = default_profile->ipc_type; + struct snd_sof_pdata *plat_data = sdev->pdata; + struct device *dev = sdev->dev; + int ret = 0; + + /* firmware path */ + if (base_profile->fw_path) + out_profile->fw_path = base_profile->fw_path; + else + out_profile->fw_path = default_profile->fw_path; + + /* firmware filename */ + if (base_profile->fw_name) + out_profile->fw_name = base_profile->fw_name; + else + out_profile->fw_name = default_profile->fw_name; + + /* + * Check the custom firmware path/filename and adjust the ipc_type to + * match with the existing file for the remaining path configuration. + * + * For default path and firmware name do a verification before + * continuing further. + */ + if (base_profile->fw_path || base_profile->fw_name) { + ret = sof_test_firmware_file(dev, out_profile, &ipc_type); + if (ret) + return ret; + + if (!(desc->ipc_supported_mask & BIT(ipc_type))) { + dev_err(dev, "Unsupported IPC type %d needed by %s/%s\n", + ipc_type, out_profile->fw_path, + out_profile->fw_name); + return -EINVAL; + } + } + + /* firmware library path */ + if (base_profile->fw_lib_path) + out_profile->fw_lib_path = base_profile->fw_lib_path; + else if (default_profile->fw_lib_path) + out_profile->fw_lib_path = default_profile->fw_lib_path; + + if (base_profile->fw_path_postfix) + out_profile->fw_path_postfix = base_profile->fw_path_postfix; + + /* topology path */ + if (base_profile->tplg_path) + out_profile->tplg_path = base_profile->tplg_path; + else + out_profile->tplg_path = default_profile->tplg_path; + + /* topology name */ + out_profile->tplg_name = plat_data->tplg_filename; + + out_profile->ipc_type = ipc_type; + + /* Test only default firmware file */ + if (!base_profile->fw_path && !base_profile->fw_name) + ret = sof_test_firmware_file(dev, out_profile, NULL); + + if (!ret) + ret = sof_test_topology_file(dev, out_profile); + + if (ret) + memset(out_profile, 0, sizeof(*out_profile)); + + return ret; +} + +static void sof_free_profile_strings(struct device *dev, + struct sof_loadable_file_profile *profile) +{ + devm_kfree(dev, profile->fw_path); + devm_kfree(dev, profile->fw_lib_path); + devm_kfree(dev, profile->fw_name); + devm_kfree(dev, profile->tplg_path); + + memset(profile, 0, sizeof(*profile)); +} + +static int +sof_default_fw_layout(struct device *dev, const enum sof_fw_layout_type layout_type, + const char *vendor, const char *platform, + const char *fw_path_postfix, + struct sof_loadable_file_profile *default_profile) +{ + int ret = -ENOMEM; + const char *str; + + switch (layout_type) { + case SOF_FW_LAYOUT_IPC3_SOF: + default_profile->ipc_type = SOF_IPC_TYPE_3; + /* + * firmware path: /sof + * firmware name: sof-.ri + * topology path: /sof-tplg/ + */ + if (fw_path_postfix) + str = devm_kasprintf(dev, GFP_KERNEL, "%s/sof/%s", + vendor, fw_path_postfix); + else + str = devm_kasprintf(dev, GFP_KERNEL, "%s/sof", vendor); + if (!str) + return -ENOMEM; + + default_profile->fw_path = str; + + default_profile->fw_name = devm_kasprintf(dev, GFP_KERNEL, + "sof-%s.ri", platform); + if (!default_profile->fw_name) + goto err; + + default_profile->tplg_path = devm_kasprintf(dev, GFP_KERNEL, + "%s/sof-tplg", vendor); + if (!default_profile->tplg_path) + goto err; + break; + case SOF_FW_LAYOUT_IPC4_SOF: + default_profile->ipc_type = SOF_IPC_TYPE_4; + /* + * firmware path: /sof-ipc4/ + * firmware name: sof-.ri + * firmware lib path: /sof-ipc4-lib/ + * topology path: /sof-ipc4-tplg/ + */ + if (fw_path_postfix) + str = devm_kasprintf(dev, GFP_KERNEL, "%s/sof-ipc4/%s/%s", + vendor, platform, fw_path_postfix); + else + str = devm_kasprintf(dev, GFP_KERNEL, "%s/sof-ipc4/%s", + vendor, platform); + if (!str) + return -ENOMEM; + + default_profile->fw_path = str; + + default_profile->fw_name = devm_kasprintf(dev, GFP_KERNEL, + "sof-%s.ri", platform); + if (!default_profile->fw_name) + goto err; + + if (fw_path_postfix) + str = devm_kasprintf(dev, GFP_KERNEL, "%s/sof-ipc4-lib/%s/%s", + vendor, platform, fw_path_postfix); + else + str = devm_kasprintf(dev, GFP_KERNEL, "%s/sof-ipc4-lib/%s", + vendor, platform); + if (!str) + goto err; + + default_profile->fw_lib_path = str; + + default_profile->tplg_path = devm_kasprintf(dev, GFP_KERNEL, + "%s/sof-ipc4-tplg", vendor); + if (!default_profile->tplg_path) + goto err; + break; + case SOF_FW_LAYOUT_IPC4_INTEL_ACE: + default_profile->ipc_type = SOF_IPC_TYPE_4; + /* + * firmware path: intel/sof-ipc4/ + * firmware name: sof-.ri + * firmware lib path: intel/sof-ipc4-lib/ + * topology path: intel/sof-ace-tplg/ + */ + if (fw_path_postfix) + str = devm_kasprintf(dev, GFP_KERNEL, "intel/sof-ipc4/%s/%s", + platform, fw_path_postfix); + else + str = devm_kasprintf(dev, GFP_KERNEL, "intel/sof-ipc4/%s", + platform); + if (!str) + return -ENOMEM; + + default_profile->fw_path = str; + + default_profile->fw_name = devm_kasprintf(dev, GFP_KERNEL, + "sof-%s.ri", platform); + if (!default_profile->fw_name) + goto err; + + if (fw_path_postfix) + str = devm_kasprintf(dev, GFP_KERNEL, "intel/sof-ipc4-lib/%s/%s", + platform, fw_path_postfix); + else + str = devm_kasprintf(dev, GFP_KERNEL, "intel/sof-ipc4-lib/%s", + platform); + if (!str) + goto err; + + default_profile->fw_lib_path = str; + + default_profile->tplg_path = devm_kstrdup(dev, "intel/sof-ace-tplg", + GFP_KERNEL); + if (!default_profile->tplg_path) + goto err; + break; + case SOF_FW_LAYOUT_IPC4_INTEL_AVS: + default_profile->ipc_type = SOF_IPC_TYPE_4; + /* + * firmware path: intel/avs/ + * firmware name: dsp_basefw.bin + * firmware lib path: intel/avs-lib/ + * topology path: intel/avs-tplg/ + */ + if (fw_path_postfix) + str = devm_kasprintf(dev, GFP_KERNEL, "intel/avs/%s/%s", + platform, fw_path_postfix); + else + str = devm_kasprintf(dev, GFP_KERNEL, "intel/avs/%s", + platform); + if (!str) + return -ENOMEM; + + default_profile->fw_path = str; + + default_profile->fw_name = devm_kstrdup(dev, "dsp_basefw.bin", + GFP_KERNEL); + if (!default_profile->fw_name) + goto err; + + if (fw_path_postfix) + str = devm_kasprintf(dev, GFP_KERNEL, "intel/avs/%s/%s", + platform, fw_path_postfix); + else + str = devm_kasprintf(dev, GFP_KERNEL, "intel/avs/%s", + platform); + if (!str) + goto err; + + default_profile->fw_lib_path = str; + + default_profile->tplg_path = devm_kstrdup(dev, "intel/avs-tplg", + GFP_KERNEL); + if (!default_profile->tplg_path) + goto err; + break; + default: + dev_err(dev, "Invalid firmware layout type: %d\n", layout_type); + return -EINVAL; + } + + return 0; + +err: + sof_free_profile_strings(dev, default_profile); + + return ret; +} + +static int +sof_file_profile_for_ipc_type(struct snd_sof_dev *sdev, + enum sof_ipc_type ipc_type, + const struct sof_dev_desc *desc, + struct sof_loadable_file_profile *base_profile, + struct sof_loadable_file_profile *out_profile) +{ + struct sof_loadable_file_profile default_profile = { 0 }; + bool found = false; + int i, ret; + + memset(out_profile, 0, sizeof(*out_profile)); + + for (i = 0; i < ARRAY_SIZE(fw_layouts); i++) { + if (fw_layouts[i].ipc_type != ipc_type) + continue; + + ret = sof_default_fw_layout(sdev->dev, i, desc->vendor, + desc->platform, + base_profile->fw_path_postfix, + &default_profile); + if (ret) + return ret; + + ret = sof_create_fw_profile(sdev, desc, &default_profile, + base_profile, out_profile); + if (!ret) { + found = true; + break; + } + + sof_free_profile_strings(sdev->dev, &default_profile); + } + + if (!found) + return -ENOENT; + + return 0; +} + +static void +sof_missing_firmware_notification(struct snd_sof_dev *sdev, + enum sof_ipc_type ipc_type, + struct sof_loadable_file_profile *base_profile) +{ + struct sof_loadable_file_profile default_profile = { 0 }; + struct snd_sof_pdata *plat_data = sdev->pdata; + const struct sof_dev_desc *desc = plat_data->desc; + struct device *dev = sdev->dev; + int ipc_type_count, i, j, ret; + char *marker; + + dev_err(dev, "SOF firmware and/or topology file not found.\n"); + dev_info(dev, "Supported default profiles\n"); + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION)) + ipc_type_count = SOF_IPC_TYPE_COUNT - 1; + else + ipc_type_count = base_profile->ipc_type; + + for (i = 0; i <= ipc_type_count; i++) { + if (!(desc->ipc_supported_mask & BIT(i))) + continue; + + if (i == ipc_type) + marker = "Requested"; + else + marker = "Fallback"; + + dev_info(dev, "- ipc type %d (%s):\n", i, marker); + for (j = 0; j < ARRAY_SIZE(fw_layouts); j++) { + if (fw_layouts[j].ipc_type != i) + continue; + + ret = sof_default_fw_layout(sdev->dev, j, desc->vendor, + desc->platform, + base_profile->fw_path_postfix, + &default_profile); + if (ret) + return; + + dev_info(dev, " Firmware layout: %s\n", + fw_layouts[j].layout_name); + dev_info(dev, " Firmware file: %s/%s\n", + default_profile.fw_path, default_profile.fw_name); + dev_info(dev, " Topology file: %s/%s\n", + default_profile.tplg_path, plat_data->tplg_filename); + + sof_free_profile_strings(sdev->dev, &default_profile); + } + } + + if (base_profile->fw_path || base_profile->fw_name || + base_profile->tplg_path || base_profile->tplg_name) + dev_info(dev, "Verify the path/name override module parameters.\n"); + + dev_info(dev, "Check if you have 'sof-firmware' package installed.\n"); + dev_info(dev, "Optionally it can be manually downloaded from:\n"); + dev_info(dev, " https://github.com/thesofproject/sof-bin/\n"); +} + +static void sof_print_profile_info(struct snd_sof_dev *sdev, + enum sof_ipc_type ipc_type, + struct sof_loadable_file_profile *profile) +{ + struct device *dev = sdev->dev; + + if (ipc_type != profile->ipc_type) + dev_info(dev, + "Using fallback IPC type %d (requested type was %d)\n", + profile->ipc_type, ipc_type); + + dev_info(dev, "Firmware paths/files for ipc type %d:\n", profile->ipc_type); + + dev_info(dev, " Firmware file: %s/%s\n", profile->fw_path, profile->fw_name); + if (profile->fw_lib_path) + dev_info(dev, " Firmware lib path: %s\n", profile->fw_lib_path); + dev_info(dev, " Topology file: %s/%s\n", profile->tplg_path, profile->tplg_name); +} + +int sof_create_ipc_file_profile(struct snd_sof_dev *sdev, + struct sof_loadable_file_profile *base_profile, + struct sof_loadable_file_profile *out_profile) +{ + const struct sof_dev_desc *desc = sdev->pdata->desc; + int ipc_fallback_start, ret, i; + + ret = sof_file_profile_for_ipc_type(sdev, base_profile->ipc_type, desc, + base_profile, out_profile); + if (!ret) + goto out; + + /* + * No firmware file was found for the requested IPC type, as fallback + * if SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION is selected, check + * all IPC versions in a backwards direction (from newer to older) + * if SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION is not selected, + * check only older IPC versions than the selected/default version + */ + if (IS_ENABLED(CONFIG_SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION)) + ipc_fallback_start = SOF_IPC_TYPE_COUNT - 1; + else + ipc_fallback_start = (int)base_profile->ipc_type - 1; + + for (i = ipc_fallback_start; i >= 0 ; i--) { + if (i == base_profile->ipc_type || + !(desc->ipc_supported_mask & BIT(i))) + continue; + + ret = sof_file_profile_for_ipc_type(sdev, i, desc, base_profile, + out_profile); + if (!ret) + break; + } + +out: + if (ret) + sof_missing_firmware_notification(sdev, base_profile->ipc_type, + base_profile); + else + sof_print_profile_info(sdev, base_profile->ipc_type, out_profile); + + return ret; +} +EXPORT_SYMBOL(sof_create_ipc_file_profile); diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 65a7041cbab9d7..d3b667aae34dd7 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -608,18 +608,13 @@ static struct snd_sof_dsp_ops sof_imx8x_ops = { SNDRV_PCM_INFO_NO_PERIOD_WAKEUP }; +static const char vendor_string[] = "imx"; + static struct sof_dev_desc sof_of_imx8qxp_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "imx/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "imx/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-imx8x.ri", - }, + .vendor = vendor_string, + .platform = "imx8x", .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", .ops = &sof_imx8x_ops, }; @@ -627,15 +622,8 @@ static struct sof_dev_desc sof_of_imx8qxp_desc = { static struct sof_dev_desc sof_of_imx8qm_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "imx/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "imx/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-imx8.ri", - }, + .vendor = vendor_string, + .platform = "imx8", .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", .ops = &sof_imx8_ops, }; diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c index 9d58dda8f079d1..02d2c4fb8de379 100644 --- a/sound/soc/sof/imx/imx8m.c +++ b/sound/soc/sof/imx/imx8m.c @@ -473,15 +473,8 @@ static struct snd_sof_dsp_ops sof_imx8m_ops = { static struct sof_dev_desc sof_of_imx8mp_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "imx/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "imx/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-imx8m.ri", - }, + .vendor = "imx", + .platform = "imx8m", .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", .ops = &sof_imx8m_ops, }; diff --git a/sound/soc/sof/imx/imx8ulp.c b/sound/soc/sof/imx/imx8ulp.c index 2673c1d4ddea16..41961b91a01a40 100644 --- a/sound/soc/sof/imx/imx8ulp.c +++ b/sound/soc/sof/imx/imx8ulp.c @@ -480,15 +480,8 @@ static struct snd_sof_dsp_ops sof_imx8ulp_ops = { static struct sof_dev_desc sof_of_imx8ulp_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "imx/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "imx/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-imx8ulp.ri", - }, + .vendor = "imx", + .platform = "imx8ulp", .nocodec_tplg_filename = "sof-imx8ulp-nocodec.tplg", .ops = &sof_imx8ulp_ops, }; diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 776b66389c345b..dee6c7f73e80a6 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -55,7 +55,7 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev) if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { struct sof_ipc4_fw_data *ipc4_data; - sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 511fce8e0e198b..84fda61b95aa41 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -641,15 +641,8 @@ static const struct sof_dev_desc sof_acpi_broadwell_desc = { .chip_info = &bdw_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-bdw.ri", - }, + .vendor = "intel", + .platform = "bdw", .nocodec_tplg_filename = "sof-bdw-nocodec.tplg", .ops = &sof_bdw_ops, }; diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index a976dc91d2ec69..e1c7d694aabb8a 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -366,6 +366,8 @@ static const struct sof_intel_dsp_desc cht_chip_info = { .hw_ip_version = SOF_INTEL_BAYTRAIL, }; +static const char vendor_string[] = "intel"; + /* BYTCR uses different IRQ index */ static const struct sof_dev_desc sof_acpi_baytrailcr_desc = { .machines = snd_soc_acpi_intel_baytrail_machines, @@ -376,15 +378,8 @@ static const struct sof_dev_desc sof_acpi_baytrailcr_desc = { .chip_info = &byt_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-byt.ri", - }, + .vendor = vendor_string, + .platform = "byt", .nocodec_tplg_filename = "sof-byt-nocodec.tplg", .ops = &sof_byt_ops, }; @@ -398,15 +393,8 @@ static const struct sof_dev_desc sof_acpi_baytrail_desc = { .chip_info = &byt_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-byt.ri", - }, + .vendor = vendor_string, + .platform = "byt", .nocodec_tplg_filename = "sof-byt-nocodec.tplg", .ops = &sof_byt_ops, }; @@ -420,15 +408,8 @@ static const struct sof_dev_desc sof_acpi_cherrytrail_desc = { .chip_info = &cht_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-cht.ri", - }, + .vendor = vendor_string, + .platform = "cht", .nocodec_tplg_filename = "sof-cht-nocodec.tplg", .ops = &sof_cht_ops, }; diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 598cf50abadb3a..85e1e4760d0e59 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -402,7 +402,7 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev) if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { struct sof_ipc4_fw_data *ipc4_data; - sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 318a21c12cd005..f3649a083fb7e3 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -621,6 +621,9 @@ void hda_ops_free(struct snd_sof_dev *sdev) if (!hda_use_tplg_nhlt) intel_nhlt_free(ipc4_data->nhlt); + + kfree(sdev->private); + sdev->private = NULL; } } EXPORT_SYMBOL_NS(hda_ops_free, SND_SOC_SOF_INTEL_HDA_COMMON); diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c index 8e29d6bb6fe82f..04069859199217 100644 --- a/sound/soc/sof/intel/icl.c +++ b/sound/soc/sof/intel/icl.c @@ -123,7 +123,7 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev) if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { struct sof_ipc4_fw_data *ipc4_data; - sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c index 479db350ea6da1..01466a7a823526 100644 --- a/sound/soc/sof/intel/lnl.c +++ b/sound/soc/sof/intel/lnl.c @@ -120,7 +120,7 @@ int sof_lnl_ops_init(struct snd_sof_dev *sdev) sof_lnl_ops.get_stream_position = mtl_dsp_get_stream_hda_link_position; - sdev->private = devm_kzalloc(sdev->dev, sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); + sdev->private = kzalloc(sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index 254dbbeac1d076..030c03ba5dcc4f 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -698,7 +698,7 @@ int sof_mtl_ops_init(struct snd_sof_dev *sdev) sof_mtl_ops.get_stream_position = mtl_dsp_get_stream_hda_link_position; - sdev->private = devm_kzalloc(sdev->dev, sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); + sdev->private = kzalloc(sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/pci-apl.c b/sound/soc/sof/intel/pci-apl.c index 4b287b5e9077cb..f1a800058ae680 100644 --- a/sound/soc/sof/intel/pci-apl.c +++ b/sound/soc/sof/intel/pci-apl.c @@ -19,6 +19,8 @@ /* platform specific devices */ #include "hda.h" +static const char vendor_string[] = "intel"; + static const struct sof_dev_desc bxt_desc = { .machines = snd_soc_acpi_intel_bxt_machines, .use_acpi_target_states = true, @@ -30,21 +32,8 @@ static const struct sof_dev_desc bxt_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/apl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/apl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-apl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "apl", .nocodec_tplg_filename = "sof-apl-nocodec.tplg", .ops = &sof_apl_ops, .ops_init = sof_apl_ops_init, @@ -62,21 +51,8 @@ static const struct sof_dev_desc glk_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/glk", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/glk", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-glk.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "glk", .nocodec_tplg_filename = "sof-glk-nocodec.tplg", .ops = &sof_apl_ops, .ops_init = sof_apl_ops_init, diff --git a/sound/soc/sof/intel/pci-cnl.c b/sound/soc/sof/intel/pci-cnl.c index 9fa0cd2eae79a3..a408ec22740f8f 100644 --- a/sound/soc/sof/intel/pci-cnl.c +++ b/sound/soc/sof/intel/pci-cnl.c @@ -19,6 +19,8 @@ /* platform specific devices */ #include "hda.h" +static const char vendor_string[] = "intel"; + static const struct sof_dev_desc cnl_desc = { .machines = snd_soc_acpi_intel_cnl_machines, .alt_machines = snd_soc_acpi_intel_cnl_sdw_machines, @@ -31,21 +33,8 @@ static const struct sof_dev_desc cnl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/cnl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/cnl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-cnl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "cnl", .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", .ops = &sof_cnl_ops, .ops_init = sof_cnl_ops_init, @@ -64,21 +53,8 @@ static const struct sof_dev_desc cfl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/cnl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/cnl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-cfl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "cfl", .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", .ops = &sof_cnl_ops, .ops_init = sof_cnl_ops_init, @@ -97,21 +73,8 @@ static const struct sof_dev_desc cml_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/cnl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/cnl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-cml.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "cml", .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", .ops = &sof_cnl_ops, .ops_init = sof_cnl_ops_init, diff --git a/sound/soc/sof/intel/pci-icl.c b/sound/soc/sof/intel/pci-icl.c index b99c7c9aad7dd3..421df56c83e041 100644 --- a/sound/soc/sof/intel/pci-icl.c +++ b/sound/soc/sof/intel/pci-icl.c @@ -19,6 +19,8 @@ /* platform specific devices */ #include "hda.h" +static const char vendor_string[] = "intel"; + static const struct sof_dev_desc icl_desc = { .machines = snd_soc_acpi_intel_icl_machines, .alt_machines = snd_soc_acpi_intel_icl_sdw_machines, @@ -31,21 +33,8 @@ static const struct sof_dev_desc icl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/icl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/icl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-icl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "icl", .nocodec_tplg_filename = "sof-icl-nocodec.tplg", .ops = &sof_icl_ops, .ops_init = sof_icl_ops_init, @@ -63,21 +52,8 @@ static const struct sof_dev_desc jsl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/jsl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/jsl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-jsl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "jsl", .nocodec_tplg_filename = "sof-jsl-nocodec.tplg", .ops = &sof_cnl_ops, .ops_init = sof_cnl_ops_init, diff --git a/sound/soc/sof/intel/pci-lnl.c b/sound/soc/sof/intel/pci-lnl.c index 78a57eb9cbc377..3d971b195c6e48 100644 --- a/sound/soc/sof/intel/pci-lnl.c +++ b/sound/soc/sof/intel/pci-lnl.c @@ -32,15 +32,8 @@ static const struct sof_dev_desc lnl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_4, .dspless_mode_supported = true, - .default_fw_path = { - [SOF_IPC_TYPE_4] = "intel/sof-ipc4/lnl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_4] = "intel/sof-ace-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_4] = "sof-lnl.ri", - }, + .vendor = "intel", + .platform = "lnl", .nocodec_tplg_filename = "sof-lnl-nocodec.tplg", .ops = &sof_lnl_ops, .ops_init = sof_lnl_ops_init, diff --git a/sound/soc/sof/intel/pci-mtl.c b/sound/soc/sof/intel/pci-mtl.c index 0f378f45486dec..bb320d0178aedb 100644 --- a/sound/soc/sof/intel/pci-mtl.c +++ b/sound/soc/sof/intel/pci-mtl.c @@ -32,18 +32,8 @@ static const struct sof_dev_desc mtl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_4, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_4] = "intel/sof-ipc4/mtl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/mtl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_4] = "intel/sof-ace-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_4] = "sof-mtl.ri", - }, + .vendor = "intel", + .platform = "mtl", .nocodec_tplg_filename = "sof-mtl-nocodec.tplg", .ops = &sof_mtl_ops, .ops_init = sof_mtl_ops_init, @@ -62,18 +52,8 @@ static const struct sof_dev_desc arl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_4, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_4] = "intel/sof-ipc4/arl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/arl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_4] = "intel/sof-ace-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_4] = "sof-arl.ri", - }, + .vendor = "intel", + .platform = "mtl", .nocodec_tplg_filename = "sof-arl-nocodec.tplg", .ops = &sof_mtl_ops, .ops_init = sof_mtl_ops_init, diff --git a/sound/soc/sof/intel/pci-skl.c b/sound/soc/sof/intel/pci-skl.c index 9dde439a0b0f55..b6d87f2663d21d 100644 --- a/sound/soc/sof/intel/pci-skl.c +++ b/sound/soc/sof/intel/pci-skl.c @@ -17,6 +17,8 @@ /* platform specific devices */ #include "hda.h" +static const char vendor_string[] = "intel"; + static struct sof_dev_desc skl_desc = { .machines = snd_soc_acpi_intel_skl_machines, .resindex_lpe_base = 0, @@ -27,15 +29,8 @@ static struct sof_dev_desc skl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_4, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_4] = "intel/avs/skl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "skl", .nocodec_tplg_filename = "sof-skl-nocodec.tplg", .ops = &sof_skl_ops, .ops_init = sof_skl_ops_init, @@ -52,15 +47,8 @@ static struct sof_dev_desc kbl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_4, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_4] = "intel/avs/kbl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "kbl", .nocodec_tplg_filename = "sof-kbl-nocodec.tplg", .ops = &sof_skl_ops, .ops_init = sof_skl_ops_init, diff --git a/sound/soc/sof/intel/pci-tgl.c b/sound/soc/sof/intel/pci-tgl.c index 0660d4b2ac96b6..311bc84bf92ef8 100644 --- a/sound/soc/sof/intel/pci-tgl.c +++ b/sound/soc/sof/intel/pci-tgl.c @@ -19,6 +19,8 @@ /* platform specific devices */ #include "hda.h" +static const char vendor_string[] = "intel"; + static const struct sof_dev_desc tgl_desc = { .machines = snd_soc_acpi_intel_tgl_machines, .alt_machines = snd_soc_acpi_intel_tgl_sdw_machines, @@ -31,21 +33,8 @@ static const struct sof_dev_desc tgl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/tgl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/tgl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-tgl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "tgl", .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, @@ -64,21 +53,8 @@ static const struct sof_dev_desc tglh_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/tgl-h", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/tgl-h", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-tgl-h.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "tgl-h", .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, @@ -96,21 +72,8 @@ static const struct sof_dev_desc ehl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/ehl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/ehl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-ehl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "ehl", .nocodec_tplg_filename = "sof-ehl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, @@ -129,21 +92,8 @@ static const struct sof_dev_desc adls_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/adl-s", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/adl-s", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-adl-s.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "adl-s", .nocodec_tplg_filename = "sof-adl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, @@ -162,21 +112,8 @@ static const struct sof_dev_desc adl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/adl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/adl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-adl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "adl", .nocodec_tplg_filename = "sof-adl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, @@ -195,21 +132,8 @@ static const struct sof_dev_desc adl_n_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/adl-n", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/adl-n", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-adl-n.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "adl-n", .nocodec_tplg_filename = "sof-adl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, @@ -228,21 +152,8 @@ static const struct sof_dev_desc rpls_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/rpl-s", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/rpl-s", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-rpl-s.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "rpl-s", .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, @@ -261,21 +172,8 @@ static const struct sof_dev_desc rpl_desc = { .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4), .ipc_default = SOF_IPC_TYPE_3, .dspless_mode_supported = true, /* Only supported for HDaudio */ - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - [SOF_IPC_TYPE_4] = "intel/avs/rpl", - }, - .default_lib_path = { - [SOF_IPC_TYPE_4] = "intel/avs-lib/rpl", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - [SOF_IPC_TYPE_4] = "intel/avs-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-rpl.ri", - [SOF_IPC_TYPE_4] = "dsp_basefw.bin", - }, + .vendor = vendor_string, + .platform = "rpl", .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c index c90173003c2ba8..73af0d6ad9e84a 100644 --- a/sound/soc/sof/intel/pci-tng.c +++ b/sound/soc/sof/intel/pci-tng.c @@ -210,15 +210,8 @@ static const struct sof_dev_desc tng_desc = { .chip_info = &tng_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "intel/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "intel/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-byt.ri", - }, + .vendor = "intel", + .platform = "byt", .nocodec_tplg_filename = "sof-byt.tplg", .ops = &sof_tng_ops, }; diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index d24e64e71b58f5..93824e6ce57307 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -62,7 +62,7 @@ int sof_skl_ops_init(struct snd_sof_dev *sdev) /* probe/remove/shutdown */ sof_skl_ops.shutdown = hda_dsp_shutdown; - sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index f7de1f5ba06d10..d890cac6cb01bc 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -82,7 +82,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev) if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { struct sof_ipc4_fw_data *ipc4_data; - sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c index 8544d65bc2cfae..536c222f1decfb 100644 --- a/sound/soc/sof/mediatek/mt8186/mt8186.c +++ b/sound/soc/sof/mediatek/mt8186/mt8186.c @@ -605,19 +605,14 @@ static struct snd_sof_of_mach sof_mt8186_machs[] = { {} }; +static const char vendor_string[] = "mediatek"; + static const struct sof_dev_desc sof_of_mt8186_desc = { .of_machines = sof_mt8186_machs, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "mediatek/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "mediatek/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-mt8186.ri", - }, + .vendor = vendor_string, + .platform = "mt8186", .nocodec_tplg_filename = "sof-mt8186-nocodec.tplg", .ops = &sof_mt8186_ops, }; @@ -683,15 +678,8 @@ static const struct sof_dev_desc sof_of_mt8188_desc = { .of_machines = sof_mt8188_machs, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "mediatek/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "mediatek/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-mt8188.ri", - }, + .vendor = vendor_string, + .platform = "mt8188", .nocodec_tplg_filename = "sof-mt8188-nocodec.tplg", .ops = &sof_mt8188_ops, .ops_init = sof_mt8188_ops_init, diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index fab2d5af861007..33d18b7935d259 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -637,15 +637,8 @@ static const struct sof_dev_desc sof_of_mt8195_desc = { .of_machines = sof_mt8195_machs, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "mediatek/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "mediatek/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-mt8195.ri", - }, + .vendor = "mediatek", + .platform = "mt8195", .nocodec_tplg_filename = "sof-mt8195-nocodec.tplg", .ops = &sof_mt8195_ops, .ipc_timeout = 1000, diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c index 5c4e5ab31abff7..e4b61f08202c65 100644 --- a/sound/soc/sof/sof-acpi-dev.c +++ b/sound/soc/sof/sof-acpi-dev.c @@ -74,18 +74,10 @@ int sof_acpi_probe(struct platform_device *pdev, const struct sof_dev_desc *desc sof_pdata->desc = desc; sof_pdata->dev = &pdev->dev; - sof_pdata->fw_filename = desc->default_fw_filename[SOF_IPC_TYPE_3]; - - /* alternate fw and tplg filenames ? */ - if (fw_path) - sof_pdata->fw_filename_prefix = fw_path; - else - sof_pdata->fw_filename_prefix = desc->default_fw_path[SOF_IPC_TYPE_3]; - - if (tplg_path) - sof_pdata->tplg_filename_prefix = tplg_path; - else - sof_pdata->tplg_filename_prefix = desc->default_tplg_path[SOF_IPC_TYPE_3]; + + sof_pdata->ipc_file_profile_base.ipc_type = desc->ipc_default; + sof_pdata->ipc_file_profile_base.fw_path = fw_path; + sof_pdata->ipc_file_profile_base.tplg_path = tplg_path; /* set callback to be called on successful device probe to enable runtime_pm */ sof_pdata->sof_probe_complete = sof_acpi_probe_complete; diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 563fe6f7789f73..de40a5e227f4c8 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -11,7 +11,6 @@ #include #include #include "sof-audio.h" -#include "sof-of-dev.h" #include "ops.h" static bool is_virtual_widget(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget, @@ -989,122 +988,3 @@ int sof_dai_get_bclk(struct snd_soc_pcm_runtime *rtd) return sof_dai_get_clk(rtd, SOF_DAI_CLK_INTEL_SSP_BCLK); } EXPORT_SYMBOL(sof_dai_get_bclk); - -static struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev) -{ - struct snd_sof_pdata *sof_pdata = sdev->pdata; - const struct sof_dev_desc *desc = sof_pdata->desc; - struct snd_sof_of_mach *mach = desc->of_machines; - - if (!mach) - return NULL; - - for (; mach->compatible; mach++) { - if (of_machine_is_compatible(mach->compatible)) { - sof_pdata->tplg_filename = mach->sof_tplg_filename; - if (mach->fw_filename) - sof_pdata->fw_filename = mach->fw_filename; - - return mach; - } - } - - return NULL; -} - -/* - * SOF Driver enumeration. - */ -int sof_machine_check(struct snd_sof_dev *sdev) -{ - struct snd_sof_pdata *sof_pdata = sdev->pdata; - const struct sof_dev_desc *desc = sof_pdata->desc; - struct snd_soc_acpi_mach *mach; - - if (!IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)) { - const struct snd_sof_of_mach *of_mach; - - if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && - sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) - goto nocodec; - - /* find machine */ - mach = snd_sof_machine_select(sdev); - if (mach) { - sof_pdata->machine = mach; - - if (sof_pdata->subsystem_id_set) { - mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor; - mach->mach_params.subsystem_device = sof_pdata->subsystem_device; - mach->mach_params.subsystem_id_set = true; - } - - snd_sof_set_mach_params(mach, sdev); - return 0; - } - - of_mach = sof_of_machine_select(sdev); - if (of_mach) { - sof_pdata->of_machine = of_mach; - return 0; - } - - if (!IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)) { - dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n"); - return -ENODEV; - } - } else { - dev_warn(sdev->dev, "Force to use nocodec mode\n"); - } - -nocodec: - /* select nocodec mode */ - dev_warn(sdev->dev, "Using nocodec machine driver\n"); - mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL); - if (!mach) - return -ENOMEM; - - mach->drv_name = "sof-nocodec"; - if (!sof_pdata->tplg_filename) - sof_pdata->tplg_filename = desc->nocodec_tplg_filename; - - sof_pdata->machine = mach; - snd_sof_set_mach_params(mach, sdev); - - return 0; -} -EXPORT_SYMBOL(sof_machine_check); - -int sof_machine_register(struct snd_sof_dev *sdev, void *pdata) -{ - struct snd_sof_pdata *plat_data = pdata; - const char *drv_name; - const void *mach; - int size; - - drv_name = plat_data->machine->drv_name; - mach = plat_data->machine; - size = sizeof(*plat_data->machine); - - /* register machine driver, pass machine info as pdata */ - plat_data->pdev_mach = - platform_device_register_data(sdev->dev, drv_name, - PLATFORM_DEVID_NONE, mach, size); - if (IS_ERR(plat_data->pdev_mach)) - return PTR_ERR(plat_data->pdev_mach); - - dev_dbg(sdev->dev, "created machine %s\n", - dev_name(&plat_data->pdev_mach->dev)); - - return 0; -} -EXPORT_SYMBOL(sof_machine_register); - -void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata) -{ - struct snd_sof_pdata *plat_data = pdata; - - if (!IS_ERR_OR_NULL(plat_data->pdev_mach)) - platform_device_unregister(plat_data->pdev_mach); -} -EXPORT_SYMBOL(sof_machine_unregister); diff --git a/sound/soc/sof/sof-of-dev.c b/sound/soc/sof/sof-of-dev.c index b0e8bd06f78ae5..b12e810636c224 100644 --- a/sound/soc/sof/sof-of-dev.c +++ b/sound/soc/sof/sof-of-dev.c @@ -41,6 +41,29 @@ static void sof_of_probe_complete(struct device *dev) pm_runtime_enable(dev); } +struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev) +{ + struct snd_sof_pdata *sof_pdata = sdev->pdata; + const struct sof_dev_desc *desc = sof_pdata->desc; + struct snd_sof_of_mach *mach = desc->of_machines; + + if (!mach) + return NULL; + + for (; mach->compatible; mach++) { + if (of_machine_is_compatible(mach->compatible)) { + sof_pdata->tplg_filename = mach->sof_tplg_filename; + if (mach->fw_filename) + sof_pdata->fw_filename = mach->fw_filename; + + return mach; + } + } + + return NULL; +} +EXPORT_SYMBOL(sof_of_machine_select); + int sof_of_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -64,17 +87,10 @@ int sof_of_probe(struct platform_device *pdev) sof_pdata->desc = desc; sof_pdata->dev = &pdev->dev; - sof_pdata->fw_filename = desc->default_fw_filename[SOF_IPC_TYPE_3]; - - if (fw_path) - sof_pdata->fw_filename_prefix = fw_path; - else - sof_pdata->fw_filename_prefix = desc->default_fw_path[SOF_IPC_TYPE_3]; - if (tplg_path) - sof_pdata->tplg_filename_prefix = tplg_path; - else - sof_pdata->tplg_filename_prefix = desc->default_tplg_path[SOF_IPC_TYPE_3]; + sof_pdata->ipc_file_profile_base.ipc_type = desc->ipc_default; + sof_pdata->ipc_file_profile_base.fw_path = fw_path; + sof_pdata->ipc_file_profile_base.tplg_path = tplg_path; /* set callback to be called on successful device probe to enable runtime_pm */ sof_pdata->sof_probe_complete = sof_of_probe_complete; diff --git a/sound/soc/sof/sof-of-dev.h b/sound/soc/sof/sof-of-dev.h index 2948b3a0d9fef9..879ca4edb4272c 100644 --- a/sound/soc/sof/sof-of-dev.h +++ b/sound/soc/sof/sof-of-dev.h @@ -16,6 +16,15 @@ struct snd_sof_of_mach { const char *sof_tplg_filename; }; +#if IS_ENABLED(CONFIG_SND_SOC_SOF_OF_DEV) +struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev); +#else +static inline struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev) +{ + return NULL; +} +#endif + extern const struct dev_pm_ops sof_of_pm; int sof_of_probe(struct platform_device *pdev); diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 1d706490588e3c..57c0a9291a6210 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -183,6 +183,7 @@ static void sof_pci_probe_complete(struct device *dev) int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { + struct sof_loadable_file_profile *path_override; struct device *dev = &pci->dev; const struct sof_dev_desc *desc = (const struct sof_dev_desc *)pci_id->driver_data; @@ -225,106 +226,37 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) sof_pdata->desc = desc; sof_pdata->dev = dev; - sof_pdata->ipc_type = desc->ipc_default; + path_override = &sof_pdata->ipc_file_profile_base; if (sof_pci_ipc_type < 0) { - sof_pdata->ipc_type = desc->ipc_default; + path_override->ipc_type = desc->ipc_default; + } else if (sof_pci_ipc_type < SOF_IPC_TYPE_COUNT) { + path_override->ipc_type = sof_pci_ipc_type; } else { - dev_info(dev, "overriding default IPC %d to requested %d\n", - desc->ipc_default, sof_pci_ipc_type); - if (sof_pci_ipc_type >= SOF_IPC_TYPE_COUNT) { - dev_err(dev, "invalid request value %d\n", sof_pci_ipc_type); - ret = -EINVAL; - goto out; - } - if (!(BIT(sof_pci_ipc_type) & desc->ipc_supported_mask)) { - dev_err(dev, "invalid request value %d, supported mask is %#x\n", - sof_pci_ipc_type, desc->ipc_supported_mask); - ret = -EINVAL; - goto out; - } - sof_pdata->ipc_type = sof_pci_ipc_type; - } - - if (fw_filename) { - sof_pdata->fw_filename = fw_filename; - - dev_dbg(dev, "Module parameter used, changed fw filename to %s\n", - sof_pdata->fw_filename); - } else { - sof_pdata->fw_filename = desc->default_fw_filename[sof_pdata->ipc_type]; - } - - /* - * for platforms using the SOF community key, change the - * default path automatically to pick the right files from the - * linux-firmware tree. This can be overridden with the - * fw_path kernel parameter, e.g. for developers. - */ - - /* alternate fw and tplg filenames ? */ - if (fw_path) { - sof_pdata->fw_filename_prefix = fw_path; - - dev_dbg(dev, - "Module parameter used, changed fw path to %s\n", - sof_pdata->fw_filename_prefix); - - } else if (dmi_check_system(community_key_platforms) && sof_dmi_use_community_key) { - sof_pdata->fw_filename_prefix = - devm_kasprintf(dev, GFP_KERNEL, "%s/%s", - sof_pdata->desc->default_fw_path[sof_pdata->ipc_type], - "community"); - - dev_dbg(dev, - "Platform uses community key, changed fw path to %s\n", - sof_pdata->fw_filename_prefix); - } else { - sof_pdata->fw_filename_prefix = - sof_pdata->desc->default_fw_path[sof_pdata->ipc_type]; + dev_err(dev, "Invalid IPC type requested: %d\n", sof_pci_ipc_type); + ret = -EINVAL; + goto out; } - if (lib_path) { - sof_pdata->fw_lib_prefix = lib_path; - - dev_dbg(dev, "Module parameter used, changed fw_lib path to %s\n", - sof_pdata->fw_lib_prefix); - - } else if (sof_pdata->desc->default_lib_path[sof_pdata->ipc_type]) { - if (dmi_check_system(community_key_platforms) && sof_dmi_use_community_key) { - sof_pdata->fw_lib_prefix = - devm_kasprintf(dev, GFP_KERNEL, "%s/%s", - sof_pdata->desc->default_lib_path[sof_pdata->ipc_type], - "community"); - - dev_dbg(dev, - "Platform uses community key, changed fw_lib path to %s\n", - sof_pdata->fw_lib_prefix); - } else { - sof_pdata->fw_lib_prefix = - sof_pdata->desc->default_lib_path[sof_pdata->ipc_type]; - } - } + path_override->fw_path = fw_path; + path_override->fw_name = fw_filename; + path_override->fw_lib_path = lib_path; + path_override->tplg_path = tplg_path; - if (tplg_path) - sof_pdata->tplg_filename_prefix = tplg_path; - else - sof_pdata->tplg_filename_prefix = - sof_pdata->desc->default_tplg_path[sof_pdata->ipc_type]; + if (dmi_check_system(community_key_platforms) && + sof_dmi_use_community_key) + path_override->fw_path_postfix = "community"; /* * the topology filename will be provided in the machine descriptor, unless * it is overridden by a module parameter or DMI quirk. */ if (tplg_filename) { - sof_pdata->tplg_filename = tplg_filename; - - dev_dbg(dev, "Module parameter used, changed tplg filename to %s\n", - sof_pdata->tplg_filename); + path_override->tplg_name = tplg_filename; } else { dmi_check_system(sof_tplg_table); if (sof_dmi_override_tplg_name) - sof_pdata->tplg_filename = sof_dmi_override_tplg_name; + path_override->tplg_name = sof_dmi_override_tplg_name; } /* set callback to be called on successful device probe to enable runtime_pm */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index d4f6702e93dcb8..90522be7542f53 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -693,6 +693,13 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev); */ extern struct snd_compress_ops sof_compressed_ops; +/* + * Firmware (firmware, libraries, topologies) file location + */ +int sof_create_ipc_file_profile(struct snd_sof_dev *sdev, + struct sof_loadable_file_profile *base_profile, + struct sof_loadable_file_profile *out_profile); + /* * Firmware loading. */ @@ -812,8 +819,6 @@ int sof_stream_pcm_open(struct snd_sof_dev *sdev, int sof_stream_pcm_close(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); -int sof_machine_check(struct snd_sof_dev *sdev); - /* SOF client support */ #if IS_ENABLED(CONFIG_SND_SOC_SOF_CLIENT) int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id,