mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-18 03:23:53 -04:00
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>
144 lines
3.9 KiB
C
144 lines
3.9 KiB
C
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
|
|
//
|
|
// This file is provided under a dual BSD/GPLv2 license. When using or
|
|
// redistributing this file, you may do so under either license.
|
|
//
|
|
// Copyright(c) 2025 Intel Corporation.
|
|
//
|
|
|
|
#include <linux/device.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/firmware.h>
|
|
#include <sound/soc.h>
|
|
#include <sound/soc-acpi.h>
|
|
#include "sof-function-topology-lib.h"
|
|
|
|
enum tplg_device_id {
|
|
TPLG_DEVICE_SDCA_JACK,
|
|
TPLG_DEVICE_SDCA_AMP,
|
|
TPLG_DEVICE_SDCA_MIC,
|
|
TPLG_DEVICE_INTEL_PCH_DMIC,
|
|
TPLG_DEVICE_HDMI,
|
|
TPLG_DEVICE_MAX
|
|
};
|
|
|
|
#define SDCA_DEVICE_MASK (BIT(TPLG_DEVICE_SDCA_JACK) | BIT(TPLG_DEVICE_SDCA_AMP) | \
|
|
BIT(TPLG_DEVICE_SDCA_MIC))
|
|
|
|
#define SOF_INTEL_PLATFORM_NAME_MAX 4
|
|
|
|
int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,
|
|
const char *prefix, const char ***tplg_files, bool best_effort)
|
|
{
|
|
struct snd_soc_acpi_mach_params mach_params = mach->mach_params;
|
|
struct snd_soc_dai_link *dai_link;
|
|
const struct firmware *fw;
|
|
char platform[SOF_INTEL_PLATFORM_NAME_MAX];
|
|
unsigned long tplg_mask = 0;
|
|
int tplg_num = 0;
|
|
int tplg_dev;
|
|
int ret;
|
|
int i;
|
|
|
|
ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform);
|
|
if (ret != 1) {
|
|
dev_err(card->dev, "Invalid platform name %s of tplg %s\n",
|
|
platform, mach->sof_tplg_filename);
|
|
return -EINVAL;
|
|
}
|
|
|
|
for_each_card_prelinks(card, i, dai_link) {
|
|
char *tplg_dev_name;
|
|
|
|
dev_dbg(card->dev, "dai_link %s id %d\n", dai_link->name, dai_link->id);
|
|
if (strstr(dai_link->name, "SimpleJack")) {
|
|
tplg_dev = TPLG_DEVICE_SDCA_JACK;
|
|
tplg_dev_name = "sdca-jack";
|
|
} else if (strstr(dai_link->name, "SmartAmp")) {
|
|
tplg_dev = TPLG_DEVICE_SDCA_AMP;
|
|
tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL,
|
|
"sdca-%damp", dai_link->num_cpus);
|
|
if (!tplg_dev_name)
|
|
return -ENOMEM;
|
|
} else if (strstr(dai_link->name, "SmartMic")) {
|
|
tplg_dev = TPLG_DEVICE_SDCA_MIC;
|
|
tplg_dev_name = "sdca-mic";
|
|
} else if (strstr(dai_link->name, "dmic")) {
|
|
switch (mach_params.dmic_num) {
|
|
case 2:
|
|
tplg_dev_name = "dmic-2ch";
|
|
break;
|
|
case 4:
|
|
tplg_dev_name = "dmic-4ch";
|
|
break;
|
|
default:
|
|
dev_warn(card->dev,
|
|
"unsupported number of dmics: %d\n",
|
|
mach_params.dmic_num);
|
|
continue;
|
|
}
|
|
tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC;
|
|
} else if (strstr(dai_link->name, "iDisp")) {
|
|
tplg_dev = TPLG_DEVICE_HDMI;
|
|
tplg_dev_name = "hdmi-pcm5";
|
|
|
|
} else {
|
|
/* The dai link is not supported by separated tplg yet */
|
|
dev_dbg(card->dev,
|
|
"dai_link %s is not supported by separated tplg yet\n",
|
|
dai_link->name);
|
|
if (best_effort)
|
|
continue;
|
|
|
|
return 0;
|
|
}
|
|
if (tplg_mask & BIT(tplg_dev))
|
|
continue;
|
|
|
|
tplg_mask |= BIT(tplg_dev);
|
|
|
|
/*
|
|
* The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg
|
|
* where <platform> is only required for the DMIC function as the nhlt blob
|
|
* is platform dependent.
|
|
*/
|
|
switch (tplg_dev) {
|
|
case TPLG_DEVICE_INTEL_PCH_DMIC:
|
|
(*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
|
|
"%s/sof-%s-%s-id%d.tplg",
|
|
prefix, platform,
|
|
tplg_dev_name, dai_link->id);
|
|
break;
|
|
default:
|
|
(*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
|
|
"%s/sof-%s-id%d.tplg",
|
|
prefix, tplg_dev_name,
|
|
dai_link->id);
|
|
break;
|
|
}
|
|
if (!(*tplg_files)[tplg_num])
|
|
return -ENOMEM;
|
|
tplg_num++;
|
|
}
|
|
|
|
dev_dbg(card->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num);
|
|
|
|
/* Check presence of sub-topologies */
|
|
for (i = 0; i < tplg_num; i++) {
|
|
ret = firmware_request_nowarn(&fw, (*tplg_files)[i], card->dev);
|
|
if (!ret) {
|
|
release_firmware(fw);
|
|
} else {
|
|
dev_warn(card->dev,
|
|
"Failed to open topology file: %s, you might need to\n",
|
|
(*tplg_files)[i]);
|
|
dev_warn(card->dev,
|
|
"download it from https://github.com/thesofproject/sof-bin/\n");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return tplg_num;
|
|
}
|
|
EXPORT_SYMBOL_GPL(sof_sdw_get_tplg_files);
|