// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Actions Semiconductor Owl SoC's I2C driver
 *
 * Copyright (c) 2014 Actions Semi Inc.
 * Author: David Liu <liuwei@actions-semi.com>
 *
 * Copyright (c) 2018 Linaro Ltd.
 * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>

/* I2C registers */
#define OWL_I2C_REG_CTL		0x0000
#define OWL_I2C_REG_CLKDIV	0x0004
#define OWL_I2C_REG_STAT	0x0008
#define OWL_I2C_REG_ADDR	0x000C
#define OWL_I2C_REG_TXDAT	0x0010
#define OWL_I2C_REG_RXDAT	0x0014
#define OWL_I2C_REG_CMD		0x0018
#define OWL_I2C_REG_FIFOCTL	0x001C
#define OWL_I2C_REG_FIFOSTAT	0x0020
#define OWL_I2C_REG_DATCNT	0x0024
#define OWL_I2C_REG_RCNT	0x0028

/* I2Cx_CTL Bit Mask */
#define OWL_I2C_CTL_RB		BIT(1)
#define OWL_I2C_CTL_GBCC(x)	(((x) & 0x3) << 2)
#define	OWL_I2C_CTL_GBCC_NONE	OWL_I2C_CTL_GBCC(0)
#define	OWL_I2C_CTL_GBCC_START	OWL_I2C_CTL_GBCC(1)
#define	OWL_I2C_CTL_GBCC_STOP	OWL_I2C_CTL_GBCC(2)
#define	OWL_I2C_CTL_GBCC_RSTART	OWL_I2C_CTL_GBCC(3)
#define OWL_I2C_CTL_IRQE	BIT(5)
#define OWL_I2C_CTL_EN		BIT(7)
#define OWL_I2C_CTL_AE		BIT(8)
#define OWL_I2C_CTL_SHSM	BIT(10)

#define OWL_I2C_DIV_FACTOR(x)	((x) & 0xff)

/* I2Cx_STAT Bit Mask */
#define OWL_I2C_STAT_RACK	BIT(0)
#define OWL_I2C_STAT_BEB	BIT(1)
#define OWL_I2C_STAT_IRQP	BIT(2)
#define OWL_I2C_STAT_LAB	BIT(3)
#define OWL_I2C_STAT_STPD	BIT(4)
#define OWL_I2C_STAT_STAD	BIT(5)
#define OWL_I2C_STAT_BBB	BIT(6)
#define OWL_I2C_STAT_TCB	BIT(7)
#define OWL_I2C_STAT_LBST	BIT(8)
#define OWL_I2C_STAT_SAMB	BIT(9)
#define OWL_I2C_STAT_SRGC	BIT(10)

/* I2Cx_CMD Bit Mask */
#define OWL_I2C_CMD_SBE		BIT(0)
#define OWL_I2C_CMD_RBE		BIT(4)
#define OWL_I2C_CMD_DE		BIT(8)
#define OWL_I2C_CMD_NS		BIT(9)
#define OWL_I2C_CMD_SE		BIT(10)
#define OWL_I2C_CMD_MSS		BIT(11)
#define OWL_I2C_CMD_WRS		BIT(12)
#define OWL_I2C_CMD_SECL	BIT(15)

#define OWL_I2C_CMD_AS(x)	(((x) & 0x7) << 1)
#define OWL_I2C_CMD_SAS(x)	(((x) & 0x7) << 5)

/* I2Cx_FIFOCTL Bit Mask */
#define OWL_I2C_FIFOCTL_NIB	BIT(0)
#define OWL_I2C_FIFOCTL_RFR	BIT(1)
#define OWL_I2C_FIFOCTL_TFR	BIT(2)

/* I2Cc_FIFOSTAT Bit Mask */
#define OWL_I2C_FIFOSTAT_CECB	BIT(0)
#define OWL_I2C_FIFOSTAT_RNB	BIT(1)
#define OWL_I2C_FIFOSTAT_RFE	BIT(2)
#define OWL_I2C_FIFOSTAT_TFF	BIT(5)
#define OWL_I2C_FIFOSTAT_TFD	GENMASK(23, 16)
#define OWL_I2C_FIFOSTAT_RFD	GENMASK(15, 8)

/* I2C bus timeout */
#define OWL_I2C_TIMEOUT_MS	(4 * 1000)
#define OWL_I2C_TIMEOUT		msecs_to_jiffies(OWL_I2C_TIMEOUT_MS)

#define OWL_I2C_MAX_RETRIES	50

