@ -50,12 +50,12 @@ DECLARE_GLOBAL_DATA_PTR;
# define MAX_TX_SPACE 256
# define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */
typedef struct I2C_BD
{
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 */
@ -65,7 +65,7 @@ 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 {
@ -117,7 +117,7 @@ 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 ;
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 ) ) ;
@ -127,7 +127,7 @@ i2c_roundrate(int hz, int speed, int filter, int modval,
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 ) ) ;
@ -135,7 +135,7 @@ i2c_roundrate(int hz, int speed, int filter, int modval,
}
brgdiv = 2 * ( * brgval + 3 + ( 2 * filter ) ) ;
div = moddiv * brgdiv ;
div = moddiv * brgdiv ;
* totspeed = hz / div ;
PRINTD ( ( " \t \t accepted brgval=%d, totspeed=%d \n " , * brgval , * totspeed ) ) ;
@ -146,8 +146,7 @@ i2c_roundrate(int hz, int speed, int filter, int modval,
/*
* 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 ;
volatile i2c8xx_t * i2c = ( i2c8xx_t * ) & immap - > im_i2c ;
@ -161,7 +160,8 @@ i2c_setrate (int hz, int speed)
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,7 +182,8 @@ 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 ,
@ -191,10 +192,9 @@ i2c_setrate (int hz, int speed)
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 iic_t * iip = ( iic_t * ) & cp - > cp_dparam [ PROFF_IIC ] ;
@ -220,8 +220,8 @@ i2c_init(int speed, int slaveaddr)
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 ) ) +
dpaddr = dpram_alloc_align ( ( NUM_RX_BDS * sizeof ( I2C_BD ) ) +
( NUM_TX_BDS * sizeof ( I2C_BD ) ) +
MAX_TX_SPACE , 8 ) ;
}
# else
@ -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 ) ) ;
@ -293,7 +293,7 @@ i2c_init(int speed, int slaveaddr)
# 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,12 +333,10 @@ 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 ) ) ;
@ -352,7 +349,7 @@ i2c_send(i2c_state_t *state,
if ( state - > tx_idx > = NUM_TX_BDS | | state - > tx_space < ( 2 + size ) )
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,13 +357,17 @@ 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 {
@ -396,7 +397,7 @@ i2c_send(i2c_state_t *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,12 +407,12 @@ 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 )
@ -422,8 +423,8 @@ i2c_receive(i2c_state_t *state,
| | 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 ) ) ;
@ -469,9 +470,9 @@ i2c_receive(i2c_state_t *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,7 +480,7 @@ 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 iic_t * iip = ( iic_t * ) & cp - > cp_dparam [ PROFF_IIC ] ;
@ -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 ) ;
@ -631,7 +634,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
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 ;
@ -678,7 +682,8 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
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 ;