/*
 * Copyright (c) 2003-2015 Broadcom Corporation
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>

#define XLP9XX_I2C_DIV			0x0
#define XLP9XX_I2C_CTRL			0x1
#define XLP9XX_I2C_CMD			0x2
#define XLP9XX_I2C_STATUS		0x3
#define XLP9XX_I2C_MTXFIFO		0x4
#define XLP9XX_I2C_MRXFIFO		0x5
#define XLP9XX_I2C_MFIFOCTRL		0x6
#define XLP9XX_I2C_STXFIFO		0x7
#define XLP9XX_I2C_SRXFIFO		0x8
#define XLP9XX_I2C_SFIFOCTRL		0x9
#define XLP9XX_I2C_SLAVEADDR		0xA
#define XLP9XX_I2C_OWNADDR		0xB
#define XLP9XX_I2C_FIFOWCNT		0xC
#define XLP9XX_I2C_INTEN		0xD
#define XLP9XX_I2C_INTST		0xE
#define XLP9XX_I2C_WAITCNT		0xF
#define XLP9XX_I2C_TIMEOUT		0X10
#define XLP9XX_I2C_GENCALLADDR		0x11

#define XLP9XX_I2C_STATUS_BUSY		BIT(0)

#define XLP9XX_I2C_CMD_START		BIT(7)
#define XLP9XX_I2C_CMD_STOP		BIT(6)
#define XLP9XX_I2C_CMD_READ		BIT(5)
#define XLP9XX_I2C_CMD_WRITE		BIT(4)
#define XLP9XX_I2C_CMD_ACK		BIT(3)

#define XLP9XX_I2C_CTRL_MCTLEN_SHIFT	16
#define XLP9XX_I2C_CTRL_MCTLEN_MASK	0xffff0000
#define XLP9XX_I2C_CTRL_RST		BIT(8)
#define XLP9XX_I2C_CTRL_EN		BIT(6)
#define XLP9XX_I2C_CTRL_MASTER		BIT(4)
#define XLP9XX_I2C_CTRL_FIFORD		BIT(1)
#define XLP9XX_I2C_CTRL_ADDMODE		BIT(0)

#define XLP9XX_I2C_INTEN_NACKADDR	BIT(25)
#define XLP9XX_I2C_INTEN_SADDR		BIT(13)
#define XLP9XX_I2C_INTEN_DATADONE	BIT(12)
#define XLP9XX_I2C_INTEN_ARLOST		BIT(11)
#define XLP9XX_I2C_INTEN_MFIFOFULL	BIT(4)
#define XLP9XX_I2C_INTEN_MFIFOEMTY	BIT(3)
#define XLP9XX_I2C_INTEN_MFIFOHI	BIT(2)
#define XLP9XX_I2C_INTEN_BUSERR		BIT(0)

#define XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT		8
#define XLP9XX_I2C_MFIFOCTRL_LOTH_SHIFT		0
#define XLP9XX_I2C_MFIFOCTRL_RST		BIT(16)

#define XLP9XX_I2C_SLAVEADDR_RW			BIT(0)
#define XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT		1

#define XLP9XX_I2C_IP_CLK_FREQ		133000000UL
#define XLP9XX_I2C_FIFO_SIZE		0x80U
#define XLP9XX_I2C_TIMEOUT_MS		1000
#define XLP9XX_I2C_BUSY_TIMEOUT		50

#define XLP9XX_I2C_FIFO_WCNT_MASK	0xff
#define XLP9XX_I2C_STATUS_ERRMASK	(XLP9XX_I2C_INTEN_ARLOST | \
			XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_BUSERR)

struct xlp9xx_i2c_dev {
	struct device *dev;
	struct i2c_adapter adapter;
	struct completion msg_complete;
	struct i2c_smbus_alert_setup alert_data;
	struct i2c_client *ara;
	int irq;
	bool msg_read;
	bool len_recv;
	bool client_pec;
	u32 __iomem *base;
	u32 msg_buf_remaining;
	u32 msg_len;
	u32 ip_clk_hz;
	u32 clk_hz;
	u32 msg_err;
	u8 *msg_buf;
};

static inline void xlp9xx_write_i2c_reg(struct xlp9xx_i2c_dev *priv,
					unsigned long reg, u32 val)
{
	writel(val, priv->base + reg);
}

static inline u32 xlp9xx_read_i2c_reg(struct xlp9xx_i2c_dev *priv,
				      unsigned long reg)
{
	return readl(priv->base + reg);
}

static void xlp9xx_i2c_mask_irq(struct xlp9xx_i2c_dev *priv, u32 mask)
{
	u32 inten;

	inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) & ~mask;
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten);
}

static void xlp9xx_i2c_unmask_irq(struct xlp9xx_i2c_dev *priv, u32 mask)
{
	u32 inten;

	inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) | mask;
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten);
}

static void xlp9xx_i2c_update_rx_fifo_thres(struct xlp9xx_i2c_dev *priv)
{
	u32 thres;

	if (priv->len_recv)
		/* interrupt after the first read to examine
		 * the length byte before proceeding further
		 */
		thres = 1;
	else if (priv->msg_buf_remaining > XLP9XX_I2C_FIFO_SIZE)
		thres = XLP9XX_I2C_FIFO_SIZE;
	else
		thres = priv->msg_buf_remaining;

	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
			     thres << XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT);
}

