diff options
Diffstat (limited to 'sound/soc/intel/avs')
38 files changed, 812 insertions, 506 deletions
diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c index 3dccf0a57a3a..b922eeaba843 100644 --- a/sound/soc/intel/avs/apl.c +++ b/sound/soc/intel/avs/apl.c @@ -10,6 +10,7 @@ #include <linux/slab.h> #include <sound/hdaudio_ext.h> #include "avs.h" +#include "debug.h" #include "messages.h" #include "path.h" #include "registers.h" diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 4c096afc5848..0f8ddd0e9e5f 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -22,7 +22,6 @@ struct avs_dev; struct avs_tplg; struct avs_tplg_library; -struct avs_soc_component; struct avs_ipc_msg; #ifdef CONFIG_ACPI @@ -348,91 +347,18 @@ struct avs_soc_component { extern const struct snd_soc_dai_ops avs_dai_fe_ops; -int avs_soc_component_register(struct device *dev, const char *name, - struct snd_soc_component_driver *drv, - struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais); -int avs_dmic_platform_register(struct avs_dev *adev, const char *name); -int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask, - unsigned long *tdms); -int avs_hda_platform_register(struct avs_dev *adev, const char *name); +int avs_register_dmic_component(struct avs_dev *adev, const char *name); +int avs_register_i2s_component(struct avs_dev *adev, const char *name, unsigned long port_mask, + unsigned long *tdms); +int avs_register_hda_component(struct avs_dev *adev, const char *name); +int avs_register_component(struct device *dev, const char *name, + struct snd_soc_component_driver *drv, + struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais); int avs_register_all_boards(struct avs_dev *adev); void avs_unregister_all_boards(struct avs_dev *adev); -/* Firmware tracing helpers */ - -#define avs_log_buffer_size(adev) \ - ((adev)->fw_cfg.trace_log_bytes / (adev)->hw_cfg.dsp_cores) - -#define avs_log_buffer_addr(adev, core) \ -({ \ - s32 __offset = avs_dsp_op(adev, log_buffer_offset, core); \ - (__offset < 0) ? NULL : \ - (avs_sram_addr(adev, AVS_DEBUG_WINDOW) + __offset); \ -}) - -static inline int avs_log_buffer_status_locked(struct avs_dev *adev, union avs_notify_msg *msg) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&adev->trace_lock, flags); - ret = avs_dsp_op(adev, log_buffer_status, msg); - spin_unlock_irqrestore(&adev->trace_lock, flags); - - return ret; -} - -struct avs_apl_log_buffer_layout { - u32 read_ptr; - u32 write_ptr; - u8 buffer[]; -} __packed; -static_assert(sizeof(struct avs_apl_log_buffer_layout) == 8); - -#define avs_apl_log_payload_size(adev) \ - (avs_log_buffer_size(adev) - sizeof(struct avs_apl_log_buffer_layout)) - -#define avs_apl_log_payload_addr(addr) \ - (addr + sizeof(struct avs_apl_log_buffer_layout)) - -#ifdef CONFIG_DEBUG_FS -#define AVS_SET_ENABLE_LOGS_OP(name) \ - .enable_logs = avs_##name##_enable_logs - -bool avs_logging_fw(struct avs_dev *adev); -void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len); -void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len); - -int avs_probe_platform_register(struct avs_dev *adev, const char *name); - -void avs_debugfs_init(struct avs_dev *adev); -void avs_debugfs_exit(struct avs_dev *adev); -#else -#define AVS_SET_ENABLE_LOGS_OP(name) - -static inline bool avs_logging_fw(struct avs_dev *adev) -{ - return false; -} - -static inline void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len) -{ -} - -static inline void -avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len) -{ -} - -static inline int avs_probe_platform_register(struct avs_dev *adev, const char *name) -{ - return 0; -} - -static inline void avs_debugfs_init(struct avs_dev *adev) { } -static inline void avs_debugfs_exit(struct avs_dev *adev) { } -#endif +int avs_parse_sched_cfg(struct avs_dev *adev, const char *buf, size_t len); /* Filesystems integration */ diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index fb49167f5fc4..52e6266a7cb8 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -17,6 +17,8 @@ #include <sound/soc-acpi.h> #include <sound/soc-component.h> #include "avs.h" +#include "debug.h" +#include "pcm.h" #include "utils.h" static char *i2s_test; @@ -56,19 +58,13 @@ static const struct dmi_system_id kblr_dmi_table[] = { static struct snd_soc_acpi_mach *dmi_match_quirk(void *arg) { struct snd_soc_acpi_mach *mach = arg; - const struct dmi_system_id *dmi_id; struct dmi_system_id *dmi_table; - if (mach->quirk_data == NULL) - return mach; - dmi_table = (struct dmi_system_id *)mach->quirk_data; - dmi_id = dmi_first_match(dmi_table); - if (!dmi_id) - return NULL; - - return mach; + if (!dmi_table || dmi_first_match(dmi_table)) + return mach; + return NULL; } #define AVS_SSP(x) (BIT(x)) @@ -368,10 +364,10 @@ struct avs_acpi_boards { /* supported I2S boards per platform */ static const struct avs_acpi_boards i2s_boards[] = { - AVS_MACH_ENTRY(HDA_SKL_LP, avs_skl_i2s_machines), - AVS_MACH_ENTRY(HDA_KBL_LP, avs_kbl_i2s_machines), - AVS_MACH_ENTRY(HDA_APL, avs_apl_i2s_machines), - AVS_MACH_ENTRY(HDA_GML, avs_gml_i2s_machines), + AVS_MACH_ENTRY(HDA_SKL_LP, avs_skl_i2s_machines), + AVS_MACH_ENTRY(HDA_KBL_LP, avs_kbl_i2s_machines), + AVS_MACH_ENTRY(HDA_APL, avs_apl_i2s_machines), + AVS_MACH_ENTRY(HDA_GML, avs_gml_i2s_machines), AVS_MACH_ENTRY(HDA_CNL_LP, avs_cnl_i2s_machines), AVS_MACH_ENTRY(HDA_CNL_H, avs_cnl_i2s_machines), AVS_MACH_ENTRY(HDA_CML_LP, avs_cnl_i2s_machines), @@ -386,185 +382,122 @@ static const struct avs_acpi_boards i2s_boards[] = { { }, }; -static const struct avs_acpi_boards *avs_get_i2s_boards(struct avs_dev *adev) +static struct snd_soc_acpi_mach *avs_get_i2s_machines(struct avs_dev *adev) { int id, i; id = adev->base.pci->device; for (i = 0; i < ARRAY_SIZE(i2s_boards); i++) if (i2s_boards[i].id == id) - return &i2s_boards[i]; + return i2s_boards[i].machs; return NULL; } -/* platform devices owned by AVS audio are removed with this hook */ -static void board_pdev_unregister(void *data) +/* Platform devices spawned by AVS driver are removed with this hook. */ +static void avs_unregister_board(void *pdev) { - platform_device_unregister(data); + platform_device_unregister(pdev); } -static int __maybe_unused avs_register_probe_board(struct avs_dev *adev) +static struct platform_device *avs_register_board(struct avs_dev *adev, const char *name, + const void *data, size_t size) { - struct platform_device *board; - struct snd_soc_acpi_mach mach = {{0}}; + struct platform_device *pdev; int ret; - ret = avs_probe_platform_register(adev, "probe-platform"); - if (ret < 0) - return ret; - - mach.mach_params.platform = "probe-platform"; + pdev = platform_device_register_data(NULL, name, PLATFORM_DEVID_AUTO, data, size); + if (IS_ERR(pdev)) + return pdev; - board = platform_device_register_data(NULL, "avs_probe_mb", PLATFORM_DEVID_NONE, - (const void *)&mach, sizeof(mach)); - if (IS_ERR(board)) { - dev_err(adev->dev, "probe board register failed\n"); - return PTR_ERR(board); - } + ret = devm_add_action_or_reset(adev->dev, avs_unregister_board, pdev); + if (ret) + return ERR_PTR(ret); - ret = devm_add_action(adev->dev, board_pdev_unregister, board); - if (ret < 0) { - platform_device_unregister(board); - return ret; - } - return 0; + return pdev; } -static int avs_register_dmic_board(struct avs_dev *adev) +static struct platform_device *avs_register_board_pdata(struct avs_dev *adev, const char *name, + struct snd_soc_acpi_mach *mach, + struct hda_codec *codec, + unsigned long *tdms, char *codec_name) { - struct platform_device *codec, *board; - struct snd_soc_acpi_mach mach = {{0}}; struct avs_mach_pdata *pdata; - int ret; - - if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) { - dev_dbg(adev->dev, "no DMIC endpoints present\n"); - return 0; - } - - codec = platform_device_register_simple("dmic-codec", PLATFORM_DEVID_NONE, NULL, 0); - if (IS_ERR(codec)) { - dev_err(adev->dev, "dmic codec register failed\n"); - return PTR_ERR(codec); - } - - ret = devm_add_action(adev->dev, board_pdev_unregister, codec); - if (ret < 0) { - platform_device_unregister(codec); - return ret; - } - - ret = avs_dmic_platform_register(adev, "dmic-platform"); - if (ret < 0) - return ret; pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) - return -ENOMEM; - pdata->obsolete_card_names = obsolete_card_names; - mach.pdata = pdata; - mach.tplg_filename = "dmic-tplg.bin"; - mach.mach_params.platform = "dmic-platform"; - - board = platform_device_register_data(NULL, "avs_dmic", PLATFORM_DEVID_NONE, - (const void *)&mach, sizeof(mach)); - if (IS_ERR(board)) { - dev_err(adev->dev, "dmic board register failed\n"); - return PTR_ERR(board); - } + return ERR_PTR(-ENOMEM); - ret = devm_add_action(adev->dev, board_pdev_unregister, board); - if (ret < 0) { - platform_device_unregister(board); - return ret; - } + pdata->codec = codec; + pdata->tdms = tdms; + pdata->codec_name = codec_name; + pdata->obsolete_card_names = obsolete_card_names; + mach->pdata = pdata; - return 0; + return avs_register_board(adev, name, mach, sizeof(*mach)); } -static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach) +static int __maybe_unused avs_register_probe_board(struct avs_dev *adev) { - struct platform_device *board; - struct avs_mach_pdata *pdata; - int num_ssps; - char *name; - int ret; - int uid; - - num_ssps = adev->hw_cfg.i2s_caps.ctrl_count; - if (fls(mach->mach_params.i2s_link_mask) > num_ssps) { - dev_err(adev->dev, "Platform supports %d SSPs but board %s requires SSP%ld\n", - num_ssps, mach->drv_name, - (unsigned long)__fls(mach->mach_params.i2s_link_mask)); - return -ENODEV; - } + struct platform_device *pdev; - pdata = mach->pdata; - if (!pdata) - pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - pdata->obsolete_card_names = obsolete_card_names; - mach->pdata = pdata; + pdev = avs_register_board(adev, "avs_probe_mb", NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); - uid = mach->mach_params.i2s_link_mask; - if (avs_mach_singular_ssp(mach)) - uid = (uid << AVS_CHANNELS_MAX) + avs_mach_ssp_tdm(mach, avs_mach_ssp_port(mach)); + return avs_register_probe_component(adev, dev_name(&pdev->dev)); +} - name = devm_kasprintf(adev->dev, GFP_KERNEL, "%s.%d-platform", mach->drv_name, uid); - if (!name) - return -ENOMEM; +static int avs_register_dmic_board(struct avs_dev *adev) +{ + static struct snd_soc_acpi_mach mach = { + .tplg_filename = "dmic-tplg.bin", + }; + struct platform_device *pdev; + char *codec_name; - ret = avs_i2s_platform_register(adev, name, mach->mach_params.i2s_link_mask, pdata->tdms); - if (ret < 0) - return ret; + if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) { + dev_dbg(adev->dev, "no DMIC endpoints present\n"); + return 0; + } - mach->mach_params.platform = name; + /* DMIC present in Intel PCH is enumerated statically. */ + pdev = avs_register_board(adev, "dmic-codec", NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); - board = platform_device_register_data(NULL, mach->drv_name, uid, - (const void *)mach, sizeof(*mach)); - if (IS_ERR(board)) { - dev_err(adev->dev, "ssp board register failed\n"); - return PTR_ERR(board); - } + codec_name = devm_kstrdup(adev->dev, dev_name(&pdev->dev), GFP_KERNEL); + if (!codec_name) + return -ENOMEM; - ret = devm_add_action(adev->dev, board_pdev_unregister, board); - if (ret < 0) { - platform_device_unregister(board); - return ret; - } + pdev = avs_register_board_pdata(adev, "avs_dmic", &mach, NULL, NULL, codec_name); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); - return 0; + return avs_register_dmic_component(adev, dev_name(&pdev->dev)); } static int avs_register_i2s_test_board(struct avs_dev *adev, int ssp_port, int tdm_slot) { - struct snd_soc_acpi_mach *mach; - int tdm_mask = BIT(tdm_slot); - unsigned long *tdm_cfg; - char *tplg_name; - int ret; - - mach = devm_kzalloc(adev->dev, sizeof(*mach), GFP_KERNEL); - tdm_cfg = devm_kcalloc(adev->dev, ssp_port + 1, sizeof(unsigned long), GFP_KERNEL); - tplg_name = devm_kasprintf(adev->dev, GFP_KERNEL, AVS_STRING_FMT("i2s", "-test-tplg.bin", - ssp_port, tdm_slot)); - if (!mach || !tdm_cfg || !tplg_name) + struct snd_soc_acpi_mach mach = {{0}}; + struct platform_device *pdev; + unsigned long *tdms; + + tdms = devm_kcalloc(adev->dev, ssp_port + 1, sizeof(*tdms), GFP_KERNEL); + mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL, + AVS_STRING_FMT("i2s", "-test-tplg.bin", + ssp_port, tdm_slot)); + if (!tdms || !mach.tplg_filename) return -ENOMEM; - mach->drv_name = "avs_i2s_test"; - mach->mach_params.i2s_link_mask = AVS_SSP(ssp_port); - tdm_cfg[ssp_port] = tdm_mask; - mach->pdata = tdm_cfg; - mach->tplg_filename = tplg_name; + tdms[ssp_port] = BIT(tdm_slot); + mach.drv_name = "avs_i2s_test"; + mach.mach_params.i2s_link_mask = AVS_SSP(ssp_port); - ret = avs_register_i2s_board(adev, mach); - if (ret < 0) { - dev_warn(adev->dev, "register i2s %s failed: %d\n", mach->drv_name, ret); - return ret; - } + pdev = avs_register_board_pdata(adev, mach.drv_name, &mach, NULL, tdms, NULL); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); - return 0; + return avs_register_i2s_component(adev, dev_name(&pdev->dev), AVS_SSP(ssp_port), tdms); } static int avs_register_i2s_test_boards(struct avs_dev *adev) @@ -574,6 +507,9 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev) unsigned long tdm_slots; u32 *array, num_elems; + if (!i2s_test) + return 0; + ret = parse_int_array(i2s_test, strlen(i2s_test), (int **)&array); if (ret) { dev_err(adev->dev, "failed to parse i2s_test parameter\n"); @@ -599,9 +535,26 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev) return 0; } +static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach) +{ + u32 i2s_mask = mach->mach_params.i2s_link_mask; + struct platform_device *pdev; + unsigned long *tdms = NULL; + + if (mach->pdata) + tdms = ((struct avs_mach_pdata *)mach->pdata)->tdms; + + pdev = avs_register_board_pdata(adev, mach->drv_name, mach, NULL, tdms, NULL); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return avs_register_i2s_component(adev, dev_name(&pdev->dev), i2s_mask, tdms); +} + static int avs_register_i2s_boards(struct avs_dev *adev) { - const struct avs_acpi_boards *boards; + int num_ssps = adev->hw_cfg.i2s_caps.ctrl_count; + struct snd_soc_acpi_mach *machs; struct snd_soc_acpi_mach *mach; int ret; @@ -610,19 +563,22 @@ static int avs_register_i2s_boards(struct avs_dev *adev) return 0; } - if (i2s_test) - return avs_register_i2s_test_boards(adev); - - boards = avs_get_i2s_boards(adev); - if (!boards) { + machs = avs_get_i2s_machines(adev); + if (!machs) { dev_dbg(adev->dev, "no I2S endpoints supported\n"); return 0; } - for (mach = boards->machs; mach->id[0]; mach++) { + for (mach = machs; mach->id[0]; mach++) { if (!acpi_dev_present(mach->id, mach->uid, -1)) continue; + if (fls(mach->mach_params.i2s_link_mask) > num_ssps) { + dev_err(adev->dev, "Platform supports %d SSPs but board %s requires SSP%ld\n", + num_ssps, mach->drv_name, + (unsigned long)__fls(mach->mach_params.i2s_link_mask)); + continue; + } if (mach->machine_quirk) if (!mach->machine_quirk(mach)) continue; @@ -637,49 +593,20 @@ static int avs_register_i2s_boards(struct avs_dev *adev) static int avs_register_hda_board(struct avs_dev *adev, struct hda_codec *codec) { - struct snd_soc_acpi_mach mach = {{0}}; - struct platform_device *board; - struct avs_mach_pdata *pdata; struct hdac_device *hdev = &codec->core; - char *pname; - int ret, id; - - pname = devm_kasprintf(adev->dev, GFP_KERNEL, "%s-platform", dev_name(&hdev->dev)); - if (!pname) - return -ENOMEM; - - pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - pdata->obsolete_card_names = obsolete_card_names; - pdata->codec = codec; - - ret = avs_hda_platform_register(adev, pname); - if (ret < 0) - return ret; + struct snd_soc_acpi_mach mach = {{0}}; + struct platform_device *pdev; - mach.pdata = pdata; - mach.mach_params.platform = pname; mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL, "hda-%08x-tplg.bin", hdev->vendor_id); if (!mach.tplg_filename) return -ENOMEM; - id = adev->base.core.idx * HDA_MAX_CODECS + hdev->addr; - board = platform_device_register_data(NULL, "avs_hdaudio", id, (const void *)&mach, - sizeof(mach)); - if (IS_ERR(board)) { - dev_err(adev->dev, "hda board register failed\n"); - return PTR_ERR(board); - } - - ret = devm_add_action(adev->dev, board_pdev_unregister, board); - if (ret < 0) { - platform_device_unregister(board); - return ret; - } + pdev = avs_register_board_pdata(adev, "avs_hdaudio", &mach, codec, NULL, NULL); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); - return 0; + return avs_register_hda_component(adev, dev_name(&pdev->dev)); } static int avs_register_hda_boards(struct avs_dev *adev) @@ -722,6 +649,10 @@ int avs_register_all_boards(struct avs_dev *adev) dev_warn(adev->dev, "enumerate DMIC endpoints failed: %d\n", ret); + ret = avs_register_i2s_test_boards(adev); + if (ret) + dev_dbg(adev->dev, "enumerate I2S TEST endpoints failed: %d\n", ret); + ret = avs_register_i2s_boards(adev); if (ret < 0) dev_warn(adev->dev, "enumerate I2S endpoints failed: %d\n", diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 3ef0db254142..6782dc7efae3 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -165,8 +165,8 @@ avs_da7219_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_param return 0; } -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -176,8 +176,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); @@ -193,6 +191,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -218,18 +217,16 @@ static int avs_da7219_probe(struct platform_device *pdev) struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -259,10 +256,6 @@ static int avs_da7219_probe(struct platform_device *pdev) card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/dmic.c b/sound/soc/intel/avs/boards/dmic.c index a1448a98874d..bf6f580a5164 100644 --- a/sound/soc/intel/avs/boards/dmic.c +++ b/sound/soc/intel/avs/boards/dmic.c @@ -14,30 +14,6 @@ SND_SOC_DAILINK_DEF(dmic_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); SND_SOC_DAILINK_DEF(dmic_wov_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC WoV Pin"))); -SND_SOC_DAILINK_DEF(dmic_codec, DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); -/* Name overridden on probe */ -SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM(""))); - -static struct snd_soc_dai_link card_dai_links[] = { - /* Back ends */ - { - .name = "DMIC", - .id = 0, - .capture_only = 1, - .nonatomic = 1, - .no_pcm = 1, - SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), - }, - { - .name = "DMIC WoV", - .id = 1, - .capture_only = 1, - .nonatomic = 1, - .no_pcm = 1, - .ignore_suspend = 1, - SND_SOC_DAILINK_REG(dmic_wov_pin, dmic_codec, platform), - }, -}; static const struct snd_soc_dapm_widget card_widgets[] = { SND_SOC_DAPM_MIC("SoC DMIC", NULL), @@ -47,12 +23,56 @@ static const struct snd_soc_dapm_route card_routes[] = { {"DMic", NULL, "SoC DMIC"}, }; +static int avs_create_dai_links(struct device *dev, const char *codec_name, + struct snd_soc_dai_link **links, int *num_links) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + const int num_dl = 2; + + dl = devm_kcalloc(dev, num_dl, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->codecs) + return -ENOMEM; + + dl->codecs->name = devm_kstrdup(dev, codec_name, GFP_KERNEL); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "dmic-hifi"); + if (!dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + platform->name = dev_name(dev); + dl[0].num_cpus = 1; + dl[0].num_codecs = 1; + dl[0].platforms = platform; + dl[0].num_platforms = 1; + dl[0].nonatomic = 1; + dl[0].no_pcm = 1; + dl[0].capture_only = 1; + memcpy(&dl[1], &dl[0], sizeof(*dl)); + + dl[0].name = "DMIC"; + dl[0].cpus = dmic_pin; + dl[0].id = 0; + dl[1].name = "DMIC WoV"; + dl[1].cpus = dmic_wov_pin; + dl[1].id = 1; + dl[1].ignore_suspend = 1; + + *links = dl; + *num_links = num_dl; + return 0; +} + static int avs_dmic_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct snd_soc_acpi_mach *mach; struct avs_mach_pdata *pdata; struct snd_soc_card *card; - struct device *dev = &pdev->dev; int ret; mach = dev_get_platdata(dev); @@ -62,6 +82,10 @@ static int avs_dmic_probe(struct platform_device *pdev) if (!card) return -ENOMEM; + ret = avs_create_dai_links(dev, pdata->codec_name, &card->dai_link, &card->num_links); + if (ret) + return ret; + if (pdata->obsolete_card_names) { card->name = "avs_dmic"; } else { @@ -70,18 +94,12 @@ static int avs_dmic_probe(struct platform_device *pdev) } card->dev = dev; card->owner = THIS_MODULE; - card->dai_link = card_dai_links; - card->num_links = ARRAY_SIZE(card_dai_links); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); card->dapm_routes = card_routes; card->num_dapm_routes = ARRAY_SIZE(card_routes); card->fully_routed = true; - ret = snd_soc_fixup_dai_links_platform_name(card, mach->mach_params.platform); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/es8336.c b/sound/soc/intel/avs/boards/es8336.c index 1955f2d383c5..eb2b40894e3f 100644 --- a/sound/soc/intel/avs/boards/es8336.c +++ b/sound/soc/intel/avs/boards/es8336.c @@ -132,7 +132,7 @@ static int avs_es8336_codec_init(struct snd_soc_pcm_runtime *runtime) snd_jack_set_key(data->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_soc_component_set_jack(component, &data->jack, NULL); - card->dapm.idle_bias_off = true; + card->dapm.idle_bias = false; return 0; } @@ -195,8 +195,9 @@ static int avs_es8336_be_fixup(struct snd_soc_pcm_runtime *runtime, return 0; } -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) + +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -206,8 +207,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -222,6 +221,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -263,18 +263,16 @@ static int avs_es8336_probe(struct platform_device *pdev) struct avs_card_drvdata *data; struct snd_soc_card *card; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -306,10 +304,6 @@ static int avs_es8336_probe(struct platform_device *pdev) card->fully_routed = true; snd_soc_card_set_drvdata(card, data); - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c index 19b2255a8ac3..aec769e2396c 100644 --- a/sound/soc/intel/avs/boards/hdaudio.c +++ b/sound/soc/intel/avs/boards/hdaudio.c @@ -16,7 +16,7 @@ #include "../utils.h" static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int pcm_count, - const char *platform_name, struct snd_soc_dai_link **links) + struct snd_soc_dai_link **links) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -29,7 +29,7 @@ static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; + platform->name = dev_name(dev); pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list); for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) { @@ -142,7 +142,7 @@ static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm) list_for_each_entry(pcm, &codec->pcm_list_head, list) pcm_count++; - ret = avs_create_dai_links(card->dev, codec, pcm_count, mach->mach_params.platform, &links); + ret = avs_create_dai_links(card->dev, codec, pcm_count, &links); if (ret < 0) { dev_err(card->dev, "create links failed: %d\n", ret); return ret; @@ -197,7 +197,7 @@ static int avs_hdaudio_probe(struct platform_device *pdev) if (!binder->codecs->name) return -ENOMEM; - binder->platforms->name = mach->mach_params.platform; + binder->platforms->name = dev_name(dev); binder->num_platforms = 1; binder->codecs->dai_name = "codec-probing-DAI"; binder->num_codecs = 1; @@ -207,7 +207,10 @@ static int avs_hdaudio_probe(struct platform_device *pdev) return -ENOMEM; if (pdata->obsolete_card_names) { - card->name = binder->codecs->name; + card->name = devm_kasprintf(dev, GFP_KERNEL, "hdaudioB%dD%d", codec->bus->core.idx, + codec->core.addr); + if (!card->name) + return -ENOMEM; } else { card->driver_name = "avs_hdaudio"; if (hda_codec_is_display(codec)) diff --git a/sound/soc/intel/avs/boards/i2s_test.c b/sound/soc/intel/avs/boards/i2s_test.c index f7b6d7715738..9a6b89ffdf14 100644 --- a/sound/soc/intel/avs/boards/i2s_test.c +++ b/sound/soc/intel/avs/boards/i2s_test.c @@ -14,8 +14,8 @@ #include <sound/soc-dapm.h> #include "../utils.h" -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -25,8 +25,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -39,6 +37,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -59,11 +58,9 @@ static int avs_i2s_test_probe(struct platform_device *pdev) struct avs_mach_pdata *pdata; struct snd_soc_card *card; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; if (!avs_mach_singular_ssp(mach)) { @@ -94,7 +91,7 @@ static int avs_i2s_test_probe(struct platform_device *pdev) if (!card->name) return -ENOMEM; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d\n", ret); return ret; @@ -106,10 +103,6 @@ static int avs_i2s_test_probe(struct platform_device *pdev) card->num_links = 1; card->fully_routed = true; - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/max98357a.c b/sound/soc/intel/avs/boards/max98357a.c index 72053f83e98b..e9a87804f918 100644 --- a/sound/soc/intel/avs/boards/max98357a.c +++ b/sound/soc/intel/avs/boards/max98357a.c @@ -46,8 +46,8 @@ avs_max98357a_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_pa return 0; } -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -57,8 +57,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -73,6 +71,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -96,18 +95,16 @@ static int avs_max98357a_probe(struct platform_device *pdev) struct avs_mach_pdata *pdata; struct snd_soc_card *card; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -135,10 +132,6 @@ static int avs_max98357a_probe(struct platform_device *pdev) card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/max98373.c b/sound/soc/intel/avs/boards/max98373.c index cdba1c3ee20b..8b45b643ca29 100644 --- a/sound/soc/intel/avs/boards/max98373.c +++ b/sound/soc/intel/avs/boards/max98373.c @@ -95,8 +95,8 @@ static const struct snd_soc_ops avs_max98373_ops = { .hw_params = avs_max98373_hw_params, }; -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -106,8 +106,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -125,6 +123,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in !dl->codecs[1].name || !dl->codecs[1].dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 2; dl->platforms = platform; @@ -149,18 +148,16 @@ static int avs_max98373_probe(struct platform_device *pdev) struct avs_mach_pdata *pdata; struct snd_soc_card *card; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -190,10 +187,6 @@ static int avs_max98373_probe(struct platform_device *pdev) card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c index a68e227044c5..db073125fa4d 100644 --- a/sound/soc/intel/avs/boards/max98927.c +++ b/sound/soc/intel/avs/boards/max98927.c @@ -92,8 +92,8 @@ static const struct snd_soc_ops avs_max98927_ops = { .hw_params = avs_max98927_hw_params, }; -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -103,8 +103,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -122,6 +120,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in !dl->codecs[1].name || !dl->codecs[1].dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 2; dl->platforms = platform; @@ -146,18 +145,16 @@ static int avs_max98927_probe(struct platform_device *pdev) struct avs_mach_pdata *pdata; struct snd_soc_card *card; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -187,10 +184,6 @@ static int avs_max98927_probe(struct platform_device *pdev) card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c index 3fb1a5d07ae1..9ca400a6412e 100644 --- a/sound/soc/intel/avs/boards/nau8825.c +++ b/sound/soc/intel/avs/boards/nau8825.c @@ -172,8 +172,8 @@ static const struct snd_soc_ops avs_nau8825_ops = { .trigger = avs_nau8825_trigger, }; -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -183,8 +183,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -199,6 +197,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -250,18 +249,16 @@ static int avs_nau8825_probe(struct platform_device *pdev) struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -293,10 +290,6 @@ static int avs_nau8825_probe(struct platform_device *pdev) card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/probe.c b/sound/soc/intel/avs/boards/probe.c index 06c1f19f27aa..73884f8a535c 100644 --- a/sound/soc/intel/avs/boards/probe.c +++ b/sound/soc/intel/avs/boards/probe.c @@ -9,45 +9,54 @@ #include <linux/device.h> #include <linux/module.h> #include <sound/soc.h> -#include <sound/soc-acpi.h> -SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); -SND_SOC_DAILINK_DEF(probe_cp, DAILINK_COMP_ARRAY(COMP_CPU("Probe Extraction CPU DAI"))); -SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("probe-platform"))); +static int avs_create_dai_links(struct device *dev, struct snd_soc_dai_link **links, int *num_links) +{ + struct snd_soc_dai_link *dl; -static struct snd_soc_dai_link probe_mb_dai_links[] = { - { - .name = "Compress Probe Capture", - .nonatomic = 1, - SND_SOC_DAILINK_REG(probe_cp, dummy, platform), - }, -}; + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + if (!dl) + return -ENOMEM; + + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->platforms = devm_kzalloc(dev, sizeof(*dl->platforms), GFP_KERNEL); + if (!dl->cpus || !dl->platforms) + return -ENOMEM; + + dl->name = "Compress Probe Capture"; + dl->cpus->dai_name = "Probe Extraction CPU DAI"; + dl->num_cpus = 1; + dl->codecs = &snd_soc_dummy_dlc; + dl->num_codecs = 1; + dl->platforms->name = dev_name(dev); + dl->num_platforms = 1; + dl->nonatomic = 1; + + *links = dl; + *num_links = 1; + return 0; +} static int avs_probe_mb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; int ret; - mach = dev_get_platdata(dev); - card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) return -ENOMEM; + ret = avs_create_dai_links(dev, &card->dai_link, &card->num_links); + if (ret) + return ret; + card->driver_name = "avs_probe_mb"; card->long_name = card->name = "AVS PROBE"; card->dev = dev; card->owner = THIS_MODULE; - card->dai_link = probe_mb_dai_links; - card->num_links = ARRAY_SIZE(probe_mb_dai_links); card->fully_routed = true; - ret = snd_soc_fixup_dai_links_platform_name(card, mach->mach_params.platform); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c index ec5382925157..4055ecc60838 100644 --- a/sound/soc/intel/avs/boards/rt274.c +++ b/sound/soc/intel/avs/boards/rt274.c @@ -117,7 +117,7 @@ static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime) return ret; } - card->dapm.idle_bias_off = true; + card->dapm.idle_bias = false; return 0; } @@ -147,8 +147,8 @@ static int avs_rt274_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pc return 0; } -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -158,8 +158,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -174,6 +172,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -214,18 +213,16 @@ static int avs_rt274_probe(struct platform_device *pdev) struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -257,10 +254,6 @@ static int avs_rt274_probe(struct platform_device *pdev) card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c index 2566e971ce1c..4c9ac545555a 100644 --- a/sound/soc/intel/avs/boards/rt286.c +++ b/sound/soc/intel/avs/boards/rt286.c @@ -115,8 +115,8 @@ static const struct snd_soc_ops avs_rt286_ops = { .hw_params = avs_rt286_hw_params, }; -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -126,8 +126,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -142,6 +140,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -183,18 +182,16 @@ static int avs_rt286_probe(struct platform_device *pdev) struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); @@ -227,10 +224,6 @@ static int avs_rt286_probe(struct platform_device *pdev) card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c index 7be34c8ad167..2d7a7748d577 100644 --- a/sound/soc/intel/avs/boards/rt298.c +++ b/sound/soc/intel/avs/boards/rt298.c @@ -132,8 +132,8 @@ static const struct snd_soc_ops avs_rt298_ops = { .hw_params = avs_rt298_hw_params, }; -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -143,8 +143,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -159,6 +157,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -203,18 +202,16 @@ static int avs_rt298_probe(struct platform_device *pdev) struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -246,10 +243,6 @@ static int avs_rt298_probe(struct platform_device *pdev) card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/rt5514.c b/sound/soc/intel/avs/boards/rt5514.c index 45f091f2ce22..00b99e36d23c 100644 --- a/sound/soc/intel/avs/boards/rt5514.c +++ b/sound/soc/intel/avs/boards/rt5514.c @@ -84,8 +84,8 @@ static const struct snd_soc_ops avs_rt5514_ops = { .hw_params = avs_rt5514_hw_params, }; -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -95,8 +95,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -111,6 +109,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -136,18 +135,16 @@ static int avs_rt5514_probe(struct platform_device *pdev) struct avs_mach_pdata *pdata; struct snd_soc_card *card; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -173,10 +170,6 @@ static int avs_rt5514_probe(struct platform_device *pdev) card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/rt5640.c b/sound/soc/intel/avs/boards/rt5640.c index 706b84ffe1ef..97d1fa944188 100644 --- a/sound/soc/intel/avs/boards/rt5640.c +++ b/sound/soc/intel/avs/boards/rt5640.c @@ -67,7 +67,7 @@ static int avs_rt5640_codec_init(struct snd_soc_pcm_runtime *runtime) return ret; snd_soc_component_set_jack(codec_dai->component, jack, NULL); - card->dapm.idle_bias_off = true; + card->dapm.idle_bias = false; return 0; } diff --git a/sound/soc/intel/avs/boards/rt5663.c b/sound/soc/intel/avs/boards/rt5663.c index 51648801710a..68fea325376a 100644 --- a/sound/soc/intel/avs/boards/rt5663.c +++ b/sound/soc/intel/avs/boards/rt5663.c @@ -134,8 +134,8 @@ static const struct snd_soc_ops avs_rt5663_ops = { }; -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -145,8 +145,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -161,6 +159,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -202,18 +201,16 @@ static int avs_rt5663_probe(struct platform_device *pdev) struct snd_soc_card *card; struct rt5663_private *priv; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -245,10 +242,6 @@ static int avs_rt5663_probe(struct platform_device *pdev) card->fully_routed = true; snd_soc_card_set_drvdata(card, priv); - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c index 9677b9ebeff1..81863728da1d 100644 --- a/sound/soc/intel/avs/boards/rt5682.c +++ b/sound/soc/intel/avs/boards/rt5682.c @@ -204,8 +204,8 @@ avs_rt5682_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_param return 0; } -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -215,8 +215,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -231,6 +229,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 1; dl->platforms = platform; @@ -272,7 +271,6 @@ static int avs_rt5682_probe(struct platform_device *pdev) struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; if (pdev->id_entry && pdev->id_entry->driver_data) @@ -282,14 +280,13 @@ static int avs_rt5682_probe(struct platform_device *pdev) dev_dbg(dev, "avs_rt5682_quirk = %lx\n", avs_rt5682_quirk); mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -321,10 +318,6 @@ static int avs_rt5682_probe(struct platform_device *pdev) card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c index 3786eef8c494..ae0e6e27a8b8 100644 --- a/sound/soc/intel/avs/boards/ssm4567.c +++ b/sound/soc/intel/avs/boards/ssm4567.c @@ -81,8 +81,8 @@ avs_ssm4567_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_para return 0; } -static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - int tdm_slot, struct snd_soc_dai_link **dai_link) +static int avs_create_dai_link(struct device *dev, int ssp_port, int tdm_slot, + struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -92,8 +92,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in if (!dl || !platform) return -ENOMEM; - platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); @@ -111,6 +109,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in !dl->codecs[1].name || !dl->codecs[1].dai_name) return -ENOMEM; + platform->name = dev_name(dev); dl->num_cpus = 1; dl->num_codecs = 2; dl->platforms = platform; @@ -135,18 +134,16 @@ static int avs_ssm4567_probe(struct platform_device *pdev) struct avs_mach_pdata *pdata; struct snd_soc_card *card; struct device *dev = &pdev->dev; - const char *pname; int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); - pname = mach->mach_params.platform; pdata = mach->pdata; ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); if (ret) return ret; - ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + ret = avs_create_dai_link(dev, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; @@ -176,10 +173,6 @@ static int avs_ssm4567_probe(struct platform_device *pdev) card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; - ret = snd_soc_fixup_dai_links_platform_name(card, pname); - if (ret) - return ret; - return devm_snd_soc_register_deferrable_card(dev, card); } diff --git a/sound/soc/intel/avs/cnl.c b/sound/soc/intel/avs/cnl.c index 03f8fb0dc187..5b5359e9128b 100644 --- a/sound/soc/intel/avs/cnl.c +++ b/sound/soc/intel/avs/cnl.c @@ -8,6 +8,7 @@ #include <sound/hdaudio_ext.h> #include "avs.h" +#include "debug.h" #include "messages.h" #include "registers.h" diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 5ebadba07ecc..6e0e65584c7f 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -27,6 +27,7 @@ #include "../../codecs/hda.h" #include "avs.h" #include "cldma.h" +#include "debug.h" #include "messages.h" #include "pcm.h" diff --git a/sound/soc/intel/avs/debug.h b/sound/soc/intel/avs/debug.h new file mode 100644 index 000000000000..94fe8729a5c1 --- /dev/null +++ b/sound/soc/intel/avs/debug.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2024-2025 Intel Corporation + * + * Authors: Cezary Rojewski <cezary.rojewski@intel.com> + * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> + */ + +#ifndef __SOUND_SOC_INTEL_AVS_DEBUG_H +#define __SOUND_SOC_INTEL_AVS_DEBUG_H + +#include "messages.h" +#include "registers.h" + +struct avs_dev; + +#define avs_log_buffer_size(adev) \ + ((adev)->fw_cfg.trace_log_bytes / (adev)->hw_cfg.dsp_cores) + +#define avs_log_buffer_addr(adev, core) \ +({ \ + s32 __offset = avs_dsp_op(adev, log_buffer_offset, core); \ + (__offset < 0) ? NULL : \ + (avs_sram_addr(adev, AVS_DEBUG_WINDOW) + __offset); \ +}) + +static inline int avs_log_buffer_status_locked(struct avs_dev *adev, union avs_notify_msg *msg) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&adev->trace_lock, flags); + ret = avs_dsp_op(adev, log_buffer_status, msg); + spin_unlock_irqrestore(&adev->trace_lock, flags); + + return ret; +} + +struct avs_apl_log_buffer_layout { + u32 read_ptr; + u32 write_ptr; + u8 buffer[]; +} __packed; +static_assert(sizeof(struct avs_apl_log_buffer_layout) == 8); + +#define avs_apl_log_payload_size(adev) \ + (avs_log_buffer_size(adev) - sizeof(struct avs_apl_log_buffer_layout)) + +#define avs_apl_log_payload_addr(addr) \ + (addr + sizeof(struct avs_apl_log_buffer_layout)) + +#ifdef CONFIG_DEBUG_FS +int avs_register_probe_component(struct avs_dev *adev, const char *name); + +#define AVS_SET_ENABLE_LOGS_OP(name) \ + .enable_logs = avs_##name##_enable_logs + +bool avs_logging_fw(struct avs_dev *adev); +void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len); +void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len); + +void avs_debugfs_init(struct avs_dev *adev); +void avs_debugfs_exit(struct avs_dev *adev); + +#else +static inline int avs_register_probe_component(struct avs_dev *adev, const char *name) +{ + return -EOPNOTSUPP; +} + +#define AVS_SET_ENABLE_LOGS_OP(name) + +static inline bool avs_logging_fw(struct avs_dev *adev) +{ + return false; +} + +static inline void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len) +{ +} + +static inline void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, + unsigned int len) +{ +} + +static inline void avs_debugfs_init(struct avs_dev *adev) { } +static inline void avs_debugfs_exit(struct avs_dev *adev) { } +#endif + +#endif diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index f508f215ecd2..3534de46f9e4 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -13,6 +13,7 @@ #include <linux/string_helpers.h> #include <sound/soc.h> #include "avs.h" +#include "debug.h" #include "messages.h" static unsigned int __kfifo_fromio(struct kfifo *fifo, const void __iomem *src, unsigned int len) diff --git a/sound/soc/intel/avs/icl.c b/sound/soc/intel/avs/icl.c index f8d327ea2656..d655e727bebd 100644 --- a/sound/soc/intel/avs/icl.c +++ b/sound/soc/intel/avs/icl.c @@ -10,6 +10,7 @@ #include <sound/hdaudio.h> #include <sound/hdaudio_ext.h> #include "avs.h" +#include "debug.h" #include "messages.h" #define ICL_VS_LTRP_GB_ICCMAX 95 diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index 6bfb9d1a1ca8..c0feb9edd7f6 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -10,6 +10,7 @@ #include <linux/slab.h> #include <sound/hdaudio_ext.h> #include "avs.h" +#include "debug.h" #include "messages.h" #include "registers.h" #include "trace.h" diff --git a/sound/soc/intel/avs/lnl.c b/sound/soc/intel/avs/lnl.c index 03208596dfb1..4fbc62bfd6c5 100644 --- a/sound/soc/intel/avs/lnl.c +++ b/sound/soc/intel/avs/lnl.c @@ -8,6 +8,7 @@ #include <sound/hdaudio_ext.h> #include "avs.h" +#include "debug.h" #include "registers.h" int avs_lnl_core_stall(struct avs_dev *adev, u32 core_mask, bool stall) diff --git a/sound/soc/intel/avs/mtl.c b/sound/soc/intel/avs/mtl.c index e7b7915b2a82..d8bdd03275d7 100644 --- a/sound/soc/intel/avs/mtl.c +++ b/sound/soc/intel/avs/mtl.c @@ -8,6 +8,7 @@ #include <sound/hdaudio_ext.h> #include "avs.h" +#include "debug.h" #include "registers.h" #include "trace.h" diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index e8e6b1c7fc90..7aa20fcf1a33 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -115,6 +115,55 @@ avs_path_find_variant(struct avs_dev *adev, return NULL; } +static struct avs_tplg_path *avs_condpath_find_variant(struct avs_dev *adev, + struct avs_tplg_path_template *template, + struct avs_path *source, + struct avs_path *sink) +{ + struct avs_tplg_path *variant; + + list_for_each_entry(variant, &template->path_list, node) { + if (variant->source_path_id == source->template->id && + variant->sink_path_id == sink->template->id) + return variant; + } + + return NULL; +} + +static bool avs_tplg_path_template_id_equal(struct avs_tplg_path_template_id *id, + struct avs_tplg_path_template_id *id2) +{ + return id->id == id2->id && !strcmp(id->tplg_name, id2->tplg_name); +} + +static struct avs_path *avs_condpath_find_match(struct avs_dev *adev, + struct avs_tplg_path_template *template, + struct avs_path *path, int dir) +{ + struct avs_tplg_path_template_id *id, *id2; + + if (dir) { + id = &template->source; + id2 = &template->sink; + } else { + id = &template->sink; + id2 = &template->source; + } + + /* Check whether this path is either source or sink of condpath template. */ + if (id->id != path->template->owner->id || + strcmp(id->tplg_name, path->template->owner->owner->name)) + return NULL; + + /* Unidirectional condpaths are allowed. */ + if (avs_tplg_path_template_id_equal(id, id2)) + return path; + + /* Now find the counterpart. */ + return avs_path_find_path(adev, id2->tplg_name, id2->id); +} + static struct acpi_nhlt_config * avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t); @@ -1051,6 +1100,10 @@ static int avs_path_init(struct avs_dev *adev, struct avs_path *path, path->dma_id = dma_id; INIT_LIST_HEAD(&path->ppl_list); INIT_LIST_HEAD(&path->node); + INIT_LIST_HEAD(&path->source_list); + INIT_LIST_HEAD(&path->sink_list); + INIT_LIST_HEAD(&path->source_node); + INIT_LIST_HEAD(&path->sink_node); /* create all the pipelines */ list_for_each_entry(tppl, &template->ppl_list, node) { @@ -1134,12 +1187,129 @@ err: return ERR_PTR(ret); } +static void avs_condpath_free(struct avs_dev *adev, struct avs_path *path) +{ + int ret; + + list_del(&path->source_node); + list_del(&path->sink_node); + + ret = avs_path_reset(path); + if (ret < 0) + dev_err(adev->dev, "reset condpath failed: %d\n", ret); + + ret = avs_path_unbind(path); + if (ret < 0) + dev_err(adev->dev, "unbind condpath failed: %d\n", ret); + + avs_path_free_unlocked(path); +} + +static struct avs_path *avs_condpath_create(struct avs_dev *adev, + struct avs_tplg_path *template, + struct avs_path *source, + struct avs_path *sink) +{ + struct avs_path *path; + int ret; + + path = avs_path_create_unlocked(adev, 0, template); + if (IS_ERR(path)) + return path; + + ret = avs_path_bind(path); + if (ret) + goto err_bind; + + ret = avs_path_reset(path); + if (ret) + goto err_reset; + + path->source = source; + path->sink = sink; + list_add_tail(&path->source_node, &source->source_list); + list_add_tail(&path->sink_node, &sink->sink_list); + + return path; + +err_reset: + avs_path_unbind(path); +err_bind: + avs_path_free_unlocked(path); + return ERR_PTR(ret); +} + +static int avs_condpaths_walk(struct avs_dev *adev, struct avs_path *path, int dir) +{ + struct avs_soc_component *acomp; + struct avs_path *source, *sink; + struct avs_path **other; + + if (dir) { + source = path; + other = &sink; + } else { + sink = path; + other = &source; + } + + list_for_each_entry(acomp, &adev->comp_list, node) { + for (int i = 0; i < acomp->tplg->num_condpath_tmpls; i++) { + struct avs_tplg_path_template *template; + struct avs_tplg_path *variant; + struct avs_path *cpath; + + template = &acomp->tplg->condpath_tmpls[i]; + + /* Do not create unidirectional condpaths twice. */ + if (avs_tplg_path_template_id_equal(&template->source, + &template->sink) && dir) + continue; + + *other = avs_condpath_find_match(adev, template, path, dir); + if (!*other) + continue; + + variant = avs_condpath_find_variant(adev, template, source, sink); + if (!variant) + continue; + + cpath = avs_condpath_create(adev, variant, source, sink); + if (IS_ERR(cpath)) + return PTR_ERR(cpath); + } + } + + return 0; +} + +/* Caller responsible for holding adev->path_mutex. */ +static int avs_condpaths_walk_all(struct avs_dev *adev, struct avs_path *path) +{ + int ret; + + ret = avs_condpaths_walk(adev, path, SNDRV_PCM_STREAM_CAPTURE); + if (ret) + return ret; + + return avs_condpaths_walk(adev, path, SNDRV_PCM_STREAM_PLAYBACK); +} + void avs_path_free(struct avs_path *path) { + struct avs_path *cpath, *csave; struct avs_dev *adev = path->owner; mutex_lock(&adev->path_mutex); + + /* Free all condpaths this path spawned. */ + list_for_each_entry_safe(cpath, csave, &path->source_list, source_node) + avs_condpath_free(path->owner, cpath); + list_for_each_entry_safe(cpath, csave, &path->sink_list, sink_node) + avs_condpath_free(path->owner, cpath); + avs_path_free_unlocked(path); + mutex_unlock(&adev->path_mutex); } @@ -1150,6 +1320,7 @@ struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id, { struct avs_tplg_path *variant; struct avs_path *path; + int ret; variant = avs_path_find_variant(adev, template, fe_params, be_params); if (!variant) { @@ -1163,7 +1334,16 @@ struct avs_path *avs_path_create(struct avs_dev *adev, u32 dma_id, mutex_lock(&adev->comp_list_mutex); path = avs_path_create_unlocked(adev, dma_id, variant); + if (IS_ERR(path)) + goto exit; + + ret = avs_condpaths_walk_all(adev, path); + if (ret) { + avs_path_free_unlocked(path); + path = ERR_PTR(ret); + } +exit: mutex_unlock(&adev->comp_list_mutex); mutex_unlock(&adev->path_mutex); @@ -1286,6 +1466,42 @@ int avs_path_reset(struct avs_path *path) return 0; } +static int avs_condpath_pause(struct avs_dev *adev, struct avs_path *cpath) +{ + struct avs_path_pipeline *ppl; + int ret; + + if (cpath->state == AVS_PPL_STATE_PAUSED) + return 0; + + list_for_each_entry_reverse(ppl, &cpath->ppl_list, node) { + ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id, AVS_PPL_STATE_PAUSED); + if (ret) { + dev_err(adev->dev, "pause cpath failed: %d\n", ret); + cpath->state = AVS_PPL_STATE_INVALID; + return AVS_IPC_RET(ret); + } + } + + cpath->state = AVS_PPL_STATE_PAUSED; + return 0; +} + +static void avs_condpaths_pause(struct avs_dev *adev, struct avs_path *path) +{ + struct avs_path *cpath; + + mutex_lock(&adev->path_mutex); + + /* If either source or sink stops, so do the attached conditional paths. */ + list_for_each_entry(cpath, &path->source_list, source_node) + avs_condpath_pause(adev, cpath); + list_for_each_entry(cpath, &path->sink_list, sink_node) + avs_condpath_pause(adev, cpath); + + mutex_unlock(&adev->path_mutex); +} + int avs_path_pause(struct avs_path *path) { struct avs_path_pipeline *ppl; @@ -1295,6 +1511,8 @@ int avs_path_pause(struct avs_path *path) if (path->state == AVS_PPL_STATE_PAUSED) return 0; + avs_condpaths_pause(adev, path); + list_for_each_entry_reverse(ppl, &path->ppl_list, node) { ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id, AVS_PPL_STATE_PAUSED); @@ -1309,6 +1527,50 @@ int avs_path_pause(struct avs_path *path) return 0; } +static int avs_condpath_run(struct avs_dev *adev, struct avs_path *cpath, int trigger) +{ + struct avs_path_pipeline *ppl; + int ret; + + if (cpath->state == AVS_PPL_STATE_RUNNING) + return 0; + + list_for_each_entry(ppl, &cpath->ppl_list, node) { + if (ppl->template->cfg->trigger != trigger) + continue; + + ret = avs_ipc_set_pipeline_state(adev, ppl->instance_id, AVS_PPL_STATE_RUNNING); + if (ret) { + dev_err(adev->dev, "run cpath failed: %d\n", ret); + cpath->state = AVS_PPL_STATE_INVALID; + return AVS_IPC_RET(ret); + } + } + + cpath->state = AVS_PPL_STATE_RUNNING; + return 0; +} + +static void avs_condpaths_run(struct avs_dev *adev, struct avs_path *path, int trigger) +{ + struct avs_path *cpath; + + mutex_lock(&adev->path_mutex); + + /* Run conditional paths only if source and sink are both running. */ + list_for_each_entry(cpath, &path->source_list, source_node) + if (cpath->source->state == AVS_PPL_STATE_RUNNING && + cpath->sink->state == AVS_PPL_STATE_RUNNING) + avs_condpath_run(adev, cpath, trigger); + + list_for_each_entry(cpath, &path->sink_list, sink_node) + if (cpath->source->state == AVS_PPL_STATE_RUNNING && + cpath->sink->state == AVS_PPL_STATE_RUNNING) + avs_condpath_run(adev, cpath, trigger); + + mutex_unlock(&adev->path_mutex); +} + int avs_path_run(struct avs_path *path, int trigger) { struct avs_path_pipeline *ppl; @@ -1332,5 +1594,10 @@ int avs_path_run(struct avs_path *path, int trigger) } path->state = AVS_PPL_STATE_RUNNING; + + /* Granular pipeline triggering not intended for conditional paths. */ + if (trigger == AVS_TPLG_TRIGGER_AUTO) + avs_condpaths_run(adev, path, trigger); + return 0; } diff --git a/sound/soc/intel/avs/path.h b/sound/soc/intel/avs/path.h index c65ed84aa853..ceb89971a902 100644 --- a/sound/soc/intel/avs/path.h +++ b/sound/soc/intel/avs/path.h @@ -13,11 +13,24 @@ #include "avs.h" #include "topology.h" +#define AVS_COND_TYPE_NONE 0 +#define AVS_COND_TYPE_AECREF 1 + struct avs_path { u32 dma_id; struct list_head ppl_list; u32 state; + /* condpath navigation for standard paths */ + struct list_head source_list; + struct list_head sink_list; + + /* conditional path fields */ + struct avs_path *source; + struct avs_path *sink; + struct list_head source_node; + struct list_head sink_node; + struct avs_tplg_path *template; struct avs_dev *owner; /* device path management */ diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 67ce6675eea7..d31058e2de5b 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -1379,9 +1379,9 @@ static struct snd_soc_component_driver avs_component_driver = { .topology_name_prefix = "intel/avs", }; -int avs_soc_component_register(struct device *dev, const char *name, - struct snd_soc_component_driver *drv, - struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais) +int avs_register_component(struct device *dev, const char *name, + struct snd_soc_component_driver *drv, + struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais) { struct avs_soc_component *acomp; int ret; @@ -1390,16 +1390,18 @@ int avs_soc_component_register(struct device *dev, const char *name, if (!acomp) return -ENOMEM; - ret = snd_soc_component_initialize(&acomp->base, drv, dev); - if (ret < 0) - return ret; + acomp->base.name = devm_kstrdup(dev, name, GFP_KERNEL); + if (!acomp->base.name) + return -ENOMEM; - /* force name change after ASoC is done with its init */ - acomp->base.name = name; INIT_LIST_HEAD(&acomp->node); drv->use_dai_pcm_id = !obsolete_card_names; + ret = snd_soc_component_initialize(&acomp->base, drv, dev); + if (ret < 0) + return ret; + return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais); } @@ -1426,7 +1428,7 @@ static struct snd_soc_dai_driver dmic_cpu_dais[] = { }, }; -int avs_dmic_platform_register(struct avs_dev *adev, const char *name) +int avs_register_dmic_component(struct avs_dev *adev, const char *name) { const struct snd_soc_dai_ops *ops; @@ -1437,8 +1439,8 @@ int avs_dmic_platform_register(struct avs_dev *adev, const char *name) dmic_cpu_dais[0].ops = ops; dmic_cpu_dais[1].ops = ops; - return avs_soc_component_register(adev->dev, name, &avs_component_driver, dmic_cpu_dais, - ARRAY_SIZE(dmic_cpu_dais)); + return avs_register_component(adev->dev, name, &avs_component_driver, dmic_cpu_dais, + ARRAY_SIZE(dmic_cpu_dais)); } static const struct snd_soc_dai_driver i2s_dai_template = { @@ -1470,8 +1472,8 @@ static const struct snd_soc_dai_driver i2s_dai_template = { }, }; -int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask, - unsigned long *tdms) +int avs_register_i2s_component(struct avs_dev *adev, const char *name, unsigned long port_mask, + unsigned long *tdms) { struct snd_soc_dai_driver *cpus, *dai; const struct snd_soc_dai_ops *ops; @@ -1537,7 +1539,7 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l } plat_register: - return avs_soc_component_register(adev->dev, name, &avs_component_driver, cpus, cpu_count); + return avs_register_component(adev->dev, name, &avs_component_driver, cpus, cpu_count); } /* HD-Audio CPU DAI template */ @@ -1762,8 +1764,7 @@ static struct snd_soc_component_driver avs_hda_component_driver = { .topology_name_prefix = "intel/avs", }; -int avs_hda_platform_register(struct avs_dev *adev, const char *name) +int avs_register_hda_component(struct avs_dev *adev, const char *name) { - return avs_soc_component_register(adev->dev, name, - &avs_hda_component_driver, NULL, 0); + return avs_register_component(adev->dev, name, &avs_hda_component_driver, NULL, 0); } diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c index a42736b9aa55..693ecfe68fd0 100644 --- a/sound/soc/intel/avs/probes.c +++ b/sound/soc/intel/avs/probes.c @@ -11,6 +11,7 @@ #include <sound/hdaudio.h> #include <sound/soc.h> #include "avs.h" +#include "debug.h" #include "messages.h" static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id node_id, @@ -213,7 +214,7 @@ static int avs_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, } static int avs_probe_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai) + struct snd_compr_tstamp64 *tstamp, struct snd_soc_dai *dai) { struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream); struct snd_soc_pcm_stream *pstream; @@ -284,14 +285,28 @@ static struct snd_soc_dai_driver probe_cpu_dais[] = { }, }; -static struct snd_soc_component_driver avs_probe_component_driver = { +static const struct snd_soc_component_driver avs_probe_component_driver = { .name = "avs-probe-compr", .compress_ops = &avs_probe_compress_ops, .module_get_upon_open = 1, /* increment refcount when a stream is opened */ }; -int avs_probe_platform_register(struct avs_dev *adev, const char *name) +int avs_register_probe_component(struct avs_dev *adev, const char *name) { - return avs_soc_component_register(adev->dev, name, &avs_probe_component_driver, - probe_cpu_dais, ARRAY_SIZE(probe_cpu_dais)); + struct snd_soc_component *component; + int ret; + + component = devm_kzalloc(adev->dev, sizeof(*component), GFP_KERNEL); + if (!component) + return -ENOMEM; + + component->name = devm_kstrdup(adev->dev, name, GFP_KERNEL); + if (!component->name) + return -ENOMEM; + + ret = snd_soc_component_initialize(component, &avs_probe_component_driver, adev->dev); + if (ret) + return ret; + + return snd_soc_add_component(component, probe_cpu_dais, ARRAY_SIZE(probe_cpu_dais)); } diff --git a/sound/soc/intel/avs/ptl.c b/sound/soc/intel/avs/ptl.c index 2be4b545c91d..07da9b0aa2b8 100644 --- a/sound/soc/intel/avs/ptl.c +++ b/sound/soc/intel/avs/ptl.c @@ -8,6 +8,7 @@ #include <sound/hdaudio_ext.h> #include "avs.h" +#include "debug.h" #include "registers.h" #include "trace.h" diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c index d66ef000de9e..8fb86f364ff3 100644 --- a/sound/soc/intel/avs/skl.c +++ b/sound/soc/intel/avs/skl.c @@ -11,6 +11,7 @@ #include <sound/hdaudio_ext.h> #include "avs.h" #include "cldma.h" +#include "debug.h" #include "messages.h" #include "registers.h" diff --git a/sound/soc/intel/avs/tgl.c b/sound/soc/intel/avs/tgl.c index 9dbb3ad0954a..afb066516101 100644 --- a/sound/soc/intel/avs/tgl.c +++ b/sound/soc/intel/avs/tgl.c @@ -8,6 +8,7 @@ #include <linux/pci.h> #include "avs.h" +#include "debug.h" #include "messages.h" #define CPUID_TSC_LEAF 0x15 diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index f2e4ad8b8e14..dfe8cf505381 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -1387,6 +1387,27 @@ static const struct avs_tplg_token_parser path_parsers[] = { }, }; +static const struct avs_tplg_token_parser condpath_parsers[] = { + { + .token = AVS_TKN_CONDPATH_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_path, id), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_CONDPATH_SOURCE_PATH_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_path, source_path_id), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_CONDPATH_SINK_PATH_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_path, sink_path_id), + .parse = avs_parse_word_token, + }, +}; + static struct avs_tplg_path * avs_tplg_path_create(struct snd_soc_component *comp, struct avs_tplg_path_template *owner, struct snd_soc_tplg_vendor_array *tuples, u32 block_size, @@ -1454,6 +1475,39 @@ static const struct avs_tplg_token_parser path_tmpl_parsers[] = { }, }; +static const struct avs_tplg_token_parser condpath_tmpl_parsers[] = { + { + .token = AVS_TKN_CONDPATH_TMPL_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_path_template, id), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_CONDPATH_TMPL_SOURCE_TPLG_NAME_STRING, + .type = SND_SOC_TPLG_TUPLE_TYPE_STRING, + .offset = offsetof(struct avs_tplg_path_template, source.tplg_name), + .parse = avs_parse_string_token, + }, + { + .token = AVS_TKN_CONDPATH_TMPL_SOURCE_PATH_TMPL_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_path_template, source.id), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_CONDPATH_TMPL_SINK_TPLG_NAME_STRING, + .type = SND_SOC_TPLG_TUPLE_TYPE_STRING, + .offset = offsetof(struct avs_tplg_path_template, sink.tplg_name), + .parse = avs_parse_string_token, + }, + { + .token = AVS_TKN_CONDPATH_TMPL_SINK_PATH_TMPL_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_path_template, sink.id), + .parse = avs_parse_word_token, + }, +}; + static int parse_path_template(struct snd_soc_component *comp, struct snd_soc_tplg_vendor_array *tuples, u32 block_size, struct avs_tplg_path_template *template, @@ -1524,6 +1578,56 @@ avs_tplg_path_template_create(struct snd_soc_component *comp, struct avs_tplg *o return template; } +static int avs_tplg_parse_condpath_templates(struct snd_soc_component *comp, + struct snd_soc_tplg_vendor_array *tuples, + u32 block_size) +{ + struct avs_soc_component *acomp = to_avs_soc_component(comp); + struct avs_tplg *tplg = acomp->tplg; + int ret, i; + + ret = parse_dictionary_header(comp, tuples, (void **)&tplg->condpath_tmpls, + &tplg->num_condpath_tmpls, + sizeof(*tplg->condpath_tmpls), + AVS_TKN_MANIFEST_NUM_CONDPATH_TMPLS_U32); + if (ret) + return ret; + + block_size -= le32_to_cpu(tuples->size); + /* With header parsed, move on to parsing entries. */ + tuples = avs_tplg_vendor_array_next(tuples); + + for (i = 0; i < tplg->num_condpath_tmpls; i++) { + struct avs_tplg_path_template *template; + u32 esize; + + template = &tplg->condpath_tmpls[i]; + template->owner = tplg; /* Used when building sysfs hierarchy. */ + INIT_LIST_HEAD(&template->path_list); + INIT_LIST_HEAD(&template->node); + + ret = avs_tplg_vendor_entry_size(tuples, block_size, + AVS_TKN_CONDPATH_TMPL_ID_U32, &esize); + if (ret) + return ret; + + ret = parse_path_template(comp, tuples, esize, template, + condpath_tmpl_parsers, + ARRAY_SIZE(condpath_tmpl_parsers), + condpath_parsers, + ARRAY_SIZE(condpath_parsers)); + if (ret < 0) { + dev_err(comp->dev, "parse condpath_tmpl: %d failed: %d\n", i, ret); + return ret; + } + + block_size -= esize; + tuples = avs_tplg_vendor_array_at(tuples, esize); + } + + return 0; +} + static const struct avs_tplg_token_parser mod_init_config_parsers[] = { { .token = AVS_TKN_INIT_CONFIG_ID_U32, @@ -1891,6 +1995,12 @@ static int avs_manifest(struct snd_soc_component *comp, int index, return ret; } + /* Condpaths dictionary. */ + ret = avs_tplg_parse_condpath_templates(comp, tuples, + has_init_config ? offset : remaining); + if (ret < 0) + return ret; + if (!has_init_config) return 0; diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h index f5601a4e3ec8..1e83fccf2ea2 100644 --- a/sound/soc/intel/avs/topology.h +++ b/sound/soc/intel/avs/topology.h @@ -33,6 +33,7 @@ struct avs_tplg { u32 num_pplcfgs; struct avs_tplg_binding *bindings; u32 num_bindings; + struct avs_tplg_path_template *condpath_tmpls; u32 num_condpath_tmpls; struct avs_tplg_init_config *init_configs; u32 num_init_configs; @@ -155,6 +156,10 @@ struct avs_tplg_path_template { struct snd_soc_dapm_widget *w; + /* Conditional path. */ + struct avs_tplg_path_template_id source; + struct avs_tplg_path_template_id sink; + struct list_head path_list; struct avs_tplg *owner; @@ -176,6 +181,9 @@ struct avs_tplg_path { /* Path format requirements. */ struct avs_audio_format *fe_fmt; struct avs_audio_format *be_fmt; + /* Condpath path-variant requirements. */ + u32 source_path_id; + u32 sink_path_id; struct list_head ppl_list; |