// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2012 Samsung Electronics
 * R. Chandrasekar <rcsekar@samsung.com>
 */

#include <dm.h>
#include <i2s.h>
#include <log.h>
#include <sound.h>
#include <time.h>
#include <asm/arch/clk.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/i2s-regs.h>
#include <asm/io.h>

#define FIC_TX2COUNT(x)		(((x) >>  24) & 0xf)
#define FIC_TX1COUNT(x)		(((x) >>  16) & 0xf)
#define FIC_TXCOUNT(x)		(((x) >>  8) & 0xf)
#define FIC_RXCOUNT(x)		(((x) >>  0) & 0xf)
#define FICS_TXCOUNT(x)		(((x) >>  8) & 0x7f)

#define TIMEOUT_I2S_TX		100	/* i2s transfer timeout */

/*
 * Sets the frame size for I2S LR clock
 *
 * @param i2s_reg	i2s register address
 * @param rfs		Frame Size
 */
static void i2s_set_lr_framesize(struct i2s_reg *i2s_reg, unsigned int rfs)
{
	unsigned int mod = readl(&i2s_reg->mod);

	mod &= ~MOD_RCLK_MASK;

	switch (rfs) {
	case 768:
		mod |= MOD_RCLK_768FS;
		break;
	case 512:
		mod |= MOD_RCLK_512FS;
		break;
	case 384:
		mod |= MOD_RCLK_384FS;
		break;
	default:
		mod |= MOD_RCLK_256FS;
		break;
	}

	writel(mod, &i2s_reg->mod);
}

/*
 * Sets the i2s transfer control
 *
 * @param i2s_reg	i2s register address
 * @param on		1 enable tx , 0 disable tx transfer
 */
static void i2s_txctrl(struct i2s_reg *i2s_reg, int on)
{
	unsigned int con = readl(&i2s_reg->con);
	unsigned int mod = readl(&i2s_reg->mod) & ~MOD_MASK;

	if (on) {
		con |= CON_ACTIVE;
		con &= ~CON_TXCH_PAUSE;
	} else {
		con |=  CON_TXCH_PAUSE;
		con &= ~CON_ACTIVE;
	}

	writel(mod, &i2s_reg->mod);
	writel(con, &i2s_reg->con);
}

/*
 * set the bit clock frame size (in multiples of LRCLK)
 *
 * @param i2s_reg	i2s register address
 * @param bfs		bit Frame Size
 */
static void i2s_set_bitclk_framesize(struct i2s_reg *i2s_reg, unsigned bfs)
{
	unsigned int mod = readl(&i2s_reg->mod);

	mod &= ~MOD_BCLK_MASK;

	switch (bfs) {
	case 48:
		mod |= MOD_BCLK_48FS;
		break;
	case 32:
		mod |= MOD_BCLK_32FS;
		break;
	case 24:
		mod |= MOD_BCLK_24FS;
		break;
	case 16:
		mod |= MOD_BCLK_16FS;
		break;
	default:
		return;
	}
	writel(mod, &i2s_reg->mod);
}

/*
 * flushes the i2stx fifo
 *
 * @param i2s_reg	i2s register address
 * @param flush		Tx fifo flush command (0x00 - do not flush
 *				0x80 - flush tx fifo)
 */
static void i2s_fifo(struct i2s_reg *i2s_reg, unsigned int flush)
{
	/* Flush the FIFO */
	setbits_le32(&i2s_reg->fic, flush);
	clrbits_le32(&i2s_reg->fic, flush);
}

/*
 * Set System Clock direction
 *
 * @param i2s_reg	i2s register address
 * @param dir		Clock direction
 *
 * Return:		int value 0 for success, -1 in case of error
 */
static int i2s_set_sysclk_dir(struct i2s_reg *i2s_reg, int dir)
{
	unsigned int mod = readl(&i2s_reg->mod);

	if (dir == SND_SOC_CLOCK_IN)
		mod |= MOD_CDCLKCON;
	else
		mod &= ~MOD_CDCLKCON;

	writel(mod, &i2s_reg->mod);

	return 0;
}

/*
 * Sets I2S Clcok format
 *
 * @param fmt		i2s clock properties
 * @param i2s_reg	i2s register address
 *
 * Return:		int value 0 for success, -1 in case of error
 */
