/*
 * ALSA SoC Synopsys I2S Audio Layer
 *
 * sound/soc/dwc/designware_i2s.c
 *
 * Copyright (C) 2010 ST Microelectronics
 * Rajeev Kumar <rajeevkumar.linux@gmail.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <sound/designware_i2s.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
#include "local.h"

static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
{
	writel(val, io_base + reg);
}

static inline u32 i2s_read_reg(void __iomem *io_base, int reg)
{
	return readl(io_base + reg);
}

static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream)
{
	u32 i = 0;

	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		for (i = 0; i < 4; i++)
			i2s_write_reg(dev->i2s_base, TER(i), 0);
	} else {
		for (i = 0; i < 4; i++)
			i2s_write_reg(dev->i2s_base, RER(i), 0);
	}
}

static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
{
	u32 i = 0;

	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		for (i = 0; i < 4; i++)
			i2s_read_reg(dev->i2s_base, TOR(i));
	} else {
		for (i = 0; i < 4; i++)
			i2s_read_reg(dev->i2s_base, ROR(i));
	}
}

static inline void i2s_disable_irqs(struct dw_i2s_dev *dev, u32 stream,
				    int chan_nr)
{
	u32 i, irq;

	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		for (i = 0; i < (chan_nr / 2); i++) {
			irq = i2s_read_reg(dev->i2s_base, IMR(i));
			i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
		}
	} else {
		for (i = 0; i < (chan_nr / 2); i++) {
			irq = i2s_read_reg(dev->i2s_base, IMR(i));
			i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
		}
	}
}

static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
				   int chan_nr)
{
	u32 i, irq;

	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		for (i = 0; i < (chan_nr / 2); i++) {
			irq = i2s_read_reg(dev->i2s_base, IMR(i));
			i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30);
		}
	} else {
		for (i = 0; i < (chan_nr / 2); i++) {
			irq = i2s_read_reg(dev->i2s_base, IMR(i));
			i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03);
		}
	}
}

static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
{
	struct dw_i2s_dev *dev = dev_id;
	bool irq_valid = false;
	u32 isr[4];
	int i;

	for (i = 0; i < 4; i++)
		isr[i] = i2s_read_reg(dev->i2s_base, ISR(i));

	i2s_clear_irqs(dev, SNDRV_PCM_STREAM_PLAYBACK);
	i2s_clear_irqs(dev, SNDRV_PCM_STREAM_CAPTURE);

	for (i = 0; i < 4; i++) {
		/*
		 * Check if TX fifo is empty. If empty fill FIFO with samples
		 * NOTE: Only two channels supported
		 */
		if ((isr[i] & ISR_TXFE) && (i == 0) && dev->use_pio) {
			dw_pcm_push_tx(dev);
			irq_valid = true;
		}

		/*
		 * Data available. Retrieve samples from FIFO
		 * NOTE: Only two channels supported
		 */
		if ((isr[i] & ISR_RXDA) && (i == 0) && dev->use_pio) {
			dw_pcm_pop_rx(dev);
			irq_valid = true;
		}

		/* Error Handling: TX */
		if (isr[i] & ISR_TXFO) {
			dev_err_ratelimited(dev->dev, "TX overrun (ch_id=%d)\n", i);
			irq_valid = true;
		}

		/* Error Handling: TX */
		if (isr[i] & ISR_RXFO) {
			dev_err_ratelimited(dev->dev, "RX overrun (ch_id=%d)\n", i);
			irq_valid = true;
		}
	}

	if (irq_valid)
		return IRQ_HANDLED;
	else
		return IRQ_NONE;
}

static void i2s_enable_dma(struct dw_i2s_dev *dev, u32 stream)
{
	u32 dma_reg = i2s_read_reg(dev->i2s_base, I2S_DMACR);

	/* Enable DMA handshake for stream */
	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
		dma_reg |= I2S_DMAEN_TXBLOCK;
	else
		dma_reg |= I2S_DMAEN_RXBLOCK;

	i2s_write_reg(dev->i2s_base, I2S_DMACR, dma_reg);
}

