/*
    i2c Support for Apple SMU Controller

    Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp.
                       <benh@kernel.crashing.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <asm/prom.h>
#include <asm/pmac_low_i2c.h>

MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("I2C driver for Apple PowerMac");
MODULE_LICENSE("GPL");

/*
 * SMBUS-type transfer entrypoint
 */
static s32 i2c_powermac_smbus_xfer(	struct i2c_adapter*	adap,
					u16			addr,
					unsigned short		flags,
					char			read_write,
					u8			command,
					int			size,
					union i2c_smbus_data*	data)
{
	struct pmac_i2c_bus	*bus = i2c_get_adapdata(adap);
	int			rc = 0;
	int			read = (read_write == I2C_SMBUS_READ);
	int			addrdir = (addr << 1) | read;
	u8			local[2];

	rc = pmac_i2c_open(bus, 0);
	if (rc)
		return rc;

	switch (size) {
        case I2C_SMBUS_QUICK:
		rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
		if (rc)
			goto bail;
		rc = pmac_i2c_xfer(bus, addrdir, 0, 0, NULL, 0);
	    	break;
        case I2C_SMBUS_BYTE:
		rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
		if (rc)
			goto bail;
		rc = pmac_i2c_xfer(bus, addrdir, 0, 0, &data->byte, 1);
	    	break;
        case I2C_SMBUS_BYTE_DATA:
		rc = pmac_i2c_setmode(bus, read ?
				      pmac_i2c_mode_combined :
				      pmac_i2c_mode_stdsub);
		if (rc)
			goto bail;
		rc = pmac_i2c_xfer(bus, addrdir, 1, command, &data->byte, 1);
	    	break;
        case I2C_SMBUS_WORD_DATA:
		rc = pmac_i2c_setmode(bus, read ?
				      pmac_i2c_mode_combined :
				      pmac_i2c_mode_stdsub);
		if (rc)
			goto bail;
		if (!read) {
			local[0] = data->word & 0xff;
			local[1] = (data->word >> 8) & 0xff;
		}
		rc = pmac_i2c_xfer(bus, addrdir, 1, command, local, 2);
		if (rc == 0 && read) {
			data->word = ((u16)local[1]) << 8;
			data->word |= local[0];
		}
	    	break;

	/* Note that these are broken vs. the expected smbus API where
	 * on reads, the lenght is actually returned from the function,
	 * but I think the current API makes no sense and I don't want
	 * any driver that I haven't verified for correctness to go
	 * anywhere near a pmac i2c bus anyway ...
	 *
	 * I'm also not completely sure what kind of phases to do between
	 * the actual command and the data (what I am _supposed_ to do that
	 * is). For now, I assume writes are a single stream and reads have
	 * a repeat start/addr phase (but not stop in between)
	 */
        case I2C_SMBUS_BLOCK_DATA:
		rc = pmac_i2c_setmode(bus, read ?
				      pmac_i2c_mode_combined :
				      pmac_i2c_mode_stdsub);
		if (rc)
			goto bail;
		rc = pmac_i2c_xfer(bus, addrdir, 1, command, data->block,
				   data->block[0] + 1);

		break;
	case I2C_SMBUS_I2C_BLOCK_DATA:
		rc = pmac_i2c_setmode(bus, read ?
				      pmac_i2c_mode_combined :
				      pmac_i2c_mode_stdsub);
		if (rc)
			goto bail;
		rc = pmac_i2c_xfer(bus, addrdir, 1, command,
				   read ? data->block : &data->block[1],
				   data->block[0]);
		break;

        default:
	    	rc = -EINVAL;
	}
 bail:
	pmac_i2c_close(bus);
	return rc;
}

/*
 * Generic i2c master transfer entrypoint. This driver only support single
 * messages (for "lame i2c" transfers). Anything else should use the smbus
 * entry point
 */
