// 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_LOOPBACK_VIRTUAL,
	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 *card_mach = dev_get_platdata(card->dev);
	/*
	 * Use the acpi mach from the machine driver because the machine driver
	 * may change the dmic_num based on the machine driver quirk.
	 */
	struct snd_soc_acpi_mach_params mach_params = card_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 if (strstr(dai_link->name, "Loopback_Virtual")) {
			tplg_dev = TPLG_DEVICE_LOOPBACK_VIRTUAL;
			/*
			 * Mark the LOOPBACK_VIRTUAL device but no need to create the
			 * LOOPBACK_VIRTUAL topology. Just to avoid the dai_link is not supported
			 * error.
			 */
			tplg_mask |= BIT(tplg_dev);
			continue;
		} 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);
