|
@@ -57,19 +57,19 @@ static int bit_test; /* see if the line-setting functions work */
|
|
|
static inline void sdalo(struct i2c_algo_bit_data *adap)
|
|
|
{
|
|
|
setsda(adap,0);
|
|
|
- udelay(adap->udelay);
|
|
|
+ udelay((adap->udelay + 1) / 2);
|
|
|
}
|
|
|
|
|
|
static inline void sdahi(struct i2c_algo_bit_data *adap)
|
|
|
{
|
|
|
setsda(adap,1);
|
|
|
- udelay(adap->udelay);
|
|
|
+ udelay((adap->udelay + 1) / 2);
|
|
|
}
|
|
|
|
|
|
static inline void scllo(struct i2c_algo_bit_data *adap)
|
|
|
{
|
|
|
setscl(adap,0);
|
|
|
- udelay(adap->udelay);
|
|
|
+ udelay(adap->udelay / 2);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -111,18 +111,19 @@ static void i2c_start(struct i2c_algo_bit_data *adap)
|
|
|
{
|
|
|
/* assert: scl, sda are high */
|
|
|
DEBPROTO(printk("S "));
|
|
|
- sdalo(adap);
|
|
|
+ setsda(adap, 0);
|
|
|
+ udelay(adap->udelay);
|
|
|
scllo(adap);
|
|
|
}
|
|
|
|
|
|
static void i2c_repstart(struct i2c_algo_bit_data *adap)
|
|
|
{
|
|
|
- /* scl, sda may not be high */
|
|
|
+ /* assert: scl is low */
|
|
|
DEBPROTO(printk(" Sr "));
|
|
|
- setsda(adap,1);
|
|
|
+ sdahi(adap);
|
|
|
sclhi(adap);
|
|
|
-
|
|
|
- sdalo(adap);
|
|
|
+ setsda(adap, 0);
|
|
|
+ udelay(adap->udelay);
|
|
|
scllo(adap);
|
|
|
}
|
|
|
|
|
@@ -133,7 +134,8 @@ static void i2c_stop(struct i2c_algo_bit_data *adap)
|
|
|
/* assert: scl is low */
|
|
|
sdalo(adap);
|
|
|
sclhi(adap);
|
|
|
- sdahi(adap);
|
|
|
+ setsda(adap, 1);
|
|
|
+ udelay(adap->udelay);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -156,18 +158,16 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
|
|
|
for ( i=7 ; i>=0 ; i-- ) {
|
|
|
sb = c & ( 1 << i );
|
|
|
setsda(adap,sb);
|
|
|
- udelay(adap->udelay);
|
|
|
+ udelay((adap->udelay + 1) / 2);
|
|
|
DEBPROTO(printk(KERN_DEBUG "%d",sb!=0));
|
|
|
if (sclhi(adap)<0) { /* timed out */
|
|
|
- sdahi(adap); /* we don't want to block the net */
|
|
|
DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i));
|
|
|
return -ETIMEDOUT;
|
|
|
};
|
|
|
/* do arbitration here:
|
|
|
* if ( sb && ! getsda(adap) ) -> ouch! Get out of here.
|
|
|
*/
|
|
|
- setscl(adap, 0 );
|
|
|
- udelay(adap->udelay);
|
|
|
+ scllo(adap);
|
|
|
}
|
|
|
sdahi(adap);
|
|
|
if (sclhi(adap)<0){ /* timeout */
|
|
@@ -204,7 +204,8 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
|
|
|
indata *= 2;
|
|
|
if ( getsda(adap) )
|
|
|
indata |= 0x01;
|
|
|
- scllo(adap);
|
|
|
+ setscl(adap, 0);
|
|
|
+ udelay(i == 7 ? adap->udelay / 2 : adap->udelay);
|
|
|
}
|
|
|
/* assert: scl is low */
|
|
|
DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff));
|
|
@@ -315,9 +316,9 @@ static int try_address(struct i2c_adapter *i2c_adap,
|
|
|
if (ret == 1 || i == retries)
|
|
|
break;
|
|
|
i2c_stop(adap);
|
|
|
- udelay(5/*adap->udelay*/);
|
|
|
- i2c_start(adap);
|
|
|
udelay(adap->udelay);
|
|
|
+ yield();
|
|
|
+ i2c_start(adap);
|
|
|
}
|
|
|
DEB2(if (i)
|
|
|
printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n",
|
|
@@ -377,20 +378,21 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
|
|
|
if (msg->flags & I2C_M_NO_RD_ACK)
|
|
|
continue;
|
|
|
|
|
|
+ /* assert: sda is high */
|
|
|
if ( count > 0 ) { /* send ack */
|
|
|
- sdalo(adap);
|
|
|
+ setsda(adap, 0);
|
|
|
+ udelay((adap->udelay + 1) / 2);
|
|
|
DEBPROTO(printk(" Am "));
|
|
|
} else {
|
|
|
- sdahi(adap); /* neg. ack on last byte */
|
|
|
+ /* neg. ack on last byte */
|
|
|
+ udelay((adap->udelay + 1) / 2);
|
|
|
DEBPROTO(printk(" NAm "));
|
|
|
}
|
|
|
if (sclhi(adap)<0) { /* timeout */
|
|
|
- sdahi(adap);
|
|
|
printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n");
|
|
|
return -ETIMEDOUT;
|
|
|
};
|
|
|
scllo(adap);
|
|
|
- sdahi(adap);
|
|
|
|
|
|
/* Some SMBus transactions require that we receive the
|
|
|
transaction length as the first read byte. */
|