/*
 * IMG I2S input 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_IN_RX_FIFO			0x0

#define IMG_I2S_IN_CTL				0x4
#define IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK		0xfffffffc
#define IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT		2
#define IMG_I2S_IN_CTL_16PACK_MASK		BIT(1)
#define IMG_I2S_IN_CTL_ME_MASK			BIT(0)

#define IMG_I2S_IN_CH_CTL			0x4
#define IMG_I2S_IN_CH_CTL_CCDEL_MASK		0x38000
#define IMG_I2S_IN_CH_CTL_CCDEL_SHIFT		15
#define IMG_I2S_IN_CH_CTL_FEN_MASK		BIT(14)
#define IMG_I2S_IN_CH_CTL_FMODE_MASK		BIT(13)
#define IMG_I2S_IN_CH_CTL_16PACK_MASK		BIT(12)
#define IMG_I2S_IN_CH_CTL_JUST_MASK		BIT(10)
#define IMG_I2S_IN_CH_CTL_PACKH_MASK		BIT(9)
#define IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK	BIT(8)
#define IMG_I2S_IN_CH_CTL_BLKP_MASK		BIT(7)
#define IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK	BIT(6)
#define IMG_I2S_IN_CH_CTL_LRD_MASK		BIT(3)
#define IMG_I2S_IN_CH_CTL_FW_MASK		BIT(2)
#define IMG_I2S_IN_CH_CTL_SW_MASK		BIT(1)
#define IMG_I2S_IN_CH_CTL_ME_MASK		BIT(0)

#define IMG_I2S_IN_CH_STRIDE			0x20

struct img_i2s_in {
	void __iomem *base;
	struct clk *clk_sys;
	struct snd_dmaengine_dai_dma_data dma_data;
	struct device *dev;
	unsigned int max_i2s_chan;
	void __iomem *channel_base;
	unsigned int active_channels;
	struct snd_soc_dai_driver dai_driver;
	u32 suspend_ctl;
	u32 *suspend_ch_ctl;
};

static int img_i2s_in_runtime_suspend(struct device *dev)
{
	struct img_i2s_in *i2s = dev_get_drvdata(dev);

	clk_disable_unprepare(i2s->clk_sys);

	return 0;
}

static int img_i2s_in_runtime_resume(struct device *dev)
{
	struct img_i2s_in *i2s = dev_get_drvdata(dev);
	int ret;

	ret = clk_prepare_enable(i2s->clk_sys);
	if (ret) {
		dev_err(dev, "Unable to enable sys clock\n");
		return ret;
	}

	return 0;
}

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

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

static inline void img_i2s_in_ch_writel(struct img_i2s_in *i2s, u32 chan,
					u32 val, u32 reg)
{
	writel(val, i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg);
}

static inline u32 img_i2s_in_ch_readl(struct img_i2s_in *i2s, u32 chan,
					u32 reg)
{
	return readl(i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg);
}

static inline void img_i2s_in_ch_disable(struct img_i2s_in *i2s, u32 chan)
{
	u32 reg;

	reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL);
	reg &= ~IMG_I2S_IN_CH_CTL_ME_MASK;
	img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL);
}

static inline void img_i2s_in_ch_enable(struct img_i2s_in *i2s, u32 chan)
{
	u32 reg;

	reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL);
	reg |= IMG_I2S_IN_CH_CTL_ME_MASK;
	img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL);
}

static inline void img_i2s_in_disable(struct img_i2s_in *i2s)
{
	u32 reg;

	reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
	reg &= ~IMG_I2S_IN_CTL_ME_MASK;
	img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
}

static inline void img_i2s_in_enable(struct img_i2s_in *i2s)
{
	u32 reg;

	reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
	reg |= IMG_I2S_IN_CTL_ME_MASK;
	img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
}

static inline void img_i2s_in_flush(struct img_i2s_in *i2s)
{
	int i;
	u32 reg;

	for (i = 0; i < i2s->active_channels; i++) {
		reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
		reg |= IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
		img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
		reg &= ~IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
		img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
	}
}

static int img_i2s_in_trigger(struct snd_pcm_substream *substream, int cmd,
	struct snd_soc_dai *dai)
{
	struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		img_i2s_in_enable(i2s);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		img_i2s_in_disable(i2s);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int img_i2s_in_check_rate(struct img_i2s_in *i2s,
		unsigned int sample_rate, unsigned int frame_size,
		unsigned int *bclk_filter_enable,
		unsigned int *bclk_filter_value)
{
	unsigned int bclk_freq, cur_freq;

	bclk_freq = sample_rate * frame_size;

	cur_freq = clk_get_rate(i2s->clk_sys);

	if (cur_freq >= bclk_freq * 8) {
		*bclk_filter_enable = 1;
		*bclk_filter_value = 0;
	} else if (cur_freq >= bclk_freq * 7) {
		*bclk_filter_enable = 1;
		*bclk_filter_value = 1;
	} else if (cur_freq >= bclk_freq * 6) {
		*bclk_filter_enable = 0;
		*bclk_filter_value = 0;
	} else {
		dev_err(i2s->dev,
			"Sys clock rate %u insufficient for sample rate %u\n",
			cur_freq, sample_rate);
		return -EINVAL;
	}

	return 0;
}

static int img_i2s_in_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
	unsigned int rate, channels, i2s_channels, frame_size;
	unsigned int bclk_filter_enable, bclk_filter_value;
	int i, ret = 0;
	u32 reg, control_mask, chan_control_mask;
	u32 control_set = 0, chan_control_set = 0;
	snd_pcm_format_t format;

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

	switch (format) {
	case SNDRV_PCM_FORMAT_S32_LE:
		frame_size = 64;
		chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
		chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
		chan_control_set |= IMG_I2S_IN_CH_CTL_PACKH_MASK;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		frame_size = 64;
		chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
		chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		frame_size = 32;
		control_set |= IMG_I2S_IN_CTL_16PACK_MASK;
		chan_control_set |= IMG_I2S_IN_CH_CTL_16PACK_MASK;
		break;
	default:
		return -EINVAL;
	}

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

	control_set |= ((i2s_channels - 1) << IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT);

	ret = img_i2s_in_check_rate(i2s, rate, frame_size,
			&bclk_filter_enable, &bclk_filter_value);
	if (ret < 0)
		return ret;

	if (bclk_filter_enable)
		chan_control_set |= IMG_I2S_IN_CH_CTL_FEN_MASK;

	if (bclk_filter_value)
		chan_control_set |= IMG_I2S_IN_CH_CTL_FMODE_MASK;

	control_mask = IMG_I2S_IN_CTL_16PACK_MASK |
		       IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK;

	chan_control_mask = IMG_I2S_IN_CH_CTL_16PACK_MASK |
			    IMG_I2S_IN_CH_CTL_FEN_MASK |
			    IMG_I2S_IN_CH_CTL_FMODE_MASK |
			    IMG_I2S_IN_CH_CTL_SW_MASK |
			    IMG_I2S_IN_CH_CTL_FW_MASK |
			    IMG_I2S_IN_CH_CTL_PACKH_MASK;

	reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
	reg = (reg & ~control_mask) | control_set;
	img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);

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

	for (i = 0; i < i2s->max_i2s_chan; i++) {
		reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
		reg = (reg & ~chan_control_mask) | chan_control_set;
		img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
	}

	i2s->active_channels = i2s_channels;

	img_i2s_in_flush(i2s);

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

	return 0;
}

static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
	int i, ret;
	u32 chan_control_mask, lrd_set = 0, blkp_set = 0, chan_control_set = 0;
	u32 reg;

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		lrd_set |= IMG_I2S_IN_CH_CTL_LRD_MASK;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		break;
	case SND_SOC_DAIFMT_IB_NF:
		lrd_set |= IMG_I2S_IN_CH_CTL_LRD_MASK;
		blkp_set |= IMG_I2S_IN_CH_CTL_BLKP_MASK;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		blkp_set |= IMG_I2S_IN_CH_CTL_BLKP_MASK;
		break;
	default:
		return -EINVAL;
	}

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

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		break;
	default:
		return -EINVAL;
	}

	chan_control_mask = IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;

	ret = pm_runtime_get_sync(i2s->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(i2s->dev);
		return ret;
	}

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

	/*
	 * BLKP and LRD must be set during separate register writes
	 */
	for (i = 0; i < i2s->max_i2s_chan; i++) {
		reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
		reg = (reg & ~chan_control_mask) | chan_control_set;
		img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
		reg = (reg & ~IMG_I2S_IN_CH_CTL_BLKP_MASK) | blkp_set;
		img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
		reg = (reg & ~IMG_I2S_IN_CH_CTL_LRD_MASK) | lrd_set;
		img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
	}

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

	pm_runtime_put(i2s->dev);

	return 0;
}

