void i2c_stop(struct i2c_bus *bus) { I2C_SET(bus,0,0); I2C_SET(bus,1,0); I2C_SET(bus,1,1); I2C_DEBUG(printk(">\n")); }
static int iicbb_start(device_t dev, u_char slave, int timeout) { int error; I2C_DEBUG(printf("<")); I2C_SET(dev,1,1); I2C_SET(dev,1,0); I2C_SET(dev,0,0); /* send address */ iicbb_sendbyte(dev, slave, timeout); /* check for ack */ if (iicbb_ack(dev, timeout)) { error = IIC_ENOACK; goto error; } return(0); error: iicbb_stop(dev); return (error); }
static void iicbb_zero(device_t dev, int timeout) { I2C_SET(dev,0,0); I2C_SET(dev,1,0); I2C_SET(dev,0,0); return; }
static void iicbb_one(device_t dev, int timeout) { I2C_SET(dev,0,1); I2C_SET(dev,1,1); I2C_SET(dev,0,1); return; }
void i2c_start(struct i2c_bus *bus) { I2C_SET(bus,0,1); I2C_SET(bus,1,1); I2C_SET(bus,1,0); I2C_SET(bus,0,0); I2C_DEBUG(printk("%s: < ",bus->name)); }
static int iicbb_stop(device_t dev) { I2C_SET(dev,0,0); I2C_SET(dev,1,0); I2C_SET(dev,1,1); I2C_DEBUG(printf(">")); return (0); }
static void iicbb_zero(device_t dev, int timeout) { struct iicbb_softc *sc = device_get_softc(dev); I2C_SET(sc,dev,0,0); I2C_SET(sc,dev,1,0); I2C_SET(sc,dev,0,0); return; }
int i2c_ack(struct i2c_bus *bus) { int ack; I2C_SET(bus,0,1); I2C_SET(bus,1,1); ack = I2C_GET(bus); I2C_SET(bus,0,1); return ack; }
static int iicbb_stop(device_t dev) { struct iicbb_softc *sc = device_get_softc(dev); I2C_SET(sc,dev,0,0); I2C_SET(sc,dev,1,0); I2C_SET(sc,dev,1,1); I2C_DEBUG(printf(">")); I2C_DEBUG(printf("\n")); return (0); }
unsigned char i2c_readbyte(struct i2c_bus *bus,int last) { int i; unsigned char data=0; I2C_SET(bus,0,1); for (i=7; i>=0; i--) { I2C_SET(bus,1,1); if (I2C_GET(bus)) data |= (1<<i); I2C_SET(bus,0,1); } last ? i2c_one(bus) : i2c_zero(bus); I2C_DEBUG(printk("=%02x%c ",(int)data,last?'-':'+')); return data; }
/* * Waiting for ACKNOWLEDGE. * * When a chip is being addressed or has received data it will issue an * ACKNOWLEDGE pulse. Therefore the MASTER must release the DATA line * (set it to high level) and then release the CLOCK line. * Now it must wait for the SLAVE to pull the DATA line low. * Actually on the bus this looks like a START condition so nothing happens * because of the fact that the IC's that have not been addressed are doing * nothing. * * When the SLAVE has pulled this line low the MASTER will take the CLOCK * line low and then the SLAVE will release the SDA (data) line. */ static int iicbb_ack(device_t dev, int timeout) { int noack; int k = 0; I2C_SET(dev,0,1); I2C_SET(dev,1,1); do { noack = I2C_GETSDA(dev); if (!noack) break; DELAY(10); k += 10; } while (k < timeout); I2C_SET(dev,0,1); I2C_DEBUG(printf("%c ",noack?'-':'+')); return (noack); }
static u_char iicbb_readbyte(device_t dev, int last, int timeout) { int i; unsigned char data=0; I2C_SET(dev,0,1); for (i=7; i>=0; i--) { I2C_SET(dev,1,1); if (I2C_GETSDA(dev)) data |= (1<<i); I2C_SET(dev,0,1); } if (last) { iicbb_one(dev, timeout); } else { iicbb_zero(dev, timeout); } I2C_DEBUG(printf("r%02x%c ",(int)data,last?'-':'+')); return data; }
/* * Waiting for ACKNOWLEDGE. * * When a chip is being addressed or has received data it will issue an * ACKNOWLEDGE pulse. Therefore the MASTER must release the DATA line * (set it to high level) and then release the CLOCK line. * Now it must wait for the SLAVE to pull the DATA line low. * Actually on the bus this looks like a START condition so nothing happens * because of the fact that the IC's that have not been addressed are doing * nothing. * * When the SLAVE has pulled this line low the MASTER will take the CLOCK * line low and then the SLAVE will release the SDA (data) line. */ static int iicbb_ack(device_t dev, int timeout) { struct iicbb_softc *sc = device_get_softc(dev); int noack; int k = 0; I2C_SET(sc,dev,0,1); I2C_SET(sc,dev,1,1); do { noack = I2C_GETSDA(dev); if (!noack) break; DELAY(1); k++; } while (k < timeout); I2C_SET(sc,dev,0,1); I2C_DEBUG(printf("%c ",noack?'-':'+')); return (noack); }
int i2c_sendbyte(struct i2c_bus *bus,unsigned char data,int wait_for_ack) { int i, ack; I2C_SET(bus,0,0); for (i=7; i>=0; i--) (data&(1<<i)) ? i2c_one(bus) : i2c_zero(bus); if (wait_for_ack) udelay(wait_for_ack); ack=i2c_ack(bus); I2C_DEBUG(printk("%02x%c ",(int)data,ack?'-':'+')); return ack; }
void i2c_zero(struct i2c_bus *bus) { I2C_SET(bus,0,0); I2C_SET(bus,1,0); I2C_SET(bus,0,0); }
void i2c_one(struct i2c_bus *bus) { I2C_SET(bus,0,1); I2C_SET(bus,1,1); I2C_SET(bus,0,1); }