@ -31,6 +31,7 @@
# include <i2c.h>
# include <command.h>
# include "ppc440gx_i2c.h"
# include <asm-ppc/io.h>
# ifdef CONFIG_I2C_BUS1
@ -47,16 +48,18 @@
static uchar i2c_no_probes [ ] = CONFIG_SYS_I2C_NOPROBES ;
# endif
static struct ppc4xx_i2c * i2c = ( struct ppc4xx_i2c * ) I2C_REGISTERS_BUS1_BASE_ADDRESS ;
static void _i2c_bus1_reset ( void )
{
int i , status ;
/* Reset status register */
/* write 1 in SCMP and IRQA to clear these fields */
out8 ( IIC_STS1 , 0x0A ) ;
out_ 8 ( IIC_STS1 , 0x0A ) ;
/* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */
out8 ( IIC_EXTSTS1 , 0x8F ) ;
out_ 8 ( IIC_EXTSTS1 , 0x8F ) ;
__asm__ volatile ( " eieio " ) ;
/*
@ -66,36 +69,36 @@ static void _i2c_bus1_reset (void)
i = 10 ;
do {
/* Get status */
status = in8 ( IIC_STS1 ) ;
status = in_ 8 ( IIC_STS1 ) ;
udelay ( 500 ) ; /* 500us */
i - - ;
} while ( ( status & IIC_STS_PT ) & & ( i > 0 ) ) ;
/* Soft reset controller */
status = in8 ( IIC_XTCNTLSS1 ) ;
out8 ( IIC_XTCNTLSS1 , ( status | IIC_XTCNTLSS_SRST ) ) ;
status = in_ 8 ( IIC_XTCNTLSS1 ) ;
out_ 8 ( IIC_XTCNTLSS1 , ( status | IIC_XTCNTLSS_SRST ) ) ;
__asm__ volatile ( " eieio " ) ;
/* make sure where in initial state, data hi, clock hi */
out8 ( IIC_DIRECTCNTL1 , 0xC ) ;
out_ 8 ( IIC_DIRECTCNTL1 , 0xC ) ;
for ( i = 0 ; i < 10 ; i + + ) {
if ( ( in8 ( IIC_DIRECTCNTL1 ) & 0x3 ) ! = 0x3 ) {
if ( ( in_ 8 ( IIC_DIRECTCNTL1 ) & 0x3 ) ! = 0x3 ) {
/* clock until we get to known state */
out8 ( IIC_DIRECTCNTL1 , 0x8 ) ; /* clock lo */
out_ 8 ( IIC_DIRECTCNTL1 , 0x8 ) ; /* clock lo */
udelay ( 100 ) ; /* 100us */
out8 ( IIC_DIRECTCNTL1 , 0xC ) ; /* clock hi */
out_ 8 ( IIC_DIRECTCNTL1 , 0xC ) ; /* clock hi */
udelay ( 100 ) ; /* 100us */
} else {
break ;
}
}
/* send start condition */
out8 ( IIC_DIRECTCNTL1 , 0x4 ) ;
out_ 8 ( IIC_DIRECTCNTL1 , 0x4 ) ;
udelay ( 1000 ) ; /* 1ms */
/* send stop condition */
out8 ( IIC_DIRECTCNTL1 , 0xC ) ;
out_ 8 ( IIC_DIRECTCNTL1 , 0xC ) ;
udelay ( 1000 ) ; /* 1ms */
/* Unreset controller */
out8 ( IIC_XTCNTLSS1 , ( status & ~ IIC_XTCNTLSS_SRST ) ) ;
out_ 8 ( IIC_XTCNTLSS1 , ( status & ~ IIC_XTCNTLSS_SRST ) ) ;
udelay ( 1000 ) ; /* 1ms */
}
@ -117,16 +120,16 @@ void i2c1_init (int speed, int slaveadd)
_i2c_bus1_reset ( ) ;
/* clear lo master address */
out8 ( IIC_LMADR1 , 0 ) ;
out_ 8 ( IIC_LMADR1 , 0 ) ;
/* clear hi master address */
out8 ( IIC_HMADR1 , 0 ) ;
out_ 8 ( IIC_HMADR1 , 0 ) ;
/* clear lo slave address */
out8 ( IIC_LSADR1 , 0 ) ;
out_ 8 ( IIC_LSADR1 , 0 ) ;
/* clear hi slave address */
out8 ( IIC_HSADR1 , 0 ) ;
out_ 8 ( IIC_HSADR1 , 0 ) ;
/* Clock divide Register */
/* get OPB frequency */
@ -136,25 +139,25 @@ void i2c1_init (int speed, int slaveadd)
divisor = ( freqOPB - 1 ) / 10000000 ;
if ( divisor = = 0 )
divisor = 1 ;
out8 ( IIC_CLKDIV1 , divisor ) ;
out_ 8 ( IIC_CLKDIV1 , divisor ) ;
/* no interrupts */
out8 ( IIC_INTRMSK1 , 0 ) ;
out_ 8 ( IIC_INTRMSK1 , 0 ) ;
/* clear transfer count */
out8 ( IIC_XFRCNT1 , 0 ) ;
out_ 8 ( IIC_XFRCNT1 , 0 ) ;
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
out8 ( IIC_XTCNTLSS1 , 0xF0 ) ;
out_ 8 ( IIC_XTCNTLSS1 , 0xF0 ) ;
/* Mode Control Register
Flush Slave / Master data buffer */
out8 ( IIC_MDCNTL1 , IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB ) ;
out_ 8 ( IIC_MDCNTL1 , IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB ) ;
__asm__ volatile ( " eieio " ) ;
val = in8 ( IIC_MDCNTL1 ) ;
val = in_ 8 ( IIC_MDCNTL1 ) ;
__asm__ volatile ( " eieio " ) ;
/* Ignore General Call, slave transfers are ignored,
@ -167,10 +170,10 @@ void i2c1_init (int speed, int slaveadd)
if ( speed > = 400000 ) {
val | = IIC_MDCNTL_FSM ;
}
out8 ( IIC_MDCNTL1 , val ) ;
out_ 8 ( IIC_MDCNTL1 , val ) ;
/* clear control reg */
out8 ( IIC_CNTL1 , 0x00 ) ;
out_ 8 ( IIC_CNTL1 , 0x00 ) ;
__asm__ volatile ( " eieio " ) ;
}
@ -178,7 +181,7 @@ void i2c1_init (int speed, int slaveadd)
/*
This code tries to use the features of the 405 GP i2c
controller . It will transfer up to 4 bytes in one pass
on the loop . It only does out8 ( lbz ) to the buffer when it
on the loop . It only does out_ 8 ( lbz ) to the buffer when it
is possible to do out16 ( lhz ) transfers .
cmd_type is 0 for write 1 for read .
@ -232,12 +235,12 @@ int i2c_transfer1(unsigned char cmd_type,
}
/*Clear Stop Complete Bit*/
out8 ( IIC_STS1 , IIC_STS_SCMP ) ;
out_ 8 ( IIC_STS1 , IIC_STS_SCMP ) ;
/* Check init */
i = 10 ;
do {
/* Get status */
status = in8 ( IIC_STS1 ) ;
status = in_ 8 ( IIC_STS1 ) ;
__asm__ volatile ( " eieio " ) ;
i - - ;
} while ( ( status & IIC_STS_PT ) & & ( i > 0 ) ) ;
@ -247,12 +250,12 @@ int i2c_transfer1(unsigned char cmd_type,
return ( result ) ;
}
/*flush the Master/Slave Databuffers*/
out8 ( IIC_MDCNTL1 , ( ( in8 ( IIC_MDCNTL1 ) ) | IIC_MDCNTL_FMDB | IIC_MDCNTL_FSDB ) ) ;
out_ 8 ( IIC_MDCNTL1 , ( ( in_ 8 ( IIC_MDCNTL1 ) ) | IIC_MDCNTL_FMDB | IIC_MDCNTL_FSDB ) ) ;
/*need to wait 4 OPB clocks? code below should take that long*/
/* 7-bit adressing */
out8 ( IIC_HMADR1 , 0 ) ;
out8 ( IIC_LMADR1 , chip ) ;
out_ 8 ( IIC_HMADR1 , 0 ) ;
out_ 8 ( IIC_LMADR1 , chip ) ;
__asm__ volatile ( " eieio " ) ;
tran = 0 ;
@ -280,11 +283,11 @@ int i2c_transfer1(unsigned char cmd_type,
else {
for ( j = 0 ; j < bc ; j + + ) {
/* Set buffer */
out8 ( IIC_MDBUF1 , ptr [ tran + j ] ) ;
out_ 8 ( IIC_MDBUF1 , ptr [ tran + j ] ) ;
__asm__ volatile ( " eieio " ) ;
}
}
out8 ( IIC_CNTL1 , creg ) ;
out_ 8 ( IIC_CNTL1 , creg ) ;
__asm__ volatile ( " eieio " ) ;
/* Transfer is in progress
@ -297,7 +300,7 @@ int i2c_transfer1(unsigned char cmd_type,
i = 2 * 5 * 8 ;
do {
/* Get status */
status = in8 ( IIC_STS1 ) ;
status = in_ 8 ( IIC_STS1 ) ;
__asm__ volatile ( " eieio " ) ;
udelay ( 10 ) ;
i - - ;
@ -306,7 +309,7 @@ int i2c_transfer1(unsigned char cmd_type,
if ( status & IIC_STS_ERR ) {
result = IIC_NOK ;
status = in8 ( IIC_EXTSTS1 ) ;
status = in_ 8 ( IIC_EXTSTS1 ) ;
/* Lost arbitration? */
if ( status & IIC_EXTSTS_LA )
result = IIC_NOK_LA ;
@ -331,7 +334,7 @@ int i2c_transfer1(unsigned char cmd_type,
*/
udelay ( 1 ) ;
for ( j = 0 ; j < bc ; j + + ) {
ptr [ tran + j ] = in8 ( IIC_MDBUF1 ) ;
ptr [ tran + j ] = in_ 8 ( IIC_MDBUF1 ) ;
__asm__ volatile ( " eieio " ) ;
}
} else