static int i2c_powermac_master_xfer(	struct i2c_adapter *adap,
					struct i2c_msg *msgs,
					int num)
{
	struct pmac_i2c_bus	*bus = i2c_get_adapdata(adap);
	int			rc = 0;
	int			read;
	int			addrdir;

	if (num != 1)
		return -EINVAL;
	if (msgs->flags & I2C_M_TEN)
		return -EINVAL;
	read = (msgs->flags & I2C_M_RD) != 0;
	addrdir = (msgs->addr << 1) | read;
	if (msgs->flags & I2C_M_REV_DIR_ADDR)
		addrdir ^= 1;

	rc = pmac_i2c_open(bus, 0);
	if (rc)
		return rc;
	rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
	if (rc)
		goto bail;
	rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
 bail:
	pmac_i2c_close(bus);
	return rc < 0 ? rc : msgs->len;
}

static u32 i2c_powermac_func(struct i2c_adapter * adapter)
{
	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
		I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_I2C;
}

/* For now, we only handle smbus */
static struct i2c_algorithm i2c_powermac_algorithm = {
	.smbus_xfer	= i2c_powermac_smbus_xfer,
	.master_xfer	= i2c_powermac_master_xfer,
	.functionality	= i2c_powermac_func,
};


static int i2c_powermac_remove(struct device *dev)
{
	struct i2c_adapter	*adapter = dev_get_drvdata(dev);
	struct pmac_i2c_bus	*bus = i2c_get_adapdata(adapter);
	int			rc;

	rc = i2c_del_adapter(adapter);
	pmac_i2c_detach_adapter(bus, adapter);
	i2c_set_adapdata(adapter, NULL);
	/* We aren't that prepared to deal with this... */
	if (rc)
		printk("i2c-powermac.c: Failed to remove bus %s !\n",
		       adapter->name);
	dev_set_drvdata(dev, NULL);
	kfree(adapter);

	return 0;
}


static int i2c_powermac_probe(struct device *dev)
{
	struct pmac_i2c_bus *bus = dev->platform_data;
	struct device_node *parent = NULL;
	struct i2c_adapter *adapter;
	char name[32], *basename;
	int rc;

	if (bus == NULL)
		return -EINVAL;

	/* Ok, now we need to make up a name for the interface that will
	 * match what we used to do in the past, that is basically the
	 * controller's parent device node for keywest. PMU didn't have a
	 * naming convention and SMU has a different one
	 */
	switch(pmac_i2c_get_type(bus)) {
	case pmac_i2c_bus_keywest:
		parent = of_get_parent(pmac_i2c_get_controller(bus));
		if (parent == NULL)
			return -EINVAL;
		basename = parent->name;
		break;
	case pmac_i2c_bus_pmu:
		basename = "pmu";
		break;
	case pmac_i2c_bus_smu:
		/* This is not what we used to do but I'm fixing drivers at
		 * the same time as this change
		 */
		basename = "smu";
		break;
	default:
		return -EINVAL;
	}
	snprintf(name, 32, "%s %d", basename, pmac_i2c_get_channel(bus));
	of_node_put(parent);

	adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
	if (adapter == NULL) {
		printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n");
		return -ENOMEM;
	}
	dev_set_drvdata(dev, adapter);
	strcpy(adapter->name, name);
	adapter->algo = &i2c_powermac_algorithm;
	i2c_set_adapdata(adapter, bus);
	adapter->dev.parent = dev;
	pmac_i2c_attach_adapter(bus, adapter);
	rc = i2c_add_adapter(adapter);
	if (rc) {
		printk(KERN_ERR "i2c-powermac: Adapter %s registration "
		       "failed\n", name);
		i2c_set_adapdata(adapter, NULL);
		pmac_i2c_detach_adapter(bus, adapter);
	}

	printk(KERN_INFO "PowerMac i2c bus %s registered\n", name);
	return rc;
}


static struct device_driver i2c_powermac_driver = {
	.name = "i2c-powermac",
	.bus = &platform_bus_type,
	.probe = i2c_powermac_probe,
	.remove = i2c_powermac_remove,
};

static int __init i2c_powermac_init(void)
{
	driver_register(&i2c_powermac_driver);
	return 0;
}


static void __exit i2c_powermac_cleanup(void)
{
	driver_unregister(&i2c_powermac_driver);
}

module_init(i2c_powermac_init);
module_exit(i2c_powermac_cleanup);
