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

ASoC: soc-acpi / SOF: Add best_effort flag to get_function_tplg_files op

When there is no fallback possibility available for the function topology
use it is better to try to create a profile for the card in best effort
manner, leaving out non supported links for example.

As an example: some laptops present SSPx-BT link but we don't have fragment
yet to support this. If we only have support for functional topology
without monolithic fallback then we would fail the card creation.
The reason why the monolithic topology works on the same device is that it
does not have the SSPx-BT link handled, it is ignored.

In case when there is no fallback possibility we should try to create the
card with links that we support as best effort instead of failing and
leaving the user without a card.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://patch.msgid.link/20251215101036.9370-2-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Peter Ujfalusi and committed by
Mark Brown
c8f3c9fa 8f0b4cce

+26 -4
+4 -1
include/sound/soc-acpi.h
··· 203 203 * @mach: the pointer of the machine driver 204 204 * @prefix: the prefix of the topology file name. Typically, it is the path. 205 205 * @tplg_files: the pointer of the array of the topology file names. 206 + * @best_effort: ignore non supported links and try to build the card in best effort 207 + * with supported links 206 208 */ 207 209 /* Descriptor for SST ASoC machine driver */ 208 210 struct snd_soc_acpi_mach { ··· 226 224 const u32 tplg_quirk_mask; 227 225 int (*get_function_tplg_files)(struct snd_soc_card *card, 228 226 const struct snd_soc_acpi_mach *mach, 229 - const char *prefix, const char ***tplg_files); 227 + const char *prefix, const char ***tplg_files, 228 + bool best_effort); 230 229 }; 231 230 232 231 #define SND_SOC_ACPI_MAX_CODECS 3
+4 -1
sound/soc/intel/common/sof-function-topology-lib.c
··· 28 28 #define SOF_INTEL_PLATFORM_NAME_MAX 4 29 29 30 30 int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach, 31 - const char *prefix, const char ***tplg_files) 31 + const char *prefix, const char ***tplg_files, bool best_effort) 32 32 { 33 33 struct snd_soc_acpi_mach_params mach_params = mach->mach_params; 34 34 struct snd_soc_dai_link *dai_link; ··· 87 87 dev_dbg(card->dev, 88 88 "dai_link %s is not supported by separated tplg yet\n", 89 89 dai_link->name); 90 + if (best_effort) 91 + continue; 92 + 90 93 return 0; 91 94 } 92 95 if (tplg_mask & BIT(tplg_dev))
+1 -1
sound/soc/intel/common/sof-function-topology-lib.h
··· 10 10 #define _SND_SOC_ACPI_INTEL_GET_TPLG_H 11 11 12 12 int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach, 13 - const char *prefix, const char ***tplg_files); 13 + const char *prefix, const char ***tplg_files, bool best_effort); 14 14 15 15 #endif
+17 -1
sound/soc/sof/topology.c
··· 2506 2506 if (!tplg_files) 2507 2507 return -ENOMEM; 2508 2508 2509 + /* Try to use function topologies if possible */ 2509 2510 if (!sof_pdata->disable_function_topology && !disable_function_topology && 2510 2511 sof_pdata->machine && sof_pdata->machine->get_function_tplg_files) { 2512 + /* 2513 + * When the topology name contains 'dummy' word, it means that 2514 + * there is no fallback option to monolithic topology in case 2515 + * any of the function topologies might be missing. 2516 + * In this case we should use best effort to form the card, 2517 + * ignoring functionalities that we are missing a fragment for. 2518 + * 2519 + * Note: monolithic topologies also ignore these possibly 2520 + * missing functions, so the functionality of the card would be 2521 + * identical to the case if there would be a fallback monolithic 2522 + * topology created for the configuration. 2523 + */ 2524 + bool no_fallback = strstr(file, "dummy"); 2525 + 2511 2526 tplg_cnt = sof_pdata->machine->get_function_tplg_files(scomp->card, 2512 2527 sof_pdata->machine, 2513 2528 tplg_filename_prefix, 2514 - &tplg_files); 2529 + &tplg_files, 2530 + no_fallback); 2515 2531 if (tplg_cnt < 0) { 2516 2532 kfree(tplg_files); 2517 2533 return tplg_cnt;