/*
 * Copyright (C) 2014 Freescale Semiconductor, Inc.
 *
 * Based on imx-wm8962.c
 * Copyright (C) 2012 Freescale Semiconductor, Inc.
 * Copyright (C) 2012 Linaro Ltd.
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include <sound/control.h>
#include <sound/pcm_params.h>
#include <linux/pinctrl/consumer.h>
#include <linux/spi/spi.h>
#include <linux/regulator/consumer.h>

#include "../codecs/madera.h"
#include "fsl_sai.h"

#define DAI_NAME_SIZE	32

struct imx_priv {
	struct snd_soc_card card;
	struct platform_device *pdev;
	struct snd_soc_dai *spkr_codec_dai;
	struct clk *master_clk; /* 24MHz master clock */
	struct regulator *micvdd;
};
static struct imx_priv card_priv;

static int pll_clock_rate(snd_pcm_format_t sample_format, unsigned int sample_rate)
{
	u32 pll_out;
	switch(sample_format)
	{
		case SNDRV_PCM_FORMAT_S16_LE:
		case SNDRV_PCM_FORMAT_S16_BE:
		case SNDRV_PCM_FORMAT_U16_LE:
		case SNDRV_PCM_FORMAT_U16_BE:
			pll_out = 32 * sample_rate;
			break;
		case SNDRV_PCM_FORMAT_S24_LE:
		case SNDRV_PCM_FORMAT_S24_BE:
		case SNDRV_PCM_FORMAT_U24_LE:
		case SNDRV_PCM_FORMAT_U24_BE:
			pll_out = 48 * sample_rate;
			break;
		case SNDRV_PCM_FORMAT_S32_LE:
		case SNDRV_PCM_FORMAT_S32_BE:
		case SNDRV_PCM_FORMAT_U32_LE:
		case SNDRV_PCM_FORMAT_U32_BE:
			pll_out = 64 * sample_rate;
			break;
		default:
			pll_out = 0; /* Just to get rid of the warning during compilation */
			break;
	}

	return pll_out;
}

static int imx_marley_fe_startup(struct snd_pcm_substream *substream)
{
	struct imx_priv *priv = &card_priv;
	return clk_prepare_enable(priv->master_clk);
}

static void imx_marley_fe_shutdown(struct snd_pcm_substream *substream)
{
	struct imx_priv *priv = &card_priv;
	clk_disable_unprepare(priv->master_clk);
}

static int imx_marley_fe_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;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_codec *codec = rtd->codec;
	struct imx_priv *priv = &card_priv;
	struct device *dev = &priv->pdev->dev;
	struct regulator *micvdd = priv->micvdd;
	unsigned int sample_rate = params_rate(params);
	snd_pcm_format_t sample_format = params_format(params);
	u32 dai_format, pll_out;
	int ret = 0;

	dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
		SND_SOC_DAIFMT_CBS_CFS;

	ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
	if (ret) {
		dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
		return ret;
	}

	pll_out = pll_clock_rate(sample_format, sample_rate);
	if (!pll_out) {
		dev_err(dev, "failed to get pll clock rate\n");
		return ret;
	}

	ret = snd_soc_dai_set_sysclk(cpu_dai, FSL_SAI_CLK_MAST1,
			pll_out, SND_SOC_CLOCK_OUT);
	if (ret) {
		dev_err(dev, "failed to set SYSCLK on cpu: %d\n", ret);
		return ret;
	}

	ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
	if (ret) {
		dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
		return ret;
	}

	ret = snd_soc_codec_set_pll(codec, MADERA_FLL1_SYNCCLK, MADERA_CLK_SRC_MCLK1,
						24000000, 0 /* ignored */);
	if (ret) {
		dev_err(dev, "failed to set FLL Refclk on Marley codec: %d\n", ret);
		return ret;
	}

	ret = snd_soc_codec_set_pll(codec, MADERA_FLL1_REFCLK, MADERA_CLK_SRC_MCLK1,
						24000000, 98304000);
	if (ret) {
		dev_err(dev, "failed to set FLL on Marley codec: %d\n", ret);
		return ret;
	}

	ret = snd_soc_codec_set_sysclk(codec, MADERA_CLK_SYSCLK, MADERA_CLK_SRC_FLL1,
		98304000, SND_SOC_CLOCK_IN /* ignored */ );
	if (ret) {
		dev_err(dev, "failed to set SYSCLK on Marley codec: %d\n", ret);
		return ret;
	}

	ret = snd_soc_codec_set_sysclk(codec, MADERA_CLK_DSPCLK, MADERA_CLK_SRC_FLL1,
		147456000, SND_SOC_CLOCK_IN /* ignored */ );
	if (ret) {
		dev_err(dev, "failed to set DSPCLK on Marley codec: %d\n", ret);
		return ret;
	}

	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		ret = regulator_enable(micvdd);
		if (ret != 0) {
			dev_err(dev, "Failed to enable MICVDD: %d\n", ret);
		}
	}

	return 0;
}

