// SPDX-License-Identifier: GPL-2.0-only
//
// tegra_audio_graph_card.c - Audio Graph based Tegra Machine Driver
//
// Copyright (c) 2020-2021 NVIDIA CORPORATION.  All rights reserved.

#include <linux/math64.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <sound/graph_card.h>
#include <sound/pcm_params.h>
#include <sound/soc-dai.h>

#define MAX_PLLA_OUT0_DIV 128

#define simple_to_tegra_priv(simple) \
		container_of(simple, struct tegra_audio_priv, simple)

enum srate_type {
	/*
	 * Sample rates multiple of 8000 Hz and below are supported:
	 * ( 8000, 16000, 32000, 48000, 96000, 192000 Hz )
	 */
	x8_RATE,

	/*
	 * Sample rates multiple of 11025 Hz and below are supported:
	 * ( 11025, 22050, 44100, 88200, 176400 Hz )
	 */
	x11_RATE,

	NUM_RATE_TYPE,
};

struct tegra_audio_priv {
	struct simple_util_priv simple;
	struct clk *clk_plla_out0;
	struct clk *clk_plla;
};

/* Tegra audio chip data */
struct tegra_audio_cdata {
	unsigned int plla_rates[NUM_RATE_TYPE];
	unsigned int plla_out0_rates[NUM_RATE_TYPE];
};

static bool need_clk_update(struct snd_soc_dai *dai)
{
	if (snd_soc_dai_is_dummy(dai) ||
	    !dai->driver->ops ||
	    !dai->driver->name)
		return false;

	if (strstr(dai->driver->name, "I2S") ||
	    strstr(dai->driver->name, "DMIC") ||
	    strstr(dai->driver->name, "DSPK"))
		return true;

	return false;
}

/* Setup PLL clock as per the given sample rate */
static int tegra_audio_graph_update_pll(struct snd_pcm_substream *substream,
					struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct simple_util_priv *simple = snd_soc_card_get_drvdata(rtd->card);
	struct tegra_audio_priv *priv = simple_to_tegra_priv(simple);
	struct device *dev = rtd->card->dev;
	const struct tegra_audio_cdata *data = of_device_get_match_data(dev);
	unsigned int plla_rate, plla_out0_rate, bclk;
	unsigned int srate = params_rate(params);
	int err;

	switch (srate) {
	case 11025:
	case 22050:
	case 44100:
	case 88200:
	case 176400:
		plla_out0_rate = data->plla_out0_rates[x11_RATE];
		plla_rate = data->plla_rates[x11_RATE];
		break;
	case 8000:
	case 16000:
	case 32000:
	case 48000:
	case 96000:
	case 192000:
		plla_out0_rate = data->plla_out0_rates[x8_RATE];
		plla_rate = data->plla_rates[x8_RATE];
		break;
	default:
		dev_err(rtd->card->dev, "Unsupported sample rate %u\n",
			srate);
		return -EINVAL;
	}

	/*
	 * Below is the clock relation:
	 *
	 *	PLLA
	 *	  |
	 *	  |--> PLLA_OUT0
	 *		  |
	 *		  |---> I2S modules
	 *		  |
	 *		  |---> DMIC modules
	 *		  |
	 *		  |---> DSPK modules
	 *
	 *
	 * Default PLLA_OUT0 rate might be too high when I/O is running
	 * at minimum PCM configurations. This may result in incorrect
	 * clock rates and glitchy audio. The maximum divider is 128
	 * and any thing higher than that won't work. Thus reduce PLLA_OUT0
	 * to work for lower configurations.
	 *
	 * This problem is seen for I2S only, as DMIC and DSPK minimum
	 * clock requirements are under allowed divider limits.
	 */
	bclk = srate * params_channels(params) * params_width(params);
	if (div_u64(plla_out0_rate, bclk) > MAX_PLLA_OUT0_DIV)
		plla_out0_rate >>= 1;

	dev_dbg(rtd->card->dev,
		"Update clock rates: PLLA(= %u Hz) and PLLA_OUT0(= %u Hz)\n",
		plla_rate, plla_out0_rate);

	/* Set PLLA rate */
	err = clk_set_rate(priv->clk_plla, plla_rate);
	if (err) {
		dev_err(rtd->card->dev,
			"Can't set plla rate for %u, err: %d\n",
			plla_rate, err);
		return err;
	}

	/* Set PLLA_OUT0 rate */
	err = clk_set_rate(priv->clk_plla_out0, plla_out0_rate);
	if (err) {
		dev_err(rtd->card->dev,
			"Can't set plla_out0 rate %u, err: %d\n",
			plla_out0_rate, err);
		return err;
	}

	return err;
}

