/*
 * (C) Copyright 2000
 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
 *
 * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * 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>

#if defined(CONFIG_HARD_I2C)

#include <asm/cpm_8260.h>
#include <i2c.h>

/* define to enable debug messages */
#undef  DEBUG_I2C

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_I2C_MULTI_BUS)
static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0;
#endif /* CONFIG_I2C_MULTI_BUS */

/* uSec to wait between polls of the i2c */
#define DELAY_US	100
/* uSec to wait for the CPM to start processing the buffer */
#define START_DELAY_US	1000

/*
 * tx/rx per-byte timeout: we delay DELAY_US uSec between polls so the
 * timeout will be (tx_length + rx_length) * DELAY_US * TOUT_LOOP
 */
#define TOUT_LOOP 5

/*-----------------------------------------------------------------------
 * Set default values
 */
#ifndef	CONFIG_SYS_I2C_SPEED
#define	CONFIG_SYS_I2C_SPEED	50000
#endif

#ifndef	CONFIG_SYS_I2C_SLAVE
#define	CONFIG_SYS_I2C_SLAVE	0xFE
#endif
/*-----------------------------------------------------------------------
 */

typedef void (*i2c_ecb_t)(int, int, void *);    /* error callback function */

/* This structure keeps track of the bd and buffer space usage. */
typedef struct i2c_state {
	int		rx_idx;		/* index   to next free Rx BD */
	int		tx_idx;		/* index   to next free Tx BD */
	void		*rxbd;		/* pointer to next free Rx BD */
	void		*txbd;		/* pointer to next free Tx BD */
	int		tx_space;	/* number  of Tx bytes left   */
	unsigned char	*tx_buf;	/* pointer to free Tx area    */
	i2c_ecb_t	err_cb;		/* error callback function    */
	void		*cb_data;	/* private data to be passed  */
} i2c_state_t;

/* flags for i2c_send() and i2c_receive() */
#define	I2CF_ENABLE_SECONDARY	0x01	/* secondary_address is valid	*/
#define	I2CF_START_COND		0x02	/* tx: generate start condition	*/
#define I2CF_STOP_COND		0x04	/* tx: generate stop  condition	*/

/* return codes */
#define I2CERR_NO_BUFFERS	1	/* no more BDs or buffer space	*/
#define I2CERR_MSG_TOO_LONG	2	/* tried to send/receive to much data   */
#define I2CERR_TIMEOUT		3	/* timeout in i2c_doio()	*/
#define I2CERR_QUEUE_EMPTY	4	/* i2c_doio called without send/receive */
#define I2CERR_IO_ERROR		5	/* had an error during comms	*/

/* error callback flags */
#define I2CECB_RX_ERR		0x10	/* this is a receive error	*/
#define     I2CECB_RX_OV	0x02	/* receive overrun error	*/
#define     I2CECB_RX_MASK	0x0f	/* mask for error bits		*/
#define I2CECB_TX_ERR		0x20	/* this is a transmit error	*/
#define     I2CECB_TX_CL	0x01	/* transmit collision error	*/
#define     I2CECB_TX_UN	0x02	/* transmit underflow error	*/
#define     I2CECB_TX_NAK	0x04	/* transmit no ack error	*/
#define     I2CECB_TX_MASK	0x0f	/* mask for error bits		*/
#define I2CECB_TIMEOUT		0x40	/* this is a timeout error	*/

#define ERROR_I2C_NONE		0
#define ERROR_I2C_LENGTH	1

#define I2C_WRITE_BIT		0x00
#define I2C_READ_BIT		0x01

#define I2C_RXTX_LEN	128	/* maximum tx/rx buffer length */


#define NUM_RX_BDS 4
#define NUM_TX_BDS 4
#define MAX_TX_SPACE 256

typedef struct I2C_BD
{
  unsigned short status;
  unsigned short length;
  unsigned char *addr;
} I2C_BD;
#define BD_I2C_TX_START 0x0400  /* special status for i2c: Start condition */

#define BD_I2C_TX_CL	0x0001	/* collision error */
#define BD_I2C_TX_UN	0x0002	/* underflow error */
#define BD_I2C_TX_NAK	0x0004	/* no acknowledge error */
#define BD_I2C_TX_ERR	(BD_I2C_TX_NAK|BD_I2C_TX_UN|BD_I2C_TX_CL)

