Lines Matching +full:low +full:- +full:to +full:- +full:high

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * Helper code to recover a hung i2c bus by bit-banging a recovery sequence.
34 * An i2c bus can be hung by a slave driving the clock (rare) or data lines low.
35 * The most common cause is a partially-completed transaction such as rebooting
36 * while a slave is sending a byte of data. Because i2c allows the clock to
38 * data line until power is removed, or the clock cycles enough times to
42 * Any i2c driver which is able to manually set the level of the clock and data
45 * pins to do the bus recovery, then can be assigned back to the i2c hardware.
65 * Start with clock and data high. in iic_recover_bus()
67 pins->setsda(pins->ctx, 1); in iic_recover_bus()
68 pins->setscl(pins->ctx, 1); in iic_recover_bus()
71 * At this point, SCL should be high. If it's not, some slave on the in iic_recover_bus()
72 * bus is doing clock-stretching and we should wait a while. If that in iic_recover_bus()
73 * slave is completely locked up there may be no way to recover at all. in iic_recover_bus()
74 * We wait up to 40 milliseconds, a seriously pessimistic time (even a in iic_recover_bus()
75 * cheap eeprom has a max post-write delay of only 10ms), and also long in iic_recover_bus()
76 * enough to allow SMB slaves to timeout normally after 35ms. in iic_recover_bus()
79 if (pins->getscl(pins->ctx)) in iic_recover_bus()
87 * At this point we should be able to control the clock line. Some in iic_recover_bus()
89 * the data line low waiting for more clock pulses to finish the byte. in iic_recover_bus()
90 * Cycle the clock until we see the data line go high, but only up to 9 in iic_recover_bus()
91 * times because if it's not free after 9 clocks we're never going to in iic_recover_bus()
96 if (pins->getsda(pins->ctx)) in iic_recover_bus()
100 pins->setscl(pins->ctx, 0); in iic_recover_bus()
102 pins->setscl(pins->ctx, 1); in iic_recover_bus()
108 * lines, and both lines should be high. To complete the reset of a in iic_recover_bus()
109 * slave that was part way through a transaction, we need to do a in iic_recover_bus()
110 * START/STOP sequence, which leaves both lines high at the end. in iic_recover_bus()
111 * - START: SDA transitions high->low while SCL remains high. in iic_recover_bus()
112 * - STOP: SDA transitions low->high while SCL remains high. in iic_recover_bus()
113 * Note that even though the clock line remains high, we transition the in iic_recover_bus()
116 pins->setsda(pins->ctx, 0); in iic_recover_bus()
118 pins->setsda(pins->ctx, 1); in iic_recover_bus()