// SPDX-License-Identifier: GPL-2.0+
//
// smdk_spdif.c - S/PDIF audio for SMDK
//
// Copyright (C) 2010 Samsung Electronics Co., Ltd.

#include <linux/clk.h>
#include <linux/module.h>

#include <sound/soc.h>

#include "spdif.h"

/* Audio clock settings are belonged to board specific part. Every
 * board can set audio source clock setting which is matched with H/W
 * like this function-'set_audio_clock_heirachy'.
 */
static int set_audio_clock_heirachy(struct platform_device *pdev)
{
	struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif;
	int ret = 0;

	fout_epll = clk_get(NULL, "fout_epll");
	if (IS_ERR(fout_epll)) {
		printk(KERN_WARNING "%s: Cannot find fout_epll.\n",
				__func__);
		return -EINVAL;
	}

	mout_epll = clk_get(NULL, "mout_epll");
	if (IS_ERR(mout_epll)) {
		printk(KERN_WARNING "%s: Cannot find mout_epll.\n",
				__func__);
		ret = -EINVAL;
		goto out1;
	}

	sclk_audio0 = clk_get(&pdev->dev, "sclk_audio");
	if (IS_ERR(sclk_audio0)) {
		printk(KERN_WARNING "%s: Cannot find sclk_audio.\n",
				__func__);
		ret = -EINVAL;
		goto out2;
	}

	sclk_spdif = clk_get(NULL, "sclk_spdif");
	if (IS_ERR(sclk_spdif)) {
		printk(KERN_WARNING "%s: Cannot find sclk_spdif.\n",
				__func__);
		ret = -EINVAL;
		goto out3;
	}

	/* Set audio clock hierarchy for S/PDIF */
	clk_set_parent(mout_epll, fout_epll);
	clk_set_parent(sclk_audio0, mout_epll);
	clk_set_parent(sclk_spdif, sclk_audio0);

	clk_put(sclk_spdif);
out3:
	clk_put(sclk_audio0);
out2:
	clk_put(mout_epll);
out1:
	clk_put(fout_epll);

	return ret;
}

/* We should haved to set clock directly on this part because of clock
 * scheme of Samsudng SoCs did not support to set rates from abstrct
 * clock of it's hierarchy.
 */
static int set_audio_clock_rate(unsigned long epll_rate,
				unsigned long audio_rate)
{
	struct clk *fout_epll, *sclk_spdif;

	fout_epll = clk_get(NULL, "fout_epll");
	if (IS_ERR(fout_epll)) {
		printk(KERN_ERR "%s: failed to get fout_epll\n", __func__);
		return -ENOENT;
	}

	clk_set_rate(fout_epll, epll_rate);
	clk_put(fout_epll);

	sclk_spdif = clk_get(NULL, "sclk_spdif");
	if (IS_ERR(sclk_spdif)) {
		printk(KERN_ERR "%s: failed to get sclk_spdif\n", __func__);
		return -ENOENT;
	}

	clk_set_rate(sclk_spdif, audio_rate);
	clk_put(sclk_spdif);

	return 0;
}

static int smdk_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	unsigned long pll_out, rclk_rate;
	int ret, ratio;

	switch (params_rate(params)) {
	case 44100:
		pll_out = 45158400;
		break;
	case 32000:
	case 48000:
	case 96000:
		pll_out = 49152000;
		break;
	default:
		return -EINVAL;
	}

	/* Setting ratio to 512fs helps to use S/PDIF with HDMI without
	 * modify S/PDIF ASoC machine driver.
	 */
	ratio = 512;
	rclk_rate = params_rate(params) * ratio;

	/* Set audio source clock rates */
	ret = set_audio_clock_rate(pll_out, rclk_rate);
	if (ret < 0)
		return ret;

	/* Set S/PDIF uses internal source clock */
	ret = snd_soc_dai_set_sysclk(cpu_dai, SND_SOC_SPDIF_INT_MCLK,
					rclk_rate, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	return ret;
}

static const struct snd_soc_ops smdk_spdif_ops = {
	.hw_params = smdk_hw_params,
};

SND_SOC_DAILINK_DEFS(spdif,
	DAILINK_COMP_ARRAY(COMP_CPU("samsung-spdif")),
	DAILINK_COMP_ARRAY(COMP_CODEC("spdif-dit", "dit-hifi")),
	DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-spdif")));

static struct snd_soc_dai_link smdk_dai = {
	.name = "S/PDIF",
	.stream_name = "S/PDIF PCM Playback",
	.ops = &smdk_spdif_ops,
	SND_SOC_DAILINK_REG(spdif),
};

static struct snd_soc_card smdk = {
	.name = "SMDK-S/PDIF",
	.owner = THIS_MODULE,
	.dai_link = &smdk_dai,
	.num_links = 1,
};

static struct platform_device *smdk_snd_spdif_dit_device;
static struct platform_device *smdk_snd_spdif_device;

static int __init smdk_init(void)
{
	int ret;

	smdk_snd_spdif_dit_device = platform_device_alloc("spdif-dit", -1);
	if (!smdk_snd_spdif_dit_device)
		return -ENOMEM;

	ret = platform_device_add(smdk_snd_spdif_dit_device);
	if (ret)
		goto err1;

	smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1);
	if (!smdk_snd_spdif_device) {
		ret = -ENOMEM;
		goto err2;
	}

	platform_set_drvdata(smdk_snd_spdif_device, &smdk);

	ret = platform_device_add(smdk_snd_spdif_device);
	if (ret)
		goto err3;

	/* Set audio clock hierarchy manually */
	ret = set_audio_clock_heirachy(smdk_snd_spdif_device);
	if (ret)
		goto err4;

	return 0;
err4:
	platform_device_del(smdk_snd_spdif_device);
err3:
	platform_device_put(smdk_snd_spdif_device);
err2:
	platform_device_del(smdk_snd_spdif_dit_device);
err1:
	platform_device_put(smdk_snd_spdif_dit_device);
	return ret;
}

static void __exit smdk_exit(void)
{
	platform_device_unregister(smdk_snd_spdif_device);
	platform_device_unregister(smdk_snd_spdif_dit_device);
}

module_init(smdk_init);
module_exit(smdk_exit);

MODULE_AUTHOR("Seungwhan Youn, <sw.youn@samsung.com>");
MODULE_DESCRIPTION("ALSA SoC SMDK+S/PDIF");
MODULE_LICENSE("GPL");
