/*
 *  i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters
 *    Copyright (C) 2004 Arcom Control Systems
 *    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 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/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-pca.h>

#define DEB1(fmt, args...) do { if (i2c_debug >= 1)			\
				 printk(KERN_DEBUG fmt, ## args); } while (0)
#define DEB2(fmt, args...) do { if (i2c_debug >= 2)			\
				 printk(KERN_DEBUG fmt, ## args); } while (0)
#define DEB3(fmt, args...) do { if (i2c_debug >= 3)			\
				 printk(KERN_DEBUG fmt, ## args); } while (0)

static int i2c_debug;

#define pca_outw(adap, reg, val) adap->write_byte(adap->data, reg, val)
#define pca_inw(adap, reg) adap->read_byte(adap->data, reg)

#define pca_status(adap) pca_inw(adap, I2C_PCA_STA)
#define pca_clock(adap) adap->i2c_clock
#define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)
#define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)
#define pca_wait(adap) adap->wait_for_completion(adap->data)
#define pca_reset(adap) adap->reset_chip(adap->data)

static void pca9665_reset(void *pd)
{
	struct i2c_algo_pca_data *adap = pd;
	pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
	pca_outw(adap, I2C_PCA_IND, 0xA5);
	pca_outw(adap, I2C_PCA_IND, 0x5A);
}

/*
 * Generate a start condition on the i2c bus.
 *
 * returns after the start condition has occurred
 */
static int pca_start(struct i2c_algo_pca_data *adap)
{
	int sta = pca_get_con(adap);
	DEB2("=== START\n");
	sta |= I2C_PCA_CON_STA;
	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);
	return pca_wait(adap);
}

/*
 * Generate a repeated start condition on the i2c bus
 *
 * return after the repeated start condition has occurred
 */
static int pca_repeated_start(struct i2c_algo_pca_data *adap)
{
	int sta = pca_get_con(adap);
	DEB2("=== REPEATED START\n");
	sta |= I2C_PCA_CON_STA;
	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);
	return pca_wait(adap);
}

/*
 * Generate a stop condition on the i2c bus
 *
 * returns after the stop condition has been generated
 *
 * STOPs do not generate an interrupt or set the SI flag, since the
 * part returns the idle state (0xf8). Hence we don't need to
 * pca_wait here.
 */
static void pca_stop(struct i2c_algo_pca_data *adap)
{
	int sta = pca_get_con(adap);
	DEB2("=== STOP\n");
	sta |= I2C_PCA_CON_STO;
	sta &= ~(I2C_PCA_CON_STA|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);
}

/*
 * Send the slave address and R/W bit
 *
 * returns after the address has been sent
 */
static int pca_address(struct i2c_algo_pca_data *adap,
			struct i2c_msg *msg)
{
	int sta = pca_get_con(adap);
	int addr;

	addr = ( (0x7f & msg->addr) << 1 );
	if (msg->flags & I2C_M_RD )
		addr |= 1;
	DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n",
	     msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);

	pca_outw(adap, I2C_PCA_DAT, addr);

	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);

	return pca_wait(adap);
}

/*
 * Transmit a byte.
 *
 * Returns after the byte has been transmitted
 */
static int pca_tx_byte(struct i2c_algo_pca_data *adap,
			__u8 b)
{
	int sta = pca_get_con(adap);
	DEB2("=== WRITE %#04x\n", b);
	pca_outw(adap, I2C_PCA_DAT, b);

	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
	pca_set_con(adap, sta);

	return pca_wait(adap);
}

/*
 * Receive a byte
 *
 * returns immediately.
 */
static void pca_rx_byte(struct i2c_algo_pca_data *adap,
			__u8 *b, int ack)
{
	*b = pca_inw(adap, I2C_PCA_DAT);
	DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK");
}

/*
 * Setup ACK or NACK for next received byte and wait for it to arrive.
 *
 * Returns after next byte has arrived.
 */