static int imx_marley_fe_hw_free(struct snd_pcm_substream *substream)
{
	struct imx_priv *priv = &card_priv;
	struct snd_soc_dai *spkr_codec_dai = priv->spkr_codec_dai;
	struct device *dev = &priv->pdev->dev;
	struct regulator *micvdd = priv->micvdd;
	int ret = 0;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		/* Before freeing up the I2S clocks, the speaker codec requires
		 * it to be muted and amplifier disabled. This needs to be done
		 * only if the spkr codec was brought up correctly */
		if (spkr_codec_dai) {
			ret = snd_soc_dai_digital_mute(spkr_codec_dai, 1, substream->stream);
			if (ret) {
				dev_err(dev, "failed to set SYSCLK on cpu: %d\n", ret);
				return ret;
			}
			spkr_codec_dai = NULL;
		}
	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		if (regulator_is_enabled(micvdd))
			regulator_disable(micvdd);

	return ret;
}

static int imx_marley_be_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;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct imx_priv *priv = &card_priv;
	struct device *dev = &priv->pdev->dev;
	unsigned int sample_rate = params_rate(params);
	snd_pcm_format_t sample_format = params_format(params);
	u32 dai_format, pll_out;
	int ret = 0;

	dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
		SND_SOC_DAIFMT_CBS_CFS;

	/* set codec DAI configuration */
	ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
	if (ret) {
		dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
		return ret;
	}

	pll_out = pll_clock_rate(sample_format, sample_rate);
	if (!pll_out) {
		dev_err(dev, "failed to get pll clock rate\n");
		return ret;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		ret = snd_soc_dai_set_sysclk(codec_dai, FSL_SAI_CLK_MAST1 /* ignored */,
				pll_out, SND_SOC_CLOCK_IN /* ignored */);
		if (ret) {
			dev_err(dev, "failed to set SYSCLK on codec: %d\n", ret);
			return ret;
		}
		priv->spkr_codec_dai = codec_dai;

		/* Also setup cpu only for playback */
		ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
		if (ret) {
			dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
			return ret;
		}
	}

	return 0;
}

static struct snd_soc_ops imx_marley_fe_ops = {
	.startup = imx_marley_fe_startup,
	.shutdown = imx_marley_fe_shutdown,
	.hw_params = imx_marley_fe_hw_params,
	.hw_free = imx_marley_fe_hw_free,
};

static struct snd_soc_ops imx_marley_be_ops = {
	.hw_params = imx_marley_be_hw_params,
};

/* dai link definitions */
#define SPKR_DAI_FE_LINK        0
#define MIC_DAI_LINK            1
#define SPKR_DAI_BE_LINK        2

static struct snd_soc_dai_link imx_marley_dai_link[] = {
	/* Speaker DAI FE Link */
	{
		.name = "Class-D FE",
		.stream_name = "Class-D Playback",
		.codec_dai_name = "cs47l35-aif1",
		.ops = &imx_marley_fe_ops,
		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS,
		.dynamic = 1,
		.ignore_pmdown_time = 1,
		.dpcm_playback = 1,
	},
	/* Mic DAI Link */
	{
		.name = "Marley Capture",
		.stream_name = "Marley Capture",
		.codec_dai_name = "cs47l35-aif1",
		.ops = &imx_marley_fe_ops,
		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS,
		.ignore_pmdown_time = 1,
	},
	/* Speaker DAI BE Link */
	{
		.name = "Class-D BE",
		.stream_name = "Class-D Playback",
		.platform_name = "snd-soc-dummy",
		.cpu_dai_name = "cs47l35-aif2",
		.codec_dai_name = "tfa98xx-aif",
		.ops = &imx_marley_be_ops,
		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS,
		.no_pcm = 1,
		.ignore_pmdown_time = 1,
		.dpcm_playback = 1,
	},
};

static const struct snd_soc_dapm_widget imx_marley_dapm_widgets[] = {
	SND_SOC_DAPM_MIC("AMic", NULL),
};