static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv)
{
	u32 len, i;
	u8 *buf = priv->msg_buf;

	len = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE);
	for (i = 0; i < len; i++)
		xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MTXFIFO, buf[i]);
	priv->msg_buf_remaining -= len;
	priv->msg_buf += len;
}

static void xlp9xx_i2c_update_rlen(struct xlp9xx_i2c_dev *priv)
{
	u32 val, len;

	/*
	 * Update receive length. Re-read len to get the latest value,
	 * and then add 4 to have a minimum value that can be safely
	 * written. This is to account for the byte read above, the
	 * transfer in progress and any delays in the register I/O
	 */
	val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
	len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
				  XLP9XX_I2C_FIFO_WCNT_MASK;
	len = max_t(u32, priv->msg_len, len + 4);
	if (len >= I2C_SMBUS_BLOCK_MAX + 2)
		return;
	val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
			(len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
}

static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
{
	u32 len, i;
	u8 rlen, *buf = priv->msg_buf;

	len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
				  XLP9XX_I2C_FIFO_WCNT_MASK;
	if (!len)
		return;
	if (priv->len_recv) {
		/* read length byte */
		rlen = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);

		/*
		 * We expect at least 2 interrupts for I2C_M_RECV_LEN
		 * transactions. The length is updated during the first
		 * interrupt, and the buffer contents are only copied
		 * during subsequent interrupts. If in case the interrupts
		 * get merged we would complete the transaction without
		 * copying out the bytes from RX fifo. To avoid this now we
		 * drain the fifo as and when data is available.
		 * We drained the rlen byte already, decrement total length
		 * by one.
		 */

		len--;
		if (rlen > I2C_SMBUS_BLOCK_MAX || rlen == 0) {
			rlen = 0;	/*abort transfer */
			priv->msg_buf_remaining = 0;
			priv->msg_len = 0;
			xlp9xx_i2c_update_rlen(priv);
			return;
		}

		*buf++ = rlen;
		if (priv->client_pec)
			++rlen; /* account for error check byte */
		/* update remaining bytes and message length */
		priv->msg_buf_remaining = rlen;
		priv->msg_len = rlen + 1;
		xlp9xx_i2c_update_rlen(priv);
		priv->len_recv = false;
	}

	len = min(priv->msg_buf_remaining, len);
	for (i = 0; i < len; i++, buf++)
		*buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);

	priv->msg_buf_remaining -= len;
	priv->msg_buf = buf;

	if (priv->msg_buf_remaining)
		xlp9xx_i2c_update_rx_fifo_thres(priv);
}

