/*
 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#define UNIPHIER_I2C_DTRM	0x00	/* TX register */
#define     UNIPHIER_I2C_DTRM_IRQEN	BIT(11)	/* enable interrupt */
#define     UNIPHIER_I2C_DTRM_STA	BIT(10)	/* start condition */
#define     UNIPHIER_I2C_DTRM_STO	BIT(9)	/* stop condition */
#define     UNIPHIER_I2C_DTRM_NACK	BIT(8)	/* do not return ACK */
#define     UNIPHIER_I2C_DTRM_RD	BIT(0)	/* read transaction */
#define UNIPHIER_I2C_DREC	0x04	/* RX register */
#define     UNIPHIER_I2C_DREC_MST	BIT(14)	/* 1 = master, 0 = slave */
#define     UNIPHIER_I2C_DREC_TX	BIT(13)	/* 1 = transmit, 0 = receive */
#define     UNIPHIER_I2C_DREC_STS	BIT(12)	/* stop condition detected */
#define     UNIPHIER_I2C_DREC_LRB	BIT(11)	/* no ACK */
#define     UNIPHIER_I2C_DREC_LAB	BIT(9)	/* arbitration lost */
#define     UNIPHIER_I2C_DREC_BBN	BIT(8)	/* bus not busy */
#define UNIPHIER_I2C_MYAD	0x08	/* slave address */
#define UNIPHIER_I2C_CLK	0x0c	/* clock frequency control */
#define UNIPHIER_I2C_BRST	0x10	/* bus reset */
#define     UNIPHIER_I2C_BRST_FOEN	BIT(1)	/* normal operation */
#define     UNIPHIER_I2C_BRST_RSCL	BIT(0)	/* release SCL */
#define UNIPHIER_I2C_HOLD	0x14	/* hold time control */
#define UNIPHIER_I2C_BSTS	0x18	/* bus status monitor */
#define     UNIPHIER_I2C_BSTS_SDA	BIT(1)	/* readback of SDA line */
#define     UNIPHIER_I2C_BSTS_SCL	BIT(0)	/* readback of SCL line */
#define UNIPHIER_I2C_NOISE	0x1c	/* noise filter control */
#define UNIPHIER_I2C_SETUP	0x20	/* setup time control */

#define UNIPHIER_I2C_DEFAULT_SPEED	100000
#define UNIPHIER_I2C_MAX_SPEED		400000

struct uniphier_i2c_priv {
	struct completion comp;
	struct i2c_adapter adap;
	void __iomem *membase;
	struct clk *clk;
	unsigned int busy_cnt;
};

static irqreturn_t uniphier_i2c_interrupt(int irq, void *dev_id)
{
	struct uniphier_i2c_priv *priv = dev_id;

	/*
	 * This hardware uses edge triggered interrupt.  Do not touch the
	 * hardware registers in this handler to make sure to catch the next
	 * interrupt edge.  Just send a complete signal and return.
	 */
	complete(&priv->comp);

	return IRQ_HANDLED;
}

static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
				  u32 *rxdatap)
{
	struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);
	unsigned long time_left;
	u32 rxdata;

	reinit_completion(&priv->comp);

	txdata |= UNIPHIER_I2C_DTRM_IRQEN;
	dev_dbg(&adap->dev, "write data: 0x%04x\n", txdata);
	writel(txdata, priv->membase + UNIPHIER_I2C_DTRM);

	time_left = wait_for_completion_timeout(&priv->comp, adap->timeout);
	if (unlikely(!time_left)) {
		dev_err(&adap->dev, "transaction timeout\n");
		return -ETIMEDOUT;
	}

	rxdata = readl(priv->membase + UNIPHIER_I2C_DREC);
	dev_dbg(&adap->dev, "read data: 0x%04x\n", rxdata);

	if (rxdatap)
		*rxdatap = rxdata;

	return 0;
}

static int uniphier_i2c_send_byte(struct i2c_adapter *adap, u32 txdata)
{
	u32 rxdata;
	int ret;

	ret = uniphier_i2c_xfer_byte(adap, txdata, &rxdata);
	if (ret)
		return ret;

	if (unlikely(rxdata & UNIPHIER_I2C_DREC_LAB)) {
		dev_dbg(&adap->dev, "arbitration lost\n");
		return -EAGAIN;
	}
	if (unlikely(rxdata & UNIPHIER_I2C_DREC_LRB)) {
		dev_dbg(&adap->dev, "could not get ACK\n");
		return -ENXIO;
	}

	return 0;
}

