// SPDX-License-Identifier: GPL-2.0-only
//
// Copyright (C) 2020 Intel Corporation.
//
// Intel KeemBay Platform driver.
//

#include <linux/bitrev.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "kmb_platform.h"

#define PERIODS_MIN		2
#define PERIODS_MAX		48
#define PERIOD_BYTES_MIN	4096
#define BUFFER_BYTES_MAX	(PERIODS_MAX * PERIOD_BYTES_MIN)
#define TDM_OPERATION		5
#define I2S_OPERATION		0
#define DATA_WIDTH_CONFIG_BIT	6
#define TDM_CHANNEL_CONFIG_BIT	3

static const struct snd_pcm_hardware kmb_pcm_hardware = {
	.info = SNDRV_PCM_INFO_INTERLEAVED |
		SNDRV_PCM_INFO_MMAP |
		SNDRV_PCM_INFO_MMAP_VALID |
		SNDRV_PCM_INFO_BATCH |
		SNDRV_PCM_INFO_BLOCK_TRANSFER,
	.rates = SNDRV_PCM_RATE_8000 |
		 SNDRV_PCM_RATE_16000 |
		 SNDRV_PCM_RATE_48000,
	.rate_min = 8000,
	.rate_max = 48000,
	.formats = SNDRV_PCM_FMTBIT_S16_LE |
		   SNDRV_PCM_FMTBIT_S24_LE |
		   SNDRV_PCM_FMTBIT_S32_LE |
		   SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
	.channels_min = 2,
	.channels_max = 2,
	.buffer_bytes_max = BUFFER_BYTES_MAX,
	.period_bytes_min = PERIOD_BYTES_MIN,
	.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
	.periods_min = PERIODS_MIN,
	.periods_max = PERIODS_MAX,
	.fifo_size = 16,
};

/*
 * Convert to ADV7511 HDMI hardware format.
 * ADV7511 HDMI chip need parity bit replaced by block start bit and
 * with the preamble bits left out.
 * ALSA IEC958 subframe format:
 * bit 0-3  = preamble (0x8 = block start)
 *     4-7  = AUX (=0)
 *     8-27 = audio data (without AUX if 24bit sample)
 *     28   = validity
 *     29   = user data
 *     30   = channel status
 *     31   = parity
 *
 * ADV7511 IEC958 subframe format:
 * bit 0-23  = audio data
 *     24    = validity
 *     25    = user data
 *     26    = channel status
 *     27    = block start
 *     28-31 = 0
 * MSB to LSB bit reverse by software as hardware not supporting it.
 */
static void hdmi_reformat_iec958(struct snd_pcm_runtime *runtime,
				 struct kmb_i2s_info *kmb_i2s,
				 unsigned int tx_ptr)
{
	u32(*buf)[2] = (void *)runtime->dma_area;
	unsigned long temp;
	u32 i, j, sample;

	for (i = 0; i < kmb_i2s->fifo_th; i++) {
		j = 0;
		do {
			temp = buf[tx_ptr][j];
			/* Replace parity with block start*/
			assign_bit(31, &temp, (BIT(3) & temp));
			sample = bitrev32(temp);
			buf[tx_ptr][j] = sample << 4;
			j++;
		} while (j < 2);
		tx_ptr++;
	}
}

