// 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/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].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);
		dl[i].codecs->dai_name = pcm->name;
		dl[i].num_codecs = 1;
		dl[i].num_cpus = 1;
	}

	*links = dl;
	return 0;
}

static int avs_create_dapm_routes(struct device *dev, struct hda_codec *codec, int pcm_count,
				  struct snd_soc_dapm_route **routes, int *num_routes)
{
	struct snd_soc_dapm_route *dr;
	struct hda_pcm *pcm;
	const char *cname = dev_name(&codec->core.dev);
	int i, n = 0;

	/* at max twice the number of pcms */
	dr = devm_kcalloc(dev, pcm_count * 2, sizeof(*dr), GFP_KERNEL);
	if (!dr)
		return -ENOMEM;

	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)) {
		struct hda_pcm_stream *stream;
		int dir;

		dir = SNDRV_PCM_STREAM_PLAYBACK;
		stream = &pcm->stream[dir];
		if (!stream->substreams)
			goto capture_routes;

		dr[n].sink = devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name,
					    snd_pcm_direction_name(dir));
		dr[n].source = devm_kasprintf(dev, GFP_KERNEL, "%s-cpu%d Tx", cname, i);
		if (!dr[n].sink || !dr[n].source)
			return -ENOMEM;
		n++;

capture_routes:
		dir = SNDRV_PCM_STREAM_CAPTURE;
		stream = &pcm->stream[dir];
		if (!stream->substreams)
			continue;

		dr[n].sink = devm_kasprintf(dev, GFP_KERNEL, "%s-cpu%d Rx", cname, i);
		dr[n].source = devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name,
					      snd_pcm_direction_name(dir));
		if (!dr[n].sink || !dr[n].source)
			return -ENOMEM;
		n++;
	}

	*routes = dr;
	*num_routes = n;
	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_dapm_route *routes;
	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, n, 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;
	}

	for (n = 0; n < pcm_count; n++) {
		ret = snd_soc_add_pcm_runtime(card, &links[n]);
		if (ret < 0) {
			dev_err(card->dev, "add links failed: %d\n", ret);
			return ret;
		}
	}

	ret = avs_create_dapm_routes(card->dev, codec, pcm_count, &routes, &n);
	if (ret < 0) {
		dev_err(card->dev, "create routes failed: %d\n", ret);
		return ret;
	}

	ret = snd_soc_dapm_add_routes(&card->dapm, routes, n);
	if (ret < 0) {
		dev_err(card->dev, "add routes failed: %d\n", ret);
		return ret;
	}

	return 0;
}

SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY()));

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 = dummy,
	.num_cpus = ARRAY_SIZE(dummy),
	.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 struct platform_driver avs_hdaudio_driver = {
	.probe = avs_hdaudio_probe,
	.driver = {
		.name = "avs_hdaudio",
		.pm = &snd_soc_pm_ops,
	},
};

module_platform_driver(avs_hdaudio_driver)

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