/*
 * Driver for the Renesas RCar I2C unit
 *
 * Copyright (C) 2014 Wolfram Sang <wsa@sang-engineering.com>
 *
 * Copyright (C) 2012-14 Renesas Solutions Corp.
 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 *
 * This file is based on the drivers/i2c/busses/i2c-sh7760.c
 * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
 *
 * This file used out-of-tree driver i2c-rcar.c
 * Copyright (C) 2011-2012 Renesas Electronics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c/i2c-rcar.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>

/* register offsets */
#define ICSCR	0x00	/* slave ctrl */
#define ICMCR	0x04	/* master ctrl */
#define ICSSR	0x08	/* slave status */
#define ICMSR	0x0C	/* master status */
#define ICSIER	0x10	/* slave irq enable */
#define ICMIER	0x14	/* master irq enable */
#define ICCCR	0x18	/* clock dividers */
#define ICSAR	0x1C	/* slave address */
#define ICMAR	0x20	/* master address */
#define ICRXTX	0x24	/* data port */

/* ICMCR */
#define MDBS	(1 << 7)	/* non-fifo mode switch */
#define FSCL	(1 << 6)	/* override SCL pin */
#define FSDA	(1 << 5)	/* override SDA pin */
#define OBPC	(1 << 4)	/* override pins */
#define MIE	(1 << 3)	/* master if enable */
#define TSBE	(1 << 2)
#define FSB	(1 << 1)	/* force stop bit */
#define ESG	(1 << 0)	/* en startbit gen */

/* ICMSR (also for ICMIE) */
#define MNR	(1 << 6)	/* nack received */
#define MAL	(1 << 5)	/* arbitration lost */
#define MST	(1 << 4)	/* sent a stop */
#define MDE	(1 << 3)
#define MDT	(1 << 2)
#define MDR	(1 << 1)
#define MAT	(1 << 0)	/* slave addr xfer done */


#define RCAR_BUS_PHASE_START	(MDBS | MIE | ESG)
#define RCAR_BUS_PHASE_DATA	(MDBS | MIE)
#define RCAR_BUS_PHASE_STOP	(MDBS | MIE | FSB)

#define RCAR_IRQ_SEND	(MNR | MAL | MST | MAT | MDE)
#define RCAR_IRQ_RECV	(MNR | MAL | MST | MAT | MDR)
#define RCAR_IRQ_STOP	(MST)

#define RCAR_IRQ_ACK_SEND	(~(MAT | MDE))
#define RCAR_IRQ_ACK_RECV	(~(MAT | MDR))

#define ID_LAST_MSG	(1 << 0)
#define ID_IOERROR	(1 << 1)
#define ID_DONE		(1 << 2)
#define ID_ARBLOST	(1 << 3)
#define ID_NACK		(1 << 4)

enum rcar_i2c_type {
	I2C_RCAR_GEN1,
	I2C_RCAR_GEN2,
};

struct rcar_i2c_priv {
	void __iomem *io;
	struct i2c_adapter adap;
	struct i2c_msg	*msg;
	struct clk *clk;

	wait_queue_head_t wait;

	int pos;
	u32 icccr;
	u32 flags;
	enum rcar_i2c_type devtype;
};

#define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent)
#define rcar_i2c_is_recv(p)		((p)->msg->flags & I2C_M_RD)

#define rcar_i2c_flags_set(p, f)	((p)->flags |= (f))
#define rcar_i2c_flags_has(p, f)	((p)->flags & (f))

#define LOOP_TIMEOUT	1024


static void rcar_i2c_write(struct rcar_i2c_priv *priv, int reg, u32 val)
{
	writel(val, priv->io + reg);
}

static u32 rcar_i2c_read(struct rcar_i2c_priv *priv, int reg)
{
	return readl(priv->io + reg);
}

