/*
 *  i2c_pca_platform.c
 *
 *  Platform driver for the PCA9564 I2C controller.
 *
 *  Copyright (C) 2008 Pengutronix
 *
 *  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/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/i2c-algo-pca.h>
#include <linux/i2c-pca-platform.h>
#include <linux/gpio.h>

#include <asm/irq.h>
#include <asm/io.h>

struct i2c_pca_pf_data {
	void __iomem			*reg_base;
	int				irq;	/* if 0, use polling */
	int				gpio;
	wait_queue_head_t		wait;
	struct i2c_adapter		adap;
	struct i2c_algo_pca_data	algo_data;
	unsigned long			io_base;
	unsigned long			io_size;
};

/* Read/Write functions for different register alignments */

static int i2c_pca_pf_readbyte8(void *pd, int reg)
{
	struct i2c_pca_pf_data *i2c = pd;
	return ioread8(i2c->reg_base + reg);
}

static int i2c_pca_pf_readbyte16(void *pd, int reg)
{
	struct i2c_pca_pf_data *i2c = pd;
	return ioread8(i2c->reg_base + reg * 2);
}

static int i2c_pca_pf_readbyte32(void *pd, int reg)
{
	struct i2c_pca_pf_data *i2c = pd;
	return ioread8(i2c->reg_base + reg * 4);
}

static void i2c_pca_pf_writebyte8(void *pd, int reg, int val)
{
	struct i2c_pca_pf_data *i2c = pd;
	iowrite8(val, i2c->reg_base + reg);
}

static void i2c_pca_pf_writebyte16(void *pd, int reg, int val)
{
	struct i2c_pca_pf_data *i2c = pd;
	iowrite8(val, i2c->reg_base + reg * 2);
}

static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
{
	struct i2c_pca_pf_data *i2c = pd;
	iowrite8(val, i2c->reg_base + reg * 4);
}


static int i2c_pca_pf_waitforcompletion(void *pd)
{
	struct i2c_pca_pf_data *i2c = pd;
	long ret = ~0;
	unsigned long timeout;

	if (i2c->irq) {
		ret = wait_event_interruptible_timeout(i2c->wait,
			i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
			& I2C_PCA_CON_SI, i2c->adap.timeout);
	} else {
		/* Do polling */
		timeout = jiffies + i2c->adap.timeout;
		while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
				& I2C_PCA_CON_SI) == 0)
				&& (ret = time_before(jiffies, timeout)))
			udelay(100);
	}

	return ret > 0;
}

static void i2c_pca_pf_dummyreset(void *pd)
{
	struct i2c_pca_pf_data *i2c = pd;
	printk(KERN_WARNING "%s: No reset-pin found. Chip may get stuck!\n",
		i2c->adap.name);
}

static void i2c_pca_pf_resetchip(void *pd)
{
	struct i2c_pca_pf_data *i2c = pd;

	gpio_set_value(i2c->gpio, 0);
	ndelay(100);
	gpio_set_value(i2c->gpio, 1);
}

static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id)
{
	struct i2c_pca_pf_data *i2c = dev_id;

	if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
		return IRQ_NONE;

	wake_up_interruptible(&i2c->wait);

	return IRQ_HANDLED;
}