struct owl_i2c_dev {
	struct i2c_adapter	adap;
	struct i2c_msg		*msg;
	struct completion	msg_complete;
	struct clk		*clk;
	spinlock_t		lock;
	void __iomem		*base;
	unsigned long		clk_rate;
	u32			bus_freq;
	u32			msg_ptr;
	int			err;
};

static void owl_i2c_update_reg(void __iomem *reg, unsigned int val, bool state)
{
	unsigned int regval;

	regval = readl(reg);

	if (state)
		regval |= val;
	else
		regval &= ~val;

	writel(regval, reg);
}

static void owl_i2c_reset(struct owl_i2c_dev *i2c_dev)
{
	owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
			   OWL_I2C_CTL_EN, false);
	mdelay(1);
	owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
			   OWL_I2C_CTL_EN, true);

	/* Clear status registers */
	writel(0, i2c_dev->base + OWL_I2C_REG_STAT);
}

static int owl_i2c_reset_fifo(struct owl_i2c_dev *i2c_dev)
{
	unsigned int val, timeout = 0;

	/* Reset FIFO */
	owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOCTL,
			   OWL_I2C_FIFOCTL_RFR | OWL_I2C_FIFOCTL_TFR,
			   true);

	/* Wait 50ms for FIFO reset complete */
	do {
		val = readl(i2c_dev->base + OWL_I2C_REG_FIFOCTL);
		if (!(val & (OWL_I2C_FIFOCTL_RFR | OWL_I2C_FIFOCTL_TFR)))
			break;
		usleep_range(500, 1000);
	} while (timeout++ < OWL_I2C_MAX_RETRIES);

	if (timeout > OWL_I2C_MAX_RETRIES) {
		dev_err(&i2c_dev->adap.dev, "FIFO reset timeout\n");
		return -ETIMEDOUT;
	}

	return 0;
}

static void owl_i2c_set_freq(struct owl_i2c_dev *i2c_dev)
{
	unsigned int val;

	val = DIV_ROUND_UP(i2c_dev->clk_rate, i2c_dev->bus_freq * 16);

	/* Set clock divider factor */
	writel(OWL_I2C_DIV_FACTOR(val), i2c_dev->base + OWL_I2C_REG_CLKDIV);
}

static void owl_i2c_xfer_data(struct owl_i2c_dev *i2c_dev)
{
	struct i2c_msg *msg = i2c_dev->msg;
	unsigned int stat, fifostat;

	i2c_dev->err = 0;

	/* Handle NACK from target */
	fifostat = readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT);
	if (fifostat & OWL_I2C_FIFOSTAT_RNB) {
		i2c_dev->err = -ENXIO;
		/* Clear NACK error bit by writing "1" */
		owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOSTAT,
				   OWL_I2C_FIFOSTAT_RNB, true);
		return;
	}

	/* Handle bus error */
	stat = readl(i2c_dev->base + OWL_I2C_REG_STAT);
	if (stat & OWL_I2C_STAT_BEB) {
		i2c_dev->err = -EIO;
		/* Clear BUS error bit by writing "1" */
		owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_STAT,
				   OWL_I2C_STAT_BEB, true);
		return;
	}

	/* Handle FIFO read */
	if (msg->flags & I2C_M_RD) {
		while ((readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT) &
			OWL_I2C_FIFOSTAT_RFE) && i2c_dev->msg_ptr < msg->len) {
			msg->buf[i2c_dev->msg_ptr++] = readl(i2c_dev->base +
							     OWL_I2C_REG_RXDAT);
		}
	} else {
		/* Handle the remaining bytes which were not sent */
		while (!(readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT) &
			 OWL_I2C_FIFOSTAT_TFF) && i2c_dev->msg_ptr < msg->len) {
			writel(msg->buf[i2c_dev->msg_ptr++],
			       i2c_dev->base + OWL_I2C_REG_TXDAT);
		}
	}
}

static irqreturn_t owl_i2c_interrupt(int irq, void *_dev)
{
	struct owl_i2c_dev *i2c_dev = _dev;

	spin_lock(&i2c_dev->lock);

	owl_i2c_xfer_data(i2c_dev);

	/* Clear pending interrupts */
	owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_STAT,
			   OWL_I2C_STAT_IRQP, true);

	complete_all(&i2c_dev->msg_complete);
	spin_unlock(&i2c_dev->lock);

	return IRQ_HANDLED;
}

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

static int owl_i2c_check_bus_busy(struct i2c_adapter *adap)
{
	struct owl_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
	unsigned long timeout;

	/* Check for Bus busy */
	timeout = jiffies + OWL_I2C_TIMEOUT;
	while (readl(i2c_dev->base + OWL_I2C_REG_STAT) & OWL_I2C_STAT_BBB) {
		if (time_after(jiffies, timeout)) {
			dev_err(&adap->dev, "Bus busy timeout\n");
			return -ETIMEDOUT;
		}
	}

	return 0;
}