static void rcar_i2c_init(struct rcar_i2c_priv *priv)
{
	/*
	 * reset slave mode.
	 * slave mode is not used on this driver
	 */
	rcar_i2c_write(priv, ICSIER, 0);
	rcar_i2c_write(priv, ICSAR, 0);
	rcar_i2c_write(priv, ICSCR, 0);
	rcar_i2c_write(priv, ICSSR, 0);

	/* reset master mode */
	rcar_i2c_write(priv, ICMIER, 0);
	rcar_i2c_write(priv, ICMCR, 0);
	rcar_i2c_write(priv, ICMSR, 0);
	rcar_i2c_write(priv, ICMAR, 0);
}

static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
{
	int i;

	for (i = 0; i < LOOP_TIMEOUT; i++) {
		/* make sure that bus is not busy */
		if (!(rcar_i2c_read(priv, ICMCR) & FSDA))
			return 0;
		udelay(1);
	}

	return -EBUSY;
}

static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
				    u32 bus_speed,
				    struct device *dev)
{
	u32 scgd, cdf;
	u32 round, ick;
	u32 scl;
	u32 cdf_width;
	unsigned long rate;

	switch (priv->devtype) {
	case I2C_RCAR_GEN1:
		cdf_width = 2;
		break;
	case I2C_RCAR_GEN2:
		cdf_width = 3;
		break;
	default:
		dev_err(dev, "device type error\n");
		return -EIO;
	}

	/*
	 * calculate SCL clock
	 * see
	 *	ICCCR
	 *
	 * ick	= clkp / (1 + CDF)
	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
	 *
	 * ick  : I2C internal clock < 20 MHz
	 * ticf : I2C SCL falling time  =  35 ns here
	 * tr   : I2C SCL rising  time  = 200 ns here
	 * intd : LSI internal delay    =  50 ns here
	 * clkp : peripheral_clk
	 * F[]  : integer up-valuation
	 */
	rate = clk_get_rate(priv->clk);
	cdf = rate / 20000000;
	if (cdf >= 1 << cdf_width) {
		dev_err(dev, "Input clock %lu too high\n", rate);
		return -EIO;
	}
	ick = rate / (cdf + 1);

	/*
	 * it is impossible to calculate large scale
	 * number on u32. separate it
	 *
	 * F[(ticf + tr + intd) * ick]
	 *  = F[(35 + 200 + 50)ns * ick]
	 *  = F[285 * ick / 1000000000]
	 *  = F[(ick / 1000000) * 285 / 1000]
	 */
	round = (ick + 500000) / 1000000 * 285;
	round = (round + 500) / 1000;

	/*
	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
	 *
	 * Calculation result (= SCL) should be less than
	 * bus_speed for hardware safety
	 *
	 * We could use something along the lines of
	 *	div = ick / (bus_speed + 1) + 1;
	 *	scgd = (div - 20 - round + 7) / 8;
	 *	scl = ick / (20 + (scgd * 8) + round);
	 * (not fully verified) but that would get pretty involved
	 */
	for (scgd = 0; scgd < 0x40; scgd++) {
		scl = ick / (20 + (scgd * 8) + round);
		if (scl <= bus_speed)
			goto scgd_find;
	}
	dev_err(dev, "it is impossible to calculate best SCL\n");
	return -EIO;

scgd_find:
	dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n",
		scl, bus_speed, clk_get_rate(priv->clk), round, cdf, scgd);

	/*
	 * keep icccr value
	 */
	priv->icccr = scgd << cdf_width | cdf;

	return 0;
}

static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
{
	int read = !!rcar_i2c_is_recv(priv);

	rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read);
	rcar_i2c_write(priv, ICMSR, 0);
	rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
	rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);

	return 0;
}

/*
 *		interrupt functions
 */
