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);
}
/*
{
/* 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);
}
/* assert: scl is low */
sdalo(adap);
sclhi(adap);
- sdahi(adap);
+ setsda(adap, 1);
+ udelay(adap->udelay);
}
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 */
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));
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",
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. */
int (*getscl) (void *data);
/* local settings */
- int udelay; /* half-clock-cycle time in microsecs */
- /* i.e. clock is (500 / udelay) KHz */
+ int udelay; /* half clock cycle time in us,
+ minimum 2 us for fast-mode I2C,
+ minimum 5 us for standard-mode I2C and SMBus,
+ maximum 50 us for SMBus */
int timeout; /* in jiffies */
};