// SPDX-License-Identifier: GPL-2.0-only
//
// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
//
// 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(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 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(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");