#define BD_I2C_RX_ERR	BD_SC_OV

#ifdef DEBUG_I2C
#define PRINTD(x) printf x
#else
#define PRINTD(x)
#endif

/*
 * Returns the best value of I2BRG to meet desired clock speed of I2C with
 * input parameters (clock speed, filter, and predivider value).
 * It returns computer speed value and the difference between it and desired
 * speed.
 */
static inline int
i2c_roundrate(int hz, int speed, int filter, int modval,
		int *brgval, int *totspeed)
{
    int moddiv = 1 << (5-(modval & 3)), brgdiv, div;

    PRINTD(("\t[I2C] trying hz=%d, speed=%d, filter=%d, modval=%d\n",
	hz, speed, filter, modval));

    div = moddiv * speed;
    brgdiv = (hz + div - 1) / div;

    PRINTD(("\t\tmoddiv=%d, brgdiv=%d\n", moddiv, brgdiv));

    *brgval = ((brgdiv + 1) / 2) - 3 - (2*filter);

    if ((*brgval < 0) || (*brgval > 255)) {
	  PRINTD(("\t\trejected brgval=%d\n", *brgval));
	  return -1;
    }

    brgdiv = 2 * (*brgval + 3 + (2 * filter));
    div = moddiv * brgdiv ;
    *totspeed = hz / div;

    PRINTD(("\t\taccepted brgval=%d, totspeed=%d\n", *brgval, *totspeed));

    return  0;
}

/*
 * Sets the I2C clock predivider and divider to meet required clock speed.
 */
static int i2c_setrate(int hz, int speed)
{
    immap_t	*immap = (immap_t *)CONFIG_SYS_IMMR ;
    volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c;
    int brgval,
	  modval,	/* 0-3 */
	  bestspeed_diff = speed,
	  bestspeed_brgval=0,
	  bestspeed_modval=0,
	  bestspeed_filter=0,
	  totspeed,
	  filter = 0; /* Use this fixed value */

	for (modval = 0; modval < 4; modval++)
	{
		if (i2c_roundrate (hz, speed, filter, modval, &brgval, &totspeed) == 0)
		{
			int diff = speed - totspeed ;

			if ((diff >= 0) && (diff < bestspeed_diff))
			{
				bestspeed_diff	= diff ;
				bestspeed_modval	= modval;
				bestspeed_brgval	= brgval;
				bestspeed_filter	= filter;
			}
		}
	}

    PRINTD(("[I2C] Best is:\n"));
    PRINTD(("[I2C] CPU=%dhz RATE=%d F=%d I2MOD=%08x I2BRG=%08x DIFF=%dhz\n",
		   hz, speed,
		   bestspeed_filter, bestspeed_modval, bestspeed_brgval,
		   bestspeed_diff));

    i2c->i2c_i2mod |= ((bestspeed_modval & 3) << 1) | (bestspeed_filter << 3);
    i2c->i2c_i2brg = bestspeed_brgval & 0xff;

    PRINTD(("[I2C] i2mod=%08x i2brg=%08x\n", i2c->i2c_i2mod, i2c->i2c_i2brg));

    return 1 ;
}