static unsigned int kmb_pcm_tx_fn(struct kmb_i2s_info *kmb_i2s,
				  struct snd_pcm_runtime *runtime,
				  unsigned int tx_ptr, bool *period_elapsed)
{
	unsigned int period_pos = tx_ptr % runtime->period_size;
	void __iomem *i2s_base = kmb_i2s->i2s_base;
	void *buf = runtime->dma_area;
	int i;

	if (kmb_i2s->iec958_fmt)
		hdmi_reformat_iec958(runtime, kmb_i2s, tx_ptr);

	/* KMB i2s uses two separate L/R FIFO */
	for (i = 0; i < kmb_i2s->fifo_th; i++) {
		if (kmb_i2s->config.data_width == 16) {
			writel(((u16(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0));
			writel(((u16(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0));
		} else {
			writel(((u32(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0));
			writel(((u32(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0));
		}

		period_pos++;

		if (++tx_ptr >= runtime->buffer_size)
			tx_ptr = 0;
	}

	*period_elapsed = period_pos >= runtime->period_size;

	return tx_ptr;
}

static unsigned int kmb_pcm_rx_fn(struct kmb_i2s_info *kmb_i2s,
				  struct snd_pcm_runtime *runtime,
				  unsigned int rx_ptr, bool *period_elapsed)
{
	unsigned int period_pos = rx_ptr % runtime->period_size;
	void __iomem *i2s_base = kmb_i2s->i2s_base;
	int chan = kmb_i2s->config.chan_nr;
	void *buf = runtime->dma_area;
	int i, j;

	/* KMB i2s uses two separate L/R FIFO */
	for (i = 0; i < kmb_i2s->fifo_th; i++) {
		for (j = 0; j < chan / 2; j++) {
			if (kmb_i2s->config.data_width == 16) {
				((u16 *)buf)[rx_ptr * chan + (j * 2)] =
						readl(i2s_base + LRBR_LTHR(j));
				((u16 *)buf)[rx_ptr * chan + ((j * 2) + 1)] =
						readl(i2s_base + RRBR_RTHR(j));
			} else {
				((u32 *)buf)[rx_ptr * chan + (j * 2)] =
						readl(i2s_base + LRBR_LTHR(j));
				((u32 *)buf)[rx_ptr * chan + ((j * 2) + 1)] =
						readl(i2s_base + RRBR_RTHR(j));
			}
		}
		period_pos++;

		if (++rx_ptr >= runtime->buffer_size)
			rx_ptr = 0;
	}

	*period_elapsed = period_pos >= runtime->period_size;

	return rx_ptr;
}

static inline void kmb_i2s_disable_channels(struct kmb_i2s_info *kmb_i2s,
					    u32 stream)
{
	u32 i;

	/* Disable all channels regardless of configuration*/
	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		for (i = 0; i < MAX_ISR; i++)
			writel(0, kmb_i2s->i2s_base + TER(i));
	} else {
		for (i = 0; i < MAX_ISR; i++)
			writel(0, kmb_i2s->i2s_base + RER(i));
	}
}

static inline void kmb_i2s_clear_irqs(struct kmb_i2s_info *kmb_i2s, u32 stream)
{
	struct i2s_clk_config_data *config = &kmb_i2s->config;
	u32 i;

	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		for (i = 0; i < config->chan_nr / 2; i++)
			readl(kmb_i2s->i2s_base + TOR(i));
	} else {
		for (i = 0; i < config->chan_nr / 2; i++)
			readl(kmb_i2s->i2s_base + ROR(i));
	}
}

static inline void kmb_i2s_irq_trigger(struct kmb_i2s_info *kmb_i2s,
				       u32 stream, int chan_nr, bool trigger)
{
	u32 i, irq;
	u32 flag;

	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
		flag = TX_INT_FLAG;
	else
		flag = RX_INT_FLAG;

	for (i = 0; i < chan_nr / 2; i++) {
		irq = readl(kmb_i2s->i2s_base + IMR(i));

		if (trigger)
			irq = irq & ~flag;
		else
			irq = irq | flag;

		writel(irq, kmb_i2s->i2s_base + IMR(i));
	}
}

static void kmb_pcm_operation(struct kmb_i2s_info *kmb_i2s, bool playback)
{
	struct snd_pcm_substream *substream;
	bool period_elapsed;
	unsigned int new_ptr;
	unsigned int ptr;

	if (playback)
		substream = kmb_i2s->tx_substream;
	else
		substream = kmb_i2s->rx_substream;

	if (!substream || !snd_pcm_running(substream))
		return;

	if (playback) {
		ptr = kmb_i2s->tx_ptr;
		new_ptr = kmb_pcm_tx_fn(kmb_i2s, substream->runtime,
					ptr, &period_elapsed);
		cmpxchg(&kmb_i2s->tx_ptr, ptr, new_ptr);
	} else {
		ptr = kmb_i2s->rx_ptr;
		new_ptr = kmb_pcm_rx_fn(kmb_i2s, substream->runtime,
					ptr, &period_elapsed);
		cmpxchg(&kmb_i2s->rx_ptr, ptr, new_ptr);
	}

	if (period_elapsed)
		snd_pcm_period_elapsed(substream);
}

static int kmb_pcm_open(struct snd_soc_component *component,
			struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct kmb_i2s_info *kmb_i2s;

	kmb_i2s = snd_soc_dai_get_drvdata(snd_soc_rtd_to_cpu(rtd, 0));
	snd_soc_set_runtime_hwparams(substream, &kmb_pcm_hardware);
	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
	runtime->private_data = kmb_i2s;

	return 0;
}

static int kmb_pcm_trigger(struct snd_soc_component *component,
			   struct snd_pcm_substream *substream, int cmd)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct kmb_i2s_info *kmb_i2s = runtime->private_data;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			kmb_i2s->tx_ptr = 0;
			kmb_i2s->tx_substream = substream;
		} else {
			kmb_i2s->rx_ptr = 0;
			kmb_i2s->rx_substream = substream;
		}
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			kmb_i2s->tx_substream = NULL;
		else
			kmb_i2s->rx_substream = NULL;
		kmb_i2s->iec958_fmt = false;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static irqreturn_t kmb_i2s_irq_handler(int irq, void *dev_id)
{
	struct kmb_i2s_info *kmb_i2s = dev_id;
	struct i2s_clk_config_data *config = &kmb_i2s->config;
	irqreturn_t ret = IRQ_NONE;
	u32 tx_enabled = 0;
	u32 isr[4];
	int i;

	for (i = 0; i < config->chan_nr / 2; i++)
		isr[i] = readl(kmb_i2s->i2s_base + ISR(i));

	kmb_i2s_clear_irqs(kmb_i2s, SNDRV_PCM_STREAM_PLAYBACK);
	kmb_i2s_clear_irqs(kmb_i2s, SNDRV_PCM_STREAM_CAPTURE);
	/* Only check TX interrupt if TX is active */
	tx_enabled = readl(kmb_i2s->i2s_base + ITER);

	/*
	 * Data available. Retrieve samples from FIFO
	 */

	/*
	 * 8 channel audio will have isr[0..2] triggered,
	 * reading the specific isr based on the audio configuration,
	 * to avoid reading the buffers too early.
	 */
	switch (config->chan_nr) {
	case 2:
		if (isr[0] & ISR_RXDA)
			kmb_pcm_operation(kmb_i2s, false);
		ret = IRQ_HANDLED;
		break;
	case 4:
		if (isr[1] & ISR_RXDA)
			kmb_pcm_operation(kmb_i2s, false);
		ret = IRQ_HANDLED;
		break;
	case 8:
		if (isr[3] & ISR_RXDA)
			kmb_pcm_operation(kmb_i2s, false);
		ret = IRQ_HANDLED;
		break;
	}

	for (i = 0; i < config->chan_nr / 2; i++) {
		/*
		 * Check if TX fifo is empty. If empty fill FIFO with samples
		 */
		if ((isr[i] & ISR_TXFE) && tx_enabled) {
			kmb_pcm_operation(kmb_i2s, true);
			ret = IRQ_HANDLED;
		}

		/* Error Handling: TX */
		if (isr[i] & ISR_TXFO) {
			dev_dbg(kmb_i2s->dev, "TX overrun (ch_id=%d)\n", i);
			ret = IRQ_HANDLED;
		}
		/* Error Handling: RX */
		if (isr[i] & ISR_RXFO) {
			dev_dbg(kmb_i2s->dev, "RX overrun (ch_id=%d)\n", i);
			ret = IRQ_HANDLED;
		}
	}

	return ret;
}

static int kmb_platform_pcm_new(struct snd_soc_component *component,
				struct snd_soc_pcm_runtime *soc_runtime)
{
	size_t size = kmb_pcm_hardware.buffer_bytes_max;
	/* Use SNDRV_DMA_TYPE_CONTINUOUS as KMB doesn't use PCI sg buffer */
	snd_pcm_set_managed_buffer_all(soc_runtime->pcm,
				       SNDRV_DMA_TYPE_CONTINUOUS,
				       NULL, size, size);
	return 0;
}

static snd_pcm_uframes_t kmb_pcm_pointer(struct snd_soc_component *component,
					 struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct kmb_i2s_info *kmb_i2s = runtime->private_data;
	snd_pcm_uframes_t pos;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		pos = kmb_i2s->tx_ptr;
	else
		pos = kmb_i2s->rx_ptr;

	return pos < runtime->buffer_size ? pos : 0;
}

static const struct snd_soc_component_driver kmb_component = {
	.name			= "kmb",
	.pcm_construct		= kmb_platform_pcm_new,
	.open			= kmb_pcm_open,
	.trigger		= kmb_pcm_trigger,
	.pointer		= kmb_pcm_pointer,
	.legacy_dai_naming	= 1,
};

static const struct snd_soc_component_driver kmb_component_dma = {
	.name			= "kmb",
	.legacy_dai_naming	= 1,
};

static int kmb_probe(struct snd_soc_dai *cpu_dai)
{
	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);

	if (kmb_i2s->use_pio)
		return 0;

	snd_soc_dai_init_dma_data(cpu_dai, &kmb_i2s->play_dma_data,
				  &kmb_i2s->capture_dma_data);

	return 0;
}

static inline void kmb_i2s_enable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream)
{
	u32 dma_reg;

	dma_reg = readl(kmb_i2s->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;

	writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR);
}

static inline void kmb_i2s_disable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream)
{
	u32 dma_reg;

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

static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s,
			  struct snd_pcm_substream *substream)
{
	struct i2s_clk_config_data *config = &kmb_i2s->config;

	/* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
	writel(1, kmb_i2s->i2s_base + IER);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		writel(1, kmb_i2s->i2s_base + ITER);
	else
		writel(1, kmb_i2s->i2s_base + IRER);

	if (kmb_i2s->use_pio)
		kmb_i2s_irq_trigger(kmb_i2s, substream->stream,
				    config->chan_nr, true);
	else
		kmb_i2s_enable_dma(kmb_i2s, substream->stream);

	if (kmb_i2s->clock_provider)
		writel(1, kmb_i2s->i2s_base + CER);
	else
		writel(0, kmb_i2s->i2s_base + CER);
}

static void kmb_i2s_stop(struct kmb_i2s_info *kmb_i2s,
			 struct snd_pcm_substream *substream)
{
	/* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
	kmb_i2s_clear_irqs(kmb_i2s, substream->stream);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		writel(0, kmb_i2s->i2s_base + ITER);
	else
		writel(0, kmb_i2s->i2s_base + IRER);

	kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false);

	if (!kmb_i2s->active) {
		writel(0, kmb_i2s->i2s_base + CER);
		writel(0, kmb_i2s->i2s_base + IER);
	}
}

static void kmb_disable_clk(void *clk)
{
	clk_disable_unprepare(clk);
}

static int kmb_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
	int ret;

	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_BC_FC:
		kmb_i2s->clock_provider = false;
		ret = 0;
		break;
	case SND_SOC_DAIFMT_BP_FP:
		writel(CLOCK_PROVIDER_MODE, kmb_i2s->pss_base + I2S_GEN_CFG_0);

		ret = clk_prepare_enable(kmb_i2s->clk_i2s);
		if (ret < 0)
			return ret;

		ret = devm_add_action_or_reset(kmb_i2s->dev, kmb_disable_clk,
					       kmb_i2s->clk_i2s);
		if (ret)
			return ret;

		kmb_i2s->clock_provider = true;
		break;
	default:
		return -EINVAL;
	}

	return ret;
}

static int kmb_dai_trigger(struct snd_pcm_substream *substream,
			   int cmd, struct snd_soc_dai *cpu_dai)
{
	struct kmb_i2s_info *kmb_i2s  = snd_soc_dai_get_drvdata(cpu_dai);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		/* Keep track of i2s activity before turn off
		 * the i2s interface
		 */
		kmb_i2s->active++;
		kmb_i2s_start(kmb_i2s, substream);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		kmb_i2s->active--;
		if (kmb_i2s->use_pio)
			kmb_i2s_stop(kmb_i2s, substream);
		break;
	default:
		return  -EINVAL;
	}

	return 0;
}

static void kmb_i2s_config(struct kmb_i2s_info *kmb_i2s, int stream)
{
	struct i2s_clk_config_data *config = &kmb_i2s->config;
	u32 ch_reg;

	kmb_i2s_disable_channels(kmb_i2s, stream);

	for (ch_reg = 0; ch_reg < config->chan_nr / 2; ch_reg++) {
		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
			writel(kmb_i2s->xfer_resolution,
			       kmb_i2s->i2s_base + TCR(ch_reg));

			writel(kmb_i2s->fifo_th - 1,
			       kmb_i2s->i2s_base + TFCR(ch_reg));

			writel(1, kmb_i2s->i2s_base + TER(ch_reg));
		} else {
			writel(kmb_i2s->xfer_resolution,
			       kmb_i2s->i2s_base + RCR(ch_reg));

			writel(kmb_i2s->fifo_th - 1,
			       kmb_i2s->i2s_base + RFCR(ch_reg));

			writel(1, kmb_i2s->i2s_base + RER(ch_reg));
		}
	}
}