static int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
{
	unsigned int mod = readl(&i2s_reg->mod);
	unsigned int tmp = 0;
	unsigned int ret = 0;

	/* Format is priority */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_RIGHT_J:
		tmp |= MOD_LR_RLOW;
		tmp |= MOD_SDF_MSB;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		tmp |= MOD_LR_RLOW;
		tmp |= MOD_SDF_LSB;
		break;
	case SND_SOC_DAIFMT_I2S:
		tmp |= MOD_SDF_IIS;
		break;
	default:
		debug("%s: Invalid format priority [0x%x]\n", __func__,
		      (fmt & SND_SOC_DAIFMT_FORMAT_MASK));
		return -ERANGE;
	}

	/*
	 * INV flag is relative to the FORMAT flag - if set it simply
	 * flips the polarity specified by the Standard
	 */
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_NB_IF:
		if (tmp & MOD_LR_RLOW)
			tmp &= ~MOD_LR_RLOW;
		else
			tmp |= MOD_LR_RLOW;
		break;
	default:
		debug("%s: Invalid clock ploarity input [0x%x]\n", __func__,
		      (fmt & SND_SOC_DAIFMT_INV_MASK));
		return -ERANGE;
	}

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		tmp |= MOD_SLAVE;
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
		/* Set default source clock in Master mode */
		ret = i2s_set_sysclk_dir(i2s_reg, SND_SOC_CLOCK_OUT);
		if (ret != 0) {
			debug("%s:set i2s clock direction failed\n", __func__);
			return ret;
		}
		break;
	default:
		debug("%s: Invalid master selection [0x%x]\n", __func__,
		      (fmt & SND_SOC_DAIFMT_MASTER_MASK));
		return -ERANGE;
	}

	mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE);
	mod |= tmp;
	writel(mod, &i2s_reg->mod);

	return 0;
}

/*
 * Sets the sample width in bits
 *
 * @param blc		samplewidth (size of sample in bits)
 * @param i2s_reg	i2s register address
 *
 * Return:		int value 0 for success, -1 in case of error
 */
static int i2s_set_samplesize(struct i2s_reg *i2s_reg, unsigned int blc)
{
	unsigned int mod = readl(&i2s_reg->mod);

	mod &= ~MOD_BLCP_MASK;
	mod &= ~MOD_BLC_MASK;

	switch (blc) {
	case 8:
		mod |= MOD_BLCP_8BIT;
		mod |= MOD_BLC_8BIT;
		break;
	case 16:
		mod |= MOD_BLCP_16BIT;
		mod |= MOD_BLC_16BIT;
		break;
	case 24:
		mod |= MOD_BLCP_24BIT;
		mod |= MOD_BLC_24BIT;
		break;
	default:
		debug("%s: Invalid sample size input [0x%x]\n",
		      __func__, blc);
		return -ERANGE;
	}
	writel(mod, &i2s_reg->mod);

	return 0;
}

int i2s_transfer_tx_data(struct i2s_uc_priv *pi2s_tx, void *data,
			 uint data_size)
{
	struct i2s_reg *i2s_reg = (struct i2s_reg *)pi2s_tx->base_address;
	u32 *ptr;
	int i;
	int start;

	if (data_size < FIFO_LENGTH) {
		debug("%s : Invalid data size\n", __func__);
		return -ENODATA; /* invalid pcm data size */
	}

	/* fill the tx buffer before stating the tx transmit */
	for (i = 0, ptr = data; i < FIFO_LENGTH; i++)
		writel(*ptr++, &i2s_reg->txd);

	data_size -= sizeof(*ptr) * FIFO_LENGTH;
	i2s_txctrl(i2s_reg, I2S_TX_ON);

	while (data_size > 0) {
		start = get_timer(0);
		if (!(CON_TXFIFO_FULL & (readl(&i2s_reg->con)))) {
			writel(*ptr++, &i2s_reg->txd);
			data_size -= sizeof(*ptr);
		} else {
			if (get_timer(start) > TIMEOUT_I2S_TX) {
				i2s_txctrl(i2s_reg, I2S_TX_OFF);
				debug("%s: I2S Transfer Timeout\n", __func__);
				return -ETIMEDOUT;
			}
		}
	}
	i2s_txctrl(i2s_reg, I2S_TX_OFF);

	return 0;
}