static void i2s_disable_dma(struct dw_i2s_dev *dev, u32 stream)
{
	u32 dma_reg = i2s_read_reg(dev->i2s_base, I2S_DMACR);

	/* Disable DMA handshake for stream */
	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		dma_reg &= ~I2S_DMAEN_TXBLOCK;
		i2s_write_reg(dev->i2s_base, I2S_RTXDMA, 1);
	} else {
		dma_reg &= ~I2S_DMAEN_RXBLOCK;
		i2s_write_reg(dev->i2s_base, I2S_RRXDMA, 1);
	}
	i2s_write_reg(dev->i2s_base, I2S_DMACR, dma_reg);
}

static void i2s_start(struct dw_i2s_dev *dev,
		      struct snd_pcm_substream *substream)
{
	struct i2s_clk_config_data *config = &dev->config;

	u32 reg = IER_IEN;

	if (dev->tdm_slots) {
		reg |= (dev->tdm_slots - 1) << IER_TDM_SLOTS_SHIFT;
		reg |= IER_INTF_TYPE;
		reg |= dev->frame_offset << IER_FRAME_OFF_SHIFT;
	}

	i2s_write_reg(dev->i2s_base, IER, reg);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		i2s_write_reg(dev->i2s_base, ITER, 1);
	else
		i2s_write_reg(dev->i2s_base, IRER, 1);

	/* I2S needs to enable IRQ to make a handshake with DMAC on the JH7110 SoC */
	if (dev->use_pio || dev->is_jh7110)
		i2s_enable_irqs(dev, substream->stream, config->chan_nr);
	else
		i2s_enable_dma(dev, substream->stream);

	i2s_write_reg(dev->i2s_base, CER, 1);
}

static void i2s_stop(struct dw_i2s_dev *dev,
		struct snd_pcm_substream *substream)
{

	i2s_clear_irqs(dev, substream->stream);
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		i2s_write_reg(dev->i2s_base, ITER, 0);
	else
		i2s_write_reg(dev->i2s_base, IRER, 0);

	if (dev->use_pio || dev->is_jh7110)
		i2s_disable_irqs(dev, substream->stream, 8);
	else
		i2s_disable_dma(dev, substream->stream);

	if (!dev->active) {
		i2s_write_reg(dev->i2s_base, CER, 0);
		i2s_write_reg(dev->i2s_base, IER, 0);
	}
}

static int dw_i2s_startup(struct snd_pcm_substream *substream,
			  struct snd_soc_dai *cpu_dai)
{
	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);

	if (dev->is_jh7110) {
		struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
		struct snd_soc_dai_link *dai_link = rtd->dai_link;

		dai_link->trigger_stop = SND_SOC_TRIGGER_ORDER_LDC;
	}

	return 0;
}

static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
{
	u32 ch_reg;
	struct i2s_clk_config_data *config = &dev->config;


	i2s_disable_channels(dev, stream);

	for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) {
		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
			i2s_write_reg(dev->i2s_base, TCR(ch_reg),
				      dev->xfer_resolution);
			i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
				      dev->fifo_th - 1);
			i2s_write_reg(dev->i2s_base, TER(ch_reg), TER_TXCHEN |
				      dev->tdm_mask << TER_TXSLOT_SHIFT);
		} else {
			i2s_write_reg(dev->i2s_base, RCR(ch_reg),
				      dev->xfer_resolution);
			i2s_write_reg(dev->i2s_base, RFCR(ch_reg),
				      dev->fifo_th - 1);
			i2s_write_reg(dev->i2s_base, RER(ch_reg), RER_RXCHEN |
				      dev->tdm_mask << RER_RXSLOT_SHIFT);
		}

	}
}

