@ -50,13 +50,13 @@ DECLARE_GLOBAL_DATA_PTR;
# define MAX_TX_SPACE 256
# define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */
typedef struct I2C_BD
{
unsigned short status ;
unsigned short length ;
unsigned char * addr ;
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_START 0x0400 /* special status for i2c: Start condition */
# define BD_I2C_TX_CL 0x0001 /* collision error */
# define BD_I2C_TX_UN 0x0002 /* underflow error */
@ -65,41 +65,41 @@ typedef struct I2C_BD
# define BD_I2C_RX_ERR BD_SC_OV
typedef void ( * i2c_ecb_t ) ( int , int ) ; /* error callback function */
typedef void ( * i2c_ecb_t ) ( int , int ) ; /* 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 */
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 */
} 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 */
# 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 0x01 /* no more BDs or buffer space */
# define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */
# define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */
# define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */
# define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */
# define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */
# define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */
# define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */
/* error callback flags */
# define I2CECB_RX_ERR 0x10 /* this is a receive error */
# define I2CECB_RX_ERR_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 I2CECB_RX_ERR 0x10 /* this is a receive error */
# define I2CECB_RX_ERR_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 */
# ifdef DEBUG_I2C
# define PRINTD(x) printf x
@ -115,53 +115,53 @@ typedef struct i2c_state {
*/
static inline int
i2c_roundrate ( int hz , int speed , int filter , int modval ,
int * brgval , int * totspeed )
int * brgval , int * totspeed )
{
int moddiv = 1 < < ( 5 - ( modval & 3 ) ) , brgdiv , div ;
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 ) ) ;
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 ;
div = moddiv * speed ;
brgdiv = ( hz + div - 1 ) / div ;
PRINTD ( ( " \t \t moddiv=%d, brgdiv=%d \n " , moddiv , brgdiv ) ) ;
PRINTD ( ( " \t \t moddiv=%d, brgdiv=%d \n " , moddiv , brgdiv ) ) ;
* brgval = ( ( brgdiv + 1 ) / 2 ) - 3 - ( 2 * filter ) ;
* brgval = ( ( brgdiv + 1 ) / 2 ) - 3 - ( 2 * filter ) ;
if ( ( * brgval < 0 ) | | ( * brgval > 255 ) ) {
PRINTD ( ( " \t \t rejected brgval=%d \n " , * brgval ) ) ;
return - 1 ;
}
if ( ( * brgval < 0 ) | | ( * brgval > 255 ) ) {
PRINTD ( ( " \t \t rejected brgval=%d \n " , * brgval ) ) ;
return - 1 ;
}
brgdiv = 2 * ( * brgval + 3 + ( 2 * filter ) ) ;
div = moddiv * brgdiv ;
* totspeed = hz / div ;
brgdiv = 2 * ( * brgval + 3 + ( 2 * filter ) ) ;
div = moddiv * brgdiv ;
* totspeed = hz / div ;
PRINTD ( ( " \t \t accepted brgval=%d, totspeed=%d \n " , * brgval , * totspeed ) ) ;
PRINTD ( ( " \t \t accepted brgval=%d, totspeed=%d \n " , * brgval , * totspeed ) ) ;
return 0 ;
return 0 ;
}
/*
* Sets the I2C clock predivider and divider to meet required clock speed .
*/
static int
i2c_setrate ( int hz , int speed )
static int i2c_setrate ( int hz , int speed )
{
immap_t * immap = ( immap_t * ) CONFIG_SYS_IMMR ;
immap_t * immap = ( immap_t * ) CONFIG_SYS_IMMR ;
volatile i2c8xx_t * i2c = ( i2c8xx_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 */
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 ) {
if ( i2c_roundrate
( hz , speed , filter , modval , & brgval , & totspeed ) = = 0 ) {
int diff = speed - totspeed ;
if ( ( diff > = 0 ) & & ( diff < bestspeed_diff ) ) {
@ -182,21 +182,21 @@ i2c_setrate (int hz, int speed)
bestspeed_brgval ,
bestspeed_diff ) ) ;
i2c - > i2c_i2mod | = ( ( bestspeed_modval & 3 ) < < 1 ) | ( bestspeed_filter < < 3 ) ;
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 ) ) ;
i2c - > i2c_i2brg ) ) ;
return 1 ;
}
void
i2c_init ( int speed , int slaveaddr )
void i2c_init ( int speed , int slaveaddr )
{
volatile immap_t * immap = ( immap_t * ) CONFIG_SYS_IMMR ;
volatile immap_t * immap = ( immap_t * ) CONFIG_SYS_IMMR ;
volatile cpm8xx_t * cp = ( cpm8xx_t * ) & immap - > im_cpm ;
volatile i2c8xx_t * i2c = ( i2c8xx_t * ) & immap - > im_i2c ;
volatile i2c8xx_t * i2c = ( i2c8xx_t * ) & immap - > im_i2c ;
volatile iic_t * iip = ( iic_t * ) & cp - > cp_dparam [ PROFF_IIC ] ;
ulong rbase , tbase ;
volatile I2C_BD * rxbd , * txbd ;
@ -219,10 +219,10 @@ i2c_init(int speed, int slaveaddr)
# ifdef CONFIG_SYS_ALLOC_DPRAM
dpaddr = iip - > iic_rbase ;
if ( dpaddr = = 0 ) {
/* need to allocate dual port ram */
dpaddr = dpram_alloc_align (
( NUM_RX_BDS * sizeof ( I2C_BD ) ) + ( NUM_TX_BDS * sizeof ( I2C_BD ) ) +
MAX_TX_SPACE , 8 ) ;
/* need to allocate dual port ram */
dpaddr = dpram_alloc_align ( ( NUM_RX_BDS * sizeof ( I2C_BD ) ) +
( NUM_TX_BDS * sizeof ( I2C_BD ) ) +
MAX_TX_SPACE , 8 ) ;
}
# else
dpaddr = CPM_I2C_BASE ;
@ -256,19 +256,19 @@ i2c_init(int speed, int slaveaddr)
* divide BRGCLK by 1 )
*/
PRINTD ( ( " [I2C] Setting rate... \n " ) ) ;
i2c_setrate ( gd - > cpu_clk , CONFIG_SYS_I2C_SPEED ) ;
i2c_setrate ( gd - > cpu_clk , CONFIG_SYS_I2C_SPEED ) ;
/* Set I2C controller in master mode */
i2c - > i2c_i2com = 0x01 ;
/* Set SDMA bus arbitration level to 5 (SDCR) */
immap - > im_siu_conf . sc_sdcr = 0x0001 ;
immap - > im_siu_conf . sc_sdcr = 0x0001 ;
/* Initialize Tx/Rx parameters */
iip - > iic_rbase = rbase ;
iip - > iic_tbase = tbase ;
rxbd = ( I2C_BD * ) ( ( unsigned char * ) & cp - > cp_dpmem [ iip - > iic_rbase ] ) ;
txbd = ( I2C_BD * ) ( ( unsigned char * ) & cp - > cp_dpmem [ iip - > iic_tbase ] ) ;
rxbd = ( I2C_BD * ) ( ( unsigned char * ) & cp - > cp_dpmem [ iip - > iic_rbase ] ) ;
txbd = ( I2C_BD * ) ( ( unsigned char * ) & cp - > cp_dpmem [ iip - > iic_tbase ] ) ;
PRINTD ( ( " [I2C] rbase = %04x \n " , iip - > iic_rbase ) ) ;
PRINTD ( ( " [I2C] tbase = %04x \n " , iip - > iic_tbase ) ) ;
@ -286,14 +286,14 @@ i2c_init(int speed, int slaveaddr)
/*
* Initialize required parameters if using microcode patch .
*/
iip - > iic_rbptr = iip - > iic_rbase ;
iip - > iic_tbptr = iip - > iic_tbase ;
iip - > iic_rbptr = iip - > iic_rbase ;
iip - > iic_tbptr = iip - > iic_tbase ;
iip - > iic_rstate = 0 ;
iip - > iic_tstate = 0 ;
# else
cp - > cp_cpcr = mk_cr_cmd ( CPM_CR_CH_I2C , CPM_CR_INIT_TRX ) | CPM_CR_FLG ;
do {
__asm__ __volatile__ ( " eieio " ) ;
__asm__ __volatile__ ( " eieio " ) ;
} while ( cp - > cp_cpcr & CPM_CR_FLG ) ;
# endif
@ -302,10 +302,9 @@ i2c_init(int speed, int slaveaddr)
i2c - > i2c_i2cmr = 0x00 ;
}
static void
i2c_newio ( i2c_state_t * state )
static void i2c_newio ( i2c_state_t * state )
{
volatile immap_t * immap = ( immap_t * ) CONFIG_SYS_IMMR ;
volatile immap_t * immap = ( immap_t * ) CONFIG_SYS_IMMR ;
volatile cpm8xx_t * cp = ( cpm8xx_t * ) & immap - > im_cpm ;
volatile iic_t * iip = ( iic_t * ) & cp - > cp_dparam [ PROFF_IIC ] ;
@ -316,10 +315,10 @@ i2c_newio(i2c_state_t *state)
# endif
state - > rx_idx = 0 ;
state - > tx_idx = 0 ;
state - > rxbd = ( void * ) & cp - > cp_dpmem [ iip - > iic_rbase ] ;
state - > txbd = ( void * ) & cp - > cp_dpmem [ iip - > iic_tbase ] ;
state - > rxbd = ( void * ) & cp - > cp_dpmem [ iip - > iic_rbase ] ;
state - > txbd = ( void * ) & cp - > cp_dpmem [ iip - > iic_tbase ] ;
state - > tx_space = MAX_TX_SPACE ;
state - > tx_buf = ( uchar * ) state - > txbd + NUM_TX_BDS * sizeof ( I2C_BD ) ;
state - > tx_buf = ( uchar * ) state - > txbd + NUM_TX_BDS * sizeof ( I2C_BD ) ;
state - > err_cb = NULL ;
PRINTD ( ( " [I2C] rxbd = %08x \n " , ( int ) state - > rxbd ) ) ;
@ -334,25 +333,23 @@ static int
i2c_send ( i2c_state_t * state ,
unsigned char address ,
unsigned char secondary_address ,
unsigned int flags ,
unsigned short size ,
unsigned char * dataout )
unsigned int flags , unsigned short size , unsigned char * dataout )
{
volatile I2C_BD * txbd ;
int i , j ;
int i , j ;
PRINTD ( ( " [I2C] i2c_send add=%02d sec=%02d flag=%02d size=%d \n " ,
address , secondary_address , flags , size ) ) ;
address , secondary_address , flags , size ) ) ;
/* trying to send message larger than BD */
if ( size > I2C_RXTX_LEN )
return I2CERR_MSG_TOO_LONG ;
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 ;
return I2CERR_NO_BUFFERS ;
txbd = ( I2C_BD * ) state - > txbd ;
txbd = ( I2C_BD * ) state - > txbd ;
txbd - > addr = state - > tx_buf ;
PRINTD ( ( " [I2C] txbd = %08x \n " , ( int ) txbd ) ) ;
@ -360,43 +357,47 @@ i2c_send(i2c_state_t *state,
if ( flags & I2CF_START_COND ) {
PRINTD ( ( " [I2C] Formatting addresses... \n " ) ) ;
if ( flags & I2CF_ENABLE_SECONDARY ) {
txbd - > length = size + 2 ; /* Length of msg + dest addr */
/* Length of msg + dest addr */
txbd - > length = size + 2 ;
txbd - > addr [ 0 ] = address < < 1 ;
txbd - > addr [ 1 ] = secondary_address ;
i = 2 ;
} else {
txbd - > length = size + 1 ; /* Length of msg + dest addr */
txbd - > addr [ 0 ] = address < < 1 ; /* Write dest addr to BD */
/* Length of msg + dest addr */
txbd - > length = size + 1 ;
/* Write dest addr to BD */
txbd - > addr [ 0 ] = address < < 1 ;
i = 1 ;
}
} else {
txbd - > length = size ; /* Length of message */
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 ;
txbd - > status | = BD_I2C_TX_START ;
if ( flags & I2CF_STOP_COND )
txbd - > status | = BD_SC_LAST | BD_SC_WRAP ;
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 ] ;
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 ] ) ) ;
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 ) ;
state - > txbd = ( void * ) ( txbd + 1 ) ;
return 0 ;
}
@ -406,24 +407,24 @@ i2c_receive(i2c_state_t *state,
unsigned char address ,
unsigned char secondary_address ,
unsigned int flags ,
unsigned short size_to_expect ,
unsigned char * datain )
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 ) ) ;
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 ;
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 ;
| | state - > tx_space < 2 )
return I2CERR_NO_BUFFERS ;
rxbd = ( I2C_BD * ) state - > rxbd ;
txbd = ( I2C_BD * ) state - > txbd ;
rxbd = ( I2C_BD * ) state - > rxbd ;
txbd = ( I2C_BD * ) state - > txbd ;
PRINTD ( ( " [I2C] rxbd = %08x \n " , ( int ) rxbd ) ) ;
PRINTD ( ( " [I2C] txbd = %08x \n " , ( int ) txbd ) ) ;
@ -433,8 +434,8 @@ i2c_receive(i2c_state_t *state,
/* 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 - > 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 ;
@ -455,23 +456,23 @@ i2c_receive(i2c_state_t *state,
}
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 ] ) ) ;
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 ] ) ) ;
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 - > txbd = ( void * ) ( txbd + 1 ) ;
state - > rx_idx + + ;
state - > rxbd = ( void * ) ( rxbd + 1 ) ;
state - > rxbd = ( void * ) ( rxbd + 1 ) ;
return 0 ;
}
@ -479,9 +480,9 @@ i2c_receive(i2c_state_t *state,
static int i2c_doio ( i2c_state_t * state )
{
volatile immap_t * immap = ( immap_t * ) CONFIG_SYS_IMMR ;
volatile immap_t * immap = ( immap_t * ) CONFIG_SYS_IMMR ;
volatile cpm8xx_t * cp = ( cpm8xx_t * ) & immap - > im_cpm ;
volatile i2c8xx_t * i2c = ( i2c8xx_t * ) & immap - > im_i2c ;
volatile i2c8xx_t * i2c = ( i2c8xx_t * ) & immap - > im_i2c ;
volatile iic_t * iip = ( iic_t * ) & cp - > cp_dparam [ PROFF_IIC ] ;
volatile I2C_BD * txbd , * rxbd ;
volatile int j = 0 ;
@ -512,22 +513,22 @@ static int i2c_doio(i2c_state_t *state)
if ( state - > tx_idx > 0 ) {
txbd = ( ( I2C_BD * ) state - > txbd ) - 1 ;
PRINTD ( ( " [I2C] Transmitting...(txbd=0x%08lx) \n " , ( ulong ) txbd ) ) ;
while ( ( txbd - > status & BD_SC_READY ) & & ( j + + < TOUT_LOOP ) ) {
if ( ctrlc ( ) ) {
while ( ( txbd - > status & BD_SC_READY ) & & ( j + + < TOUT_LOOP ) ) {
if ( ctrlc ( ) )
return ( - 1 ) ;
}
__asm__ __volatile__ ( " eieio " ) ;
__asm__ __volatile__ ( " eieio " ) ;
}
}
if ( ( state - > rx_idx > 0 ) & & ( j < TOUT_LOOP ) ) {
rxbd = ( ( I2C_BD * ) state - > rxbd ) - 1 ;
PRINTD ( ( " [I2C] Receiving...(rxbd=0x%08lx) \n " , ( ulong ) rxbd ) ) ;
while ( ( rxbd - > status & BD_SC_EMPTY ) & & ( j + + < TOUT_LOOP ) ) {
if ( ctrlc ( ) ) {
while ( ( rxbd - > status & BD_SC_EMPTY ) & & ( j + + < TOUT_LOOP ) ) {
if ( ctrlc ( ) )
return ( - 1 ) ;
}
__asm__ __volatile__ ( " eieio " ) ;
__asm__ __volatile__ ( " eieio " ) ;
}
}
@ -544,22 +545,24 @@ static int i2c_doio(i2c_state_t *state)
if ( ( n = state - > tx_idx ) > 0 ) {
for ( i = 0 ; i < n ; i + + ) {
txbd = ( ( I2C_BD * ) state - > txbd ) - ( n - i ) ;
txbd = ( ( I2C_BD * ) state - > txbd ) - ( n - i ) ;
if ( ( b = txbd - > status & BD_I2C_TX_ERR ) ! = 0 )
( * state - > err_cb ) ( I2CECB_TX_ERR | b , i ) ;
( * state - > err_cb ) ( I2CECB_TX_ERR | b ,
i ) ;
}
}
if ( ( n = state - > rx_idx ) > 0 ) {
for ( i = 0 ; i < n ; i + + ) {
rxbd = ( ( I2C_BD * ) state - > rxbd ) - ( n - i ) ;
rxbd = ( ( I2C_BD * ) state - > rxbd ) - ( n - i ) ;
if ( ( b = rxbd - > status & BD_I2C_RX_ERR ) ! = 0 )
( * state - > err_cb ) ( I2CECB_RX_ERR | b , i ) ;
( * state - > err_cb ) ( I2CECB_RX_ERR | b ,
i ) ;
}
}
if ( j > = TOUT_LOOP )
( * state - > err_cb ) ( I2CECB_TIMEOUT , 0 ) ;
( * state - > err_cb ) ( I2CECB_TIMEOUT , 0 ) ;
}
return ( j > = TOUT_LOOP ) ? I2CERR_TIMEOUT : 0 ;
@ -567,8 +570,7 @@ static int i2c_doio(i2c_state_t *state)
static int had_tx_nak ;
static void
i2c_test_callback ( int flags , int xnum )
static void i2c_test_callback ( int flags , int xnum )
{
if ( ( flags & I2CECB_TX_ERR ) & & ( flags & I2CECB_TX_NAK ) )
had_tx_nak = 1 ;
@ -587,7 +589,8 @@ int i2c_probe(uchar chip)
state . err_cb = i2c_test_callback ;
had_tx_nak = 0 ;
rc = i2c_receive ( & state , chip , 0 , I2CF_START_COND | I2CF_STOP_COND , 1 , buf ) ;
rc = i2c_receive ( & state , chip , 0 , I2CF_START_COND | I2CF_STOP_COND , 1 ,
buf ) ;
if ( rc ! = 0 )
return ( rc ) ;
@ -612,8 +615,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
xaddr [ 0 ] = ( addr > > 24 ) & 0xFF ;
xaddr [ 1 ] = ( addr > > 16 ) & 0xFF ;
xaddr [ 2 ] = ( addr > > 8 ) & 0xFF ;
xaddr [ 3 ] = addr & 0xFF ;
xaddr [ 2 ] = ( addr > > 8 ) & 0xFF ;
xaddr [ 3 ] = addr & 0xFF ;
# ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
/*
@ -626,12 +629,13 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
* be one byte because the extra address bits are hidden in the
* chip address .
*/
chip | = ( ( addr > > ( alen * 8 ) ) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW ) ;
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 ] ) ;
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 ;
@ -659,8 +663,8 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
xaddr [ 0 ] = ( addr > > 24 ) & 0xFF ;
xaddr [ 1 ] = ( addr > > 16 ) & 0xFF ;
xaddr [ 2 ] = ( addr > > 8 ) & 0xFF ;
xaddr [ 3 ] = addr & 0xFF ;
xaddr [ 2 ] = ( addr > > 8 ) & 0xFF ;
xaddr [ 3 ] = addr & 0xFF ;
# ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
/*
@ -673,12 +677,13 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
* be one byte because the extra address bits are hidden in the
* chip address .
*/
chip | = ( ( addr > > ( alen * 8 ) ) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW ) ;
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 ] ) ;
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 ;
@ -698,4 +703,4 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
return 0 ;
}
# endif /* CONFIG_HARD_I2C */
# endif /* CONFIG_HARD_I2C */