/*
 * IMG I2S output controller driver
 *
 * Copyright (C) 2015 Imagination Technologies Ltd.
 *
 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 */

#include <linux/clk.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>

#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>

#define IMG_I2S_OUT_TX_FIFO			0x0

#define IMG_I2S_OUT_CTL				0x4
#define IMG_I2S_OUT_CTL_DATA_EN_MASK		BIT(24)
#define IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK	0xffe000
#define IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT	13
#define IMG_I2S_OUT_CTL_FRM_SIZE_MASK		BIT(8)
#define IMG_I2S_OUT_CTL_MASTER_MASK		BIT(6)
#define IMG_I2S_OUT_CTL_CLK_MASK		BIT(5)
#define IMG_I2S_OUT_CTL_CLK_EN_MASK		BIT(4)
#define IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK	BIT(3)
#define IMG_I2S_OUT_CTL_BCLK_POL_MASK		BIT(2)
#define IMG_I2S_OUT_CTL_ME_MASK			BIT(0)

#define IMG_I2S_OUT_CH_CTL			0x4
#define IMG_I2S_OUT_CHAN_CTL_CH_MASK		BIT(11)
#define IMG_I2S_OUT_CHAN_CTL_LT_MASK		BIT(10)
#define IMG_I2S_OUT_CHAN_CTL_FMT_MASK		0xf0
#define IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT		4
#define IMG_I2S_OUT_CHAN_CTL_JUST_MASK		BIT(3)
#define IMG_I2S_OUT_CHAN_CTL_CLKT_MASK		BIT(1)
#define IMG_I2S_OUT_CHAN_CTL_ME_MASK		BIT(0)

#define IMG_I2S_OUT_CH_STRIDE			0x20

struct img_i2s_out {
	void __iomem *base;
	struct clk *clk_sys;
	struct clk *clk_ref;
	struct snd_dmaengine_dai_dma_data dma_data;
	struct device *dev;
	unsigned int max_i2s_chan;
	void __iomem *channel_base;
	bool force_clk_active;
	unsigned int active_channels;
	struct reset_control *rst;
	struct snd_soc_dai_driver dai_driver;
};

static int img_i2s_out_suspend(struct device *dev)
{
	struct img_i2s_out *i2s = dev_get_drvdata(dev);

	if (!i2s->force_clk_active)
		clk_disable_unprepare(i2s->clk_ref);

	return 0;
}

static int img_i2s_out_resume(struct device *dev)
{
	struct img_i2s_out *i2s = dev_get_drvdata(dev);
	int ret;

	if (!i2s->force_clk_active) {
		ret = clk_prepare_enable(i2s->clk_ref);
		if (ret) {
			dev_err(dev, "clk_enable failed: %d\n", ret);
			return ret;
		}
	}

	return 0;
}

static inline void img_i2s_out_writel(struct img_i2s_out *i2s, u32 val,
					u32 reg)
{
	writel(val, i2s->base + reg);
}

static inline u32 img_i2s_out_readl(struct img_i2s_out *i2s, u32 reg)
{
	return readl(i2s->base + reg);
}