static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
	struct i2s_clk_config_data *config = &dev->config;
	int ret;

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		config->data_width = 16;
		dev->ccr = 0x00;
		dev->xfer_resolution = 0x02;
		break;

	case SNDRV_PCM_FORMAT_S24_LE:
		config->data_width = 24;
		dev->ccr = 0x08;
		dev->xfer_resolution = 0x04;
		break;

	case SNDRV_PCM_FORMAT_S32_LE:
		config->data_width = 32;
		dev->ccr = 0x10;
		dev->xfer_resolution = 0x05;
		break;

	default:
		dev_err(dev->dev, "designware-i2s: unsupported PCM fmt");
		return -EINVAL;
	}

	if (dev->tdm_slots)
		config->data_width = 32;

	config->chan_nr = params_channels(params);

	switch (config->chan_nr) {
	case EIGHT_CHANNEL_SUPPORT:
	case SIX_CHANNEL_SUPPORT:
	case FOUR_CHANNEL_SUPPORT:
	case TWO_CHANNEL_SUPPORT:
		break;
	default:
		dev_err(dev->dev, "channel not supported\n");
		return -EINVAL;
	}

	dw_i2s_config(dev, substream->stream);

	i2s_write_reg(dev->i2s_base, CCR, dev->ccr);

	config->sample_rate = params_rate(params);

	if (dev->capability & DW_I2S_MASTER) {
		if (dev->i2s_clk_cfg) {
			ret = dev->i2s_clk_cfg(config);
			if (ret < 0) {
				dev_err(dev->dev, "runtime audio clk config fail\n");
				return ret;
			}
		} else {
			u32 bitclk = config->sample_rate *
					config->data_width * 2;

			ret = clk_set_rate(dev->clk, bitclk);
			if (ret) {
				dev_err(dev->dev, "Can't set I2S clock rate: %d\n",
					ret);
				return ret;
			}
		}
	}
	return 0;
}

static int dw_i2s_prepare(struct snd_pcm_substream *substream,
			  struct snd_soc_dai *dai)
{
	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		i2s_write_reg(dev->i2s_base, TXFFR, 1);
	else
		i2s_write_reg(dev->i2s_base, RXFFR, 1);

	return 0;
}

static int dw_i2s_trigger(struct snd_pcm_substream *substream,
		int cmd, struct snd_soc_dai *dai)
{
	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
	int ret = 0;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		dev->active++;
		i2s_start(dev, substream);
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		dev->active--;
		i2s_stop(dev, substream);
		break;
	default:
		ret = -EINVAL;
		break;
	}
	return ret;
}

static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
	int ret = 0;

	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_BC_FC:
		if (dev->capability & DW_I2S_SLAVE)
			ret = 0;
		else
			ret = -EINVAL;
		break;
	case SND_SOC_DAIFMT_BP_FP:
		if (dev->capability & DW_I2S_MASTER)
			ret = 0;
		else
			ret = -EINVAL;
		break;
	case SND_SOC_DAIFMT_BC_FP:
	case SND_SOC_DAIFMT_BP_FC:
		ret = -EINVAL;
		break;
	default:
		dev_dbg(dev->dev, "dwc : Invalid clock provider format\n");
		ret = -EINVAL;
		break;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
	case SND_SOC_DAIFMT_LEFT_J:
	case SND_SOC_DAIFMT_RIGHT_J:
		break;
	case SND_SOC_DAIFMT_DSP_A:
		dev->frame_offset = 1;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		dev->frame_offset = 0;
		break;
	default:
		dev_err(dev->dev, "DAI format unsupported");
		return -EINVAL;
	}

	return ret;
}

static int dw_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai,	unsigned int tx_mask,
			   unsigned int rx_mask, int slots, int slot_width)
{
	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);

	if (slot_width != 32)
		return -EINVAL;

	if (slots < 0 || slots > 16)
		return -EINVAL;

	if (rx_mask != tx_mask)
		return -EINVAL;

	if (!rx_mask)
		return -EINVAL;

	dev->tdm_slots = slots;
	dev->tdm_mask = rx_mask;

	dev->l_reg = RSLOT_TSLOT(ffs(rx_mask) - 1);
	dev->r_reg = RSLOT_TSLOT(fls(rx_mask) - 1);

	return 0;
}

static int dw_i2s_dai_probe(struct snd_soc_dai *dai)
{
	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);

	snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, &dev->capture_dma_data);
	return 0;
}