static const struct snd_soc_dapm_route imx_marley_routes[] = {
	/* Connections for the Playback path */
	{"AIF Playback", NULL, "AIF2TX1"},
	/* Connections for the Capture path */
	{"AIF2RX1", NULL, "AIF Capture"},
	{"IN1AL", NULL, "AMic"},
	{"AMic", NULL, "MICBIAS1A"},
};

static int dev_node_match(struct device *dev, void *data)
{
	return dev->of_node == data;
}

struct spi_device *find_spi_device_by_node(struct device_node *np)
{
	struct device *dev;

	dev = bus_find_device(&spi_bus_type, NULL, np, dev_node_match);
	return dev ?  to_spi_device(dev) : NULL;
}

static int imx_marley_probe(struct platform_device *pdev)
{
	struct device_node *cpu_np, *spkr_codec_np, *dsp_np;
	struct platform_device *cpu_pdev;
	struct spi_device *dsp_dev;
	struct imx_priv *priv = &card_priv;
	int ret;

	priv->pdev = pdev;

	cpu_np = of_parse_phandle(pdev->dev.of_node, "cpu-dai", 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 platform device\n");
		ret = -EINVAL;
		goto fail;
	}

	dsp_np = of_parse_phandle(pdev->dev.of_node, "dsp", 0);
	if (!dsp_np) {
		dev_err(&pdev->dev, "speaker codec phandle missing or invalid\n");
		ret = -EINVAL;
		goto fail;
	}

	spkr_codec_np = of_parse_phandle(pdev->dev.of_node, "spkr-codec", 0);
	if (!spkr_codec_np) {
		dev_err(&pdev->dev, "speaker codec phandle missing or invalid\n");
		ret = -EINVAL;
		goto fail;
	}

	dsp_dev = find_spi_device_by_node(dsp_np);
	if (!dsp_dev) {
		dev_err(&pdev->dev, "failed to find dsp device\n");
		ret = -EINVAL;
		goto fail;
	}

	/* Setup the dai links */
	imx_marley_dai_link[MIC_DAI_LINK].cpu_dai_name = dev_name(&cpu_pdev->dev);
	imx_marley_dai_link[MIC_DAI_LINK].platform_of_node = cpu_np;
	imx_marley_dai_link[MIC_DAI_LINK].codec_of_node = dsp_np;
	imx_marley_dai_link[SPKR_DAI_FE_LINK].cpu_dai_name = dev_name(&cpu_pdev->dev);
	imx_marley_dai_link[SPKR_DAI_FE_LINK].platform_of_node = cpu_np;
	imx_marley_dai_link[SPKR_DAI_FE_LINK].codec_of_node = dsp_np;
	imx_marley_dai_link[SPKR_DAI_BE_LINK].codec_of_node = spkr_codec_np;

	priv->card.dev = &pdev->dev;
	ret = snd_soc_of_parse_card_name(&priv->card, "model");
	if (ret)
		goto fail;

	priv->card.num_links = ARRAY_SIZE(imx_marley_dai_link);
	priv->card.dai_link = imx_marley_dai_link;

	/* Add widgets */
	priv->card.dapm_widgets = imx_marley_dapm_widgets;
	priv->card.num_dapm_widgets = ARRAY_SIZE(imx_marley_dapm_widgets);
	/* Add routes */
	priv->card.dapm_routes = imx_marley_routes;
	priv->card.num_dapm_routes = ARRAY_SIZE(imx_marley_routes);

	platform_set_drvdata(pdev, &priv->card);

	/* Get handle to 24Mhz clock */
	priv->master_clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(priv->master_clk)) {
		dev_err(&pdev->dev, "couldn't get master clock\n");
		ret = -ENODEV;
		goto fail;
	}

	priv->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
	if (IS_ERR(priv->micvdd)) {
		ret = PTR_ERR(priv->micvdd);
		dev_err(&pdev->dev, "Failed to get MICVDD: %d\n", ret);
		goto fail;
	}

	ret = snd_soc_register_card(&priv->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);
	if (spkr_codec_np)
		of_node_put(spkr_codec_np);
	if (dsp_np)
		of_node_put(dsp_np);

	return ret;
}

static int imx_marley_remove(struct platform_device *pdev)
{
	struct snd_soc_card *card = platform_get_drvdata(pdev);
	snd_soc_unregister_card(card);

	return 0;
}

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

static struct platform_driver imx_marley_driver = {
	.driver = {
		.name = "imx-marley",
		.owner = THIS_MODULE,
		.pm = &snd_soc_pm_ops,
		.of_match_table = imx_marley_dt_ids,
	},
	.probe = imx_marley_probe,
	.remove = imx_marley_remove,
};
module_platform_driver(imx_marley_driver);

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