static irqreturn_t xlp9xx_i2c_isr(int irq, void *dev_id)
{
	struct xlp9xx_i2c_dev *priv = dev_id;
	u32 status;

	status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTST);
	if (status == 0)
		return IRQ_NONE;

	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTST, status);
	if (status & XLP9XX_I2C_STATUS_ERRMASK) {
		priv->msg_err = status;
		goto xfer_done;
	}

	/* SADDR ACK for SMBUS_QUICK */
	if ((status & XLP9XX_I2C_INTEN_SADDR) && (priv->msg_len == 0))
		goto xfer_done;

	if (!priv->msg_read) {
		if (status & XLP9XX_I2C_INTEN_MFIFOEMTY) {
			/* TX FIFO got empty, fill it up again */
			if (priv->msg_buf_remaining)
				xlp9xx_i2c_fill_tx_fifo(priv);
			else
				xlp9xx_i2c_mask_irq(priv,
						    XLP9XX_I2C_INTEN_MFIFOEMTY);
		}
	} else {
		if (status & (XLP9XX_I2C_INTEN_DATADONE |
			      XLP9XX_I2C_INTEN_MFIFOHI)) {
			/* data is in FIFO, read it */
			if (priv->msg_buf_remaining)
				xlp9xx_i2c_drain_rx_fifo(priv);
		}
	}

	/* Transfer complete */
	if (status & XLP9XX_I2C_INTEN_DATADONE)
		goto xfer_done;

	return IRQ_HANDLED;

xfer_done:
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
	complete(&priv->msg_complete);
	return IRQ_HANDLED;
}

static int xlp9xx_i2c_check_bus_status(struct xlp9xx_i2c_dev *priv)
{
	u32 status;
	u32 busy_timeout = XLP9XX_I2C_BUSY_TIMEOUT;

	while (busy_timeout) {
		status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_STATUS);
		if ((status & XLP9XX_I2C_STATUS_BUSY) == 0)
			break;

		busy_timeout--;
		usleep_range(1000, 1100);
	}

	if (!busy_timeout)
		return -EIO;

	return 0;
}

static int xlp9xx_i2c_init(struct xlp9xx_i2c_dev *priv)
{
	u32 prescale;

	/*
	 * The controller uses 5 * SCL clock internally.
	 * So prescale value should be divided by 5.
	 */
	prescale = DIV_ROUND_UP(priv->ip_clk_hz, priv->clk_hz);
	prescale = ((prescale - 8) / 5) - 1;
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_RST);
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_EN |
			     XLP9XX_I2C_CTRL_MASTER);
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_DIV, prescale);
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);

	return 0;
}

