// SPDX-License-Identifier: GPL-2.0-only
/*
 * I2C driver for PKUnity-v3 SoC
 * Code specific to PKUnity SoC and UniCore ISA
 *
 *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
 *	Copyright (C) 2001-2010 Guan Xuetao
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <mach/hardware.h>

/*
 * Poll the i2c status register until the specified bit is set.
 * Returns 0 if timed out (100 msec).
 */
static short poll_status(unsigned long bit)
{
	int loop_cntr = 1000;

	if (bit & I2C_STATUS_TFNF) {
		do {
			udelay(10);
		} while (!(readl(I2C_STATUS) & bit) && (--loop_cntr > 0));
	} else {
		/* RXRDY handler */
		do {
			if (readl(I2C_TAR) == I2C_TAR_EEPROM)
				msleep(20);
			else
				udelay(10);
		} while (!(readl(I2C_RXFLR) & 0xf) && (--loop_cntr > 0));
	}

	return (loop_cntr > 0);
}

static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
{
	int i2c_reg = *buf;

	/* Read data */
	while (length--) {
		if (!poll_status(I2C_STATUS_TFNF)) {
			dev_dbg(&adap->dev, "Tx FIFO Not Full timeout\n");
			return -ETIMEDOUT;
		}

		/* send addr */
		writel(i2c_reg | I2C_DATACMD_WRITE, I2C_DATACMD);

		/* get ready to next write */
		i2c_reg++;

		/* send read CMD */
		writel(I2C_DATACMD_READ, I2C_DATACMD);

		/* wait until the Rx FIFO have available */
		if (!poll_status(I2C_STATUS_RFNE)) {
			dev_dbg(&adap->dev, "RXRDY timeout\n");
			return -ETIMEDOUT;
		}

		/* read the data to buf */
		*buf = (readl(I2C_DATACMD) & I2C_DATACMD_DAT_MASK);
		buf++;
	}

	return 0;
}

static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length)
{
	int i2c_reg = *buf;

	/* Do nothing but storing the reg_num to a static variable */
	if (i2c_reg == -1) {
		printk(KERN_WARNING "Error i2c reg\n");
		return -ETIMEDOUT;
	}

	if (length == 1)
		return 0;

	buf++;
	length--;
	while (length--) {
		/* send addr */
		writel(i2c_reg | I2C_DATACMD_WRITE, I2C_DATACMD);

		/* send write CMD */
		writel(*buf | I2C_DATACMD_WRITE, I2C_DATACMD);

		/* wait until the Rx FIFO have available */
		msleep(20);

		/* read the data to buf */
		i2c_reg++;
		buf++;
	}

	return 0;
}

/*
 * Generic i2c master transfer entrypoint.
 *
 */
static int puv3_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg,
		int num)
{
	int i, ret;
	unsigned char swap;

	/* Disable i2c */
	writel(I2C_ENABLE_DISABLE, I2C_ENABLE);

	/* Set the work mode and speed*/
	writel(I2C_CON_MASTER | I2C_CON_SPEED_STD | I2C_CON_SLAVEDISABLE, I2C_CON);

	writel(pmsg->addr, I2C_TAR);

	/* Enable i2c */
	writel(I2C_ENABLE_ENABLE, I2C_ENABLE);

	dev_dbg(&adap->dev, "puv3_i2c_xfer: processing %d messages:\n", num);

	for (i = 0; i < num; i++) {
		dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i,
			pmsg->flags & I2C_M_RD ? "read" : "writ",
			pmsg->len, pmsg->len > 1 ? "s" : "",
			pmsg->flags & I2C_M_RD ? "from" : "to",	pmsg->addr);

		if (pmsg->len && pmsg->buf) {	/* sanity check */
			if (pmsg->flags & I2C_M_RD)
				ret = xfer_read(adap, pmsg->buf, pmsg->len);
			else
				ret = xfer_write(adap, pmsg->buf, pmsg->len);

			if (ret)
				return ret;

		}
		dev_dbg(&adap->dev, "transfer complete\n");
		pmsg++;		/* next message */
	}

	/* XXX: fixup be16_to_cpu in bq27x00_battery.c */
	if (pmsg->addr == I2C_TAR_PWIC) {
		swap = pmsg->buf[0];
		pmsg->buf[0] = pmsg->buf[1];
		pmsg->buf[1] = swap;
	}

	return i;
}

/*
 * Return list of supported functionality.
 */
static u32 puv3_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

static const struct i2c_algorithm puv3_i2c_algorithm = {
	.master_xfer	= puv3_i2c_xfer,
	.functionality	= puv3_i2c_func,
};

/*
 * Main initialization routine.
 */
static int puv3_i2c_probe(struct platform_device *pdev)
{
	struct i2c_adapter *adapter;
	struct resource *mem;
	int rc;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem)
		return -ENODEV;

	if (!request_mem_region(mem->start, resource_size(mem), "puv3_i2c"))
		return -EBUSY;

	adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
	if (adapter == NULL) {
		dev_err(&pdev->dev, "can't allocate interface!\n");
		rc = -ENOMEM;
		goto fail_nomem;
	}
	snprintf(adapter->name, sizeof(adapter->name), "PUV3-I2C at 0x%08x",
			mem->start);
	adapter->algo = &puv3_i2c_algorithm;
	adapter->class = I2C_CLASS_HWMON;
	adapter->dev.parent = &pdev->dev;

	platform_set_drvdata(pdev, adapter);

	adapter->nr = pdev->id;
	rc = i2c_add_numbered_adapter(adapter);
	if (rc)
		goto fail_add_adapter;

	dev_info(&pdev->dev, "PKUnity v3 i2c bus adapter.\n");
	return 0;

fail_add_adapter:
	kfree(adapter);
fail_nomem:
	release_mem_region(mem->start, resource_size(mem));

	return rc;
}

static int puv3_i2c_remove(struct platform_device *pdev)
{
	struct i2c_adapter *adapter = platform_get_drvdata(pdev);
	struct resource *mem;

	i2c_del_adapter(adapter);

	put_device(&pdev->dev);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(mem->start, resource_size(mem));

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int puv3_i2c_suspend(struct device *dev)
{
	int poll_count;
	/* Disable the IIC */
	writel(I2C_ENABLE_DISABLE, I2C_ENABLE);
	for (poll_count = 0; poll_count < 50; poll_count++) {
		if (readl(I2C_ENSTATUS) & I2C_ENSTATUS_ENABLE)
			udelay(25);
	}

	return 0;
}

static SIMPLE_DEV_PM_OPS(puv3_i2c_pm, puv3_i2c_suspend, NULL);
#define PUV3_I2C_PM	(&puv3_i2c_pm)

#else
#define PUV3_I2C_PM	NULL
#endif

static struct platform_driver puv3_i2c_driver = {
	.probe		= puv3_i2c_probe,
	.remove		= puv3_i2c_remove,
	.driver		= {
		.name	= "PKUnity-v3-I2C",
		.pm	= PUV3_I2C_PM,
	}
};

module_platform_driver(puv3_i2c_driver);

MODULE_DESCRIPTION("PKUnity v3 I2C driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:puv3_i2c");
