// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2011, 2013 Renesas Solutions Corp.
 * Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
 *
 * NOTE: This driver should be converted to driver model before June 2017.
 * Please see doc/driver-model/i2c-howto.rst for instructions.
 */

#include <common.h>
#include <i2c.h>
#include <log.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/delay.h>

DECLARE_GLOBAL_DATA_PTR;

/* Every register is 32bit aligned, but only 8bits in size */
#define ureg(name) u8 name; u8 __pad_##name##0; u16 __pad_##name##1;
struct sh_i2c {
	ureg(icdr);
	ureg(iccr);
	ureg(icsr);
	ureg(icic);
	ureg(iccl);
	ureg(icch);
};
#undef ureg

/* ICCR */
#define SH_I2C_ICCR_ICE		(1 << 7)
#define SH_I2C_ICCR_RACK	(1 << 6)
#define SH_I2C_ICCR_RTS		(1 << 4)
#define SH_I2C_ICCR_BUSY	(1 << 2)
#define SH_I2C_ICCR_SCP		(1 << 0)

/* ICSR / ICIC */
#define SH_IC_BUSY	(1 << 4)
#define SH_IC_TACK	(1 << 2)
#define SH_IC_WAIT	(1 << 1)
#define SH_IC_DTE	(1 << 0)

#ifdef CONFIG_SH_I2C_8BIT
/* store 8th bit of iccl and icch in ICIC register */
#define SH_I2C_ICIC_ICCLB8	(1 << 7)
#define SH_I2C_ICIC_ICCHB8	(1 << 6)
#endif

static const struct sh_i2c *i2c_dev[CONFIG_SYS_I2C_SH_NUM_CONTROLLERS] = {
	(struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE0,
#ifdef CONFIG_SYS_I2C_SH_BASE1
	(struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE1,
#endif
#ifdef CONFIG_SYS_I2C_SH_BASE2
	(struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE2,
#endif
#ifdef CONFIG_SYS_I2C_SH_BASE3
	(struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE3,
#endif
#ifdef CONFIG_SYS_I2C_SH_BASE4
	(struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE4,
#endif
};

static u16 iccl, icch;

#define IRQ_WAIT 1000

static void sh_irq_dte(struct sh_i2c *dev)
{
	int i;

	for (i = 0; i < IRQ_WAIT; i++) {
		if (SH_IC_DTE & readb(&dev->icsr))
			break;
		udelay(10);
	}
}

static int sh_irq_dte_with_tack(struct sh_i2c *dev)
{
	int i;

	for (i = 0; i < IRQ_WAIT; i++) {
		if (SH_IC_DTE & readb(&dev->icsr))
			break;
		if (SH_IC_TACK & readb(&dev->icsr))
			return -1;
		udelay(10);
	}
	return 0;
}

static void sh_irq_busy(struct sh_i2c *dev)
{
	int i;

	for (i = 0; i < IRQ_WAIT; i++) {
		if (!(SH_IC_BUSY & readb(&dev->icsr)))
			break;
		udelay(10);
	}
}

static int sh_i2c_set_addr(struct sh_i2c *dev, u8 chip, u8 addr, int stop)
{
	u8 icic = SH_IC_TACK;

	debug("%s: chip: %x, addr: %x iccl: %x, icch %x\n",
				__func__, chip, addr, iccl, icch);
	clrbits_8(&dev->iccr, SH_I2C_ICCR_ICE);
	setbits_8(&dev->iccr, SH_I2C_ICCR_ICE);

	writeb(iccl & 0xff, &dev->iccl);
	writeb(icch & 0xff, &dev->icch);
#ifdef CONFIG_SH_I2C_8BIT
	if (iccl > 0xff)
		icic |= SH_I2C_ICIC_ICCLB8;
	if (icch > 0xff)
		icic |= SH_I2C_ICIC_ICCHB8;
#endif
	writeb(icic, &dev->icic);

	writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &dev->iccr);
	sh_irq_dte(dev);

	clrbits_8(&dev->icsr, SH_IC_TACK);
	writeb(chip << 1, &dev->icdr);
	if (sh_irq_dte_with_tack(dev) != 0)
		return -1;

	writeb(addr, &dev->icdr);
	if (stop)
		writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS), &dev->iccr);

	if (sh_irq_dte_with_tack(dev) != 0)
		return -1;
	return 0;
}

static void sh_i2c_finish(struct sh_i2c *dev)
{
	writeb(0, &dev->icsr);
	clrbits_8(&dev->iccr, SH_I2C_ICCR_ICE);
}

static int
sh_i2c_raw_write(struct sh_i2c *dev, u8 chip, uint addr, u8 val)
{
	int ret = -1;
	if (sh_i2c_set_addr(dev, chip, addr, 0) != 0)
		goto exit0;
	udelay(10);

	writeb(val, &dev->icdr);
	if (sh_irq_dte_with_tack(dev) != 0)
		goto exit0;

	writeb((SH_I2C_ICCR_ICE | SH_I2C_ICCR_RTS), &dev->iccr);
	if (sh_irq_dte_with_tack(dev) != 0)
		goto exit0;
	sh_irq_busy(dev);
	ret = 0;

exit0:
	sh_i2c_finish(dev);
	return ret;
}

static int sh_i2c_raw_read(struct sh_i2c *dev, u8 chip, u8 addr)
{
	int ret = -1;

	if (sh_i2c_set_addr(dev, chip, addr, 1) != 0)
		goto exit0;
	udelay(100);

	writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &dev->iccr);
	sh_irq_dte(dev);

	writeb(chip << 1 | 0x01, &dev->icdr);
	if (sh_irq_dte_with_tack(dev) != 0)
		goto exit0;

	writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_SCP), &dev->iccr);
	if (sh_irq_dte_with_tack(dev) != 0)
		goto exit0;

	ret = readb(&dev->icdr) & 0xff;

	writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RACK), &dev->iccr);
	readb(&dev->icdr); /* Dummy read */
	sh_irq_busy(dev);