static const struct snd_soc_dai_ops dw_i2s_dai_ops = {
	.probe		= dw_i2s_dai_probe,
	.startup	= dw_i2s_startup,
	.hw_params	= dw_i2s_hw_params,
	.prepare	= dw_i2s_prepare,
	.trigger	= dw_i2s_trigger,
	.set_fmt	= dw_i2s_set_fmt,
	.set_tdm_slot	= dw_i2s_set_tdm_slot,
};

#ifdef CONFIG_PM
static int dw_i2s_runtime_suspend(struct device *dev)
{
	struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);

	if (dw_dev->capability & DW_I2S_MASTER)
		clk_disable(dw_dev->clk);
	return 0;
}

static int dw_i2s_runtime_resume(struct device *dev)
{
	struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
	int ret;

	if (dw_dev->capability & DW_I2S_MASTER) {
		ret = clk_enable(dw_dev->clk);
		if (ret)
			return ret;
	}
	return 0;
}

static int dw_i2s_suspend(struct snd_soc_component *component)
{
	struct dw_i2s_dev *dev = snd_soc_component_get_drvdata(component);

	if (dev->capability & DW_I2S_MASTER)
		clk_disable(dev->clk);
	return 0;
}

static int dw_i2s_resume(struct snd_soc_component *component)
{
	struct dw_i2s_dev *dev = snd_soc_component_get_drvdata(component);
	struct snd_soc_dai *dai;
	int stream, ret;

	if (dev->capability & DW_I2S_MASTER) {
		ret = clk_enable(dev->clk);
		if (ret)
			return ret;
	}

	for_each_component_dais(component, dai) {
		for_each_pcm_streams(stream)
			if (snd_soc_dai_stream_active(dai, stream))
				dw_i2s_config(dev, stream);
	}

	return 0;
}

#else
#define dw_i2s_suspend	NULL
#define dw_i2s_resume	NULL
#endif

static const struct snd_soc_component_driver dw_i2s_component = {
	.name			= "dw-i2s",
	.suspend		= dw_i2s_suspend,
	.resume			= dw_i2s_resume,
	.legacy_dai_naming	= 1,
};

/*
 * The following tables allow a direct lookup of various parameters
 * defined in the I2S block's configuration in terms of sound system
 * parameters.  Each table is sized to the number of entries possible
 * according to the number of configuration bits describing an I2S
 * block parameter.
 */

/* Maximum bit resolution of a channel - not uniformly spaced */
static const u32 fifo_width[COMP_MAX_WORDSIZE] = {
	12, 16, 20, 24, 32, 0, 0, 0
};

/* Width of (DMA) bus */
static const u32 bus_widths[COMP_MAX_DATA_WIDTH] = {
	DMA_SLAVE_BUSWIDTH_1_BYTE,
	DMA_SLAVE_BUSWIDTH_2_BYTES,
	DMA_SLAVE_BUSWIDTH_4_BYTES,
	DMA_SLAVE_BUSWIDTH_UNDEFINED
};

/* PCM format to support channel resolution */
static const u32 formats[COMP_MAX_WORDSIZE] = {
	SNDRV_PCM_FMTBIT_S16_LE,
	SNDRV_PCM_FMTBIT_S16_LE,
	SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
	SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
	SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
	0,
	0,
	0
};

