Path: blob/master/sound/soc/intel/common/sof-function-topology-lib.c
26493 views
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)1//2// This file is provided under a dual BSD/GPLv2 license. When using or3// redistributing this file, you may do so under either license.4//5// Copyright(c) 2025 Intel Corporation.6//78#include <linux/device.h>9#include <linux/errno.h>10#include <linux/firmware.h>11#include <sound/soc.h>12#include <sound/soc-acpi.h>13#include "sof-function-topology-lib.h"1415enum tplg_device_id {16TPLG_DEVICE_SDCA_JACK,17TPLG_DEVICE_SDCA_AMP,18TPLG_DEVICE_SDCA_MIC,19TPLG_DEVICE_INTEL_PCH_DMIC,20TPLG_DEVICE_HDMI,21TPLG_DEVICE_MAX22};2324#define SDCA_DEVICE_MASK (BIT(TPLG_DEVICE_SDCA_JACK) | BIT(TPLG_DEVICE_SDCA_AMP) | \25BIT(TPLG_DEVICE_SDCA_MIC))2627#define SOF_INTEL_PLATFORM_NAME_MAX 42829int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach,30const char *prefix, const char ***tplg_files)31{32struct snd_soc_acpi_mach_params mach_params = mach->mach_params;33struct snd_soc_dai_link *dai_link;34const struct firmware *fw;35char platform[SOF_INTEL_PLATFORM_NAME_MAX];36unsigned long tplg_mask = 0;37int tplg_num = 0;38int tplg_dev;39int ret;40int i;4142ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform);43if (ret != 1) {44dev_err(card->dev, "Invalid platform name %s of tplg %s\n",45platform, mach->sof_tplg_filename);46return -EINVAL;47}4849for_each_card_prelinks(card, i, dai_link) {50char *tplg_dev_name;5152dev_dbg(card->dev, "dai_link %s id %d\n", dai_link->name, dai_link->id);53if (strstr(dai_link->name, "SimpleJack")) {54tplg_dev = TPLG_DEVICE_SDCA_JACK;55tplg_dev_name = "sdca-jack";56} else if (strstr(dai_link->name, "SmartAmp")) {57tplg_dev = TPLG_DEVICE_SDCA_AMP;58tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL,59"sdca-%damp", dai_link->num_cpus);60if (!tplg_dev_name)61return -ENOMEM;62} else if (strstr(dai_link->name, "SmartMic")) {63tplg_dev = TPLG_DEVICE_SDCA_MIC;64tplg_dev_name = "sdca-mic";65} else if (strstr(dai_link->name, "dmic")) {66switch (mach_params.dmic_num) {67case 2:68tplg_dev_name = "dmic-2ch";69break;70case 4:71tplg_dev_name = "dmic-4ch";72break;73default:74dev_warn(card->dev,75"unsupported number of dmics: %d\n",76mach_params.dmic_num);77continue;78}79tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC;80} else if (strstr(dai_link->name, "iDisp")) {81tplg_dev = TPLG_DEVICE_HDMI;82tplg_dev_name = "hdmi-pcm5";8384} else {85/* The dai link is not supported by separated tplg yet */86dev_dbg(card->dev,87"dai_link %s is not supported by separated tplg yet\n",88dai_link->name);89return 0;90}91if (tplg_mask & BIT(tplg_dev))92continue;9394tplg_mask |= BIT(tplg_dev);9596/*97* The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg98* where <platform> is only required for the DMIC function as the nhlt blob99* is platform dependent.100*/101switch (tplg_dev) {102case TPLG_DEVICE_INTEL_PCH_DMIC:103(*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,104"%s/sof-%s-%s-id%d.tplg",105prefix, platform,106tplg_dev_name, dai_link->id);107break;108default:109(*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,110"%s/sof-%s-id%d.tplg",111prefix, tplg_dev_name,112dai_link->id);113break;114}115if (!(*tplg_files)[tplg_num])116return -ENOMEM;117tplg_num++;118}119120dev_dbg(card->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num);121122/* Check presence of sub-topologies */123for (i = 0; i < tplg_num; i++) {124ret = firmware_request_nowarn(&fw, (*tplg_files)[i], card->dev);125if (!ret) {126release_firmware(fw);127} else {128dev_dbg(card->dev, "Failed to open topology file: %s\n", (*tplg_files)[i]);129return 0;130}131}132133return tplg_num;134}135136137138