static int pca_rx_ack(struct i2c_algo_pca_data *adap,
		       int ack)
{
	int sta = pca_get_con(adap);

	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI|I2C_PCA_CON_AA);

	if ( ack )
		sta |= I2C_PCA_CON_AA;

	pca_set_con(adap, sta);
	return pca_wait(adap);
}

static int pca_xfer(struct i2c_adapter *i2c_adap,
                    struct i2c_msg *msgs,
                    int num)
{
        struct i2c_algo_pca_data *adap = i2c_adap->algo_data;
        struct i2c_msg *msg = NULL;
        int curmsg;
	int numbytes = 0;
	int state;
	int ret;
	int completed = 1;
	unsigned long timeout = jiffies + i2c_adap->timeout;

	while ((state = pca_status(adap)) != 0xf8) {
		if (time_before(jiffies, timeout)) {
			msleep(10);
		} else {
			dev_dbg(&i2c_adap->dev, "bus is not idle. status is "
				"%#04x\n", state);
			return -EAGAIN;
		}
	}

	DEB1("{{{ XFER %d messages\n", num);

	if (i2c_debug>=2) {
		for (curmsg = 0; curmsg < num; curmsg++) {
			int addr, i;
			msg = &msgs[curmsg];

			addr = (0x7f & msg->addr) ;

			if (msg->flags & I2C_M_RD )
				printk(KERN_INFO "    [%02d] RD %d bytes from %#02x [%#02x, ...]\n",
				       curmsg, msg->len, addr, (addr<<1) | 1);
			else {
				printk(KERN_INFO "    [%02d] WR %d bytes to %#02x [%#02x%s",
				       curmsg, msg->len, addr, addr<<1,
				       msg->len == 0 ? "" : ", ");
				for(i=0; i < msg->len; i++)
					printk("%#04x%s", msg->buf[i], i == msg->len - 1 ? "" : ", ");
				printk("]\n");
			}
		}
	}

	curmsg = 0;
	ret = -EREMOTEIO;
	while (curmsg < num) {
		state = pca_status(adap);

		DEB3("STATE is 0x%02x\n", state);
		msg = &msgs[curmsg];

		switch (state) {
		case 0xf8: /* On reset or stop the bus is idle */
			completed = pca_start(adap);
			break;

		case 0x08: /* A START condition has been transmitted */
		case 0x10: /* A repeated start condition has been transmitted */
			completed = pca_address(adap, msg);
			break;

		case 0x18: /* SLA+W has been transmitted; ACK has been received */
		case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
			if (numbytes < msg->len) {
				completed = pca_tx_byte(adap,
							msg->buf[numbytes]);
				numbytes++;
				break;
			}
			curmsg++; numbytes = 0;
			if (curmsg == num)
				pca_stop(adap);
			else
				completed = pca_repeated_start(adap);
			break;

		case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after SLA+W\n");
			pca_stop(adap);
			goto out;

		case 0x40: /* SLA+R has been transmitted; ACK has been received */
			completed = pca_rx_ack(adap, msg->len > 1);
			break;

		case 0x50: /* Data bytes has been received; ACK has been returned */
			if (numbytes < msg->len) {
				pca_rx_byte(adap, &msg->buf[numbytes], 1);
				numbytes++;
				completed = pca_rx_ack(adap,
						       numbytes < msg->len - 1);
				break;
			}
			curmsg++; numbytes = 0;
			if (curmsg == num)
				pca_stop(adap);
			else
				completed = pca_repeated_start(adap);
			break;

		case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after SLA+R\n");
			pca_stop(adap);
			goto out;

		case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */
			DEB2("NOT ACK received after data byte\n");
			pca_stop(adap);
			goto out;

		case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
			DEB2("Arbitration lost\n");
			/*
			 * The PCA9564 data sheet (2006-09-01) says "A
			 * START condition will be transmitted when the
			 * bus becomes free (STOP or SCL and SDA high)"
			 * when the STA bit is set (p. 11).
			 *
			 * In case this won't work, try pca_reset()
			 * instead.
			 */
			pca_start(adap);
			goto out;

		case 0x58: /* Data byte has been received; NOT ACK has been returned */
			if ( numbytes == msg->len - 1 ) {
				pca_rx_byte(adap, &msg->buf[numbytes], 0);
				curmsg++; numbytes = 0;
				if (curmsg == num)
					pca_stop(adap);
				else
					completed = pca_repeated_start(adap);
			} else {
				DEB2("NOT ACK sent after data byte received. "
				     "Not final byte. numbytes %d. len %d\n",
				     numbytes, msg->len);
				pca_stop(adap);
				goto out;
			}
			break;
		case 0x70: /* Bus error - SDA stuck low */
			DEB2("BUS ERROR - SDA Stuck low\n");
			pca_reset(adap);
			goto out;
		case 0x90: /* Bus error - SCL stuck low */
			DEB2("BUS ERROR - SCL Stuck low\n");
			pca_reset(adap);
			goto out;
		case 0x00: /* Bus error during master or slave mode due to illegal START or STOP condition */
			DEB2("BUS ERROR - Illegal START or STOP\n");
			pca_reset(adap);
			goto out;
		default:
			dev_err(&i2c_adap->dev, "unhandled SIO state 0x%02x\n", state);
			break;
		}

		if (!completed)
			goto out;
	}

	ret = curmsg;
 out:
	DEB1("}}} transfered %d/%d messages. "
	     "status is %#04x. control is %#04x\n",
	     curmsg, num, pca_status(adap),
	     pca_get_con(adap));
	return ret;
}

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

