// 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 <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