void i2c_init(int speed, int slaveadd)
{
	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
	volatile cpm8260_t *cp = (cpm8260_t *)&immap->im_cpm;
	volatile i2c8260_t *i2c	= (i2c8260_t *)&immap->im_i2c;
	volatile iic_t *iip;
	ulong rbase, tbase;
	volatile I2C_BD *rxbd, *txbd;
	uint dpaddr;

#ifdef CONFIG_SYS_I2C_INIT_BOARD
	/* call board specific i2c bus reset routine before accessing the   */
	/* environment, which might be in a chip on that bus. For details   */
	/* about this problem see doc/I2C_Edge_Conditions.                  */
	i2c_init_board();
#endif

	dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
	if (dpaddr == 0) {
	    /* need to allocate dual port ram */
	    dpaddr = m8260_cpm_dpalloc(64 +
		(NUM_RX_BDS * sizeof(I2C_BD)) + (NUM_TX_BDS * sizeof(I2C_BD)) +
		MAX_TX_SPACE, 64);
	    *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE])) = dpaddr;
	}

	/*
	 * initialise data in dual port ram:
	 *
	 *	  dpaddr -> parameter ram (64 bytes)
	 *         rbase -> rx BD         (NUM_RX_BDS * sizeof(I2C_BD) bytes)
	 *         tbase -> tx BD         (NUM_TX_BDS * sizeof(I2C_BD) bytes)
	 *                  tx buffer     (MAX_TX_SPACE bytes)
	 */

	iip = (iic_t *)&immap->im_dprambase[dpaddr];
	memset((void*)iip, 0, sizeof(iic_t));

	rbase = dpaddr + 64;
	tbase = rbase + NUM_RX_BDS * sizeof(I2C_BD);

	/* Disable interrupts */
	i2c->i2c_i2mod = 0x00;
	i2c->i2c_i2cmr = 0x00;
	i2c->i2c_i2cer = 0xff;
	i2c->i2c_i2add = slaveadd;

	/*
	 * Set the I2C BRG Clock division factor from desired i2c rate
	 * and current CPU rate (we assume sccr dfbgr field is 0;
	 * divide BRGCLK by 1)
	 */
	PRINTD(("[I2C] Setting rate...\n"));
	i2c_setrate (gd->brg_clk, CONFIG_SYS_I2C_SPEED) ;

	/* Set I2C controller in master mode */
	i2c->i2c_i2com = 0x01;

	/* Initialize Tx/Rx parameters */
	iip->iic_rbase = rbase;
	iip->iic_tbase = tbase;
	rxbd = (I2C_BD *)((unsigned char *)&immap->im_dprambase[iip->iic_rbase]);
	txbd = (I2C_BD *)((unsigned char *)&immap->im_dprambase[iip->iic_tbase]);

	PRINTD(("[I2C] rbase = %04x\n", iip->iic_rbase));
	PRINTD(("[I2C] tbase = %04x\n", iip->iic_tbase));
	PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd));
	PRINTD(("[I2C] txbd = %08x\n", (int)txbd));

	/* Set big endian byte order */
	iip->iic_tfcr = 0x10;
	iip->iic_rfcr = 0x10;

	/* Set maximum receive size. */
	iip->iic_mrblr = I2C_RXTX_LEN;

    cp->cp_cpcr = mk_cr_cmd(CPM_CR_I2C_PAGE,
							CPM_CR_I2C_SBLOCK,
							0x00,
							CPM_CR_INIT_TRX) | CPM_CR_FLG;
    do {
		__asm__ __volatile__ ("eieio");
    } while (cp->cp_cpcr & CPM_CR_FLG);

	/* Clear events and interrupts */
	i2c->i2c_i2cer = 0xff;
	i2c->i2c_i2cmr = 0x00;
}

static
void i2c_newio(i2c_state_t *state)
{
	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
	volatile iic_t *iip;
	uint dpaddr;

	PRINTD(("[I2C] i2c_newio\n"));

	dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
	iip = (iic_t *)&immap->im_dprambase[dpaddr];
	state->rx_idx = 0;
	state->tx_idx = 0;
	state->rxbd = (void*)&immap->im_dprambase[iip->iic_rbase];
	state->txbd = (void*)&immap->im_dprambase[iip->iic_tbase];
	state->tx_space = MAX_TX_SPACE;
	state->tx_buf = (uchar*)state->txbd + NUM_TX_BDS * sizeof(I2C_BD);
	state->err_cb = NULL;
	state->cb_data = NULL;

	PRINTD(("[I2C] rxbd = %08x\n", (int)state->rxbd));
	PRINTD(("[I2C] txbd = %08x\n", (int)state->txbd));
	PRINTD(("[I2C] tx_buf = %08x\n", (int)state->tx_buf));

	/* clear the buffer memory */
	memset((char *)state->tx_buf, 0, MAX_TX_SPACE);
}

