@ -150,16 +150,19 @@ void i2c_init(int speed, int slaveadd)
bus_initialized [ current_bus ] = 1 ;
}
static int i2c_read_byte ( u8 devaddr , u8 regoffset , u8 * value )
static int i2c_read_byte ( u8 devaddr , u16 regoffset , u8 alen , u8 * value )
{
int i2c_error = 0 ;
u16 status ;
int i = 2 - alen ;
u8 tmpbuf [ 2 ] = { ( regoffset ) > > 8 , regoffset & 0xff } ;
u16 w ;
/* wait until bus not busy */
wait_for_bb ( ) ;
/* one byte only */
writew ( 1 , & i2c_base - > cnt ) ;
writew ( alen , & i2c_base - > cnt ) ;
/* set slave address */
writew ( devaddr , & i2c_base - > sa ) ;
/* no stop bit needed here */
@ -174,8 +177,12 @@ static int i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value)
goto read_exit ;
}
if ( status & I2C_STAT_XRDY ) {
/* Important: have to use byte access */
writeb ( regoffset , & i2c_base - > data ) ;
w = tmpbuf [ i + + ] ;
# if !(defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
defined ( CONFIG_OMAP44XX ) | | defined ( CONFIG_AM33XX ) )
w | = tmpbuf [ i + + ] < < 8 ;
# endif
writew ( w , & i2c_base - > data ) ;
writew ( I2C_STAT_XRDY , & i2c_base - > stat ) ;
}
if ( status & I2C_STAT_ARDY ) {
@ -303,18 +310,18 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
int i ;
if ( alen > 1 ) {
if ( alen > 2 ) {
printf ( " I2C read: addr len %d not supported \n " , alen ) ;
return 1 ;
}
if ( addr + len > 256 ) {
if ( addr + len > ( 1 < < 16 ) ) {
puts ( " I2C read: address out of range \n " ) ;
return 1 ;
}
for ( i = 0 ; i < len ; i + + ) {
if ( i2c_read_byte ( chip , addr + i , & buffer [ i ] ) ) {
if ( i2c_read_byte ( chip , addr + i , alen , & buffer [ i ] ) ) {
puts ( " I2C read: I/O error \n " ) ;
i2c_init ( CONFIG_SYS_I2C_SPEED , CONFIG_SYS_I2C_SLAVE ) ;
return 1 ;
@ -329,13 +336,15 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
int i ;
u16 status ;
int i2c_error = 0 ;
u16 w ;
u8 tmpbuf [ 2 ] = { addr > > 8 , addr & 0xff } ;
if ( alen > 1 ) {
if ( alen > 2 ) {
printf ( " I2C write: addr len %d not supported \n " , alen ) ;
return 1 ;
}
if ( addr + len > 256 ) {
if ( addr + len > ( 1 < < 16 ) ) {
printf ( " I2C write: address 0x%x + 0x%x out of range \n " ,
addr , len ) ;
return 1 ;
@ -353,28 +362,8 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
writew ( I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
I2C_CON_STP , & i2c_base - > con ) ;
/* Send address byte */
status = wait_for_pin ( ) ;
if ( status = = 0 | | status & I2C_STAT_NACK ) {
i2c_error = 1 ;
printf ( " error waiting for i2c address ACK (status=0x%x) \n " ,
status ) ;
goto write_exit ;
}
if ( status & I2C_STAT_XRDY ) {
writeb ( addr & 0xFF , & i2c_base - > data ) ;
writew ( I2C_STAT_XRDY , & i2c_base - > stat ) ;
} else {
i2c_error = 1 ;
printf ( " i2c bus not ready for transmit (status=0x%x) \n " ,
status ) ;
goto write_exit ;
}
/* address phase is over, now write data */
for ( i = 0 ; i < len ; i + + ) {
/* Send address and data */
for ( i = - alen ; i < len ; i + + ) {
status = wait_for_pin ( ) ;
if ( status = = 0 | | status & I2C_STAT_NACK ) {
@ -385,7 +374,12 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
}
if ( status & I2C_STAT_XRDY ) {
writeb ( buffer [ i ] , & i2c_base - > data ) ;
w = ( i < 0 ) ? tmpbuf [ 2 + i ] : buffer [ i ] ;
# if !(defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
defined ( CONFIG_OMAP44XX ) | | defined ( CONFIG_AM33XX ) )
w | = ( ( + + i < 0 ) ? tmpbuf [ 2 + i ] : buffer [ i ] ) < < 8 ;
# endif
writew ( w , & i2c_base - > data ) ;
writew ( I2C_STAT_XRDY , & i2c_base - > stat ) ;
} else {
i2c_error = 1 ;