/*
 * 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
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#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 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) {
		dev_err(&pdev->dev, "Adapter '%s' registration failed\n",
				adapter->name);
		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");