static
int i2c_send(i2c_state_t *state,
			 unsigned char address,
			 unsigned char secondary_address,
			 unsigned int flags,
			 unsigned short size,
			 unsigned char *dataout)
{
	volatile I2C_BD *txbd;
	int i,j;

	PRINTD(("[I2C] i2c_send add=%02d sec=%02d flag=%02d size=%d\n",
			address, secondary_address, flags, size));

	/* trying to send message larger than BD */
	if (size > I2C_RXTX_LEN)
	  return I2CERR_MSG_TOO_LONG;

	/* no more free bds */
	if (state->tx_idx >= NUM_TX_BDS || state->tx_space < (2 + size))
	  return I2CERR_NO_BUFFERS;

	txbd = (I2C_BD *)state->txbd;
	txbd->addr = state->tx_buf;

	PRINTD(("[I2C] txbd = %08x\n", (int)txbd));

    if (flags & I2CF_START_COND)
    {
	PRINTD(("[I2C] Formatting addresses...\n"));
	if (flags & I2CF_ENABLE_SECONDARY)
	{
		txbd->length = size + 2;  /* Length of message plus dest addresses */
		txbd->addr[0] = address << 1;
		txbd->addr[1] = secondary_address;
		i = 2;
	}
	else
	{
		txbd->length = size + 1;  /* Length of message plus dest address */
		txbd->addr[0] = address << 1;  /* Write destination address to BD */
		i = 1;
	}
    }
    else
    {
	txbd->length = size;  /* Length of message */
	i = 0;
    }

	/* set up txbd */
	txbd->status = BD_SC_READY;
	if (flags & I2CF_START_COND)
	  txbd->status |= BD_I2C_TX_START;
	if (flags & I2CF_STOP_COND)
	  txbd->status |= BD_SC_LAST | BD_SC_WRAP;

	/* Copy data to send into buffer */
	PRINTD(("[I2C] copy data...\n"));
	for(j = 0; j < size; i++, j++)
	  txbd->addr[i] = dataout[j];

	PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
		   txbd->length,
		   txbd->status,
		   txbd->addr[0],
		   txbd->addr[1]));

	/* advance state */
	state->tx_buf += txbd->length;
	state->tx_space -= txbd->length;
	state->tx_idx++;
	state->txbd = (void*)(txbd + 1);

	return 0;
}

static
int i2c_receive(i2c_state_t *state,
				unsigned char address,
				unsigned char secondary_address,
				unsigned int flags,
				unsigned short size_to_expect,
				unsigned char *datain)
{
	volatile I2C_BD *rxbd, *txbd;

	PRINTD(("[I2C] i2c_receive %02d %02d %02d\n", address, secondary_address, flags));

	/* Expected to receive too much */
	if (size_to_expect > I2C_RXTX_LEN)
	  return I2CERR_MSG_TOO_LONG;

	/* no more free bds */
	if (state->tx_idx >= NUM_TX_BDS || state->rx_idx >= NUM_RX_BDS
		 || state->tx_space < 2)
	  return I2CERR_NO_BUFFERS;

	rxbd = (I2C_BD *)state->rxbd;
	txbd = (I2C_BD *)state->txbd;

	PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd));
	PRINTD(("[I2C] txbd = %08x\n", (int)txbd));

	txbd->addr = state->tx_buf;

	/* set up TXBD for destination address */
	if (flags & I2CF_ENABLE_SECONDARY)
	{
		txbd->length = 2;
		txbd->addr[0] = address << 1;   /* Write data */
		txbd->addr[1] = secondary_address;  /* Internal address */
		txbd->status = BD_SC_READY;
	}
	else
	{
		txbd->length = 1 + size_to_expect;
		txbd->addr[0] = (address << 1) | 0x01;
		txbd->status = BD_SC_READY;
		memset(&txbd->addr[1], 0, txbd->length);
	}

	/* set up rxbd for reception */
	rxbd->status = BD_SC_EMPTY;
	rxbd->length = size_to_expect;
	rxbd->addr = datain;

	txbd->status |= BD_I2C_TX_START;
	if (flags & I2CF_STOP_COND)
	{
		txbd->status |= BD_SC_LAST | BD_SC_WRAP;
		rxbd->status |= BD_SC_WRAP;
	}

	PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
		   txbd->length,
		   txbd->status,
		   txbd->addr[0],
		   txbd->addr[1]));
	PRINTD(("[I2C] rxbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
		   rxbd->length,
		   rxbd->status,
		   rxbd->addr[0],
		   rxbd->addr[1]));

	/* advance state */
	state->tx_buf += txbd->length;
	state->tx_space -= txbd->length;
	state->tx_idx++;
	state->txbd = (void*)(txbd + 1);
	state->rx_idx++;
	state->rxbd = (void*)(rxbd + 1);

	return 0;
}