static int i2s_tx_init(struct i2s_uc_priv *pi2s_tx)
{
	int ret;
	struct i2s_reg *i2s_reg = (struct i2s_reg *)pi2s_tx->base_address;

	if (pi2s_tx->id == 0) {
		/* Initialize GPIO for I2S-0 */
		exynos_pinmux_config(PERIPH_ID_I2S0, 0);

		/* Set EPLL Clock */
		ret = set_epll_clk(pi2s_tx->samplingrate * pi2s_tx->rfs * 4);
	} else if (pi2s_tx->id == 1) {
		/* Initialize GPIO for I2S-1 */
		exynos_pinmux_config(PERIPH_ID_I2S1, 0);

		/* Set EPLL Clock */
		ret = set_epll_clk(pi2s_tx->audio_pll_clk);
	} else {
		debug("%s: unsupported i2s-%d bus\n", __func__, pi2s_tx->id);
		return -ERANGE;
	}

	if (ret) {
		debug("%s: epll clock set rate failed\n", __func__);
		return ret;
	}

	/* Select Clk Source for Audio 0 or 1 */
	ret = set_i2s_clk_source(pi2s_tx->id);
	if (ret) {
		debug("%s: unsupported clock for i2s-%d\n", __func__,
		      pi2s_tx->id);
		return ret;
	}

	if (pi2s_tx->id == 0) {
		/*Reset the i2s module */
		writel(CON_RESET, &i2s_reg->con);

		writel(MOD_OP_CLK | MOD_RCLKSRC, &i2s_reg->mod);
		/* set i2s prescaler */
		writel(PSREN | PSVAL, &i2s_reg->psr);
	} else {
		/* Set Prescaler to get MCLK */
		ret = set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
				(pi2s_tx->samplingrate * (pi2s_tx->rfs)),
				pi2s_tx->id);
	}
	if (ret) {
		debug("%s: unsupported prescalar for i2s-%d\n", __func__,
		      pi2s_tx->id);
		return ret;
	}

	/* Configure I2s format */
	ret = i2s_set_fmt(i2s_reg, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
			  SND_SOC_DAIFMT_CBM_CFM);
	if (ret == 0) {
		i2s_set_lr_framesize(i2s_reg, pi2s_tx->rfs);
		ret = i2s_set_samplesize(i2s_reg, pi2s_tx->bitspersample);
		if (ret != 0) {
			debug("%s:set sample rate failed\n", __func__);
			return ret;
		}

		i2s_set_bitclk_framesize(i2s_reg, pi2s_tx->bfs);
		/* disable i2s transfer flag and flush the fifo */
		i2s_txctrl(i2s_reg, I2S_TX_OFF);
		i2s_fifo(i2s_reg, FIC_TXFLUSH);
	} else {
		debug("%s: failed\n", __func__);
	}

	return ret;
}

static int samsung_i2s_tx_data(struct udevice *dev, void *data, uint data_size)
{
	struct i2s_uc_priv *priv = dev_get_uclass_priv(dev);

	return i2s_transfer_tx_data(priv, data, data_size);
}

static int samsung_i2s_probe(struct udevice *dev)
{
	struct i2s_uc_priv *priv = dev_get_uclass_priv(dev);

	return i2s_tx_init(priv);
}

static int samsung_i2s_of_to_plat(struct udevice *dev)
{
	struct i2s_uc_priv *priv = dev_get_uclass_priv(dev);
	ulong base;

	/*
	 * Get the pre-defined sound specific values from FDT.
	 * All of these are expected to be correct otherwise
	 * wrong register values in i2s setup parameters
	 * may result in no sound play.
	 */
	base = dev_read_addr(dev);
	if (base == FDT_ADDR_T_NONE) {
		debug("%s: Missing  i2s base\n", __func__);
		return -EINVAL;
	}
	priv->base_address = base;

	if (dev_read_u32u(dev, "samsung,i2s-epll-clock-frequency",
			  &priv->audio_pll_clk))
		goto err;
	debug("audio_pll_clk = %d\n", priv->audio_pll_clk);
	if (dev_read_u32u(dev, "samsung,i2s-sampling-rate",
			  &priv->samplingrate))
		goto err;
	debug("samplingrate = %d\n", priv->samplingrate);
	if (dev_read_u32u(dev, "samsung,i2s-bits-per-sample",
			  &priv->bitspersample))
		goto err;
	debug("bitspersample = %d\n", priv->bitspersample);
	if (dev_read_u32u(dev, "samsung,i2s-channels", &priv->channels))
		goto err;
	debug("channels = %d\n", priv->channels);
	if (dev_read_u32u(dev, "samsung,i2s-lr-clk-framesize", &priv->rfs))
		goto err;
	debug("rfs = %d\n", priv->rfs);
	if (dev_read_u32u(dev, "samsung,i2s-bit-clk-framesize", &priv->bfs))
		goto err;
	debug("bfs = %d\n", priv->bfs);

	if (dev_read_u32u(dev, "samsung,i2s-id", &priv->id))
		goto err;
	debug("id = %d\n", priv->id);

	return 0;

err:
	debug("fail to get sound i2s node properties\n");

	return -EINVAL;
}

static const struct i2s_ops samsung_i2s_ops = {
	.tx_data	= samsung_i2s_tx_data,
};

static const struct udevice_id samsung_i2s_ids[] = {
	{ .compatible = "samsung,s5pv210-i2s" },
	{ }
};

U_BOOT_DRIVER(samsung_i2s) = {
	.name		= "samsung_i2s",
	.id		= UCLASS_I2S,
	.of_match	= samsung_i2s_ids,
	.probe		= samsung_i2s_probe,
	.of_to_plat	= samsung_i2s_of_to_plat,
	.ops		= &samsung_i2s_ops,
};