static const struct i2c_algorithm pca_algo = {
	.master_xfer	= pca_xfer,
	.functionality	= pca_func,
};

static unsigned int pca_probe_chip(struct i2c_adapter *adap)
{
	struct i2c_algo_pca_data *pca_data = adap->algo_data;
	/* The trick here is to check if there is an indirect register
	 * available. If there is one, we will read the value we first
	 * wrote on I2C_PCA_IADR. Otherwise, we will read the last value
	 * we wrote on I2C_PCA_ADR
	 */
	pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
	pca_outw(pca_data, I2C_PCA_IND, 0xAA);
	pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO);
	pca_outw(pca_data, I2C_PCA_IND, 0x00);
	pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
	if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {
		printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name);
		return I2C_PCA_CHIP_9665;
	} else {
		printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name);
		return I2C_PCA_CHIP_9564;
	}
}

static int pca_init(struct i2c_adapter *adap)
{
	struct i2c_algo_pca_data *pca_data = adap->algo_data;

	adap->algo = &pca_algo;

	if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) {
		static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36};
		int clock;

		if (pca_data->i2c_clock > 7) {
			switch (pca_data->i2c_clock) {
			case 330000:
				pca_data->i2c_clock = I2C_PCA_CON_330kHz;
				break;
			case 288000:
				pca_data->i2c_clock = I2C_PCA_CON_288kHz;
				break;
			case 217000:
				pca_data->i2c_clock = I2C_PCA_CON_217kHz;
				break;
			case 146000:
				pca_data->i2c_clock = I2C_PCA_CON_146kHz;
				break;
			case 88000:
				pca_data->i2c_clock = I2C_PCA_CON_88kHz;
				break;
			case 59000:
				pca_data->i2c_clock = I2C_PCA_CON_59kHz;
				break;
			case 44000:
				pca_data->i2c_clock = I2C_PCA_CON_44kHz;
				break;
			case 36000:
				pca_data->i2c_clock = I2C_PCA_CON_36kHz;
				break;
			default:
				printk(KERN_WARNING
					"%s: Invalid I2C clock speed selected."
					" Using default 59kHz.\n", adap->name);
			pca_data->i2c_clock = I2C_PCA_CON_59kHz;
			}
		} else {
			printk(KERN_WARNING "%s: "
				"Choosing the clock frequency based on "
				"index is deprecated."
				" Use the nominal frequency.\n", adap->name);
		}

		pca_reset(pca_data);

		clock = pca_clock(pca_data);
		printk(KERN_INFO "%s: Clock frequency is %dkHz\n",
		     adap->name, freqs[clock]);

		pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
	} else {
		int clock;
		int mode;
		int tlow, thi;
		/* Values can be found on PCA9665 datasheet section 7.3.2.6 */
		int min_tlow, min_thi;
		/* These values are the maximum raise and fall values allowed
		 * by the I2C operation mode (Standard, Fast or Fast+)
		 * They are used (added) below to calculate the clock dividers
		 * of PCA9665. Note that they are slightly different of the
		 * real maximum, to allow the change on mode exactly on the
		 * maximum clock rate for each mode
		 */
		int raise_fall_time;

		struct i2c_algo_pca_data *pca_data = adap->algo_data;

		/* Ignore the reset function from the module,
		 * we can use the parallel bus reset
		 */
		pca_data->reset_chip = pca9665_reset;

		if (pca_data->i2c_clock > 1265800) {
			printk(KERN_WARNING "%s: I2C clock speed too high."
				" Using 1265.8kHz.\n", adap->name);
			pca_data->i2c_clock = 1265800;
		}

		if (pca_data->i2c_clock < 60300) {
			printk(KERN_WARNING "%s: I2C clock speed too low."
				" Using 60.3kHz.\n", adap->name);
			pca_data->i2c_clock = 60300;
		}

		/* To avoid integer overflow, use clock/100 for calculations */
		clock = pca_clock(pca_data) / 100;

		if (pca_data->i2c_clock > 10000) {
			mode = I2C_PCA_MODE_TURBO;
			min_tlow = 14;
			min_thi  = 5;
			raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
		} else if (pca_data->i2c_clock > 4000) {
			mode = I2C_PCA_MODE_FASTP;
			min_tlow = 17;
			min_thi  = 9;
			raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
		} else if (pca_data->i2c_clock > 1000) {
			mode = I2C_PCA_MODE_FAST;
			min_tlow = 44;
			min_thi  = 20;
			raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */
		} else {
			mode = I2C_PCA_MODE_STD;
			min_tlow = 157;
			min_thi  = 134;
			raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */
		}

		/* The minimum clock that respects the thi/tlow = 134/157 is
		 * 64800 Hz. Below that, we have to fix the tlow to 255 and
		 * calculate the thi factor.
		 */
		if (clock < 648) {
			tlow = 255;
			thi = 1000000 - clock * raise_fall_time;
			thi /= (I2C_PCA_OSC_PER * clock) - tlow;
		} else {
			tlow = (1000000 - clock * raise_fall_time) * min_tlow;
			tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow);
			thi = tlow * min_thi / min_tlow;
		}

		pca_reset(pca_data);

		printk(KERN_INFO
		     "%s: Clock frequency is %dHz\n", adap->name, clock * 100);

		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE);
		pca_outw(pca_data, I2C_PCA_IND, mode);
		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL);
		pca_outw(pca_data, I2C_PCA_IND, tlow);
		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH);
		pca_outw(pca_data, I2C_PCA_IND, thi);

		pca_set_con(pca_data, I2C_PCA_CON_ENSIO);
	}
	udelay(500); /* 500 us for oscilator to stabilise */

	return 0;
}

/*
 * registering functions to load algorithms at runtime
 */
int i2c_pca_add_bus(struct i2c_adapter *adap)
{
	int rval;

	rval = pca_init(adap);
	if (rval)
		return rval;

	return i2c_add_adapter(adap);
}
EXPORT_SYMBOL(i2c_pca_add_bus);

int i2c_pca_add_numbered_bus(struct i2c_adapter *adap)
{
	int rval;

	rval = pca_init(adap);
	if (rval)
		return rval;

	return i2c_add_numbered_adapter(adap);
}
EXPORT_SYMBOL(i2c_pca_add_numbered_bus);

MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
	"Wolfram Sang <w.sang@pengutronix.de>");
MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm");
MODULE_LICENSE("GPL");

module_param(i2c_debug, int, 0);