exit0:
	sh_i2c_finish(dev);

	return ret;
}

static void
sh_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
{
	int num, denom, tmp;

	/* No i2c support prior to relocation */
	if (!(gd->flags & GD_FLG_RELOC))
		return;

	/*
	 * Calculate the value for iccl. From the data sheet:
	 * iccl = (p-clock / transfer-rate) * (L / (L + H))
	 * where L and H are the SCL low and high ratio.
	 */
	num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_LOW;
	denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW);
	tmp = num * 10 / denom;
	if (tmp % 10 >= 5)
		iccl = (u16)((num/denom) + 1);
	else
		iccl = (u16)(num/denom);

	/* Calculate the value for icch. From the data sheet:
	   icch = (p clock / transfer rate) * (H / (L + H)) */
	num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH;
	tmp = num * 10 / denom;
	if (tmp % 10 >= 5)
		icch = (u16)((num/denom) + 1);
	else
		icch = (u16)(num/denom);

	debug("clock: %d, speed %d, iccl: %x, icch: %x\n",
			CONFIG_SH_I2C_CLOCK, speed, iccl, icch);
}

static int sh_i2c_read(struct i2c_adapter *adap, uint8_t chip,
				uint addr, int alen, u8 *data, int len)
{
	int ret, i;
	struct sh_i2c *dev = (struct sh_i2c *)i2c_dev[adap->hwadapnr];

	for (i = 0; i < len; i++) {
		ret = sh_i2c_raw_read(dev, chip, addr + i);
		if (ret < 0)
			return -1;

		data[i] = ret & 0xff;
		debug("%s: data[%d]: %02x\n", __func__, i, data[i]);
	}

	return 0;
}

static int sh_i2c_write(struct i2c_adapter *adap, uint8_t chip, uint addr,
				int alen, u8 *data, int len)
{
	struct sh_i2c *dev = (struct sh_i2c *)i2c_dev[adap->hwadapnr];
	int i;

	for (i = 0; i < len; i++) {
		debug("%s: data[%d]: %02x\n", __func__, i, data[i]);
		if (sh_i2c_raw_write(dev, chip, addr + i, data[i]) != 0)
			return -1;
	}
	return 0;
}

static int
sh_i2c_probe(struct i2c_adapter *adap, u8 dev)
{
	u8 dummy[1];

	return sh_i2c_read(adap, dev, 0, 0, dummy, sizeof dummy);
}

static unsigned int sh_i2c_set_bus_speed(struct i2c_adapter *adap,
			unsigned int speed)
{
	struct sh_i2c *dev = (struct sh_i2c *)i2c_dev[adap->hwadapnr];

	sh_i2c_finish(dev);
	sh_i2c_init(adap, speed, 0);

	return 0;
}

/*
 * Register RCAR i2c adapters
 */
U_BOOT_I2C_ADAP_COMPLETE(sh_0, sh_i2c_init, sh_i2c_probe, sh_i2c_read,
	sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 0)
#ifdef CONFIG_SYS_I2C_SH_BASE1
U_BOOT_I2C_ADAP_COMPLETE(sh_1, sh_i2c_init, sh_i2c_probe, sh_i2c_read,
	sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 1)
#endif
#ifdef CONFIG_SYS_I2C_SH_BASE2
U_BOOT_I2C_ADAP_COMPLETE(sh_2, sh_i2c_init, sh_i2c_probe, sh_i2c_read,
	sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 2)
#endif
#ifdef CONFIG_SYS_I2C_SH_BASE3
U_BOOT_I2C_ADAP_COMPLETE(sh_3, sh_i2c_init, sh_i2c_probe, sh_i2c_read,
	sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 3)
#endif
#ifdef CONFIG_SYS_I2C_SH_BASE4
U_BOOT_I2C_ADAP_COMPLETE(sh_4, sh_i2c_init, sh_i2c_probe, sh_i2c_read,
	sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 4)
#endif
