/*
 * (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>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>

#if defined(CONFIG_HARD_I2C)

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

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


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/rcv */
#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

/*
 * 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;

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

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

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

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

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

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

	debug("\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;
			}
		}
	}

	debug("[I2C] Best is:\n");
	debug("[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;

	debug("[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 = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)];
	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);
		immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)] =
			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)
	 */
	debug("[I2C] Setting rate...\n");
	i2c_setrate(gd->arch.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]);

	debug("[I2C] rbase = %04x\n", iip->iic_rbase);
	debug("[I2C] tbase = %04x\n", iip->iic_tbase);
	debug("[I2C] rxbd = %08x\n", (int) rxbd);
	debug("[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;

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

	dpaddr = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)];
	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;

	debug("[I2C] rxbd = %08x\n", (int)state->rxbd);
	debug("[I2C] txbd = %08x\n", (int)state->txbd);
	debug("[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;

	debug("[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;

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

	if (flags & I2CF_START_COND) {
		debug("[I2C] Formatting addresses...\n");
		if (flags & I2CF_ENABLE_SECONDARY) {
			/* Length of message plus dest addresses */
			txbd->length = size + 2;
			txbd->addr[0] = address << 1;
			txbd->addr[1] = secondary_address;
			i = 2;
		} else {
			/* Length of message plus dest address */
			txbd->length = size + 1;
			/* Write destination address to BD */
			txbd->addr[0] = address << 1;
			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 */
	debug("[I2C] copy data...\n");
	for (j = 0; j < size; i++, j++)
		txbd->addr[i] = dataout[j];

	debug("[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;

	debug("[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;

	debug("[I2C] rxbd = %08x\n", (int) rxbd);
	debug("[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;
	}

	debug("[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]);
	debug("[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;

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

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

	dpaddr = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)];
	iip = (iic_t *)&immap->im_dprambase[dpaddr];
	iip->iic_rbptr = iip->iic_rbase;
	iip->iic_tbptr = iip->iic_tbase;

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

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

	/* Loop until transmit & receive completed */

	n = state->tx_idx;

	if (n > 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 */

		debug("[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");
		}
	}

	n = state->rx_idx;

	if (txcnt < txtimeo && n > 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 */

		debug("[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;

	n = state->tx_idx;

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

	n = state->rx_idx;

	if (n > 0) {
		for (i = 0; i < n; i++) {
			rxbd = ((I2C_BD *) state->rxbd) - (n - i);
			b = rxbd->status & BD_I2C_RX_ERR;
			if (b != 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 (bus >= CONFIG_SYS_MAX_I2C_BUS)
		return -1;
	i2c_bus_num = bus;
	return 0;
}

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