static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
{
	struct i2c_msg *msg = priv->msg;

	/*
	 * FIXME
	 * sometimes, unknown interrupt happened.
	 * Do nothing
	 */
	if (!(msr & MDE))
		return 0;

	/*
	 * If address transfer phase finished,
	 * goto data phase.
	 */
	if (msr & MAT)
		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);

	if (priv->pos < msg->len) {
		/*
		 * Prepare next data to ICRXTX register.
		 * This data will go to _SHIFT_ register.
		 *
		 *    *
		 * [ICRXTX] -> [SHIFT] -> [I2C bus]
		 */
		rcar_i2c_write(priv, ICRXTX, msg->buf[priv->pos]);
		priv->pos++;

	} else {
		/*
		 * The last data was pushed to ICRXTX on _PREV_ empty irq.
		 * It is on _SHIFT_ register, and will sent to I2C bus.
		 *
		 *		  *
		 * [ICRXTX] -> [SHIFT] -> [I2C bus]
		 */

		if (priv->flags & ID_LAST_MSG)
			/*
			 * If current msg is the _LAST_ msg,
			 * prepare stop condition here.
			 * ID_DONE will be set on STOP irq.
			 */
			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
		else
			/*
			 * If current msg is _NOT_ last msg,
			 * it doesn't call stop phase.
			 * thus, there is no STOP irq.
			 * return ID_DONE here.
			 */
			return ID_DONE;
	}

	rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND);

	return 0;
}

static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
{
	struct i2c_msg *msg = priv->msg;

	/*
	 * FIXME
	 * sometimes, unknown interrupt happened.
	 * Do nothing
	 */
	if (!(msr & MDR))
		return 0;

	if (msr & MAT) {
		/*
		 * Address transfer phase finished,
		 * but, there is no data at this point.
		 * Do nothing.
		 */
	} else if (priv->pos < msg->len) {
		/*
		 * get received data
		 */
		msg->buf[priv->pos] = rcar_i2c_read(priv, ICRXTX);
		priv->pos++;
	}

	/*
	 * If next received data is the _LAST_,
	 * go to STOP phase,
	 * otherwise, go to DATA phase.
	 */
	if (priv->pos + 1 >= msg->len)
		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
	else
		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);

	rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV);

	return 0;
}

static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
{
	struct rcar_i2c_priv *priv = ptr;
	u32 msr;

	msr = rcar_i2c_read(priv, ICMSR);

	/* Arbitration lost */
	if (msr & MAL) {
		rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST));
		goto out;
	}

	/* Stop */
	if (msr & MST) {
		rcar_i2c_flags_set(priv, ID_DONE);
		goto out;
	}

	/* Nack */
	if (msr & MNR) {
		/* go to stop phase */
		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
		rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP);
		rcar_i2c_flags_set(priv, ID_NACK);
		goto out;
	}

	if (rcar_i2c_is_recv(priv))
		rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr));
	else
		rcar_i2c_flags_set(priv, rcar_i2c_irq_send(priv, msr));

out:
	if (rcar_i2c_flags_has(priv, ID_DONE)) {
		rcar_i2c_write(priv, ICMIER, 0);
		rcar_i2c_write(priv, ICMSR, 0);
		wake_up(&priv->wait);
	}

	return IRQ_HANDLED;
}

static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
				struct i2c_msg *msgs,
				int num)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
	struct device *dev = rcar_i2c_priv_to_dev(priv);
	int i, ret, timeout;

	pm_runtime_get_sync(dev);

	rcar_i2c_init(priv);
	/* start clock */
	rcar_i2c_write(priv, ICCCR, priv->icccr);

	ret = rcar_i2c_bus_barrier(priv);
	if (ret < 0)
		goto out;

	for (i = 0; i < num; i++) {
		/* This HW can't send STOP after address phase */
		if (msgs[i].len == 0) {
			ret = -EOPNOTSUPP;
			break;
		}

		/* init each data */
		priv->msg	= &msgs[i];
		priv->pos	= 0;
		priv->flags	= 0;
		if (priv->msg == &msgs[num - 1])
			rcar_i2c_flags_set(priv, ID_LAST_MSG);

		ret = rcar_i2c_prepare_msg(priv);

		if (ret < 0)
			break;

		timeout = wait_event_timeout(priv->wait,
					     rcar_i2c_flags_has(priv, ID_DONE),
					     5 * HZ);
		if (!timeout) {
			ret = -ETIMEDOUT;
			break;
		}

		if (rcar_i2c_flags_has(priv, ID_NACK)) {
			ret = -ENXIO;
			break;
		}

		if (rcar_i2c_flags_has(priv, ID_ARBLOST)) {
			ret = -EAGAIN;
			break;
		}

		if (rcar_i2c_flags_has(priv, ID_IOERROR)) {
			ret = -EIO;
			break;
		}

		ret = i + 1; /* The number of transfer */
	}