static int dw_configure_dai(struct dw_i2s_dev *dev,
				   struct snd_soc_dai_driver *dw_i2s_dai,
				   unsigned int rates)
{
	/*
	 * Read component parameter registers to extract
	 * the I2S block's configuration.
	 */
	u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
	u32 comp2 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp2);
	u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
	u32 idx;

	if (dev->capability & DWC_I2S_RECORD &&
			dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
		comp1 = comp1 & ~BIT(5);

	if (dev->capability & DWC_I2S_PLAY &&
			dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
		comp1 = comp1 & ~BIT(6);

	if (COMP1_TX_ENABLED(comp1)) {
		dev_dbg(dev->dev, " designware: play supported\n");
		idx = COMP1_TX_WORDSIZE_0(comp1);
		if (WARN_ON(idx >= ARRAY_SIZE(formats)))
			return -EINVAL;
		if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
			idx = 1;
		dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
		dw_i2s_dai->playback.channels_max =
				1 << (COMP1_TX_CHANNELS(comp1) + 1);
		dw_i2s_dai->playback.formats = formats[idx];
		dw_i2s_dai->playback.rates = rates;
	}

	if (COMP1_RX_ENABLED(comp1)) {
		dev_dbg(dev->dev, "designware: record supported\n");
		idx = COMP2_RX_WORDSIZE_0(comp2);
		if (WARN_ON(idx >= ARRAY_SIZE(formats)))
			return -EINVAL;
		if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
			idx = 1;
		dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
		dw_i2s_dai->capture.channels_max =
				1 << (COMP1_RX_CHANNELS(comp1) + 1);
		dw_i2s_dai->capture.formats = formats[idx];
		dw_i2s_dai->capture.rates = rates;
	}

	if (COMP1_MODE_EN(comp1)) {
		dev_dbg(dev->dev, "designware: i2s master mode supported\n");
		dev->capability |= DW_I2S_MASTER;
	} else {
		dev_dbg(dev->dev, "designware: i2s slave mode supported\n");
		dev->capability |= DW_I2S_SLAVE;
	}

	dev->fifo_th = fifo_depth / 2;
	return 0;
}

static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev,
				   struct snd_soc_dai_driver *dw_i2s_dai,
				   struct resource *res,
				   const struct i2s_platform_data *pdata)
{
	u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
	u32 idx = COMP1_APB_DATA_WIDTH(comp1);
	int ret;

	if (WARN_ON(idx >= ARRAY_SIZE(bus_widths)))
		return -EINVAL;

	ret = dw_configure_dai(dev, dw_i2s_dai, pdata->snd_rates);
	if (ret < 0)
		return ret;

	if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
		idx = 1;

	if (dev->is_jh7110) {
		/* Use platform data and snd_dmaengine_dai_dma_data struct at the same time */
		u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2);
		u32 idx2;

		if (COMP1_TX_ENABLED(comp1)) {
			idx2 = COMP1_TX_WORDSIZE_0(comp1);
			dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
			dev->play_dma_data.dt.fifo_size = dev->fifo_th * 2 *
				(fifo_width[idx2]) >> 8;
			dev->play_dma_data.dt.maxburst = 16;
		}
		if (COMP1_RX_ENABLED(comp1)) {
			idx2 = COMP2_RX_WORDSIZE_0(comp2);
			dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
			dev->capture_dma_data.dt.fifo_size = dev->fifo_th * 2 *
				(fifo_width[idx2] >> 8);
			dev->capture_dma_data.dt.maxburst = 16;
		}
	} else {
		/* Set DMA slaves info */
		dev->play_dma_data.pd.data = pdata->play_dma_data;
		dev->capture_dma_data.pd.data = pdata->capture_dma_data;
		dev->play_dma_data.pd.addr = res->start + I2S_TXDMA;
		dev->capture_dma_data.pd.addr = res->start + I2S_RXDMA;
		dev->play_dma_data.pd.max_burst = 16;
		dev->capture_dma_data.pd.max_burst = 16;
		dev->play_dma_data.pd.addr_width = bus_widths[idx];
		dev->capture_dma_data.pd.addr_width = bus_widths[idx];
		dev->play_dma_data.pd.filter = pdata->filter;
		dev->capture_dma_data.pd.filter = pdata->filter;
	}

	return 0;
}

static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev,
				   struct snd_soc_dai_driver *dw_i2s_dai,
				   struct resource *res)
{
	u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1);
	u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2);
	u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
	u32 idx2;
	int ret;

	ret = dw_configure_dai(dev, dw_i2s_dai, SNDRV_PCM_RATE_8000_192000);
	if (ret < 0)
		return ret;

	if (COMP1_TX_ENABLED(comp1)) {
		idx2 = COMP1_TX_WORDSIZE_0(comp1);

		dev->capability |= DWC_I2S_PLAY;
		dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
		dev->play_dma_data.dt.fifo_size = fifo_depth *
			(fifo_width[idx2]) >> 8;
		dev->play_dma_data.dt.maxburst = 16;
	}
	if (COMP1_RX_ENABLED(comp1)) {
		idx2 = COMP2_RX_WORDSIZE_0(comp2);

		dev->capability |= DWC_I2S_RECORD;
		dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
		dev->capture_dma_data.dt.fifo_size = fifo_depth *
			(fifo_width[idx2] >> 8);
		dev->capture_dma_data.dt.maxburst = 16;
	}

	return 0;

}