static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg,
			       int last_msg)
{
	unsigned long timeleft;
	u32 intr_mask, cmd, val, len;

	priv->msg_buf = msg->buf;
	priv->msg_buf_remaining = priv->msg_len = msg->len;
	priv->msg_err = 0;
	priv->msg_read = (msg->flags & I2C_M_RD);
	reinit_completion(&priv->msg_complete);

	/* Reset FIFO */
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
			     XLP9XX_I2C_MFIFOCTRL_RST);

	/* set slave addr */
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_SLAVEADDR,
			     (msg->addr << XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT) |
			     (priv->msg_read ? XLP9XX_I2C_SLAVEADDR_RW : 0));

	/* Build control word for transfer */
	val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
	if (!priv->msg_read)
		val &= ~XLP9XX_I2C_CTRL_FIFORD;
	else
		val |= XLP9XX_I2C_CTRL_FIFORD;	/* read */

	if (msg->flags & I2C_M_TEN)
		val |= XLP9XX_I2C_CTRL_ADDMODE;	/* 10-bit address mode*/
	else
		val &= ~XLP9XX_I2C_CTRL_ADDMODE;

	priv->len_recv = msg->flags & I2C_M_RECV_LEN;
	len = priv->len_recv ? I2C_SMBUS_BLOCK_MAX + 2 : msg->len;
	priv->client_pec = msg->flags & I2C_CLIENT_PEC;

	/* set FIFO threshold if reading */
	if (priv->msg_read)
		xlp9xx_i2c_update_rx_fifo_thres(priv);

	/* set data length to be transferred */
	val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
	      (len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);

	/* fill fifo during tx */
	if (!priv->msg_read)
		xlp9xx_i2c_fill_tx_fifo(priv);

	/* set interrupt mask */
	intr_mask = (XLP9XX_I2C_INTEN_ARLOST | XLP9XX_I2C_INTEN_BUSERR |
		     XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_DATADONE);

	if (priv->msg_read) {
		intr_mask |= XLP9XX_I2C_INTEN_MFIFOHI;
		if (msg->len == 0)
			intr_mask |= XLP9XX_I2C_INTEN_SADDR;
	} else {
		if (msg->len == 0)
			intr_mask |= XLP9XX_I2C_INTEN_SADDR;
		else
			intr_mask |= XLP9XX_I2C_INTEN_MFIFOEMTY;
	}
	xlp9xx_i2c_unmask_irq(priv, intr_mask);

	/* set cmd reg */
	cmd = XLP9XX_I2C_CMD_START;
	if (msg->len)
		cmd |= (priv->msg_read ?
			XLP9XX_I2C_CMD_READ : XLP9XX_I2C_CMD_WRITE);
	if (last_msg)
		cmd |= XLP9XX_I2C_CMD_STOP;

	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CMD, cmd);

	timeleft = msecs_to_jiffies(XLP9XX_I2C_TIMEOUT_MS);
	timeleft = wait_for_completion_timeout(&priv->msg_complete, timeleft);

	if (priv->msg_err & XLP9XX_I2C_INTEN_BUSERR) {
		dev_dbg(priv->dev, "transfer error %x!\n", priv->msg_err);
		xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CMD, XLP9XX_I2C_CMD_STOP);
		return -EIO;
	} else if (priv->msg_err & XLP9XX_I2C_INTEN_NACKADDR) {
		return -ENXIO;
	}

	if (timeleft == 0) {
		dev_dbg(priv->dev, "i2c transfer timed out!\n");
		xlp9xx_i2c_init(priv);
		return -ETIMEDOUT;
	}

	/* update msg->len with actual received length */
	if (msg->flags & I2C_M_RECV_LEN) {
		if (!priv->msg_len)
			return -EPROTO;
		msg->len = priv->msg_len;
	}
	return 0;
}

static int xlp9xx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
			   int num)
{
	int i, ret;
	struct xlp9xx_i2c_dev *priv = i2c_get_adapdata(adap);

	ret = xlp9xx_i2c_check_bus_status(priv);
	if (ret) {
		xlp9xx_i2c_init(priv);
		ret = xlp9xx_i2c_check_bus_status(priv);
		if (ret)
			return ret;
	}

	for (i = 0; i < num; i++) {
		ret = xlp9xx_i2c_xfer_msg(priv, &msgs[i], i == num - 1);
		if (ret != 0)
			return ret;
	}

	return num;
}

static u32 xlp9xx_i2c_functionality(struct i2c_adapter *adapter)
{
	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_READ_BLOCK_DATA |
			I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
}

static const struct i2c_algorithm xlp9xx_i2c_algo = {
	.master_xfer = xlp9xx_i2c_xfer,
	.functionality = xlp9xx_i2c_functionality,
};

static int xlp9xx_i2c_get_frequency(struct platform_device *pdev,
				    struct xlp9xx_i2c_dev *priv)
{
	struct clk *clk;
	u32 freq;
	int err;

	clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(clk)) {
		priv->ip_clk_hz = XLP9XX_I2C_IP_CLK_FREQ;
		dev_dbg(&pdev->dev, "using default input frequency %u\n",
			priv->ip_clk_hz);
	} else {
		priv->ip_clk_hz = clk_get_rate(clk);
	}

	err = device_property_read_u32(&pdev->dev, "clock-frequency", &freq);
	if (err) {
		freq = I2C_MAX_STANDARD_MODE_FREQ;
		dev_dbg(&pdev->dev, "using default frequency %u\n", freq);
	} else if (freq == 0 || freq > I2C_MAX_FAST_MODE_FREQ) {
		dev_warn(&pdev->dev, "invalid frequency %u, using default\n",
			 freq);
		freq = I2C_MAX_STANDARD_MODE_FREQ;
	}
	priv->clk_hz = freq;

	return 0;
}