static const struct snd_soc_dai_ops img_i2s_in_dai_ops = {
	.trigger = img_i2s_in_trigger,
	.hw_params = img_i2s_in_hw_params,
	.set_fmt = img_i2s_in_set_fmt
};

static int img_i2s_in_dai_probe(struct snd_soc_dai *dai)
{
	struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);

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

	return 0;
}

static const struct snd_soc_component_driver img_i2s_in_component = {
	.name = "img-i2s-in"
};

static int img_i2s_in_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->src_addr = dma_data->addr;
	sc->src_addr_width = dma_data->addr_width;
	sc->src_maxburst = 4 * i2s_channels;

	return 0;
}

static const struct snd_dmaengine_pcm_config img_i2s_in_dma_config = {
	.prepare_slave_config = img_i2s_in_dma_prepare_slave_config
};

static int img_i2s_in_probe(struct platform_device *pdev)
{
	struct img_i2s_in *i2s;
	struct resource *res;
	void __iomem *base;
	int ret, i;
	struct reset_control *rst;
	unsigned int max_i2s_chan_pow_2;
	struct device *dev = &pdev->dev;

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

	platform_set_drvdata(pdev, i2s);

	i2s->dev = dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(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(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->clk_sys = devm_clk_get(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);
	}

	pm_runtime_enable(&pdev->dev);
	if (!pm_runtime_enabled(&pdev->dev)) {
		ret = img_i2s_in_runtime_resume(&pdev->dev);
		if (ret)
			goto err_pm_disable;
	}
	ret = pm_runtime_get_sync(&pdev->dev);
	if (ret < 0)
		goto err_suspend;

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

	i2s->dai_driver.probe = img_i2s_in_dai_probe;
	i2s->dai_driver.capture.channels_min = 2;
	i2s->dai_driver.capture.channels_max = i2s->max_i2s_chan * 2;
	i2s->dai_driver.capture.rates = SNDRV_PCM_RATE_8000_192000;
	i2s->dai_driver.capture.formats = SNDRV_PCM_FMTBIT_S32_LE |
		SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE;
	i2s->dai_driver.ops = &img_i2s_in_dai_ops;

	rst = devm_reset_control_get_exclusive(dev, "rst");
	if (IS_ERR(rst)) {
		if (PTR_ERR(rst) == -EPROBE_DEFER) {
			ret = -EPROBE_DEFER;
			pm_runtime_put(&pdev->dev);
			goto err_suspend;
		}

		dev_dbg(dev, "No top level reset found\n");

		img_i2s_in_disable(i2s);

		for (i = 0; i < i2s->max_i2s_chan; i++)
			img_i2s_in_ch_disable(i2s, i);
	} else {
		reset_control_assert(rst);
		reset_control_deassert(rst);
	}

	img_i2s_in_writel(i2s, 0, IMG_I2S_IN_CTL);

	for (i = 0; i < i2s->max_i2s_chan; i++)
		img_i2s_in_ch_writel(i2s, i,
			(4 << IMG_I2S_IN_CH_CTL_CCDEL_SHIFT) |
			IMG_I2S_IN_CH_CTL_JUST_MASK |
			IMG_I2S_IN_CH_CTL_FW_MASK, IMG_I2S_IN_CH_CTL);

	pm_runtime_put(&pdev->dev);

	i2s->suspend_ch_ctl = devm_kcalloc(dev,
		i2s->max_i2s_chan, sizeof(*i2s->suspend_ch_ctl), GFP_KERNEL);
	if (!i2s->suspend_ch_ctl) {
		ret = -ENOMEM;
		goto err_suspend;
	}

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

	ret = devm_snd_dmaengine_pcm_register(dev, &img_i2s_in_dma_config, 0);
	if (ret)
		goto err_suspend;

	return 0;

err_suspend:
	if (!pm_runtime_enabled(&pdev->dev))
		img_i2s_in_runtime_suspend(&pdev->dev);
err_pm_disable:
	pm_runtime_disable(&pdev->dev);

	return ret;
}

static int img_i2s_in_dev_remove(struct platform_device *pdev)
{
	pm_runtime_disable(&pdev->dev);
	if (!pm_runtime_status_suspended(&pdev->dev))
		img_i2s_in_runtime_suspend(&pdev->dev);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int img_i2s_in_suspend(struct device *dev)
{
	struct img_i2s_in *i2s = dev_get_drvdata(dev);
	int i, ret;
	u32 reg;

	if (pm_runtime_status_suspended(dev)) {
		ret = img_i2s_in_runtime_resume(dev);
		if (ret)
			return ret;
	}

	for (i = 0; i < i2s->max_i2s_chan; i++) {
		reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
		i2s->suspend_ch_ctl[i] = reg;
	}

	i2s->suspend_ctl = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);

	img_i2s_in_runtime_suspend(dev);

	return 0;
}

static int img_i2s_in_resume(struct device *dev)
{
	struct img_i2s_in *i2s = dev_get_drvdata(dev);
	int i, ret;
	u32 reg;

	ret = img_i2s_in_runtime_resume(dev);
	if (ret)
		return ret;

	for (i = 0; i < i2s->max_i2s_chan; i++) {
		reg = i2s->suspend_ch_ctl[i];
		img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
	}

	img_i2s_in_writel(i2s, i2s->suspend_ctl, IMG_I2S_IN_CTL);

	if (pm_runtime_status_suspended(dev))
		img_i2s_in_runtime_suspend(dev);

	return 0;
}
#endif

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

static const struct dev_pm_ops img_i2s_in_pm_ops = {
	SET_RUNTIME_PM_OPS(img_i2s_in_runtime_suspend,
			   img_i2s_in_runtime_resume, NULL)
	SET_SYSTEM_SLEEP_PM_OPS(img_i2s_in_suspend, img_i2s_in_resume)
};

static struct platform_driver img_i2s_in_driver = {
	.driver = {
		.name = "img-i2s-in",
		.of_match_table = img_i2s_in_of_match,
		.pm = &img_i2s_in_pm_ops
	},
	.probe = img_i2s_in_probe,
	.remove = img_i2s_in_dev_remove
};
module_platform_driver(img_i2s_in_driver);

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