static inline void img_i2s_out_ch_writel(struct img_i2s_out *i2s,
					u32 chan, u32 val, u32 reg)
{
	writel(val, i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
}

static inline u32 img_i2s_out_ch_readl(struct img_i2s_out *i2s, u32 chan,
					u32 reg)
{
	return readl(i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
}

static inline void img_i2s_out_ch_disable(struct img_i2s_out *i2s, u32 chan)
{
	u32 reg;

	reg = img_i2s_out_ch_readl(i2s, chan, IMG_I2S_OUT_CH_CTL);
	reg &= ~IMG_I2S_OUT_CHAN_CTL_ME_MASK;
	img_i2s_out_ch_writel(i2s, chan, reg, IMG_I2S_OUT_CH_CTL);
}

static inline void img_i2s_out_ch_enable(struct img_i2s_out *i2s, u32 chan)
{
	u32 reg;

	reg = img_i2s_out_ch_readl(i2s, chan, IMG_I2S_OUT_CH_CTL);
	reg |= IMG_I2S_OUT_CHAN_CTL_ME_MASK;
	img_i2s_out_ch_writel(i2s, chan, reg, IMG_I2S_OUT_CH_CTL);
}

static inline void img_i2s_out_disable(struct img_i2s_out *i2s)
{
	u32 reg;

	reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
	reg &= ~IMG_I2S_OUT_CTL_ME_MASK;
	img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
}

static inline void img_i2s_out_enable(struct img_i2s_out *i2s)
{
	u32 reg;

	reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
	reg |= IMG_I2S_OUT_CTL_ME_MASK;
	img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
}

static void img_i2s_out_reset(struct img_i2s_out *i2s)
{
	int i;
	u32 core_ctl, chan_ctl;

	core_ctl = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL) &
			~IMG_I2S_OUT_CTL_ME_MASK &
			~IMG_I2S_OUT_CTL_DATA_EN_MASK;

	if (!i2s->force_clk_active)
		core_ctl &= ~IMG_I2S_OUT_CTL_CLK_EN_MASK;

	chan_ctl = img_i2s_out_ch_readl(i2s, 0, IMG_I2S_OUT_CH_CTL) &
			~IMG_I2S_OUT_CHAN_CTL_ME_MASK;

	reset_control_assert(i2s->rst);
	reset_control_deassert(i2s->rst);

	for (i = 0; i < i2s->max_i2s_chan; i++)
		img_i2s_out_ch_writel(i2s, i, chan_ctl, IMG_I2S_OUT_CH_CTL);

	for (i = 0; i < i2s->active_channels; i++)
		img_i2s_out_ch_enable(i2s, i);

	img_i2s_out_writel(i2s, core_ctl, IMG_I2S_OUT_CTL);
	img_i2s_out_enable(i2s);
}

static int img_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd,
	struct snd_soc_dai *dai)
{
	struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
	u32 reg;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
		if (!i2s->force_clk_active)
			reg |= IMG_I2S_OUT_CTL_CLK_EN_MASK;
		reg |= IMG_I2S_OUT_CTL_DATA_EN_MASK;
		img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		img_i2s_out_reset(i2s);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int img_i2s_out_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
	unsigned int channels, i2s_channels;
	long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
	int i;
	u32 reg, control_mask, control_set = 0;
	snd_pcm_format_t format;

	rate = params_rate(params);
	format = params_format(params);
	channels = params_channels(params);
	i2s_channels = channels / 2;

	if (format != SNDRV_PCM_FORMAT_S32_LE)
		return -EINVAL;

	if ((channels < 2) ||
	    (channels > (i2s->max_i2s_chan * 2)) ||
	    (channels % 2))
		return -EINVAL;

	pre_div_a = clk_round_rate(i2s->clk_ref, rate * 256);
	if (pre_div_a < 0)
		return pre_div_a;
	pre_div_b = clk_round_rate(i2s->clk_ref, rate * 384);
	if (pre_div_b < 0)
		return pre_div_b;

	diff_a = abs((pre_div_a / 256) - rate);
	diff_b = abs((pre_div_b / 384) - rate);

	/* If diffs are equal, use lower clock rate */
	if (diff_a > diff_b)
		clk_set_rate(i2s->clk_ref, pre_div_b);
	else
		clk_set_rate(i2s->clk_ref, pre_div_a);

	/*
	 * Another driver (eg alsa machine driver) may have rejected the above
	 * change. Get the current rate and set the register bit according to
	 * the new minimum diff
	 */
	clk_rate = clk_get_rate(i2s->clk_ref);

	diff_a = abs((clk_rate / 256) - rate);
	diff_b = abs((clk_rate / 384) - rate);

	if (diff_a > diff_b)
		control_set |= IMG_I2S_OUT_CTL_CLK_MASK;

	control_set |= ((i2s_channels - 1) <<
		       IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT) &
		       IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;

	control_mask = IMG_I2S_OUT_CTL_CLK_MASK |
		       IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;

	img_i2s_out_disable(i2s);

	reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
	reg = (reg & ~control_mask) | control_set;
	img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);

	for (i = 0; i < i2s_channels; i++)
		img_i2s_out_ch_enable(i2s, i);

	for (; i < i2s->max_i2s_chan; i++)
		img_i2s_out_ch_disable(i2s, i);

	img_i2s_out_enable(i2s);

	i2s->active_channels = i2s_channels;

	return 0;
}

static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
	int i;
	bool force_clk_active;
	u32 chan_control_mask, control_mask, chan_control_set = 0;
	u32 reg, control_set = 0;

	force_clk_active = ((fmt & SND_SOC_DAIFMT_CLOCK_MASK) ==
			SND_SOC_DAIFMT_CONT);

	if (force_clk_active)
		control_set |= IMG_I2S_OUT_CTL_CLK_EN_MASK;

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		control_set |= IMG_I2S_OUT_CTL_MASTER_MASK;
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		control_set |= IMG_I2S_OUT_CTL_BCLK_POL_MASK;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		control_set |= IMG_I2S_OUT_CTL_BCLK_POL_MASK;
		control_set |= IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		break;
	case SND_SOC_DAIFMT_IB_IF:
		control_set |= IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		chan_control_set |= IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		break;
	default:
		return -EINVAL;
	}

	control_mask = IMG_I2S_OUT_CTL_CLK_EN_MASK |
		       IMG_I2S_OUT_CTL_MASTER_MASK |
		       IMG_I2S_OUT_CTL_BCLK_POL_MASK |
		       IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;

	chan_control_mask = IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;

	img_i2s_out_disable(i2s);

	reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
	reg = (reg & ~control_mask) | control_set;
	img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);

	for (i = 0; i < i2s->active_channels; i++)
		img_i2s_out_ch_disable(i2s, i);

	for (i = 0; i < i2s->max_i2s_chan; i++) {
		reg = img_i2s_out_ch_readl(i2s, i, IMG_I2S_OUT_CH_CTL);
		reg = (reg & ~chan_control_mask) | chan_control_set;
		img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);
	}

	for (i = 0; i < i2s->active_channels; i++)
		img_i2s_out_ch_enable(i2s, i);

	img_i2s_out_enable(i2s);

	i2s->force_clk_active = force_clk_active;

	return 0;
}

static const struct snd_soc_dai_ops img_i2s_out_dai_ops = {
	.trigger = img_i2s_out_trigger,
	.hw_params = img_i2s_out_hw_params,
	.set_fmt = img_i2s_out_set_fmt
};

static int img_i2s_out_dai_probe(struct snd_soc_dai *dai)
{
	struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);

	snd_soc_dai_init_dma_data(dai, &i2s->dma_data, NULL);

	return 0;
}

static const struct snd_soc_component_driver img_i2s_out_component = {
	.name = "img-i2s-out"
};

static int img_i2s_out_dma_prepare_slave_config(struct snd_pcm_substream *st,
	struct snd_pcm_hw_params *params, struct dma_slave_config *sc)
{
	unsigned int i2s_channels = params_channels(params) / 2;
	struct snd_soc_pcm_runtime *rtd = st->private_data;
	struct snd_dmaengine_dai_dma_data *dma_data;
	int ret;

	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st);

	ret = snd_hwparams_to_dma_slave_config(st, params, sc);
	if (ret)
		return ret;

	sc->dst_addr = dma_data->addr;
	sc->dst_addr_width = dma_data->addr_width;
	sc->dst_maxburst = 4 * i2s_channels;

	return 0;
}

static const struct snd_dmaengine_pcm_config img_i2s_out_dma_config = {
	.prepare_slave_config = img_i2s_out_dma_prepare_slave_config
};

