// SPDX-License-Identifier: GPL-2.0-only
//
// Copyright(c) 2021-2022 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
//

#include <linux/module.h>
#include <linux/platform_device.h>
#include <sound/hda_codec.h>
#include <sound/hda_i915.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "../../../codecs/hda.h"

static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int pcm_count,
				const char *platform_name, struct snd_soc_dai_link **links)
{
	struct snd_soc_dai_link_component *platform;
	struct snd_soc_dai_link *dl;
	struct hda_pcm *pcm;
	const char *cname = dev_name(&codec->core.dev);
	int i;

	dl = devm_kcalloc(dev, pcm_count, sizeof(*dl), GFP_KERNEL);
	platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL);
	if (!dl || !platform)
		return -ENOMEM;

	platform->name = platform_name;
	pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);

	for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
		dl[i].name = devm_kasprintf(dev, GFP_KERNEL, "%s link%d", cname, i);
		if (!dl[i].name)
			return -ENOMEM;

		dl[i].id = i;
		dl[i].nonatomic = 1;
		dl[i].no_pcm = 1;
		dl[i].dpcm_playback = 1;
		dl[i].dpcm_capture = 1;
		dl[i].platforms = platform;
		dl[i].num_platforms = 1;
		dl[i].ignore_pmdown_time = 1;

		dl[i].codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL);
		dl[i].cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
		if (!dl[i].codecs || !dl[i].cpus)
			return -ENOMEM;

		dl[i].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "%s-cpu%d", cname, i);
		if (!dl[i].cpus->dai_name)
			return -ENOMEM;

		dl[i].codecs->name = devm_kstrdup_const(dev, cname, GFP_KERNEL);
		if (!dl[i].codecs->name)
			return -ENOMEM;

		dl[i].codecs->dai_name = pcm->name;
		dl[i].num_codecs = 1;
		dl[i].num_cpus = 1;
	}

	*links = dl;
	return 0;
}

/* Should be aligned with SectionPCM's name from topology */
#define FEDAI_NAME_PREFIX "HDMI"

static struct snd_pcm *
avs_card_hdmi_pcm_at(struct snd_soc_card *card, int hdmi_idx)
{
	struct snd_soc_pcm_runtime *rtd;
	int dir = SNDRV_PCM_STREAM_PLAYBACK;

	for_each_card_rtds(card, rtd) {
		struct snd_pcm *spcm;
		int ret, n;

		spcm = rtd->pcm ? rtd->pcm->streams[dir].pcm : NULL;
		if (!spcm || !strstr(spcm->id, FEDAI_NAME_PREFIX))
			continue;

		ret = sscanf(spcm->id, FEDAI_NAME_PREFIX "%d", &n);
		if (ret != 1)
			continue;
		if (n == hdmi_idx)
			return rtd->pcm;
	}

	return NULL;
}

static int avs_card_late_probe(struct snd_soc_card *card)
{
	struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
	struct hda_codec *codec = mach->pdata;
	struct hda_pcm *hpcm;
	/* Topology pcm indexing is 1-based */
	int i = 1;

	list_for_each_entry(hpcm, &codec->pcm_list_head, list) {
		struct snd_pcm *spcm;

		spcm = avs_card_hdmi_pcm_at(card, i);
		if (spcm) {
			hpcm->pcm = spcm;
			hpcm->device = spcm->device;
			dev_info(card->dev, "%s: mapping HDMI converter %d to PCM %d (%p)\n",
				 __func__, i, hpcm->device, spcm);
		} else {
			hpcm->pcm = NULL;
			hpcm->device = SNDRV_PCM_INVALID_DEVICE;
			dev_warn(card->dev, "%s: no PCM in topology for HDMI converter %d\n",
				 __func__, i);
		}
		i++;
	}

	return hda_codec_probe_complete(codec);
}

static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm)
{
	struct snd_soc_acpi_mach *mach;
	struct snd_soc_dai_link *links = NULL;
	struct snd_soc_card *card = rtm->card;
	struct hda_codec *codec;
	struct hda_pcm *pcm;
	int ret, pcm_count = 0;

	mach = dev_get_platdata(card->dev);
	codec = mach->pdata;

	if (list_empty(&codec->pcm_list_head))
		return -EINVAL;
	list_for_each_entry(pcm, &codec->pcm_list_head, list)
		pcm_count++;

	ret = avs_create_dai_links(card->dev, codec, pcm_count, mach->mach_params.platform, &links);
	if (ret < 0) {
		dev_err(card->dev, "create links failed: %d\n", ret);
		return ret;
	}

	ret = snd_soc_add_pcm_runtimes(card, links, pcm_count);
	if (ret < 0) {
		dev_err(card->dev, "add links failed: %d\n", ret);
		return ret;
	}

	return 0;
}

static const struct snd_soc_dai_link probing_link = {
	.name = "probing-LINK",
	.id = -1,
	.nonatomic = 1,
	.no_pcm = 1,
	.dpcm_playback = 1,
	.dpcm_capture = 1,
	.cpus = &snd_soc_dummy_dlc,
	.num_cpus = 1,
	.init = avs_probing_link_init,
};

static int avs_hdaudio_probe(struct platform_device *pdev)
{
	struct snd_soc_dai_link *binder;
	struct snd_soc_acpi_mach *mach;
	struct snd_soc_card *card;
	struct device *dev = &pdev->dev;
	struct hda_codec *codec;

	mach = dev_get_platdata(dev);
	codec = mach->pdata;

	/* codec may be unloaded before card's probe() fires */
	if (!device_is_registered(&codec->core.dev))
		return -ENODEV;

	binder = devm_kmemdup(dev, &probing_link, sizeof(probing_link), GFP_KERNEL);
	if (!binder)
		return -ENOMEM;

	binder->platforms = devm_kzalloc(dev, sizeof(*binder->platforms), GFP_KERNEL);
	binder->codecs = devm_kzalloc(dev, sizeof(*binder->codecs), GFP_KERNEL);
	if (!binder->platforms || !binder->codecs)
		return -ENOMEM;

	binder->codecs->name = devm_kstrdup_const(dev, dev_name(&codec->core.dev), GFP_KERNEL);
	if (!binder->codecs->name)
		return -ENOMEM;

	binder->platforms->name = mach->mach_params.platform;
	binder->num_platforms = 1;
	binder->codecs->dai_name = "codec-probing-DAI";
	binder->num_codecs = 1;

	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
	if (!card)
		return -ENOMEM;

	card->name = binder->codecs->name;
	card->dev = dev;
	card->owner = THIS_MODULE;
	card->dai_link = binder;
	card->num_links = 1;
	card->fully_routed = true;
	if (hda_codec_is_display(codec))
		card->late_probe = avs_card_late_probe;

	return devm_snd_soc_register_card(dev, card);
}

static const struct platform_device_id avs_hdaudio_driver_ids[] = {
	{
		.name = "avs_hdaudio",
	},
	{},
};
MODULE_DEVICE_TABLE(platform, avs_hdaudio_driver_ids);

static struct platform_driver avs_hdaudio_driver = {
	.probe = avs_hdaudio_probe,
	.driver = {
		.name = "avs_hdaudio",
		.pm = &snd_soc_pm_ops,
	},
	.id_table = avs_hdaudio_driver_ids,
};

module_platform_driver(avs_hdaudio_driver)

MODULE_DESCRIPTION("Intel HD-Audio machine driver");
MODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>");
MODULE_LICENSE("GPL");