#ifdef CONFIG_OF
/* clocks initialization with master mode on JH7110 SoC */
static int jh7110_i2s_crg_master_init(struct dw_i2s_dev *dev)
{
	static struct clk_bulk_data clks[] = {
		{ .id = "mclk" },
		{ .id = "mclk_ext" },
		{ .id = "mclk_inner" },
		{ .id = "apb" },
		{ .id = "i2sclk" },
	};
	struct reset_control *resets = devm_reset_control_array_get_exclusive(dev->dev);
	int ret;
	struct clk *pclk;
	struct clk *bclk_mst;
	struct clk *mclk;
	struct clk *mclk_ext;
	struct clk *mclk_inner;

	if (IS_ERR(resets))
		return dev_err_probe(dev->dev, PTR_ERR(resets), "failed to get i2s resets\n");

	ret = clk_bulk_get(dev->dev, ARRAY_SIZE(clks), clks);
	if (ret)
		return dev_err_probe(dev->dev, ret, "failed to get i2s clocks\n");

	mclk = clks[0].clk;
	mclk_ext = clks[1].clk;
	mclk_inner = clks[2].clk;
	pclk = clks[3].clk;
	bclk_mst = clks[4].clk;

	ret = clk_prepare_enable(pclk);
	if (ret)
		goto exit;

	/* Use inner mclk first and avoid uninitialized gpio for external mclk */
	ret = clk_set_parent(mclk, mclk_inner);
	if (ret)
		goto err_dis_pclk;

	ret = clk_prepare_enable(bclk_mst);
	if (ret)
		goto err_dis_pclk;

	/* deassert resets before set clock parent */
	ret = reset_control_deassert(resets);
	if (ret)
		goto err_dis_all;

	/* external clock (12.288MHz) for Audio */
	ret = clk_set_parent(mclk, mclk_ext);
	if (ret)
		goto err_dis_all;

	/* i2sclk will be got and enabled repeatedly later and should be disabled now. */
	clk_disable_unprepare(bclk_mst);
	clk_bulk_put(ARRAY_SIZE(clks), clks);
	dev->is_jh7110 = true;

	return 0;

err_dis_all:
	clk_disable_unprepare(bclk_mst);
err_dis_pclk:
	clk_disable_unprepare(pclk);
exit:
	clk_bulk_put(ARRAY_SIZE(clks), clks);
	return ret;
}