static int owl_i2c_xfer_common(struct i2c_adapter *adap, struct i2c_msg *msgs,
			       int num, bool atomic)
{
	struct owl_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
	struct i2c_msg *msg;
	unsigned long time_left, flags;
	unsigned int i2c_cmd, val;
	unsigned int addr;
	int ret, idx;

	spin_lock_irqsave(&i2c_dev->lock, flags);

	/* Reset I2C controller */
	owl_i2c_reset(i2c_dev);

	/* Set bus frequency */
	owl_i2c_set_freq(i2c_dev);

	/*
	 * Spinlock should be released before calling reset FIFO and
	 * bus busy check since those functions may sleep
	 */
	spin_unlock_irqrestore(&i2c_dev->lock, flags);

	/* Reset FIFO */
	ret = owl_i2c_reset_fifo(i2c_dev);
	if (ret)
		goto unlocked_err_exit;

	/* Check for bus busy */
	ret = owl_i2c_check_bus_busy(adap);
	if (ret)
		goto unlocked_err_exit;

	spin_lock_irqsave(&i2c_dev->lock, flags);

	/* Check for Arbitration lost */
	val = readl(i2c_dev->base + OWL_I2C_REG_STAT);
	if (val & OWL_I2C_STAT_LAB) {
		val &= ~OWL_I2C_STAT_LAB;
		writel(val, i2c_dev->base + OWL_I2C_REG_STAT);
		ret = -EAGAIN;
		goto err_exit;
	}

	if (!atomic)
		reinit_completion(&i2c_dev->msg_complete);

	/* Enable/disable I2C controller interrupt */
	owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
			   OWL_I2C_CTL_IRQE, !atomic);

	/*
	 * Select: FIFO enable, controller mode, Stop enable, Data count enable,
	 * Send start bit
	 */
	i2c_cmd = OWL_I2C_CMD_SECL | OWL_I2C_CMD_MSS | OWL_I2C_CMD_SE |
		  OWL_I2C_CMD_NS | OWL_I2C_CMD_DE | OWL_I2C_CMD_SBE;

	/* Handle repeated start condition */
	if (num > 1) {
		/* Set internal address length and enable repeated start */
		i2c_cmd |= OWL_I2C_CMD_AS(msgs[0].len + 1) |
			   OWL_I2C_CMD_SAS(1) | OWL_I2C_CMD_RBE;

		/* Write target address */
		addr = i2c_8bit_addr_from_msg(&msgs[0]);
		writel(addr, i2c_dev->base + OWL_I2C_REG_TXDAT);

		/* Write internal register address */
		for (idx = 0; idx < msgs[0].len; idx++)
			writel(msgs[0].buf[idx],
			       i2c_dev->base + OWL_I2C_REG_TXDAT);

		msg = &msgs[1];
	} else {
		/* Set address length */
		i2c_cmd |= OWL_I2C_CMD_AS(1);
		msg = &msgs[0];
	}

	i2c_dev->msg = msg;
	i2c_dev->msg_ptr = 0;

	/* Set data count for the message */
	writel(msg->len, i2c_dev->base + OWL_I2C_REG_DATCNT);

	addr = i2c_8bit_addr_from_msg(msg);
	writel(addr, i2c_dev->base + OWL_I2C_REG_TXDAT);

	if (!(msg->flags & I2C_M_RD)) {
		/* Write data to FIFO */
		for (idx = 0; idx < msg->len; idx++) {
			/* Check for FIFO full */
			if (readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT) &
			    OWL_I2C_FIFOSTAT_TFF)
				break;

			writel(msg->buf[idx],
			       i2c_dev->base + OWL_I2C_REG_TXDAT);
		}

		i2c_dev->msg_ptr = idx;
	}

	/* Ignore the NACK if needed */
	if (msg->flags & I2C_M_IGNORE_NAK)
		owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOCTL,
				   OWL_I2C_FIFOCTL_NIB, true);
	else
		owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOCTL,
				   OWL_I2C_FIFOCTL_NIB, false);

	/* Start the transfer */
	writel(i2c_cmd, i2c_dev->base + OWL_I2C_REG_CMD);

	spin_unlock_irqrestore(&i2c_dev->lock, flags);

	if (atomic) {
		/* Wait for Command Execute Completed or NACK Error bits */
		ret = readl_poll_timeout_atomic(i2c_dev->base + OWL_I2C_REG_FIFOSTAT,
						val, val & (OWL_I2C_FIFOSTAT_CECB |
							    OWL_I2C_FIFOSTAT_RNB),
						10, OWL_I2C_TIMEOUT_MS * 1000);
	} else {
		time_left = wait_for_completion_timeout(&i2c_dev->msg_complete,
							adap->timeout);
		if (!time_left)
			ret = -ETIMEDOUT;
	}

	spin_lock_irqsave(&i2c_dev->lock, flags);

	if (ret) {
		dev_err(&adap->dev, "Transaction timed out\n");
		/* Send stop condition and release the bus */
		owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
				   OWL_I2C_CTL_GBCC_STOP | OWL_I2C_CTL_RB,
				   true);
		goto err_exit;
	}

	if (atomic)
		owl_i2c_xfer_data(i2c_dev);

	ret = i2c_dev->err < 0 ? i2c_dev->err : num;