static
int i2c_doio(i2c_state_t *state)
{
	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
	volatile iic_t *iip;
	volatile i2c8260_t *i2c	= (i2c8260_t *)&immap->im_i2c;
	volatile I2C_BD *txbd, *rxbd;
	int  n, i, b, rxcnt = 0, rxtimeo = 0, txcnt = 0, txtimeo = 0, rc = 0;
	uint dpaddr;

	PRINTD(("[I2C] i2c_doio\n"));

	if (state->tx_idx <= 0 && state->rx_idx <= 0) {
		PRINTD(("[I2C] No I/O is queued\n"));
		return I2CERR_QUEUE_EMPTY;
	}

	dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
	iip = (iic_t *)&immap->im_dprambase[dpaddr];
	iip->iic_rbptr = iip->iic_rbase;
	iip->iic_tbptr = iip->iic_tbase;

	/* Enable I2C */
	PRINTD(("[I2C] Enabling I2C...\n"));
	i2c->i2c_i2mod |= 0x01;

	/* Begin transmission */
	i2c->i2c_i2com |= 0x80;

	/* Loop until transmit & receive completed */

	if ((n = state->tx_idx) > 0) {

		txbd = ((I2C_BD*)state->txbd) - n;
		for (i = 0; i < n; i++) {
			txtimeo += TOUT_LOOP * txbd->length;
			txbd++;
		}

		txbd--; /* wait until last in list is done */

		PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd));

		udelay(START_DELAY_US);	/* give it time to start */
		while((txbd->status & BD_SC_READY) && (++txcnt < txtimeo)) {
			udelay(DELAY_US);
			if (ctrlc())
				return (-1);
			__asm__ __volatile__ ("eieio");
		}
	}

	if (txcnt < txtimeo && (n = state->rx_idx) > 0) {

		rxbd = ((I2C_BD*)state->rxbd) - n;
		for (i = 0; i < n; i++) {
			rxtimeo += TOUT_LOOP * rxbd->length;
			rxbd++;
		}

		rxbd--; /* wait until last in list is done */

		PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd));

		udelay(START_DELAY_US);	/* give it time to start */
		while((rxbd->status & BD_SC_EMPTY) && (++rxcnt < rxtimeo)) {
			udelay(DELAY_US);
			if (ctrlc())
				return (-1);
			__asm__ __volatile__ ("eieio");
		}
	}

	/* Turn off I2C */
	i2c->i2c_i2mod &= ~0x01;

	if ((n = state->tx_idx) > 0) {
		for (i = 0; i < n; i++) {
			txbd = ((I2C_BD*)state->txbd) - (n - i);
			if ((b = txbd->status & BD_I2C_TX_ERR) != 0) {
				if (state->err_cb != NULL)
					(*state->err_cb)(I2CECB_TX_ERR|b, i,
						state->cb_data);
				if (rc == 0)
					rc = I2CERR_IO_ERROR;
			}
		}
	}

	if ((n = state->rx_idx) > 0) {
		for (i = 0; i < n; i++) {
			rxbd = ((I2C_BD*)state->rxbd) - (n - i);
			if ((b = rxbd->status & BD_I2C_RX_ERR) != 0) {
				if (state->err_cb != NULL)
					(*state->err_cb)(I2CECB_RX_ERR|b, i,
						state->cb_data);
				if (rc == 0)
					rc = I2CERR_IO_ERROR;
			}
		}
	}

	if ((txtimeo > 0 && txcnt >= txtimeo) || \
	    (rxtimeo > 0 && rxcnt >= rxtimeo)) {
		if (state->err_cb != NULL)
			(*state->err_cb)(I2CECB_TIMEOUT, -1, state->cb_data);
		if (rc == 0)
			rc = I2CERR_TIMEOUT;
	}

	return (rc);
}

static void
i2c_probe_callback(int flags, int xnum, void *data)
{
	/*
	 * the only acceptable errors are a transmit NAK or a receive
	 * overrun - tx NAK means the device does not exist, rx OV
	 * means the device must have responded to the slave address
	 * even though the transfer failed
	 */
	if (flags == (I2CECB_TX_ERR|I2CECB_TX_NAK))
		*(int *)data |= 1;
	if (flags == (I2CECB_RX_ERR|I2CECB_RX_OV))
		*(int *)data |= 2;
}