/* clocks initialization with slave mode on JH7110 SoC */
static int jh7110_i2s_crg_slave_init(struct dw_i2s_dev *dev)
{
	static struct clk_bulk_data clks[] = {
		{ .id = "mclk" },
		{ .id = "mclk_ext" },
		{ .id = "apb" },
		{ .id = "bclk_ext" },
		{ .id = "lrck_ext" },
		{ .id = "bclk" },
		{ .id = "lrck" },
		{ .id = "mclk_inner" },
		{ .id = "i2sclk" },
	};
	struct reset_control *resets = devm_reset_control_array_get_exclusive(dev->dev);
	int ret;
	struct clk *pclk;
	struct clk *bclk_mst;
	struct clk *bclk_ext;
	struct clk *lrck_ext;
	struct clk *bclk;
	struct clk *lrck;
	struct clk *mclk;
	struct clk *mclk_ext;
	struct clk *mclk_inner;

	if (IS_ERR(resets))
		return dev_err_probe(dev->dev, PTR_ERR(resets), "failed to get i2s resets\n");

	ret = clk_bulk_get(dev->dev, ARRAY_SIZE(clks), clks);
	if (ret)
		return dev_err_probe(dev->dev, ret, "failed to get i2s clocks\n");

	mclk = clks[0].clk;
	mclk_ext = clks[1].clk;
	pclk = clks[2].clk;
	bclk_ext = clks[3].clk;
	lrck_ext = clks[4].clk;
	bclk = clks[5].clk;
	lrck = clks[6].clk;
	mclk_inner = clks[7].clk;
	bclk_mst = clks[8].clk;

	ret = clk_prepare_enable(pclk);
	if (ret)
		goto exit;

	ret = clk_set_parent(mclk, mclk_inner);
	if (ret)
		goto err_dis_pclk;

	ret = clk_prepare_enable(bclk_mst);
	if (ret)
		goto err_dis_pclk;

	ret = reset_control_deassert(resets);
	if (ret)
		goto err_dis_all;

	/* The sources of BCLK and LRCK are the external codec. */
	ret = clk_set_parent(bclk, bclk_ext);
	if (ret)
		goto err_dis_all;

	ret = clk_set_parent(lrck, lrck_ext);
	if (ret)
		goto err_dis_all;

	ret = clk_set_parent(mclk, mclk_ext);
	if (ret)
		goto err_dis_all;

	/* The i2sclk will be got and enabled repeatedly later and should be disabled now. */
	clk_disable_unprepare(bclk_mst);
	clk_bulk_put(ARRAY_SIZE(clks), clks);
	dev->is_jh7110 = true;

	return 0;

err_dis_all:
	clk_disable_unprepare(bclk_mst);
err_dis_pclk:
	clk_disable_unprepare(pclk);
exit:
	clk_bulk_put(ARRAY_SIZE(clks), clks);
	return ret;
}

/* Special syscon initialization about RX channel with slave mode on JH7110 SoC */
static int jh7110_i2srx_crg_init(struct dw_i2s_dev *dev)
{
	struct regmap *regmap;
	unsigned int args[2];

	regmap = syscon_regmap_lookup_by_phandle_args(dev->dev->of_node,
						      "starfive,syscon",
						      2, args);
	if (IS_ERR(regmap))
		return dev_err_probe(dev->dev, PTR_ERR(regmap), "getting the regmap failed\n");

	/* Enable I2Srx with syscon register, args[0]: offset, args[1]: mask */
	regmap_update_bits(regmap, args[0], args[1], args[1]);

	return jh7110_i2s_crg_slave_init(dev);
}

static int jh7110_i2stx0_clk_cfg(struct i2s_clk_config_data *config)
{
	struct dw_i2s_dev *dev = container_of(config, struct dw_i2s_dev, config);
	u32 bclk_rate = config->sample_rate * 64;

	return clk_set_rate(dev->clk, bclk_rate);
}
#endif /* CONFIG_OF */

static int dw_i2s_probe(struct platform_device *pdev)
{
	const struct i2s_platform_data *pdata = pdev->dev.platform_data;
	struct dw_i2s_dev *dev;
	struct resource *res;
	int ret, irq;
	struct snd_soc_dai_driver *dw_i2s_dai;
	const char *clk_id;

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

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

	dw_i2s_dai->ops = &dw_i2s_dai_ops;

	dev->i2s_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(dev->i2s_base))
		return PTR_ERR(dev->i2s_base);

	dev->dev = &pdev->dev;
	dev->is_jh7110 = false;
	if (pdata) {
		if (pdata->i2s_pd_init) {
			ret = pdata->i2s_pd_init(dev);
			if (ret)
				return ret;
		}
	}

	if (!dev->is_jh7110) {
		dev->reset = devm_reset_control_array_get_optional_shared(&pdev->dev);
		if (IS_ERR(dev->reset))
			return PTR_ERR(dev->reset);

		ret = reset_control_deassert(dev->reset);
		if (ret)
			return ret;
	}

	irq = platform_get_irq_optional(pdev, 0);
	if (irq >= 0) {
		ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
				pdev->name, dev);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to request irq\n");
			goto err_assert_reset;
		}
	}

	dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
	dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
	if (pdata) {
		dev->capability = pdata->cap;
		clk_id = NULL;
		dev->quirks = pdata->quirks;
		if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) {
			dev->i2s_reg_comp1 = pdata->i2s_reg_comp1;
			dev->i2s_reg_comp2 = pdata->i2s_reg_comp2;
		}
		ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
	} else {
		clk_id = "i2sclk";
		ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
	}
	if (ret < 0)
		goto err_assert_reset;

	if (dev->capability & DW_I2S_MASTER) {
		if (pdata) {
			dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
			if (!dev->i2s_clk_cfg) {
				dev_err(&pdev->dev, "no clock configure method\n");
				ret = -ENODEV;
				goto err_assert_reset;
			}
		}
		dev->clk = devm_clk_get_enabled(&pdev->dev, clk_id);

		if (IS_ERR(dev->clk)) {
			ret = PTR_ERR(dev->clk);
			goto err_assert_reset;
		}
	}

	dev_set_drvdata(&pdev->dev, dev);
	ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component,
					 dw_i2s_dai, 1);
	if (ret != 0) {
		dev_err(&pdev->dev, "not able to register dai\n");
		goto err_assert_reset;
	}

	if (!pdata || dev->is_jh7110) {
		if (irq >= 0) {
			ret = dw_pcm_register(pdev);
			dev->use_pio = true;
			dev->l_reg = LRBR_LTHR(0);
			dev->r_reg = RRBR_RTHR(0);
		} else {
			ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
					0);
			dev->use_pio = false;
		}

		if (ret) {
			dev_err(&pdev->dev, "could not register pcm: %d\n",
					ret);
			goto err_assert_reset;
		}
	}

	pm_runtime_enable(&pdev->dev);
	return 0;

