Lines Matching +full:i2c +full:- +full:sda +full:- +full:hold +full:- +full:time +full:- +full:ns
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
31 * Generic I2C bit-banging code
41 * From Linux I2C generic interface
42 * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
136 device_set_desc(dev, "I2C bit-banging driver"); in iicbb_probe()
146 sc->iicbus = device_add_child(dev, "iicbus", DEVICE_UNIT_ANY); in iicbb_attach()
147 if (!sc->iicbus) in iicbb_attach()
150 sc->scl_low_timeout = DEFAULT_SCL_LOW_TIMEOUT; in iicbb_attach()
154 "delay", CTLFLAG_RD, &sc->udelay, in iicbb_attach()
159 "scl_low_timeout", CTLFLAG_RWTUN, &sc->scl_low_timeout, in iicbb_attach()
163 "io_latency", CTLFLAG_RWTUN, &sc->io_latency, in iicbb_attach()
175 /* We only have one child, the I2C bus, which needs our own node. */ in iicbb_get_node()
185 if (child == sc->iicbus) in iicbb_child_detached()
186 sc->iicbus = NULL; in iicbb_child_detached()
197 /* retrieve the interface I2C address */ in iicbb_print_child()
200 retval += printf(" on %s master-only\n", in iicbb_print_child()
219 &i2c_debug, 0, "Enable i2c bit-banging driver debug");
243 timeout = now + sc->scl_low_timeout * SBT_1US; in iicbb_waitforscl()
252 pause_sbt("iicbb-scl-low", SBT_1MS, 0, C_PREL(2)); in iicbb_waitforscl()
264 iicbb_clockin(device_t dev, int sda) in iicbb_clockin() argument
270 * - set SDA to the value; in iicbb_clockin()
271 * - release SCL and wait until it's high. in iicbb_clockin()
274 * There should be a data set-up time, 250 ns minimum, between setting in iicbb_clockin()
275 * SDA and raising SCL. It's expected that the I/O access latency will in iicbb_clockin()
278 I2C_SETSDA(dev, sda); in iicbb_clockin()
295 * - pull SCL low and hold for udelay. in iicbb_clockout()
298 DELAY(sc->udelay); in iicbb_clockout()
310 DELAY(sc->udelay); in iicbb_sendbit()
327 * line low and then the SLAVE will release the SDA (data) line.
336 /* Release SDA so that the slave can drive it. */ in iicbb_getack()
343 /* Sample SDA until ACK (low) or udelay runs out. */ in iicbb_getack()
350 } while(t < sc->udelay); in iicbb_getack()
352 DELAY(sc->udelay - t); in iicbb_getack()
355 I2C_DEBUG(printf("%c ", noack ? '-' : '+')); in iicbb_getack()
364 for (i = 7; i >= 0; i--) { in iicbb_sendbyte()
382 * Release SDA so that the slave can drive it. in iicbb_readbyte()
383 * We do not use iicbb_clockin() here because we need to release SDA in iicbb_readbyte()
388 for (i = 7; i >= 0; i--) { in iicbb_readbyte()
395 DELAY((sc->udelay + 1) / 2); in iicbb_readbyte()
398 DELAY((sc->udelay + 1) / 2); in iicbb_readbyte()
403 * Send master->slave ACK (low) for more data, in iicbb_readbyte()
407 I2C_DEBUG(printf("r%02x%c ", *data, last ? '-' : '+')); in iicbb_readbyte()
444 /* SDA will go low in the middle of the SCL high phase. */ in iicbb_start_impl()
445 DELAY((sc->udelay + 1) / 2); in iicbb_start_impl()
449 * SDA must be high after the earlier stop condition or the end in iicbb_start_impl()
457 /* Start: SDA high->low. */ in iicbb_start_impl()
461 DELAY((sc->udelay + 1) / 2); in iicbb_start_impl()
498 * Stop: SDA goes from low to high in the middle of the SCL high phase. in iicbb_stop()
503 DELAY((sc->udelay + 1) / 2); in iicbb_stop()
505 DELAY((sc->udelay + 1) / 2); in iicbb_stop()
528 len--; in iicbb_write()
549 len--; in iicbb_read()
580 busfreq = IICBUS_GET_FREQUENCY(sc->iicbus, speed); in iicbb_set_speed()
581 period = 1000000 / 2 / busfreq; /* Hz -> uS */ in iicbb_set_speed()
582 period -= sc->io_latency; in iicbb_set_speed()
583 sc->udelay = MAX(period, 1); in iicbb_set_speed()