static int tegra_audio_graph_hw_params(struct snd_pcm_substream *substream,
				       struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
	int err;

	if (need_clk_update(cpu_dai)) {
		err = tegra_audio_graph_update_pll(substream, params);
		if (err)
			return err;
	}

	return simple_util_hw_params(substream, params);
}

static const struct snd_soc_ops tegra_audio_graph_ops = {
	.startup	= simple_util_startup,
	.shutdown	= simple_util_shutdown,
	.hw_params	= tegra_audio_graph_hw_params,
};

static int tegra_audio_graph_card_probe(struct snd_soc_card *card)
{
	struct simple_util_priv *simple = snd_soc_card_get_drvdata(card);
	struct tegra_audio_priv *priv = simple_to_tegra_priv(simple);

	priv->clk_plla = devm_clk_get(card->dev, "pll_a");
	if (IS_ERR(priv->clk_plla)) {
		dev_err(card->dev, "Can't retrieve clk pll_a\n");
		return PTR_ERR(priv->clk_plla);
	}

	priv->clk_plla_out0 = devm_clk_get(card->dev, "plla_out0");
	if (IS_ERR(priv->clk_plla_out0)) {
		dev_err(card->dev, "Can't retrieve clk plla_out0\n");
		return PTR_ERR(priv->clk_plla_out0);
	}

	return graph_util_card_probe(card);
}

static int tegra_audio_graph_probe(struct platform_device *pdev)
{
	struct tegra_audio_priv *priv;
	struct device *dev = &pdev->dev;
	struct snd_soc_card *card;

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

	card = simple_priv_to_card(&priv->simple);
	card->driver_name = "tegra-ape";

	card->probe = tegra_audio_graph_card_probe;

	/* audio_graph_parse_of() depends on below */
	card->component_chaining = 1;
	priv->simple.ops = &tegra_audio_graph_ops;
	priv->simple.force_dpcm = 1;

	return audio_graph_parse_of(&priv->simple, dev);
}

static const struct tegra_audio_cdata tegra210_data = {
	/* PLLA */
	.plla_rates[x8_RATE] = 368640000,
	.plla_rates[x11_RATE] = 338688000,
	/* PLLA_OUT0 */
	.plla_out0_rates[x8_RATE] = 49152000,
	.plla_out0_rates[x11_RATE] = 45158400,
};

static const struct tegra_audio_cdata tegra186_data = {
	/* PLLA */
	.plla_rates[x8_RATE] = 245760000,
	.plla_rates[x11_RATE] = 270950400,
	/* PLLA_OUT0 */
	.plla_out0_rates[x8_RATE] = 49152000,
	.plla_out0_rates[x11_RATE] = 45158400,
};

static const struct of_device_id graph_of_tegra_match[] = {
	{ .compatible = "nvidia,tegra210-audio-graph-card",
	  .data = &tegra210_data },
	{ .compatible = "nvidia,tegra186-audio-graph-card",
	  .data = &tegra186_data },
	{},
};
MODULE_DEVICE_TABLE(of, graph_of_tegra_match);

static struct platform_driver tegra_audio_graph_card = {
	.driver = {
		.name = "tegra-audio-graph-card",
		.pm = &snd_soc_pm_ops,
		.of_match_table = graph_of_tegra_match,
	},
	.probe = tegra_audio_graph_probe,
	.remove = simple_util_remove,
};
module_platform_driver(tegra_audio_graph_card);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ASoC Tegra Audio Graph Sound Card");
MODULE_AUTHOR("Sameer Pujar <spujar@nvidia.com>");
