From: Cezary Rojewski Date: Wed, 27 Aug 2025 14:22:25 +0000 (+0200) Subject: ASoC: Intel: avs: New board registration routines X-Git-Tag: v6.18-rc1~135^2~13^2~22^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3351e814cb49dff7ef4808f5ebfb299162994118;p=thirdparty%2Fkernel%2Flinux.git ASoC: Intel: avs: New board registration routines To support multiple instances of the same card utilize PLATFORM_DEVID_AUTO when registering new platform devices. This adaptation is also an opportunity to streamline the devices registration - avs_register_board(). All the new functions are equivalents of the existing ones apart from adjusting platform_device_register_data() call with PLATFORM_DEVID_AUTO and code size reduction given the presence of unified register function. Follow up changes will complete the transition and cleanup the duplicate members. Reviewed-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Message-ID: <20250827142229.869139-2-cezary.rojewski@intel.com> Signed-off-by: Mark Brown --- diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index e1d6fa344aa12..0195e5201a056 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -399,6 +399,90 @@ static const struct avs_acpi_boards *avs_get_i2s_boards(struct avs_dev *adev) return NULL; } +/* Platform devices spawned by AVS driver are removed with this hook. */ +static void avs_unregister_board(void *pdev) +{ + platform_device_unregister(pdev); +} + +static struct platform_device *avs_register_board(struct avs_dev *adev, const char *name, + const void *data, size_t size) +{ + struct platform_device *pdev; + int ret; + + pdev = platform_device_register_data(NULL, name, PLATFORM_DEVID_AUTO, data, size); + if (IS_ERR(pdev)) + return pdev; + + ret = devm_add_action_or_reset(adev->dev, avs_unregister_board, pdev); + if (ret) + return ERR_PTR(ret); + + return pdev; +} + +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 avs_mach_pdata *pdata; + + pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->codec = codec; + pdata->tdms = tdms; + pdata->codec_name = codec_name; + pdata->obsolete_card_names = obsolete_card_names; + mach->pdata = pdata; + + return avs_register_board(adev, name, mach, sizeof(*mach)); +} + +static int __maybe_unused avs_register_probe_board2(struct avs_dev *adev) +{ + struct platform_device *pdev; + + pdev = avs_register_board(adev, "avs_probe_mb", NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return avs_register_probe_component(adev, dev_name(&pdev->dev)); +} + +__maybe_unused +static int avs_register_dmic_board2(struct avs_dev *adev) +{ + static struct snd_soc_acpi_mach mach = { + .tplg_filename = "dmic-tplg.bin", + }; + struct platform_device *pdev; + char *codec_name; + + if (!acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1)) { + dev_dbg(adev->dev, "no DMIC endpoints present\n"); + return 0; + } + + /* 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); + + codec_name = devm_kstrdup(adev->dev, dev_name(&pdev->dev), GFP_KERNEL); + if (!codec_name) + return -ENOMEM; + + pdev = avs_register_board_pdata(adev, "avs_dmic", &mach, NULL, NULL, codec_name); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return avs_register_dmic_component(adev, dev_name(&pdev->dev)); +} + /* platform devices owned by AVS audio are removed with this hook */ static void board_pdev_unregister(void *data) { @@ -569,6 +653,31 @@ static int avs_register_i2s_test_board(struct avs_dev *adev, int ssp_port, int t return 0; } +__maybe_unused +static int avs_register_i2s_test_board2(struct avs_dev *adev, int ssp_port, int tdm_slot) +{ + 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; + + tdms[ssp_port] = BIT(tdm_slot); + mach.drv_name = "avs_i2s_test"; + mach.mach_params.i2s_link_mask = AVS_SSP(ssp_port); + + 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), AVS_SSP(ssp_port), tdms); +} + static int avs_register_i2s_test_boards(struct avs_dev *adev) { int max_ssps = adev->hw_cfg.i2s_caps.ctrl_count; @@ -601,6 +710,23 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev) return 0; } +__maybe_unused +static int avs_register_i2s_board2(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; @@ -684,6 +810,25 @@ static int avs_register_hda_board(struct avs_dev *adev, struct hda_codec *codec) return 0; } +__maybe_unused +static int avs_register_hda_board2(struct avs_dev *adev, struct hda_codec *codec) +{ + struct hdac_device *hdev = &codec->core; + struct snd_soc_acpi_mach mach = {{0}}; + struct platform_device *pdev; + + mach.tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL, "hda-%08x-tplg.bin", + hdev->vendor_id); + if (!mach.tplg_filename) + return -ENOMEM; + + pdev = avs_register_board_pdata(adev, "avs_hdaudio", &mach, codec, NULL, NULL); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return avs_register_hda_component(adev, dev_name(&pdev->dev)); +} + static int avs_register_hda_boards(struct avs_dev *adev) { struct hdac_bus *bus = &adev->base.core;