Lines Matching +full:master +full:- +full:side
1 // SPDX-License-Identifier: GPL-2.0-only
3 * GPIO-based I2C Arbitration Using a Challenge & Response Mechanism
12 #include <linux/i2c-mux.h>
19 * struct i2c_arbitrator_data - Driver data for I2C arbitrator
22 * @their_gpio: GPIO descriptor that the other side will use to claim.
38 * i2c_arbitrator_select - claim the I2C bus
40 * Use the GPIO-based signalling protocol; return -EBUSY if we fail.
48 stop_time = jiffies + usecs_to_jiffies(arb->wait_free_us) + 1; in i2c_arbitrator_select()
51 gpiod_set_value(arb->our_gpio, 1); in i2c_arbitrator_select()
52 udelay(arb->slew_delay_us); in i2c_arbitrator_select()
54 /* Wait for the other master to release it */ in i2c_arbitrator_select()
55 stop_retry = jiffies + usecs_to_jiffies(arb->wait_retry_us) + 1; in i2c_arbitrator_select()
57 int gpio_val = gpiod_get_value(arb->their_gpio); in i2c_arbitrator_select()
68 gpiod_set_value(arb->our_gpio, 0); in i2c_arbitrator_select()
70 usleep_range(arb->wait_retry_us, arb->wait_retry_us * 2); in i2c_arbitrator_select()
74 gpiod_set_value(arb->our_gpio, 0); in i2c_arbitrator_select()
75 udelay(arb->slew_delay_us); in i2c_arbitrator_select()
76 dev_err(muxc->dev, "Could not claim bus, timeout\n"); in i2c_arbitrator_select()
77 return -EBUSY; in i2c_arbitrator_select()
81 * i2c_arbitrator_deselect - release the I2C bus
83 * Release the I2C bus using the GPIO-based signalling protocol.
89 /* Release the bus and wait for the other master to notice */ in i2c_arbitrator_deselect()
90 gpiod_set_value(arb->our_gpio, 0); in i2c_arbitrator_deselect()
91 udelay(arb->slew_delay_us); in i2c_arbitrator_deselect()
98 struct device *dev = &pdev->dev; in i2c_arbitrator_probe()
99 struct device_node *np = dev->of_node; in i2c_arbitrator_probe()
109 return -ENODEV; in i2c_arbitrator_probe()
113 return -EINVAL; in i2c_arbitrator_probe()
119 return -ENOMEM; in i2c_arbitrator_probe()
125 arb->our_gpio = devm_gpiod_get(dev, "our-claim", GPIOD_OUT_LOW); in i2c_arbitrator_probe()
126 if (IS_ERR(arb->our_gpio)) { in i2c_arbitrator_probe()
127 dev_err(dev, "could not get \"our-claim\" GPIO (%ld)\n", in i2c_arbitrator_probe()
128 PTR_ERR(arb->our_gpio)); in i2c_arbitrator_probe()
129 return PTR_ERR(arb->our_gpio); in i2c_arbitrator_probe()
132 arb->their_gpio = devm_gpiod_get(dev, "their-claim", GPIOD_IN); in i2c_arbitrator_probe()
133 if (IS_ERR(arb->their_gpio)) { in i2c_arbitrator_probe()
134 dev_err(dev, "could not get \"their-claim\" GPIO (%ld)\n", in i2c_arbitrator_probe()
135 PTR_ERR(arb->their_gpio)); in i2c_arbitrator_probe()
136 return PTR_ERR(arb->their_gpio); in i2c_arbitrator_probe()
139 /* At the moment we only support a single two master (us + 1 other) */ in i2c_arbitrator_probe()
140 dummy = devm_gpiod_get_index(dev, "their-claim", 1, GPIOD_IN); in i2c_arbitrator_probe()
142 dev_err(dev, "Only one other master is supported\n"); in i2c_arbitrator_probe()
143 return -EINVAL; in i2c_arbitrator_probe()
144 } else if (PTR_ERR(dummy) == -EPROBE_DEFER) { in i2c_arbitrator_probe()
145 return -EPROBE_DEFER; in i2c_arbitrator_probe()
149 if (of_property_read_u32(np, "slew-delay-us", &arb->slew_delay_us)) in i2c_arbitrator_probe()
150 arb->slew_delay_us = 10; in i2c_arbitrator_probe()
151 if (of_property_read_u32(np, "wait-retry-us", &arb->wait_retry_us)) in i2c_arbitrator_probe()
152 arb->wait_retry_us = 3000; in i2c_arbitrator_probe()
153 if (of_property_read_u32(np, "wait-free-us", &arb->wait_free_us)) in i2c_arbitrator_probe()
154 arb->wait_free_us = 50000; in i2c_arbitrator_probe()
157 parent_np = of_parse_phandle(np, "i2c-parent", 0); in i2c_arbitrator_probe()
159 dev_err(dev, "Cannot parse i2c-parent\n"); in i2c_arbitrator_probe()
160 return -EINVAL; in i2c_arbitrator_probe()
162 muxc->parent = of_get_i2c_adapter_by_node(parent_np); in i2c_arbitrator_probe()
164 if (!muxc->parent) { in i2c_arbitrator_probe()
166 return -EPROBE_DEFER; in i2c_arbitrator_probe()
172 i2c_put_adapter(muxc->parent); in i2c_arbitrator_probe()
182 i2c_put_adapter(muxc->parent); in i2c_arbitrator_remove()
186 { .compatible = "i2c-arb-gpio-challenge", },
195 .name = "i2c-arb-gpio-challenge",
202 MODULE_DESCRIPTION("GPIO-based I2C Arbitration");
205 MODULE_ALIAS("platform:i2c-arb-gpio-challenge");