// SPDX-License-Identifier: GPL-2.0
//
// ALSA SoC driver for Migo-R
//
// Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>

#include <linux/clkdev.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/module.h>

#include <asm/clock.h>

#include <cpu/sh7722.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>

#include "../codecs/wm8978.h"
#include "siu.h"

/* Default 8000Hz sampling frequency */
static unsigned long codec_freq = 8000 * 512;

static unsigned int use_count;

/* External clock, sourced from the codec at the SIUMCKB pin */
static unsigned long siumckb_recalc(struct clk *clk)
{
	return codec_freq;
}

static struct sh_clk_ops siumckb_clk_ops = {
	.recalc = siumckb_recalc,
};

static struct clk siumckb_clk = {
	.ops		= &siumckb_clk_ops,
	.rate		= 0, /* initialised at run-time */
};

static struct clk_lookup *siumckb_lookup;

static int migor_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 *codec_dai = rtd->codec_dai;
	int ret;
	unsigned int rate = params_rate(params);

	ret = snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 13000000,
				     SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_OPCLKRATE, rate * 512);
	if (ret < 0)
		return ret;

	codec_freq = rate * 512;
	/*
	 * This propagates the parent frequency change to children and
	 * recalculates the frequency table
	 */
	clk_set_rate(&siumckb_clk, codec_freq);
	dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq);

	ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, SIU_CLKB_EXT,
				     codec_freq / 2, SND_SOC_CLOCK_IN);

	if (!ret)
		use_count++;

	return ret;
}

static int migor_hw_free(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;

	if (use_count) {
		use_count--;

		if (!use_count)
			snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 0,
					       SND_SOC_CLOCK_IN);
	} else {
		dev_dbg(codec_dai->dev, "Unbalanced hw_free!\n");
	}

	return 0;
}

static const struct snd_soc_ops migor_dai_ops = {
	.hw_params = migor_hw_params,
	.hw_free = migor_hw_free,
};

static const struct snd_soc_dapm_widget migor_dapm_widgets[] = {
	SND_SOC_DAPM_HP("Headphone", NULL),
	SND_SOC_DAPM_MIC("Onboard Microphone", NULL),
	SND_SOC_DAPM_MIC("External Microphone", NULL),
};

static const struct snd_soc_dapm_route audio_map[] = {
	/* Headphone output connected to LHP/RHP, enable OUT4 for VMID */
	{ "Headphone", NULL,  "OUT4 VMID" },
	{ "OUT4 VMID", NULL,  "LHP" },
	{ "OUT4 VMID", NULL,  "RHP" },

	/* On-board microphone */
	{ "RMICN", NULL, "Mic Bias" },
	{ "RMICP", NULL, "Mic Bias" },
	{ "Mic Bias", NULL, "Onboard Microphone" },

	/* External microphone */
	{ "LMICN", NULL, "Mic Bias" },
	{ "LMICP", NULL, "Mic Bias" },
	{ "Mic Bias", NULL, "External Microphone" },
};

/* migor digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link migor_dai = {
	.name = "wm8978",
	.stream_name = "WM8978",
	.cpu_dai_name = "siu-pcm-audio",
	.codec_dai_name = "wm8978-hifi",
	.platform_name = "siu-pcm-audio",
	.codec_name = "wm8978.0-001a",
	.dai_fmt = SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_I2S |
		   SND_SOC_DAIFMT_CBS_CFS,
	.ops = &migor_dai_ops,
};

/* migor audio machine driver */
static struct snd_soc_card snd_soc_migor = {
	.name = "Migo-R",
	.owner = THIS_MODULE,
	.dai_link = &migor_dai,
	.num_links = 1,

	.dapm_widgets = migor_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(migor_dapm_widgets),
	.dapm_routes = audio_map,
	.num_dapm_routes = ARRAY_SIZE(audio_map),
};

static struct platform_device *migor_snd_device;

static int __init migor_init(void)
{
	int ret;

	ret = clk_register(&siumckb_clk);
	if (ret < 0)
		return ret;

	siumckb_lookup = clkdev_create(&siumckb_clk, "siumckb_clk", NULL);
	if (!siumckb_lookup) {
		ret = -ENOMEM;
		goto eclkdevalloc;
	}

	/* Port number used on this machine: port B */
	migor_snd_device = platform_device_alloc("soc-audio", 1);
	if (!migor_snd_device) {
		ret = -ENOMEM;
		goto epdevalloc;
	}

	platform_set_drvdata(migor_snd_device, &snd_soc_migor);

	ret = platform_device_add(migor_snd_device);
	if (ret)
		goto epdevadd;

	return 0;

epdevadd:
	platform_device_put(migor_snd_device);
epdevalloc:
	clkdev_drop(siumckb_lookup);
eclkdevalloc:
	clk_unregister(&siumckb_clk);
	return ret;
}

static void __exit migor_exit(void)
{
	clkdev_drop(siumckb_lookup);
	clk_unregister(&siumckb_clk);
	platform_device_unregister(migor_snd_device);
}

module_init(migor_init);
module_exit(migor_exit);

MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
MODULE_DESCRIPTION("ALSA SoC Migor");
MODULE_LICENSE("GPL v2");