static int kmb_dai_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *hw_params,
			     struct snd_soc_dai *cpu_dai)
{
	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
	struct i2s_clk_config_data *config = &kmb_i2s->config;
	u32 write_val;
	int ret;

	switch (params_format(hw_params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		config->data_width = 16;
		kmb_i2s->ccr = 0x00;
		kmb_i2s->xfer_resolution = 0x02;
		kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
		kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		config->data_width = 32;
		kmb_i2s->ccr = 0x14;
		kmb_i2s->xfer_resolution = 0x05;
		kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
		kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
		break;
	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
		kmb_i2s->iec958_fmt = true;
		fallthrough;
	case SNDRV_PCM_FORMAT_S32_LE:
		config->data_width = 32;
		kmb_i2s->ccr = 0x10;
		kmb_i2s->xfer_resolution = 0x05;
		kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
		kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
		break;
	default:
		dev_err(kmb_i2s->dev, "kmb: unsupported PCM fmt");
		return -EINVAL;
	}

	config->chan_nr = params_channels(hw_params);

	switch (config->chan_nr) {
	case 8:
	case 4:
		/*
		 * Platform is not capable of providing clocks for
		 * multi channel audio
		 */
		if (kmb_i2s->clock_provider)
			return -EINVAL;

		write_val = ((config->chan_nr / 2) << TDM_CHANNEL_CONFIG_BIT) |
				(config->data_width << DATA_WIDTH_CONFIG_BIT) |
				TDM_OPERATION;

		writel(write_val, kmb_i2s->pss_base + I2S_GEN_CFG_0);
		break;
	case 2:
		/*
		 * Platform is only capable of providing clocks need for
		 * 2 channel master mode
		 */
		if (!(kmb_i2s->clock_provider))
			return -EINVAL;

		write_val = ((config->chan_nr / 2) << TDM_CHANNEL_CONFIG_BIT) |
				(config->data_width << DATA_WIDTH_CONFIG_BIT) |
				CLOCK_PROVIDER_MODE | I2S_OPERATION;

		writel(write_val, kmb_i2s->pss_base + I2S_GEN_CFG_0);
		break;
	default:
		dev_dbg(kmb_i2s->dev, "channel not supported\n");
		return -EINVAL;
	}

	kmb_i2s_config(kmb_i2s, substream->stream);

	writel(kmb_i2s->ccr, kmb_i2s->i2s_base + CCR);

	config->sample_rate = params_rate(hw_params);

	if (kmb_i2s->clock_provider) {
		/* Only 2 ch supported in Master mode */
		u32 bitclk = config->sample_rate * config->data_width * 2;

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

	return 0;
}

static int kmb_dai_prepare(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *cpu_dai)
{
	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		writel(1, kmb_i2s->i2s_base + TXFFR);
	else
		writel(1, kmb_i2s->i2s_base + RXFFR);

	return 0;
}

static int kmb_dai_startup(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *cpu_dai)
{
	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
	struct snd_dmaengine_dai_dma_data *dma_data;

	if (kmb_i2s->use_pio)
		return 0;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dma_data = &kmb_i2s->play_dma_data;
	else
		dma_data = &kmb_i2s->capture_dma_data;

	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);

	return 0;
}

static int kmb_dai_hw_free(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *cpu_dai)
{
	struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai);
	/* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */
	if (kmb_i2s->use_pio)
		kmb_i2s_clear_irqs(kmb_i2s, substream->stream);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		writel(0, kmb_i2s->i2s_base + ITER);
	else
		writel(0, kmb_i2s->i2s_base + IRER);