static int uniphier_i2c_tx(struct i2c_adapter *adap, u16 addr, u16 len,
			   const u8 *buf)
{
	int ret;

	dev_dbg(&adap->dev, "start condition\n");
	ret = uniphier_i2c_send_byte(adap, addr << 1 |
				     UNIPHIER_I2C_DTRM_STA |
				     UNIPHIER_I2C_DTRM_NACK);
	if (ret)
		return ret;

	while (len--) {
		ret = uniphier_i2c_send_byte(adap,
					     UNIPHIER_I2C_DTRM_NACK | *buf++);
		if (ret)
			return ret;
	}

	return 0;
}

static int uniphier_i2c_rx(struct i2c_adapter *adap, u16 addr, u16 len,
			   u8 *buf)
{
	int ret;

	dev_dbg(&adap->dev, "start condition\n");
	ret = uniphier_i2c_send_byte(adap, addr << 1 |
				     UNIPHIER_I2C_DTRM_STA |
				     UNIPHIER_I2C_DTRM_NACK |
				     UNIPHIER_I2C_DTRM_RD);
	if (ret)
		return ret;

	while (len--) {
		u32 rxdata;

		ret = uniphier_i2c_xfer_byte(adap,
					     len ? 0 : UNIPHIER_I2C_DTRM_NACK,
					     &rxdata);
		if (ret)
			return ret;
		*buf++ = rxdata;
	}

	return 0;
}

static int uniphier_i2c_stop(struct i2c_adapter *adap)
{
	dev_dbg(&adap->dev, "stop condition\n");
	return uniphier_i2c_send_byte(adap, UNIPHIER_I2C_DTRM_STO |
				      UNIPHIER_I2C_DTRM_NACK);
}

static int uniphier_i2c_master_xfer_one(struct i2c_adapter *adap,
					struct i2c_msg *msg, bool stop)
{
	bool is_read = msg->flags & I2C_M_RD;
	bool recovery = false;
	int ret;

	dev_dbg(&adap->dev, "%s: addr=0x%02x, len=%d, stop=%d\n",
		is_read ? "receive" : "transmit", msg->addr, msg->len, stop);

	if (is_read)
		ret = uniphier_i2c_rx(adap, msg->addr, msg->len, msg->buf);
	else
		ret = uniphier_i2c_tx(adap, msg->addr, msg->len, msg->buf);

	if (ret == -EAGAIN) /* could not acquire bus. bail out without STOP */
		return ret;

	if (ret == -ETIMEDOUT) {
		/* This error is fatal.  Needs recovery. */
		stop = false;
		recovery = true;
	}

	if (stop) {
		int ret2 = uniphier_i2c_stop(adap);

		if (ret2) {
			/* Failed to issue STOP.  The bus needs recovery. */
			recovery = true;
			ret = ret ?: ret2;
		}
	}

	if (recovery)
		i2c_recover_bus(adap);

	return ret;
}

static int uniphier_i2c_check_bus_busy(struct i2c_adapter *adap)
{
	struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);

	if (!(readl(priv->membase + UNIPHIER_I2C_DREC) &
						UNIPHIER_I2C_DREC_BBN)) {
		if (priv->busy_cnt++ > 3) {
			/*
			 * If bus busy continues too long, it is probably
			 * in a wrong state.  Try bus recovery.
			 */
			i2c_recover_bus(adap);
			priv->busy_cnt = 0;
		}

		return -EAGAIN;
	}

	priv->busy_cnt = 0;
	return 0;
}

static int uniphier_i2c_master_xfer(struct i2c_adapter *adap,
				    struct i2c_msg *msgs, int num)
{
	struct i2c_msg *msg, *emsg = msgs + num;
	int ret;

	ret = uniphier_i2c_check_bus_busy(adap);
	if (ret)
		return ret;

	for (msg = msgs; msg < emsg; msg++) {
		/* Emit STOP if it is the last message or I2C_M_STOP is set. */
		bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP);

		ret = uniphier_i2c_master_xfer_one(adap, msg, stop);
		if (ret)
			return ret;
	}

	return num;
}

static u32 uniphier_i2c_functionality(struct i2c_adapter *adap)
{
	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

static const struct i2c_algorithm uniphier_i2c_algo = {
	.master_xfer = uniphier_i2c_master_xfer,
	.functionality = uniphier_i2c_functionality,
};

static void uniphier_i2c_reset(struct uniphier_i2c_priv *priv, bool reset_on)
{
	u32 val = UNIPHIER_I2C_BRST_RSCL;

	val |= reset_on ? 0 : UNIPHIER_I2C_BRST_FOEN;
	writel(val, priv->membase + UNIPHIER_I2C_BRST);
}

static int uniphier_i2c_get_scl(struct i2c_adapter *adap)
{
	struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);

	return !!(readl(priv->membase + UNIPHIER_I2C_BSTS) &
							UNIPHIER_I2C_BSTS_SCL);
}