static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
{
	struct i2c_pca_pf_data *i2c;
	struct resource *res;
	struct i2c_pca9564_pf_platform_data *platform_data =
				pdev->dev.platform_data;
	int ret = 0;
	int irq;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	/* If irq is 0, we do polling. */

	if (res == NULL) {
		ret = -ENODEV;
		goto e_print;
	}

	if (!request_mem_region(res->start, resource_size(res), res->name)) {
		ret = -ENOMEM;
		goto e_print;
	}

	i2c = kzalloc(sizeof(struct i2c_pca_pf_data), GFP_KERNEL);
	if (!i2c) {
		ret = -ENOMEM;
		goto e_alloc;
	}

	init_waitqueue_head(&i2c->wait);

	i2c->reg_base = ioremap(res->start, resource_size(res));
	if (!i2c->reg_base) {
		ret = -ENOMEM;
		goto e_remap;
	}
	i2c->io_base = res->start;
	i2c->io_size = resource_size(res);
	i2c->irq = irq;

	i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
	i2c->adap.owner = THIS_MODULE;
	snprintf(i2c->adap.name, sizeof(i2c->adap.name),
		 "PCA9564/PCA9665 at 0x%08lx",
		 (unsigned long) res->start);
	i2c->adap.algo_data = &i2c->algo_data;
	i2c->adap.dev.parent = &pdev->dev;

	if (platform_data) {
		i2c->adap.timeout = platform_data->timeout;
		i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
		i2c->gpio = platform_data->gpio;
	} else {
		i2c->adap.timeout = HZ;
		i2c->algo_data.i2c_clock = 59000;
		i2c->gpio = -1;
	}

	i2c->algo_data.data = i2c;
	i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
	i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;

	switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
	case IORESOURCE_MEM_32BIT:
		i2c->algo_data.write_byte = i2c_pca_pf_writebyte32;
		i2c->algo_data.read_byte = i2c_pca_pf_readbyte32;
		break;
	case IORESOURCE_MEM_16BIT:
		i2c->algo_data.write_byte = i2c_pca_pf_writebyte16;
		i2c->algo_data.read_byte = i2c_pca_pf_readbyte16;
		break;
	case IORESOURCE_MEM_8BIT:
	default:
		i2c->algo_data.write_byte = i2c_pca_pf_writebyte8;
		i2c->algo_data.read_byte = i2c_pca_pf_readbyte8;
		break;
	}

	/* Use gpio_is_valid() when in mainline */
	if (i2c->gpio > -1) {
		ret = gpio_request(i2c->gpio, i2c->adap.name);
		if (ret == 0) {
			gpio_direction_output(i2c->gpio, 1);
			i2c->algo_data.reset_chip = i2c_pca_pf_resetchip;
		} else {
			printk(KERN_WARNING "%s: Registering gpio failed!\n",
				i2c->adap.name);
			i2c->gpio = ret;
		}
	}

	if (irq) {
		ret = request_irq(irq, i2c_pca_pf_handler,
			IRQF_TRIGGER_FALLING, i2c->adap.name, i2c);
		if (ret)
			goto e_reqirq;
	}

	if (i2c_pca_add_numbered_bus(&i2c->adap) < 0) {
		ret = -ENODEV;
		goto e_adapt;
	}

	platform_set_drvdata(pdev, i2c);

	printk(KERN_INFO "%s registered.\n", i2c->adap.name);

	return 0;

e_adapt:
	if (irq)
		free_irq(irq, i2c);
e_reqirq:
	if (i2c->gpio > -1)
		gpio_free(i2c->gpio);

	iounmap(i2c->reg_base);
e_remap:
	kfree(i2c);
e_alloc:
	release_mem_region(res->start, resource_size(res));
e_print:
	printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret);
	return ret;
}

static int __devexit i2c_pca_pf_remove(struct platform_device *pdev)
{
	struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev);
	platform_set_drvdata(pdev, NULL);

	i2c_del_adapter(&i2c->adap);

	if (i2c->irq)
		free_irq(i2c->irq, i2c);

	if (i2c->gpio > -1)
		gpio_free(i2c->gpio);

	iounmap(i2c->reg_base);
	release_mem_region(i2c->io_base, i2c->io_size);
	kfree(i2c);

	return 0;
}

static struct platform_driver i2c_pca_pf_driver = {
	.probe = i2c_pca_pf_probe,
	.remove = __devexit_p(i2c_pca_pf_remove),
	.driver = {
		.name = "i2c-pca-platform",
		.owner = THIS_MODULE,
	},
};

static int __init i2c_pca_pf_init(void)
{
	return platform_driver_register(&i2c_pca_pf_driver);
}

static void __exit i2c_pca_pf_exit(void)
{
	platform_driver_unregister(&i2c_pca_pf_driver);
}

MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
MODULE_LICENSE("GPL");

module_init(i2c_pca_pf_init);
module_exit(i2c_pca_pf_exit);

