/*
 * (C) Copyright 2003,Motorola Inc.
 * Xianghua Xiao <x.xiao@motorola.com>
 * Adapted for Motorola 85xx chip.
 *
 * (C) Copyright 2003
 * Gleb Natapov <gnatapov@mrv.com>
 * Some bits are taken from linux driver writen by adrian@humboldt.co.uk
 *
 * Modified for MPC86xx by Jeff Brown
 *
 * Hardware I2C driver for MPC107 PCI bridge.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <command.h>
#include <asm/io.h>

#ifdef CONFIG_HARD_I2C
#include <i2c.h>

#define TIMEOUT (CFG_HZ/4)

#define I2C_Addr ((u8 *)(CFG_CCSRBAR + 0x3100))

#define I2CADR  &I2C_Addr[0]
#define I2CFDR  &I2C_Addr[4]
#define I2CCCR  &I2C_Addr[8]
#define I2CCSR  &I2C_Addr[12]
#define I2CCDR  &I2C_Addr[16]
#define I2CDFSRR &I2C_Addr[20]

#define I2C_READ  1
#define I2C_WRITE 0

void
i2c_init(int speed, int slaveadd)
{
	/* stop I2C controller */
	writeb(0x0, I2CCCR);

	/* set clock */
	writeb(0x3f, I2CFDR);

	/* set default filter */
	writeb(0x10, I2CDFSRR);

	/* write slave address */
	writeb(slaveadd, I2CADR);

	/* clear status register */
	writeb(0x0, I2CCSR);

	/* start I2C controller */
	writeb(MPC86xx_I2CCR_MEN, I2CCCR);
}

static __inline__ int
i2c_wait4bus(void)
{
	ulong timeval = get_timer(0);

	while (readb(I2CCSR) & MPC86xx_I2CSR_MBB) {
		if (get_timer(timeval) > TIMEOUT) {
			return -1;
		}
	}

	return 0;
}

static __inline__ int
i2c_wait(int write)
{
	u32 csr;
	ulong timeval = get_timer(0);

	do {
		csr = readb(I2CCSR);
		if (!(csr & MPC86xx_I2CSR_MIF))
			continue;

		writeb(0x0, I2CCSR);

		if (csr & MPC86xx_I2CSR_MAL) {
			debug("i2c_wait: MAL\n");
			return -1;
		}

		if (!(csr & MPC86xx_I2CSR_MCF)) {
			debug("i2c_wait: unfinished\n");
			return -1;
		}

		if (write == I2C_WRITE && (csr & MPC86xx_I2CSR_RXAK)) {
			debug("i2c_wait: No RXACK\n");
			return -1;
		}

		return 0;
	} while (get_timer(timeval) < TIMEOUT);

	debug("i2c_wait: timed out\n");
	return -1;
}

static __inline__ int
i2c_write_addr(u8 dev, u8 dir, int rsta)
{
	writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | MPC86xx_I2CCR_MTX
	       | (rsta ? MPC86xx_I2CCR_RSTA : 0),
	       I2CCCR);

	writeb((dev << 1) | dir, I2CCDR);

	if (i2c_wait(I2C_WRITE) < 0)
		return 0;

	return 1;
}

static __inline__ int
__i2c_write(u8 *data, int length)
{
	int i;

	writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA | MPC86xx_I2CCR_MTX,
	       I2CCCR);

	for (i = 0; i < length; i++) {
		writeb(data[i], I2CCDR);

		if (i2c_wait(I2C_WRITE) < 0)
			break;
	}

	return i;
}

static __inline__ int
__i2c_read(u8 *data, int length)
{
	int i;

	writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA
	       | ((length == 1) ? MPC86xx_I2CCR_TXAK : 0),
	       I2CCCR);

	/* dummy read */
	readb(I2CCDR);

	for (i = 0; i < length; i++) {
		if (i2c_wait(I2C_READ) < 0)
			break;

		/* Generate ack on last next to last byte */
		if (i == length - 2)
			writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_MSTA
			       | MPC86xx_I2CCR_TXAK, I2CCCR);

		/* Generate stop on last byte */
		if (i == length - 1)
			writeb(MPC86xx_I2CCR_MEN | MPC86xx_I2CCR_TXAK, I2CCCR);

		data[i] = readb(I2CCDR);
	}

	return i;
}

int
i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
{
	int i = 0;
	u8 *a = (u8 *) &addr;

	if (i2c_wait4bus() < 0)
		goto exit;

	if (i2c_write_addr(dev, I2C_WRITE, 0) == 0)
		goto exit;

	if (__i2c_write(&a[4 - alen], alen) != alen)
		goto exit;

	if (i2c_write_addr(dev, I2C_READ, 1) == 0)
		goto exit;

	i = __i2c_read(data, length);

exit:
	writeb(MPC86xx_I2CCR_MEN, I2CCCR);

	return !(i == length);
}

int
i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
{
	int i = 0;
	u8 *a = (u8 *) &addr;

	if (i2c_wait4bus() < 0)
		goto exit;

	if (i2c_write_addr(dev, I2C_WRITE, 0) == 0)
		goto exit;

	if (__i2c_write(&a[4 - alen], alen) != alen)
		goto exit;

	i = __i2c_write(data, length);

exit:
	writeb(MPC86xx_I2CCR_MEN, I2CCCR);

	return !(i == length);
}

int
i2c_probe(uchar chip)
{
	int tmp;

	/*
	 * Try to read the first location of the chip.  The underlying
	 * driver doesn't appear to support sending just the chip address
	 * and looking for an <ACK> back.
	 */
	udelay(10000);

	return i2c_read(chip, 0, 1, (char *)&tmp, 1);
}

uchar
i2c_reg_read(uchar i2c_addr, uchar reg)
{
	char buf[1];

	i2c_read(i2c_addr, reg, 1, buf, 1);

	return buf[0];
}

void
i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
{
	i2c_write(i2c_addr, reg, 1, &val, 1);
}

#endif /* CONFIG_HARD_I2C */