	if (kmb_i2s->use_pio)
		kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false);
	else
		kmb_i2s_disable_dma(kmb_i2s, substream->stream);

	if (!kmb_i2s->active) {
		writel(0, kmb_i2s->i2s_base + CER);
		writel(0, kmb_i2s->i2s_base + IER);
	}

	return 0;
}

static const struct snd_soc_dai_ops kmb_dai_ops = {
	.probe		= kmb_probe,
	.startup	= kmb_dai_startup,
	.trigger	= kmb_dai_trigger,
	.hw_params	= kmb_dai_hw_params,
	.hw_free	= kmb_dai_hw_free,
	.prepare	= kmb_dai_prepare,
	.set_fmt	= kmb_set_dai_fmt,
};

static struct snd_soc_dai_driver intel_kmb_hdmi_dai[] = {
	{
		.name = "intel_kmb_hdmi_i2s",
		.playback = {
			.channels_min = 2,
			.channels_max = 2,
			.rates = SNDRV_PCM_RATE_48000,
			.rate_min = 48000,
			.rate_max = 48000,
			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
				    SNDRV_PCM_FMTBIT_S24_LE |
				    SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE),
		},
		.ops = &kmb_dai_ops,
	},
};

static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = {
	{
		.name = "intel_kmb_i2s",
		.playback = {
			.channels_min = 2,
			.channels_max = 2,
			.rates = SNDRV_PCM_RATE_8000 |
				 SNDRV_PCM_RATE_16000 |
				 SNDRV_PCM_RATE_48000,
			.rate_min = 8000,
			.rate_max = 48000,
			.formats = (SNDRV_PCM_FMTBIT_S32_LE |
				    SNDRV_PCM_FMTBIT_S24_LE |
				    SNDRV_PCM_FMTBIT_S16_LE),
		},
		.capture = {
			.channels_min = 2,
			.channels_max = 2,
			.rates = SNDRV_PCM_RATE_8000 |
				 SNDRV_PCM_RATE_16000 |
				 SNDRV_PCM_RATE_48000,
			.rate_min = 8000,
			.rate_max = 48000,
			.formats = (SNDRV_PCM_FMTBIT_S32_LE |
				    SNDRV_PCM_FMTBIT_S24_LE |
				    SNDRV_PCM_FMTBIT_S16_LE),
		},
		.ops = &kmb_dai_ops,
	},
};