static int xlp9xx_i2c_smbus_setup(struct xlp9xx_i2c_dev *priv,
				  struct platform_device *pdev)
{
	struct i2c_client *ara;

	if (!priv->alert_data.irq)
		return -EINVAL;

	ara = i2c_new_smbus_alert_device(&priv->adapter, &priv->alert_data);
	if (IS_ERR(ara))
		return PTR_ERR(ara);

	priv->ara = ara;

	return 0;
}

static int xlp9xx_i2c_probe(struct platform_device *pdev)
{
	struct xlp9xx_i2c_dev *priv;
	int err = 0;

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

	priv->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(priv->base))
		return PTR_ERR(priv->base);

	priv->irq = platform_get_irq(pdev, 0);
	if (priv->irq < 0)
		return priv->irq;
	/* SMBAlert irq */
	priv->alert_data.irq = platform_get_irq(pdev, 1);
	if (priv->alert_data.irq <= 0)
		priv->alert_data.irq = 0;

	xlp9xx_i2c_get_frequency(pdev, priv);
	xlp9xx_i2c_init(priv);

	err = devm_request_irq(&pdev->dev, priv->irq, xlp9xx_i2c_isr, 0,
			       pdev->name, priv);
	if (err) {
		dev_err(&pdev->dev, "IRQ request failed!\n");
		return err;
	}

	init_completion(&priv->msg_complete);
	priv->adapter.dev.parent = &pdev->dev;
	priv->adapter.algo = &xlp9xx_i2c_algo;
	priv->adapter.class = I2C_CLASS_HWMON;
	ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&pdev->dev));
	priv->adapter.dev.of_node = pdev->dev.of_node;
	priv->dev = &pdev->dev;

	snprintf(priv->adapter.name, sizeof(priv->adapter.name), "xlp9xx-i2c");
	i2c_set_adapdata(&priv->adapter, priv);

	err = i2c_add_adapter(&priv->adapter);
	if (err)
		return err;

	err = xlp9xx_i2c_smbus_setup(priv, pdev);
	if (err)
		dev_dbg(&pdev->dev, "No active SMBus alert %d\n", err);

	platform_set_drvdata(pdev, priv);
	dev_dbg(&pdev->dev, "I2C bus:%d added\n", priv->adapter.nr);

	return 0;
}

static int xlp9xx_i2c_remove(struct platform_device *pdev)
{
	struct xlp9xx_i2c_dev *priv;

	priv = platform_get_drvdata(pdev);
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
	synchronize_irq(priv->irq);
	i2c_del_adapter(&priv->adapter);
	xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, 0);

	return 0;
}

static const struct of_device_id xlp9xx_i2c_of_match[] = {
	{ .compatible = "netlogic,xlp980-i2c", },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, xlp9xx_i2c_of_match);

#ifdef CONFIG_ACPI
static const struct acpi_device_id xlp9xx_i2c_acpi_ids[] = {
	{"BRCM9007", 0},
	{"CAV9007",  0},
	{}
};
MODULE_DEVICE_TABLE(acpi, xlp9xx_i2c_acpi_ids);
#endif

static struct platform_driver xlp9xx_i2c_driver = {
	.probe = xlp9xx_i2c_probe,
	.remove = xlp9xx_i2c_remove,
	.driver = {
		.name = "xlp9xx-i2c",
		.of_match_table = xlp9xx_i2c_of_match,
		.acpi_match_table = ACPI_PTR(xlp9xx_i2c_acpi_ids),
	},
};

module_platform_driver(xlp9xx_i2c_driver);

MODULE_AUTHOR("Subhendu Sekhar Behera <sbehera@broadcom.com>");
MODULE_DESCRIPTION("XLP9XX/5XX I2C Bus Controller Driver");
MODULE_LICENSE("GPL v2");