out:
	pm_runtime_put(dev);

	if (ret < 0 && ret != -ENXIO)
		dev_err(dev, "error %d : %x\n", ret, priv->flags);

	return ret;
}

static u32 rcar_i2c_func(struct i2c_adapter *adap)
{
	/* This HW can't do SMBUS_QUICK and NOSTART */
	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
}

static const struct i2c_algorithm rcar_i2c_algo = {
	.master_xfer	= rcar_i2c_master_xfer,
	.functionality	= rcar_i2c_func,
};

static const struct of_device_id rcar_i2c_dt_ids[] = {
	{ .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 },
	{ .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 },
	{ .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 },
	{ .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7791", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7792", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7793", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
	{},
};
MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);

static int rcar_i2c_probe(struct platform_device *pdev)
{
	struct i2c_rcar_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct rcar_i2c_priv *priv;
	struct i2c_adapter *adap;
	struct resource *res;
	struct device *dev = &pdev->dev;
	u32 bus_speed;
	int irq, ret;

	priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(priv->clk)) {
		dev_err(dev, "cannot get clock\n");
		return PTR_ERR(priv->clk);
	}

	bus_speed = 100000; /* default 100 kHz */
	ret = of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed);
	if (ret < 0 && pdata && pdata->bus_speed)
		bus_speed = pdata->bus_speed;

	if (pdev->dev.of_node)
		priv->devtype = (long)of_match_device(rcar_i2c_dt_ids,
						      dev)->data;
	else
		priv->devtype = platform_get_device_id(pdev)->driver_data;

	ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
	if (ret < 0)
		return ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->io = devm_ioremap_resource(dev, res);
	if (IS_ERR(priv->io))
		return PTR_ERR(priv->io);

	irq = platform_get_irq(pdev, 0);
	init_waitqueue_head(&priv->wait);

	adap			= &priv->adap;
	adap->nr		= pdev->id;
	adap->algo		= &rcar_i2c_algo;
	adap->class		= I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;
	adap->retries		= 3;
	adap->dev.parent	= dev;
	adap->dev.of_node	= dev->of_node;
	i2c_set_adapdata(adap, priv);
	strlcpy(adap->name, pdev->name, sizeof(adap->name));

	ret = devm_request_irq(dev, irq, rcar_i2c_irq, 0,
			       dev_name(dev), priv);
	if (ret < 0) {
		dev_err(dev, "cannot get irq %d\n", irq);
		return ret;
	}

	ret = i2c_add_numbered_adapter(adap);
	if (ret < 0) {
		dev_err(dev, "reg adap failed: %d\n", ret);
		return ret;
	}

	pm_runtime_enable(dev);
	platform_set_drvdata(pdev, priv);

	dev_info(dev, "probed\n");

	return 0;
}

static int rcar_i2c_remove(struct platform_device *pdev)
{
	struct rcar_i2c_priv *priv = platform_get_drvdata(pdev);
	struct device *dev = &pdev->dev;

	i2c_del_adapter(&priv->adap);
	pm_runtime_disable(dev);

	return 0;
}

static struct platform_device_id rcar_i2c_id_table[] = {
	{ "i2c-rcar",		I2C_RCAR_GEN1 },
	{ "i2c-rcar_gen1",	I2C_RCAR_GEN1 },
	{ "i2c-rcar_gen2",	I2C_RCAR_GEN2 },
	{},
};
MODULE_DEVICE_TABLE(platform, rcar_i2c_id_table);

static struct platform_driver rcar_i2c_driver = {
	.driver	= {
		.name	= "i2c-rcar",
		.owner	= THIS_MODULE,
		.of_match_table = rcar_i2c_dt_ids,
	},
	.probe		= rcar_i2c_probe,
	.remove		= rcar_i2c_remove,
	.id_table	= rcar_i2c_id_table,
};

module_platform_driver(rcar_i2c_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Renesas R-Car I2C bus driver");
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