static struct snd_soc_dai_driver intel_kmb_tdm_dai[] = {
	{
		.name = "intel_kmb_tdm",
		.capture = {
			.channels_min = 4,
			.channels_max = 8,
			.rates = SNDRV_PCM_RATE_8000 |
				 SNDRV_PCM_RATE_16000 |
				 SNDRV_PCM_RATE_48000,
			.rate_min = 8000,
			.rate_max = 48000,
			.formats = (SNDRV_PCM_FMTBIT_S32_LE |
				    SNDRV_PCM_FMTBIT_S24_LE |
				    SNDRV_PCM_FMTBIT_S16_LE),
		},
		.ops = &kmb_dai_ops,
	},
};

static const struct of_device_id kmb_plat_of_match[] = {
	{ .compatible = "intel,keembay-i2s", .data = &intel_kmb_i2s_dai},
	{ .compatible = "intel,keembay-hdmi-i2s", .data = &intel_kmb_hdmi_dai},
	{ .compatible = "intel,keembay-tdm", .data = &intel_kmb_tdm_dai},
	{}
};

static int kmb_plat_dai_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_dai_driver *kmb_i2s_dai;
	struct device *dev = &pdev->dev;
	struct kmb_i2s_info *kmb_i2s;
	struct resource *res;
	int ret, irq;
	u32 comp1_reg;

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

	kmb_i2s_dai = (struct snd_soc_dai_driver *)device_get_match_data(&pdev->dev);

	/* Prepare the related clocks */
	kmb_i2s->clk_apb = devm_clk_get(dev, "apb_clk");
	if (IS_ERR(kmb_i2s->clk_apb)) {
		dev_err(dev, "Failed to get apb clock\n");
		return PTR_ERR(kmb_i2s->clk_apb);
	}

	ret = clk_prepare_enable(kmb_i2s->clk_apb);
	if (ret < 0)
		return ret;

	ret = devm_add_action_or_reset(dev, kmb_disable_clk, kmb_i2s->clk_apb);
	if (ret) {
		dev_err(dev, "Failed to add clk_apb reset action\n");
		return ret;
	}

	kmb_i2s->clk_i2s = devm_clk_get(dev, "osc");
	if (IS_ERR(kmb_i2s->clk_i2s)) {
		dev_err(dev, "Failed to get osc clock\n");
		return PTR_ERR(kmb_i2s->clk_i2s);
	}

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

	kmb_i2s->pss_base = devm_platform_ioremap_resource(pdev, 1);
	if (IS_ERR(kmb_i2s->pss_base))
		return PTR_ERR(kmb_i2s->pss_base);

	kmb_i2s->dev = &pdev->dev;

	comp1_reg = readl(kmb_i2s->i2s_base + I2S_COMP_PARAM_1);

	kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2;

	kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas"));

	if (kmb_i2s->use_pio) {
		irq = platform_get_irq_optional(pdev, 0);
		if (irq > 0) {
			ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0,
					       pdev->name, kmb_i2s);
			if (ret < 0) {
				dev_err(dev, "failed to request irq\n");
				return ret;
			}
		}
		ret = devm_snd_soc_register_component(dev, &kmb_component,
						      kmb_i2s_dai, 1);
	} else {
		kmb_i2s->play_dma_data.addr = res->start + I2S_TXDMA;
		kmb_i2s->capture_dma_data.addr = res->start + I2S_RXDMA;
		ret = snd_dmaengine_pcm_register(&pdev->dev,
						 NULL, 0);
		if (ret) {
			dev_err(&pdev->dev, "could not register dmaengine: %d\n",
				ret);
			return ret;
		}
		ret = devm_snd_soc_register_component(dev, &kmb_component_dma,
						      kmb_i2s_dai, 1);
	}

	if (ret) {
		dev_err(dev, "not able to register dai\n");
		return ret;
	}

	/* To ensure none of the channels are enabled at boot up */
	kmb_i2s_disable_channels(kmb_i2s, SNDRV_PCM_STREAM_PLAYBACK);
	kmb_i2s_disable_channels(kmb_i2s, SNDRV_PCM_STREAM_CAPTURE);

	dev_set_drvdata(dev, kmb_i2s);

	return ret;
}

static struct platform_driver kmb_plat_dai_driver = {
	.driver		= {
		.name		= "kmb-plat-dai",
		.of_match_table = kmb_plat_of_match,
	},
	.probe		= kmb_plat_dai_probe,
};

module_platform_driver(kmb_plat_dai_driver);

MODULE_DESCRIPTION("ASoC Intel KeemBay Platform driver");
MODULE_AUTHOR("Sia Jee Heng <jee.heng.sia@intel.com>");
MODULE_AUTHOR("Sit, Michael Wei Hong <michael.wei.hong.sit@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:kmb_platform");