static int img_i2s_out_probe(struct platform_device *pdev)
{
	struct img_i2s_out *i2s;
	struct resource *res;
	void __iomem *base;
	int i, ret;
	unsigned int max_i2s_chan_pow_2;
	u32 reg;
	struct device *dev = &pdev->dev;

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

	platform_set_drvdata(pdev, i2s);

	i2s->dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	i2s->base = base;

	if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels",
			&i2s->max_i2s_chan)) {
		dev_err(&pdev->dev, "No img,i2s-channels property\n");
		return -EINVAL;
	}

	max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan);

	i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20);

	i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst");
	if (IS_ERR(i2s->rst)) {
		if (PTR_ERR(i2s->rst) != -EPROBE_DEFER)
			dev_err(&pdev->dev, "No top level reset found\n");
		return PTR_ERR(i2s->rst);
	}

	i2s->clk_sys = devm_clk_get(&pdev->dev, "sys");
	if (IS_ERR(i2s->clk_sys)) {
		if (PTR_ERR(i2s->clk_sys) != -EPROBE_DEFER)
			dev_err(dev, "Failed to acquire clock 'sys'\n");
		return PTR_ERR(i2s->clk_sys);
	}

	i2s->clk_ref = devm_clk_get(&pdev->dev, "ref");
	if (IS_ERR(i2s->clk_ref)) {
		if (PTR_ERR(i2s->clk_ref) != -EPROBE_DEFER)
			dev_err(dev, "Failed to acquire clock 'ref'\n");
		return PTR_ERR(i2s->clk_ref);
	}

	ret = clk_prepare_enable(i2s->clk_sys);
	if (ret)
		return ret;

	reg = IMG_I2S_OUT_CTL_FRM_SIZE_MASK;
	img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);

	reg = IMG_I2S_OUT_CHAN_CTL_JUST_MASK |
		IMG_I2S_OUT_CHAN_CTL_LT_MASK |
		IMG_I2S_OUT_CHAN_CTL_CH_MASK |
		(8 << IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT);

	for (i = 0; i < i2s->max_i2s_chan; i++)
		img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);

	img_i2s_out_reset(i2s);

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = img_i2s_out_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}

	i2s->active_channels = 1;
	i2s->dma_data.addr = res->start + IMG_I2S_OUT_TX_FIFO;
	i2s->dma_data.addr_width = 4;
	i2s->dma_data.maxburst = 4;

	i2s->dai_driver.probe = img_i2s_out_dai_probe;
	i2s->dai_driver.playback.channels_min = 2;
	i2s->dai_driver.playback.channels_max = i2s->max_i2s_chan * 2;
	i2s->dai_driver.playback.rates = SNDRV_PCM_RATE_8000_192000;
	i2s->dai_driver.playback.formats = SNDRV_PCM_FMTBIT_S32_LE;
	i2s->dai_driver.ops = &img_i2s_out_dai_ops;

	ret = devm_snd_soc_register_component(&pdev->dev,
			&img_i2s_out_component, &i2s->dai_driver, 1);
	if (ret)
		goto err_suspend;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
			&img_i2s_out_dma_config, 0);
	if (ret)
		goto err_suspend;

	return 0;

err_suspend:
	if (!pm_runtime_status_suspended(&pdev->dev))
		img_i2s_out_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);
	clk_disable_unprepare(i2s->clk_sys);

	return ret;
}

static int img_i2s_out_dev_remove(struct platform_device *pdev)
{
	struct img_i2s_out *i2s = platform_get_drvdata(pdev);

	pm_runtime_disable(&pdev->dev);
	if (!pm_runtime_status_suspended(&pdev->dev))
		img_i2s_out_suspend(&pdev->dev);

	clk_disable_unprepare(i2s->clk_sys);

	return 0;
}

static const struct of_device_id img_i2s_out_of_match[] = {
	{ .compatible = "img,i2s-out" },
	{}
};
MODULE_DEVICE_TABLE(of, img_i2s_out_of_match);

static const struct dev_pm_ops img_i2s_out_pm_ops = {
	SET_RUNTIME_PM_OPS(img_i2s_out_suspend,
			   img_i2s_out_resume, NULL)
};

static struct platform_driver img_i2s_out_driver = {
	.driver = {
		.name = "img-i2s-out",
		.of_match_table = img_i2s_out_of_match,
		.pm = &img_i2s_out_pm_ops
	},
	.probe = img_i2s_out_probe,
	.remove = img_i2s_out_dev_remove
};
module_platform_driver(img_i2s_out_driver);

MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
MODULE_DESCRIPTION("IMG I2S Output Driver");
MODULE_LICENSE("GPL v2");