err_assert_reset:
	reset_control_assert(dev->reset);
	return ret;
}

static void dw_i2s_remove(struct platform_device *pdev)
{
	struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);

	reset_control_assert(dev->reset);
	pm_runtime_disable(&pdev->dev);
}

#ifdef CONFIG_OF
static const struct i2s_platform_data jh7110_i2stx0_data = {
	.cap = DWC_I2S_PLAY | DW_I2S_MASTER,
	.channel = TWO_CHANNEL_SUPPORT,
	.snd_fmts = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
	.snd_rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
	.i2s_clk_cfg = jh7110_i2stx0_clk_cfg,
	.i2s_pd_init = jh7110_i2s_crg_master_init,
};

static const struct i2s_platform_data jh7110_i2stx1_data = {
	.cap = DWC_I2S_PLAY | DW_I2S_SLAVE,
	.channel = TWO_CHANNEL_SUPPORT,
	.snd_fmts = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
	.snd_rates = SNDRV_PCM_RATE_8000_192000,
	.i2s_pd_init = jh7110_i2s_crg_slave_init,
};

static const struct i2s_platform_data jh7110_i2srx_data = {
	.cap = DWC_I2S_RECORD | DW_I2S_SLAVE,
	.channel = TWO_CHANNEL_SUPPORT,
	.snd_fmts = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
	.snd_rates = SNDRV_PCM_RATE_8000_192000,
	.i2s_pd_init = jh7110_i2srx_crg_init,
};

static const struct of_device_id dw_i2s_of_match[] = {
	{ .compatible = "snps,designware-i2s",	 },
	{ .compatible = "starfive,jh7110-i2stx0", .data = &jh7110_i2stx0_data, },
	{ .compatible = "starfive,jh7110-i2stx1", .data = &jh7110_i2stx1_data,},
	{ .compatible = "starfive,jh7110-i2srx", .data = &jh7110_i2srx_data,},
	{},
};

MODULE_DEVICE_TABLE(of, dw_i2s_of_match);
#endif

static const struct dev_pm_ops dwc_pm_ops = {
	SET_RUNTIME_PM_OPS(dw_i2s_runtime_suspend, dw_i2s_runtime_resume, NULL)
};

static struct platform_driver dw_i2s_driver = {
	.probe		= dw_i2s_probe,
	.remove		= dw_i2s_remove,
	.driver		= {
		.name	= "designware-i2s",
		.of_match_table = of_match_ptr(dw_i2s_of_match),
		.pm = &dwc_pm_ops,
	},
};

module_platform_driver(dw_i2s_driver);

MODULE_AUTHOR("Rajeev Kumar <rajeevkumar.linux@gmail.com>");
MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:designware_i2s");
