// SPDX-License-Identifier: GPL-2.0+
/*
 * Renesas RCar IIC driver
 *
 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
 *
 * Based on
 * Copyright (C) 2011, 2013 Renesas Solutions Corp.
 * Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
 */

#include <clk.h>
#include <dm.h>
#include <i2c.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/delay.h>

struct rcar_iic_priv {
	void __iomem		*base;
	struct clk		clk;
	u8			iccl;
	u8			icch;
};

#define RCAR_IIC_ICDR		0x00
#define RCAR_IIC_ICCR		0x04
#define RCAR_IIC_ICSR		0x08
#define RCAR_IIC_ICIC		0x0c
#define RCAR_IIC_ICCL		0x10
#define RCAR_IIC_ICCH		0x14

/* ICCR */
#define RCAR_IIC_ICCR_ICE	BIT(7)
#define RCAR_IIC_ICCR_RACK	BIT(6)
#define RCAR_IIC_ICCR_RTS	BIT(4)
#define RCAR_IIC_ICCR_BUSY	BIT(2)
#define RCAR_IIC_ICCR_SCP	BIT(0)

/* ICSR / ICIC */
#define RCAR_IC_BUSY		BIT(4)
#define RCAR_IC_TACK		BIT(2)
#define RCAR_IC_DTE		BIT(0)

#define IRQ_WAIT 1000

static void sh_irq_dte(struct udevice *dev)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);
	int i;

	for (i = 0; i < IRQ_WAIT; i++) {
		if (RCAR_IC_DTE & readb(priv->base + RCAR_IIC_ICSR))
			break;
		udelay(10);
	}
}

static int sh_irq_dte_with_tack(struct udevice *dev)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);
	u8 icsr;
	int i;

	for (i = 0; i < IRQ_WAIT; i++) {
		icsr = readb(priv->base + RCAR_IIC_ICSR);
		if (RCAR_IC_DTE & icsr)
			break;
		if (RCAR_IC_TACK & icsr)
			return -ETIMEDOUT;
		udelay(10);
	}
	return 0;
}

static void sh_irq_busy(struct udevice *dev)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);
	int i;

	for (i = 0; i < IRQ_WAIT; i++) {
		if (!(RCAR_IC_BUSY & readb(priv->base + RCAR_IIC_ICSR)))
			break;
		udelay(10);
	}
}

static int rcar_iic_set_addr(struct udevice *dev, u8 chip, u8 read)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);

	clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
	setbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);

	writeb(priv->iccl, priv->base + RCAR_IIC_ICCL);
	writeb(priv->icch, priv->base + RCAR_IIC_ICCH);
	writeb(RCAR_IC_TACK, priv->base + RCAR_IIC_ICIC);

	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS | RCAR_IIC_ICCR_BUSY,
	       priv->base + RCAR_IIC_ICCR);
	sh_irq_dte(dev);

	clrbits_8(priv->base + RCAR_IIC_ICSR, RCAR_IC_TACK);
	writeb(chip << 1 | read, priv->base + RCAR_IIC_ICDR);
	return sh_irq_dte_with_tack(dev);
}

static void rcar_iic_finish(struct udevice *dev)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);

	writeb(0, priv->base + RCAR_IIC_ICSR);
	clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
}

static int rcar_iic_read_common(struct udevice *dev, struct i2c_msg *msg)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);
	int i, ret = -EREMOTEIO;

	if (rcar_iic_set_addr(dev, msg->addr, 1) != 0)
		goto err;

	udelay(10);

	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
	       priv->base + RCAR_IIC_ICCR);

	for (i = 0; i < msg->len; i++) {
		if (sh_irq_dte_with_tack(dev) != 0)
			goto err;

		msg->buf[i] = readb(priv->base + RCAR_IIC_ICDR) & 0xff;

		if (msg->len - 1 == i) {
			writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RACK,
			       priv->base + RCAR_IIC_ICCR);
		}
	}

	sh_irq_busy(dev);
	ret = 0;

err:
	rcar_iic_finish(dev);
	return ret;
}

static int rcar_iic_write_common(struct udevice *dev, struct i2c_msg *msg)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);
	int i, ret = -EREMOTEIO;

	if (rcar_iic_set_addr(dev, msg->addr, 0) != 0)
		goto err;

	udelay(10);

	for (i = 0; i < msg->len; i++) {
		writeb(msg->buf[i], priv->base + RCAR_IIC_ICDR);
		if (sh_irq_dte_with_tack(dev) != 0)
			goto err;
	}

	if (msg->flags & I2C_M_STOP) {
		writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS,
		       priv->base + RCAR_IIC_ICCR);
		if (sh_irq_dte_with_tack(dev) != 0)
			goto err;
	}

	sh_irq_busy(dev);
	ret = 0;

err:
	rcar_iic_finish(dev);
	return ret;
}

static int rcar_iic_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
{
	int ret;

	for (; nmsgs > 0; nmsgs--, msg++) {
		if (msg->flags & I2C_M_RD)
			ret = rcar_iic_read_common(dev, msg);
		else
			ret = rcar_iic_write_common(dev, msg);

		if (ret)
			return -EREMOTEIO;
	}

	return ret;
}

static int rcar_iic_set_speed(struct udevice *dev, uint speed)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);
	const unsigned int ratio_high = 4;
	const unsigned int ratio_low = 5;
	int clkrate, denom;

	clkrate = clk_get_rate(&priv->clk);
	if (clkrate < 0)
		return clkrate;

	/*
	 * Calculate the value for ICCL and ICCH. From the data sheet:
	 * iccl = (p-clock / transfer-rate) * (L / (L + H))
	 * icch = (p clock / transfer rate) * (H / (L + H))
	 * where L and H are the SCL low and high ratio.
	 */
	denom = speed * (ratio_high + ratio_low);
	priv->iccl = DIV_ROUND_CLOSEST(clkrate * ratio_low, denom);
	priv->icch = DIV_ROUND_CLOSEST(clkrate * ratio_high, denom);

	return 0;
}

static int rcar_iic_probe_chip(struct udevice *dev, uint addr, uint flags)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);
	int ret;

	rcar_iic_set_addr(dev, addr, 1);
	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
	       priv->base + RCAR_IIC_ICCR);
	ret = sh_irq_dte_with_tack(dev);
	rcar_iic_finish(dev);

	return ret;
}

static int rcar_iic_probe(struct udevice *dev)
{
	struct rcar_iic_priv *priv = dev_get_priv(dev);
	int ret;

	priv->base = dev_read_addr_ptr(dev);

	ret = clk_get_by_index(dev, 0, &priv->clk);
	if (ret)
		return ret;

	ret = clk_enable(&priv->clk);
	if (ret)
		return ret;

	rcar_iic_finish(dev);

	return rcar_iic_set_speed(dev, I2C_SPEED_STANDARD_RATE);
}

static const struct dm_i2c_ops rcar_iic_ops = {
	.xfer		= rcar_iic_xfer,
	.probe_chip	= rcar_iic_probe_chip,
	.set_bus_speed	= rcar_iic_set_speed,
};

static const struct udevice_id rcar_iic_ids[] = {
	{ .compatible = "renesas,rmobile-iic" },
	{ }
};

U_BOOT_DRIVER(iic_rcar) = {
	.name		= "iic_rcar",
	.id		= UCLASS_I2C,
	.of_match	= rcar_iic_ids,
	.probe		= rcar_iic_probe,
	.priv_auto	= sizeof(struct rcar_iic_priv),
	.ops		= &rcar_iic_ops,
};
