int i2c_bitbang_write_byte(void *v, uint8_t val, int flags, i2c_bitbang_ops_t ops) { uint32_t bit; uint8_t mask; int error; BB_DIR(OUTPUT); for (mask = 0x80; mask != 0; mask >>= 1) { bit = (val & mask) ? SDA : 0; BB_SET(bit ); delay(1); /* data setup time (250 nS) */ BB_SET(bit | SCL); delay(4); /* clock high time (4.0 uS) */ BB_SET(bit ); delay(5); /* clock low time (4.7 uS) */ } BB_DIR(INPUT); BB_SET(SDA ); delay(5); BB_SET(SDA | SCL); delay(4); error = (BB_READ & SDA) ? EIO : 0; BB_SET(SDA ); delay(5); if (flags & I2C_F_STOP) (void) i2c_bitbang_send_stop(v, flags, ops); return (error); }
static int slugiic_send_stop(void *arg, int flags) { struct slugiic_softc *sc = arg; return (i2c_bitbang_send_stop(sc, flags, &sc->sc_ibo)); }
int i2c_wait_for_scl(void *v, i2c_bitbang_ops_t ops) { int bail = 0; while(((BB_READ & SCL) == 0) && bail < SCL_BAIL_COUNT) { delay(1); bail++; } if (bail == SCL_BAIL_COUNT) { i2c_bitbang_send_stop(v, 0, ops); return (EIO); } return (0); }
int i2c_bitbang_read_byte(void *v, uint8_t *valp, int flags, i2c_bitbang_ops_t ops) { int i; uint8_t val = 0; uint32_t bit; BB_DIR(INPUT); BB_SET(SDA ); for (i = 0; i < 8; i++) { val <<= 1; BB_SET(SDA | SCL); if (i2c_wait_for_scl(v, ops) != 0) return (EIO); delay(4); /* clock high time (4.0 uS) */ if (BB_READ & SDA) val |= 1; BB_SET(SDA ); delay(5); /* clock low time (4.7 uS) */ } bit = (flags & I2C_F_LAST) ? SDA : 0; BB_DIR(OUTPUT); BB_SET(bit ); delay(1); /* data setup time (250 nS) */ BB_SET(bit | SCL); if (i2c_wait_for_scl(v, ops) != 0) return (EIO); delay(4); /* clock high time (4.0 uS) */ BB_SET(bit ); delay(5); /* clock low time (4.7 uS) */ BB_DIR(INPUT); BB_SET(SDA ); delay(5); if ((flags & (I2C_F_STOP | I2C_F_LAST)) == (I2C_F_STOP | I2C_F_LAST)) (void) i2c_bitbang_send_stop(v, flags, ops); *valp = val; return (0); }
int gpioiic_i2c_send_stop(void *cookie, int flags) { return i2c_bitbang_send_stop(cookie, flags, &gpioiic_bbops); }
static int igma_i2c_send_stop(void *cookie, int flags) { return i2c_bitbang_send_stop(cookie, flags, &igma_i2cbb_ops); }
int radeonfb_i2c_send_stop(void *cookie, int flags) { return i2c_bitbang_send_stop(cookie, flags, &radeonfb_i2cbb_ops); }
int armadillo9iic_send_stop(void *cookie, int flags) { return i2c_bitbang_send_stop(cookie, flags, &armadillo9iic_bbops); }
static int iomdiic_send_stop(void *cookie, int flags) { return (i2c_bitbang_send_stop(cookie, flags, &iomdiic_bbops)); }