// SPDX-License-Identifier: GPL-2.0
// Copyright 2017-2020 NXP

#include <linux/module.h>
#include <linux/of_platform.h>
#include <sound/jack.h>
#include <sound/pcm_params.h>
#include <sound/hdmi-codec.h>
#include "fsl_sai.h"

/**
 * struct cpu_priv - CPU private data
 * @sysclk_freq: SYSCLK rates for set_sysclk()
 * @sysclk_dir: SYSCLK directions for set_sysclk()
 * @sysclk_id: SYSCLK ids for set_sysclk()
 * @slot_width: Slot width of each frame
 *
 * Note: [1] for tx and [0] for rx
 */
struct cpu_priv {
	unsigned long sysclk_freq[2];
	u32 sysclk_dir[2];
	u32 sysclk_id[2];
	u32 slot_width;
};

struct imx_hdmi_data {
	struct snd_soc_dai_link dai;
	struct snd_soc_card card;
	struct snd_soc_jack hdmi_jack;
	struct snd_soc_jack_pin hdmi_jack_pin;
	struct cpu_priv cpu_priv;
	u32 dai_fmt;
};

static int imx_hdmi_hw_params(struct snd_pcm_substream *substream,
			      struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct imx_hdmi_data *data = snd_soc_card_get_drvdata(rtd->card);
	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
	struct snd_soc_card *card = rtd->card;
	struct device *dev = card->dev;
	u32 slot_width = data->cpu_priv.slot_width;
	int ret;

	/* MCLK always is (256 or 192) * rate. */
	ret = snd_soc_dai_set_sysclk(cpu_dai, data->cpu_priv.sysclk_id[tx],
				     8 * slot_width * params_rate(params),
				     tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN);
	if (ret && ret != -ENOTSUPP) {
		dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
		return ret;
	}

	ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2, slot_width);
	if (ret && ret != -ENOTSUPP) {
		dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
		return ret;
	}

	return 0;
}

static struct snd_soc_ops imx_hdmi_ops = {
	.hw_params = imx_hdmi_hw_params,
};

static const struct snd_soc_dapm_widget imx_hdmi_widgets[] = {
	SND_SOC_DAPM_LINE("HDMI Jack", NULL),
};

static int imx_hdmi_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_card *card = rtd->card;
	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
	struct snd_soc_component *component = codec_dai->component;
	struct imx_hdmi_data *data = snd_soc_card_get_drvdata(card);
	int ret;

	data->hdmi_jack_pin.pin = "HDMI Jack";
	data->hdmi_jack_pin.mask = SND_JACK_LINEOUT;
	/* enable jack detection */
	ret = snd_soc_card_jack_new(card, "HDMI Jack", SND_JACK_LINEOUT,
				    &data->hdmi_jack, &data->hdmi_jack_pin, 1);
	if (ret) {
		dev_err(card->dev, "Can't new HDMI Jack %d\n", ret);
		return ret;
	}

	ret = snd_soc_component_set_jack(component, &data->hdmi_jack, NULL);
	if (ret && ret != -EOPNOTSUPP) {
		dev_err(card->dev, "Can't set HDMI Jack %d\n", ret);
		return ret;
	}

	return 0;
};

static int imx_hdmi_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	bool hdmi_out = of_property_read_bool(np, "hdmi-out");
	bool hdmi_in = of_property_read_bool(np, "hdmi-in");
	struct snd_soc_dai_link_component *dlc;
	struct platform_device *cpu_pdev;
	struct device_node *cpu_np;
	struct imx_hdmi_data *data;
	int ret;

	dlc = devm_kzalloc(&pdev->dev, 3 * sizeof(*dlc), GFP_KERNEL);
	if (!dlc)
		return -ENOMEM;

	cpu_np = of_parse_phandle(np, "audio-cpu", 0);
	if (!cpu_np) {
		dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
		ret = -EINVAL;
		goto fail;
	}

	cpu_pdev = of_find_device_by_node(cpu_np);
	if (!cpu_pdev) {
		dev_err(&pdev->dev, "failed to find SAI platform device\n");
		ret = -EINVAL;
		goto fail;
	}

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data) {
		ret = -ENOMEM;
		goto fail;
	}

	data->dai.cpus = &dlc[0];
	data->dai.num_cpus = 1;
	data->dai.platforms = &dlc[1];
	data->dai.num_platforms = 1;
	data->dai.codecs = &dlc[2];
	data->dai.num_codecs = 1;

	data->dai.name = "i.MX HDMI";
	data->dai.stream_name = "i.MX HDMI";
	data->dai.cpus->dai_name = dev_name(&cpu_pdev->dev);
	data->dai.platforms->of_node = cpu_np;
	data->dai.ops = &imx_hdmi_ops;
	data->dai.playback_only = true;
	data->dai.capture_only = false;
	data->dai.init = imx_hdmi_init;

	if (of_node_name_eq(cpu_np, "sai")) {
		data->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1;
		data->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
	}

	if (of_device_is_compatible(np, "fsl,imx-audio-sii902x")) {
		data->dai_fmt = SND_SOC_DAIFMT_LEFT_J;
		data->cpu_priv.slot_width = 24;
	} else {
		data->dai_fmt = SND_SOC_DAIFMT_I2S;
		data->cpu_priv.slot_width = 32;
	}

	if ((hdmi_out && hdmi_in) || (!hdmi_out && !hdmi_in)) {
		dev_err(&pdev->dev, "Invalid HDMI DAI link\n");
		ret = -EINVAL;
		goto fail;
	}

	if (hdmi_out) {
		data->dai.playback_only = true;
		data->dai.capture_only = false;
		data->dai.codecs->dai_name = "i2s-hifi";
		data->dai.codecs->name = "hdmi-audio-codec.1";
		data->dai.dai_fmt = data->dai_fmt |
				    SND_SOC_DAIFMT_NB_NF |
				    SND_SOC_DAIFMT_CBS_CFS;
	}

	if (hdmi_in) {
		data->dai.playback_only = false;
		data->dai.capture_only = true;
		data->dai.codecs->dai_name = "i2s-hifi";
		data->dai.codecs->name = "hdmi-audio-codec.2";
		data->dai.dai_fmt = data->dai_fmt |
				    SND_SOC_DAIFMT_NB_NF |
				    SND_SOC_DAIFMT_CBM_CFM;
	}

	data->card.dapm_widgets = imx_hdmi_widgets;
	data->card.num_dapm_widgets = ARRAY_SIZE(imx_hdmi_widgets);
	data->card.dev = &pdev->dev;
	data->card.owner = THIS_MODULE;
	ret = snd_soc_of_parse_card_name(&data->card, "model");
	if (ret)
		goto fail;

	data->card.num_links = 1;
	data->card.dai_link = &data->dai;

	snd_soc_card_set_drvdata(&data->card, data);
	ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
		goto fail;
	}

fail:
	if (cpu_np)
		of_node_put(cpu_np);

	return ret;
}

static const struct of_device_id imx_hdmi_dt_ids[] = {
	{ .compatible = "fsl,imx-audio-hdmi", },
	{ .compatible = "fsl,imx-audio-sii902x", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);

static struct platform_driver imx_hdmi_driver = {
	.driver = {
		.name = "imx-hdmi",
		.owner = THIS_MODULE,
		.pm = &snd_soc_pm_ops,
		.of_match_table = imx_hdmi_dt_ids,
	},
	.probe = imx_hdmi_probe,
};
module_platform_driver(imx_hdmi_driver);

MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("Freescale i.MX hdmi audio ASoC machine driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:imx-hdmi");
