1# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2%YAML 1.2 3--- 4$id: http://devicetree.org/schemas/i2c/i2c-arb-gpio-challenge.yaml# 5$schema: http://devicetree.org/meta-schemas/core.yaml# 6 7title: GPIO-based I2C Arbitration Using a Challenge & Response Mechanism 8 9maintainers: 10 - Doug Anderson <dianders@chromium.org> 11 - Peter Rosin <peda@axentia.se> 12 13description: | 14 This uses GPIO lines and a challenge & response mechanism to arbitrate who is 15 the master of an I2C bus in a multimaster situation. 16 17 In many cases using GPIOs to arbitrate is not needed and a design can use the 18 standard I2C multi-master rules. Using GPIOs is generally useful in the case 19 where there is a device on the bus that has errata and/or bugs that makes 20 standard multimaster mode not feasible. 21 22 Note that this scheme works well enough but has some downsides: 23 * It is nonstandard (not using standard I2C multimaster) 24 * Having two masters on a bus in general makes it relatively hard to debug 25 problems (hard to tell if i2c issues were caused by one master, another, 26 or some device on the bus). 27 28 Algorithm: 29 All masters on the bus have a 'bus claim' line which is an output that the 30 others can see. These are all active low with pull-ups enabled. We'll 31 describe these lines as: 32 * OUR_CLAIM: output from us signaling to other hosts that we want the bus 33 * THEIR_CLAIMS: output from others signaling that they want the bus 34 35 The basic algorithm is to assert your line when you want the bus, then make 36 sure that the other side doesn't want it also. A detailed explanation is 37 best done with an example. 38 39 Let's say we want to claim the bus. We: 40 1. Assert OUR_CLAIM. 41 2. Waits a little bit for the other sides to notice (slew time, say 10 42 microseconds). 43 3. Check THEIR_CLAIMS. If none are asserted then the we have the bus and we 44 are done. 45 4. Otherwise, wait for a few milliseconds and see if THEIR_CLAIMS are released. 46 5. If not, back off, release the claim and wait for a few more milliseconds. 47 6. Go back to 1 (until retry time has expired). 48 49properties: 50 compatible: 51 const: i2c-arb-gpio-challenge 52 53 i2c-parent: 54 $ref: /schemas/types.yaml#/definitions/phandle 55 description: 56 The I2C bus that this multiplexer's master-side port is connected to. 57 58 our-claim-gpios: 59 maxItems: 1 60 description: 61 The GPIO that we use to claim the bus. 62 63 slew-delay-us: 64 default: 10 65 description: 66 Time to wait for a GPIO to go high. 67 68 their-claim-gpios: 69 minItems: 1 70 maxItems: 8 71 description: 72 The GPIOs that the other sides use to claim the bus. Note that some 73 implementations may only support a single other master. 74 75 wait-free-us: 76 default: 50000 77 description: 78 We'll give up after this many microseconds. 79 80 wait-retry-us: 81 default: 3000 82 description: 83 We'll attempt another claim after this many microseconds. 84 85 i2c-arb: 86 type: object 87 $ref: /schemas/i2c/i2c-controller.yaml 88 unevaluatedProperties: false 89 description: 90 I2C arbitration bus node. 91 92required: 93 - compatible 94 - i2c-arb 95 - our-claim-gpios 96 - their-claim-gpios 97 98additionalProperties: false 99 100examples: 101 - | 102 #include <dt-bindings/gpio/gpio.h> 103 #include <dt-bindings/interrupt-controller/irq.h> 104 105 i2c-arbitrator { 106 compatible = "i2c-arb-gpio-challenge"; 107 i2c-parent = <&i2c_4>; 108 109 our-claim-gpios = <&gpf0 3 GPIO_ACTIVE_LOW>; 110 their-claim-gpios = <&gpe0 4 GPIO_ACTIVE_LOW>; 111 slew-delay-us = <10>; 112 wait-retry-us = <3000>; 113 wait-free-us = <50000>; 114 115 i2c-arb { 116 #address-cells = <1>; 117 #size-cells = <0>; 118 119 sbs-battery@b { 120 compatible = "sbs,sbs-battery"; 121 reg = <0xb>; 122 sbs,poll-retry-count = <1>; 123 }; 124 125 embedded-controller@1e { 126 compatible = "google,cros-ec-i2c"; 127 reg = <0x1e>; 128 interrupts = <6 IRQ_TYPE_LEVEL_HIGH>; 129 interrupt-parent = <&gpx1>; 130 pinctrl-names = "default"; 131 pinctrl-0 = <&ec_irq>; 132 wakeup-source; 133 }; 134 }; 135 }; 136