File Index
Files and directories
Sign in
FILE

sof-function-topology-lib.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/intel/common/sof-function-topology-lib.c C
  1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2//
  3// This file is provided under a dual BSD/GPLv2 license.  When using or
  4// redistributing this file, you may do so under either license.
  5//
  6// Copyright(c) 2025 Intel Corporation.
  7//
  8
  9#include <linux/device.h>
 10#include <linux/errno.h>
 11#include <linux/firmware.h>
 12#include <sound/soc.h>
 13#include <sound/soc-acpi.h>
 14#include "sof-function-topology-lib.h"
 15
 16enum tplg_device_id {
 17	TPLG_DEVICE_SDCA_JACK,
 18	TPLG_DEVICE_SDCA_AMP,
 19	TPLG_DEVICE_SDCA_MIC,
 20	TPLG_DEVICE_INTEL_PCH_DMIC,
 21	TPLG_DEVICE_HDMI,
 22	TPLG_DEVICE_MAX
 23};
 24
 25#define SDCA_DEVICE_MASK (BIT(TPLG_DEVICE_SDCA_JACK) | BIT(TPLG_DEVICE_SDCA_AMP) | \
 26			  BIT(TPLG_DEVICE_SDCA_MIC))
 27
 28#define SOF_INTEL_PLATFORM_NAME_MAX 4
 29
 30int 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, bool best_effort)
 32{
 33	struct snd_soc_acpi_mach_params mach_params = mach->mach_params;
 34	struct snd_soc_dai_link *dai_link;
 35	const struct firmware *fw;
 36	char platform[SOF_INTEL_PLATFORM_NAME_MAX];
 37	unsigned long tplg_mask = 0;
 38	int tplg_num = 0;
 39	int tplg_dev;
 40	int ret;
 41	int i;
 42
 43	ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform);
 44	if (ret != 1) {
 45		dev_err(card->dev, "Invalid platform name %s of tplg %s\n",
 46			platform, mach->sof_tplg_filename);
 47		return -EINVAL;
 48	}
 49
 50	for_each_card_prelinks(card, i, dai_link) {
 51		char *tplg_dev_name;
 52
 53		dev_dbg(card->dev, "dai_link %s id %d\n", dai_link->name, dai_link->id);
 54		if (strstr(dai_link->name, "SimpleJack")) {
 55			tplg_dev = TPLG_DEVICE_SDCA_JACK;
 56			tplg_dev_name = "sdca-jack";
 57		} else if (strstr(dai_link->name, "SmartAmp")) {
 58			tplg_dev = TPLG_DEVICE_SDCA_AMP;
 59			tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL,
 60						       "sdca-%damp", dai_link->num_cpus);
 61			if (!tplg_dev_name)
 62				return -ENOMEM;
 63		} else if (strstr(dai_link->name, "SmartMic")) {
 64			tplg_dev = TPLG_DEVICE_SDCA_MIC;
 65			tplg_dev_name = "sdca-mic";
 66		} else if (strstr(dai_link->name, "dmic")) {
 67			switch (mach_params.dmic_num) {
 68			case 2:
 69				tplg_dev_name = "dmic-2ch";
 70				break;
 71			case 4:
 72				tplg_dev_name = "dmic-4ch";
 73				break;
 74			default:
 75				dev_warn(card->dev,
 76					 "unsupported number of dmics: %d\n",
 77					 mach_params.dmic_num);
 78				continue;
 79			}
 80			tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC;
 81		} else if (strstr(dai_link->name, "iDisp")) {
 82			tplg_dev = TPLG_DEVICE_HDMI;
 83			tplg_dev_name = "hdmi-pcm5";
 84
 85		} else {
 86			/* The dai link is not supported by separated tplg yet */
 87			dev_dbg(card->dev,
 88				"dai_link %s is not supported by separated tplg yet\n",
 89				dai_link->name);
 90			if (best_effort)
 91				continue;
 92
 93			return 0;
 94		}
 95		if (tplg_mask & BIT(tplg_dev))
 96			continue;
 97
 98		tplg_mask |= BIT(tplg_dev);
 99
100		/*
101		 * The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg
102		 * where <platform> is only required for the DMIC function as the nhlt blob
103		 * is platform dependent.
104		 */
105		switch (tplg_dev) {
106		case TPLG_DEVICE_INTEL_PCH_DMIC:
107			(*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
108								 "%s/sof-%s-%s-id%d.tplg",
109								 prefix, platform,
110								 tplg_dev_name, dai_link->id);
111			break;
112		default:
113			(*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL,
114								 "%s/sof-%s-id%d.tplg",
115								 prefix, tplg_dev_name,
116								 dai_link->id);
117			break;
118		}
119		if (!(*tplg_files)[tplg_num])
120			return -ENOMEM;
121		tplg_num++;
122	}
123
124	dev_dbg(card->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num);
125
126	/* Check presence of sub-topologies */
127	for (i = 0; i < tplg_num; i++) {
128		ret = firmware_request_nowarn(&fw, (*tplg_files)[i], card->dev);
129		if (!ret) {
130			release_firmware(fw);
131		} else {
132			dev_warn(card->dev,
133				 "Failed to open topology file: %s, you might need to\n",
134				 (*tplg_files)[i]);
135			dev_warn(card->dev,
136				 "download it from https://github.com/thesofproject/sof-bin/\n");
137			return 0;
138		}
139	}
140
141	return tplg_num;
142}
143EXPORT_SYMBOL_GPL(sof_sdw_get_tplg_files);
~/ Read-only file preview.