/*
 * Copyright (C) 2014 Panasonic Corporation
 * Copyright (C) 2015 Socionext Inc.
 *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <dm/device.h>
#include <dm/root.h>
#include <i2c.h>
#include <fdtdec.h>

DECLARE_GLOBAL_DATA_PTR;

struct uniphier_i2c_regs {
	u32 dtrm;			/* data transmission */
#define I2C_DTRM_STA	(1 << 10)
#define I2C_DTRM_STO	(1 << 9)
#define I2C_DTRM_NACK	(1 << 8)
#define I2C_DTRM_RD	(1 << 0)
	u32 drec;			/* data reception */
#define I2C_DREC_STS	(1 << 12)
#define I2C_DREC_LRB	(1 << 11)
#define I2C_DREC_LAB	(1 << 9)
	u32 myad;			/* slave address */
	u32 clk;			/* clock frequency control */
	u32 brst;			/* bus reset */
#define I2C_BRST_FOEN	(1 << 1)
#define I2C_BRST_BRST	(1 << 0)
	u32 hold;			/* hold time control */
	u32 bsts;			/* bus status monitor */
	u32 noise;			/* noise filter control */
	u32 setup;			/* setup time control */
};

#define IOBUS_FREQ	100000000

struct uniphier_i2c_dev {
	struct uniphier_i2c_regs __iomem *regs;	/* register base */
	unsigned long input_clk;	/* master clock (Hz) */
	unsigned long wait_us;		/* wait for every byte transfer (us) */
};

static int uniphier_i2c_probe(struct udevice *dev)
{
	fdt_addr_t addr;
	fdt_size_t size;
	struct uniphier_i2c_dev *priv = dev_get_priv(dev);

	addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);

	priv->regs = map_sysmem(addr, size);

	if (!priv->regs)
		return -ENOMEM;

	priv->input_clk = IOBUS_FREQ;

	/* deassert reset */
	writel(0x3, &priv->regs->brst);

	return 0;
}

static int uniphier_i2c_remove(struct udevice *dev)
{
	struct uniphier_i2c_dev *priv = dev_get_priv(dev);

	unmap_sysmem(priv->regs);

	return 0;
}

static int send_and_recv_byte(struct uniphier_i2c_dev *dev, u32 dtrm)
{
	writel(dtrm, &dev->regs->dtrm);

	/*
	 * This controller only provides interruption to inform the completion
	 * of each byte transfer.  (No status register to poll it.)
	 * Unfortunately, U-Boot does not have a good support of interrupt.
	 * Wait for a while.
	 */
	udelay(dev->wait_us);

	return readl(&dev->regs->drec);
}

static int send_byte(struct uniphier_i2c_dev *dev, u32 dtrm, bool *stop)
{
	int ret = 0;
	u32 drec;

	drec = send_and_recv_byte(dev, dtrm);

	if (drec & I2C_DREC_LAB) {
		debug("uniphier_i2c: bus arbitration failed\n");
		*stop = false;
		ret = -EREMOTEIO;
	}
	if (drec & I2C_DREC_LRB) {
		debug("uniphier_i2c: slave did not return ACK\n");
		ret = -EREMOTEIO;
	}
	return ret;
}

static int uniphier_i2c_transmit(struct uniphier_i2c_dev *dev, uint addr,
				 uint len, const u8 *buf, bool *stop)
{
	int ret;

	debug("%s: addr = %x, len = %d\n", __func__, addr, len);

	ret = send_byte(dev, I2C_DTRM_STA | I2C_DTRM_NACK | addr << 1, stop);
	if (ret < 0)
		goto fail;

	while (len--) {
		ret = send_byte(dev, I2C_DTRM_NACK | *buf++, stop);
		if (ret < 0)
			goto fail;
	}

fail:
	if (*stop)
		writel(I2C_DTRM_STO | I2C_DTRM_NACK, &dev->regs->dtrm);

	return ret;
}

static int uniphier_i2c_receive(struct uniphier_i2c_dev *dev, uint addr,
				uint len, u8 *buf, bool *stop)
{
	int ret;

	debug("%s: addr = %x, len = %d\n", __func__, addr, len);

	ret = send_byte(dev, I2C_DTRM_STA | I2C_DTRM_NACK |
			I2C_DTRM_RD | addr << 1, stop);
	if (ret < 0)
		goto fail;

	while (len--)
		*buf++ = send_and_recv_byte(dev, len ? 0 : I2C_DTRM_NACK);

fail:
	if (*stop)
		writel(I2C_DTRM_STO | I2C_DTRM_NACK, &dev->regs->dtrm);

	return ret;
}

static int uniphier_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
			     int nmsgs)
{
	int ret = 0;
	struct uniphier_i2c_dev *dev = dev_get_priv(bus);
	bool stop;

	for (; nmsgs > 0; nmsgs--, msg++) {
		/* If next message is read, skip the stop condition */
		stop = nmsgs > 1 && msg[1].flags & I2C_M_RD ? false : true;

		if (msg->flags & I2C_M_RD)
			ret = uniphier_i2c_receive(dev, msg->addr, msg->len,
						   msg->buf, &stop);
		else
			ret = uniphier_i2c_transmit(dev, msg->addr, msg->len,
						    msg->buf, &stop);

		if (ret < 0)
			break;
	}

	return ret;
}

static int uniphier_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
{
	struct uniphier_i2c_dev *priv = dev_get_priv(bus);

	/* max supported frequency is 400 kHz */
	if (speed > 400000)
		return -EINVAL;

	/* bus reset: make sure the bus is idle when change the frequency */
	writel(0x1, &priv->regs->brst);

	writel((priv->input_clk / speed / 2 << 16) | (priv->input_clk / speed),
	       &priv->regs->clk);

	writel(0x3, &priv->regs->brst);

	/*
	 * Theoretically, each byte can be transferred in
	 * 1000000 * 9 / speed usec.  For safety, wait more than double.
	 */
	priv->wait_us = 20000000 / speed;

	return 0;
}


static const struct dm_i2c_ops uniphier_i2c_ops = {
	.xfer = uniphier_i2c_xfer,
	.set_bus_speed = uniphier_i2c_set_bus_speed,
};

static const struct udevice_id uniphier_i2c_of_match[] = {
	{ .compatible = "socionext,uniphier-i2c" },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(uniphier_i2c) = {
	.name = "uniphier-i2c",
	.id = UCLASS_I2C,
	.of_match = uniphier_i2c_of_match,
	.probe = uniphier_i2c_probe,
	.remove = uniphier_i2c_remove,
	.priv_auto_alloc_size = sizeof(struct uniphier_i2c_dev),
	.ops = &uniphier_i2c_ops,
};