err_exit:
	spin_unlock_irqrestore(&i2c_dev->lock, flags);

unlocked_err_exit:
	/* Disable I2C controller */
	owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
			   OWL_I2C_CTL_EN, false);

	return ret;
}

static int owl_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
			int num)
{
	return owl_i2c_xfer_common(adap, msgs, num, false);
}

static int owl_i2c_xfer_atomic(struct i2c_adapter *adap,
			       struct i2c_msg *msgs, int num)
{
	return owl_i2c_xfer_common(adap, msgs, num, true);
}

static const struct i2c_algorithm owl_i2c_algorithm = {
	.xfer = owl_i2c_xfer,
	.xfer_atomic = owl_i2c_xfer_atomic,
	.functionality = owl_i2c_func,
};

static const struct i2c_adapter_quirks owl_i2c_quirks = {
	.flags		= I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST,
	.max_read_len   = 240,
	.max_write_len  = 240,
	.max_comb_1st_msg_len = 6,
	.max_comb_2nd_msg_len = 240,
};

static int owl_i2c_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct owl_i2c_dev *i2c_dev;
	int ret, irq;

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

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

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	if (of_property_read_u32(dev->of_node, "clock-frequency",
				 &i2c_dev->bus_freq))
		i2c_dev->bus_freq = I2C_MAX_STANDARD_MODE_FREQ;

	/* We support only frequencies of 100k and 400k for now */
	if (i2c_dev->bus_freq != I2C_MAX_STANDARD_MODE_FREQ &&
	    i2c_dev->bus_freq != I2C_MAX_FAST_MODE_FREQ) {
		dev_err(dev, "invalid clock-frequency %d\n", i2c_dev->bus_freq);
		return -EINVAL;
	}

	i2c_dev->clk = devm_clk_get_enabled(dev, NULL);
	if (IS_ERR(i2c_dev->clk)) {
		dev_err(dev, "failed to enable clock\n");
		return PTR_ERR(i2c_dev->clk);
	}

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

	init_completion(&i2c_dev->msg_complete);
	spin_lock_init(&i2c_dev->lock);
	i2c_dev->adap.owner = THIS_MODULE;
	i2c_dev->adap.algo = &owl_i2c_algorithm;
	i2c_dev->adap.timeout = OWL_I2C_TIMEOUT;
	i2c_dev->adap.quirks = &owl_i2c_quirks;
	i2c_dev->adap.dev.parent = dev;
	i2c_dev->adap.dev.of_node = dev->of_node;
	snprintf(i2c_dev->adap.name, sizeof(i2c_dev->adap.name),
		 "%s", "OWL I2C adapter");
	i2c_set_adapdata(&i2c_dev->adap, i2c_dev);

	platform_set_drvdata(pdev, i2c_dev);

	ret = devm_request_irq(dev, irq, owl_i2c_interrupt, 0, pdev->name,
			       i2c_dev);
	if (ret) {
		dev_err(dev, "failed to request irq %d\n", irq);
		return ret;
	}

	return i2c_add_adapter(&i2c_dev->adap);
}

static const struct of_device_id owl_i2c_of_match[] = {
	{ .compatible = "actions,s500-i2c" },
	{ .compatible = "actions,s700-i2c" },
	{ .compatible = "actions,s900-i2c" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, owl_i2c_of_match);

static struct platform_driver owl_i2c_driver = {
	.probe		= owl_i2c_probe,
	.driver		= {
		.name	= "owl-i2c",
		.of_match_table = owl_i2c_of_match,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
	},
};
module_platform_driver(owl_i2c_driver);

MODULE_AUTHOR("David Liu <liuwei@actions-semi.com>");
MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
MODULE_DESCRIPTION("Actions Semiconductor Owl SoC's I2C driver");
MODULE_LICENSE("GPL");