int
i2c_probe(uchar chip)
{
	i2c_state_t state;
	int rc, err_flag;
	uchar buf[1];

	i2c_newio(&state);

	state.err_cb = i2c_probe_callback;
	state.cb_data = (void *) &err_flag;
	err_flag = 0;

	rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf);

	if (rc != 0)
		return (rc);	/* probe failed */

	rc = i2c_doio(&state);

	if (rc == 0)
		return (0);	/* device exists - read succeeded */

	if (rc == I2CERR_TIMEOUT)
		return (-1);	/* device does not exist - timeout */

	if (rc != I2CERR_IO_ERROR || err_flag == 0)
		return (rc);	/* probe failed */

	if (err_flag & 1)
		return (-1);	/* device does not exist - had transmit NAK */

	return (0);	/* device exists - had receive overrun */
}


int
i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
	i2c_state_t state;
	uchar xaddr[4];
	int rc;

	xaddr[0] = (addr >> 24) & 0xFF;
	xaddr[1] = (addr >> 16) & 0xFF;
	xaddr[2] = (addr >>  8) & 0xFF;
	xaddr[3] =  addr        & 0xFF;

#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
	 /*
	  * EEPROM chips that implement "address overflow" are ones
	  * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address
	  * and the extra bits end up in the "chip address" bit slots.
	  * This makes a 24WC08 (1Kbyte) chip look like four 256 byte
	  * chips.
	  *
	  * Note that we consider the length of the address field to still
	  * be one byte because the extra address bits are hidden in the
	  * chip address.
	  */
	chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
#endif

	i2c_newio(&state);

	rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]);
	if (rc != 0) {
		printf("i2c_read: i2c_send failed (%d)\n", rc);
		return 1;
	}

	rc = i2c_receive(&state, chip, 0, I2CF_STOP_COND, len, buffer);
	if (rc != 0) {
		printf("i2c_read: i2c_receive failed (%d)\n", rc);
		return 1;
	}

	rc = i2c_doio(&state);
	if (rc != 0) {
		printf("i2c_read: i2c_doio failed (%d)\n", rc);
		return 1;
	}
	return 0;
}

int
i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
	i2c_state_t state;
	uchar xaddr[4];
	int rc;

	xaddr[0] = (addr >> 24) & 0xFF;
	xaddr[1] = (addr >> 16) & 0xFF;
	xaddr[2] = (addr >>  8) & 0xFF;
	xaddr[3] =  addr        & 0xFF;

#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
	 /*
	  * EEPROM chips that implement "address overflow" are ones
	  * like Catalyst 24WC04/08/16 which has 9/10/11 bits of address
	  * and the extra bits end up in the "chip address" bit slots.
	  * This makes a 24WC08 (1Kbyte) chip look like four 256 byte
	  * chips.
	  *
	  * Note that we consider the length of the address field to still
	  * be one byte because the extra address bits are hidden in the
	  * chip address.
	  */
	chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
#endif

	i2c_newio(&state);

	rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]);
	if (rc != 0) {
		printf("i2c_write: first i2c_send failed (%d)\n", rc);
		return 1;
	}

	rc = i2c_send(&state, 0, 0, I2CF_STOP_COND, len, buffer);
	if (rc != 0) {
		printf("i2c_write: second i2c_send failed (%d)\n", rc);
		return 1;
	}

	rc = i2c_doio(&state);
	if (rc != 0) {
		printf("i2c_write: i2c_doio failed (%d)\n", rc);
		return 1;
	}
	return 0;
}

#if defined(CONFIG_I2C_MULTI_BUS)
/*
 * Functions for multiple I2C bus handling
 */
unsigned int i2c_get_bus_num(void)
{
	return i2c_bus_num;
}

int i2c_set_bus_num(unsigned int bus)
{
#if defined(CONFIG_I2C_MUX)
	if (bus < CONFIG_SYS_MAX_I2C_BUS) {
		i2c_bus_num = bus;
	} else {
		int	ret;

		ret = i2x_mux_select_mux(bus);
		if (ret == 0)
			i2c_bus_num = bus;
		else
			return ret;
	}
#else
	if (bus >= CONFIG_SYS_MAX_I2C_BUS)
		return -1;
	i2c_bus_num = bus;
#endif
	return 0;
}
/* TODO: add 100/400k switching */
unsigned int i2c_get_bus_speed(void)
{
	return CONFIG_SYS_I2C_SPEED;
}

int i2c_set_bus_speed(unsigned int speed)
{
	if (speed != CONFIG_SYS_I2C_SPEED)
		return -1;

	return 0;
}

#endif	/* CONFIG_I2C_MULTI_BUS */
#endif	/* CONFIG_HARD_I2C */
