Commit | Line | Data |
---|---|---|
b81dfaa0 DA |
1 | GPIO-based I2C Arbitration Using a Challenge & Response Mechanism |
2 | ================================================================= | |
3 | This uses GPIO lines and a challenge & response mechanism to arbitrate who is | |
4 | the master of an I2C bus in a multimaster situation. | |
5 | ||
6 | In many cases using GPIOs to arbitrate is not needed and a design can use | |
7 | the standard I2C multi-master rules. Using GPIOs is generally useful in | |
8 | the case where there is a device on the bus that has errata and/or bugs | |
9 | that makes standard multimaster mode not feasible. | |
10 | ||
a83bea7c DA |
11 | Note that this scheme works well enough but has some downsides: |
12 | * It is nonstandard (not using standard I2C multimaster) | |
13 | * Having two masters on a bus in general makes it relatively hard to debug | |
14 | problems (hard to tell if i2c issues were caused by one master, another, or | |
15 | some device on the bus). | |
16 | ||
b81dfaa0 DA |
17 | |
18 | Algorithm: | |
19 | ||
20 | All masters on the bus have a 'bus claim' line which is an output that the | |
21 | others can see. These are all active low with pull-ups enabled. We'll | |
22 | describe these lines as: | |
23 | ||
24 | - OUR_CLAIM: output from us signaling to other hosts that we want the bus | |
25 | - THEIR_CLAIMS: output from others signaling that they want the bus | |
26 | ||
27 | The basic algorithm is to assert your line when you want the bus, then make | |
28 | sure that the other side doesn't want it also. A detailed explanation is best | |
29 | done with an example. | |
30 | ||
31 | Let's say we want to claim the bus. We: | |
32 | 1. Assert OUR_CLAIM. | |
33 | 2. Waits a little bit for the other sides to notice (slew time, say 10 | |
34 | microseconds). | |
35 | 3. Check THEIR_CLAIMS. If none are asserted then the we have the bus and we are | |
36 | done. | |
37 | 4. Otherwise, wait for a few milliseconds and see if THEIR_CLAIMS are released. | |
38 | 5. If not, back off, release the claim and wait for a few more milliseconds. | |
39 | 6. Go back to 1 (until retry time has expired). | |
40 | ||
41 | ||
42 | Required properties: | |
43 | - compatible: i2c-arb-gpio-challenge | |
44 | - our-claim-gpio: The GPIO that we use to claim the bus. | |
45 | - their-claim-gpios: The GPIOs that the other sides use to claim the bus. | |
46 | Note that some implementations may only support a single other master. | |
e8813c15 | 47 | - I2C arbitration bus node. See i2c-arb.txt in this directory. |
b81dfaa0 DA |
48 | |
49 | Optional properties: | |
50 | - slew-delay-us: microseconds to wait for a GPIO to go high. Default is 10 us. | |
51 | - wait-retry-us: we'll attempt another claim after this many microseconds. | |
52 | Default is 3000 us. | |
53 | - wait-free-us: we'll give up after this many microseconds. Default is 50000 us. | |
54 | ||
55 | ||
56 | Example: | |
57 | i2c@12CA0000 { | |
58 | compatible = "acme,some-i2c-device"; | |
59 | #address-cells = <1>; | |
60 | #size-cells = <0>; | |
61 | }; | |
62 | ||
63 | i2c-arbitrator { | |
64 | compatible = "i2c-arb-gpio-challenge"; | |
b81dfaa0 DA |
65 | |
66 | i2c-parent = <&{/i2c@12CA0000}>; | |
67 | ||
68 | our-claim-gpio = <&gpf0 3 1>; | |
69 | their-claim-gpios = <&gpe0 4 1>; | |
70 | slew-delay-us = <10>; | |
71 | wait-retry-us = <3000>; | |
72 | wait-free-us = <50000>; | |
73 | ||
e8813c15 | 74 | i2c-arb { |
b81dfaa0 DA |
75 | #address-cells = <1>; |
76 | #size-cells = <0>; | |
77 | ||
78 | i2c@52 { | |
79 | // Normal I2C device | |
80 | }; | |
81 | }; | |
82 | }; |