static void uniphier_i2c_set_scl(struct i2c_adapter *adap, int val)
{
	struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);

	writel(val ? UNIPHIER_I2C_BRST_RSCL : 0,
	       priv->membase + UNIPHIER_I2C_BRST);
}

static int uniphier_i2c_get_sda(struct i2c_adapter *adap)
{
	struct uniphier_i2c_priv *priv = i2c_get_adapdata(adap);

	return !!(readl(priv->membase + UNIPHIER_I2C_BSTS) &
							UNIPHIER_I2C_BSTS_SDA);
}

static void uniphier_i2c_unprepare_recovery(struct i2c_adapter *adap)
{
	uniphier_i2c_reset(i2c_get_adapdata(adap), false);
}

static struct i2c_bus_recovery_info uniphier_i2c_bus_recovery_info = {
	.recover_bus = i2c_generic_scl_recovery,
	.get_scl = uniphier_i2c_get_scl,
	.set_scl = uniphier_i2c_set_scl,
	.get_sda = uniphier_i2c_get_sda,
	.unprepare_recovery = uniphier_i2c_unprepare_recovery,
};

static void uniphier_i2c_hw_init(struct uniphier_i2c_priv *priv,
				 u32 bus_speed, unsigned long clk_rate)
{
	uniphier_i2c_reset(priv, true);

	writel((clk_rate / bus_speed / 2 << 16) | (clk_rate / bus_speed),
	       priv->membase + UNIPHIER_I2C_CLK);

	uniphier_i2c_reset(priv, false);
}

static int uniphier_i2c_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct uniphier_i2c_priv *priv;
	struct resource *regs;
	u32 bus_speed;
	unsigned long clk_rate;
	int irq, ret;

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

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

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "failed to get IRQ number\n");
		return irq;
	}

	if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed))
		bus_speed = UNIPHIER_I2C_DEFAULT_SPEED;

	if (!bus_speed || bus_speed > UNIPHIER_I2C_MAX_SPEED) {
		dev_err(dev, "invalid clock-frequency %d\n", bus_speed);
		return -EINVAL;
	}

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

	ret = clk_prepare_enable(priv->clk);
	if (ret)
		return ret;

	clk_rate = clk_get_rate(priv->clk);
	if (!clk_rate) {
		dev_err(dev, "input clock rate should not be zero\n");
		ret = -EINVAL;
		goto err;
	}

	init_completion(&priv->comp);
	priv->adap.owner = THIS_MODULE;
	priv->adap.algo = &uniphier_i2c_algo;
	priv->adap.dev.parent = dev;
	priv->adap.dev.of_node = dev->of_node;
	strlcpy(priv->adap.name, "UniPhier I2C", sizeof(priv->adap.name));
	priv->adap.bus_recovery_info = &uniphier_i2c_bus_recovery_info;
	i2c_set_adapdata(&priv->adap, priv);
	platform_set_drvdata(pdev, priv);

	uniphier_i2c_hw_init(priv, bus_speed, clk_rate);

	ret = devm_request_irq(dev, irq, uniphier_i2c_interrupt, 0, pdev->name,
			       priv);
	if (ret) {
		dev_err(dev, "failed to request irq %d\n", irq);
		goto err;
	}

	ret = i2c_add_adapter(&priv->adap);
err:
	if (ret)
		clk_disable_unprepare(priv->clk);

	return ret;
}

static int uniphier_i2c_remove(struct platform_device *pdev)
{
	struct uniphier_i2c_priv *priv = platform_get_drvdata(pdev);

	i2c_del_adapter(&priv->adap);
	clk_disable_unprepare(priv->clk);

	return 0;
}

static const struct of_device_id uniphier_i2c_match[] = {
	{ .compatible = "socionext,uniphier-i2c" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, uniphier_i2c_match);

static struct platform_driver uniphier_i2c_drv = {
	.probe  = uniphier_i2c_probe,
	.remove = uniphier_i2c_remove,
	.driver = {
		.name  = "uniphier-i2c",
		.of_match_table = uniphier_i2c_match,
	},
};
module_platform_driver(uniphier_i2c_drv);

MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier I2C bus driver");
MODULE_LICENSE("GPL");
