2 * Copyright (c) 2015 Google, Inc
3 * Written by Simon Glass <sjg@chromium.org>
5 * SPDX-License-Identifier: GPL-2.0+
14 DECLARE_GLOBAL_DATA_PTR
;
16 struct i2c_arbitrator_priv
{
17 struct gpio_desc ap_claim
;
18 struct gpio_desc ec_claim
;
24 int i2c_arbitrator_deselect(struct udevice
*mux
, struct udevice
*bus
,
27 struct i2c_arbitrator_priv
*priv
= dev_get_priv(mux
);
30 debug("%s: %s\n", __func__
, mux
->name
);
31 ret
= dm_gpio_set_value(&priv
->ap_claim
, 0);
32 udelay(priv
->slew_delay_us
);
37 int i2c_arbitrator_select(struct udevice
*mux
, struct udevice
*bus
,
40 struct i2c_arbitrator_priv
*priv
= dev_get_priv(mux
);
44 debug("%s: %s\n", __func__
, mux
->name
);
45 /* Start a round of trying to claim the bus */
51 /* Indicate that we want to claim the bus */
52 ret
= dm_gpio_set_value(&priv
->ap_claim
, 1);
55 udelay(priv
->slew_delay_us
);
57 /* Wait for the EC to release it */
58 start_retry
= get_timer(0);
59 while (get_timer(start_retry
) < priv
->wait_retry_ms
) {
60 ret
= dm_gpio_get_value(&priv
->ec_claim
);
64 /* We got it, so return */
72 /* It didn't release, so give up, wait, and try again */
73 ret
= dm_gpio_set_value(&priv
->ap_claim
, 0);
77 mdelay(priv
->wait_retry_ms
);
78 } while (get_timer(start
) < priv
->wait_free_ms
);
80 /* Give up, release our claim */
81 printf("I2C: Could not claim bus, timeout %lu\n", get_timer(start
));
88 static int i2c_arbitrator_probe(struct udevice
*dev
)
90 struct i2c_arbitrator_priv
*priv
= dev_get_priv(dev
);
91 const void *blob
= gd
->fdt_blob
;
92 int node
= dev_of_offset(dev
);
95 debug("%s: %s\n", __func__
, dev
->name
);
96 priv
->slew_delay_us
= fdtdec_get_int(blob
, node
, "slew-delay-us", 0);
97 priv
->wait_retry_ms
= fdtdec_get_int(blob
, node
, "wait-retry-us", 0) /
99 priv
->wait_free_ms
= fdtdec_get_int(blob
, node
, "wait-free-us", 0) /
101 ret
= gpio_request_by_name(dev
, "our-claim-gpio", 0, &priv
->ap_claim
,
105 ret
= gpio_request_by_name(dev
, "their-claim-gpios", 0, &priv
->ec_claim
,
113 dm_gpio_free(dev
, &priv
->ap_claim
);
115 debug("%s: ret=%d\n", __func__
, ret
);
119 static int i2c_arbitrator_remove(struct udevice
*dev
)
121 struct i2c_arbitrator_priv
*priv
= dev_get_priv(dev
);
123 dm_gpio_free(dev
, &priv
->ap_claim
);
124 dm_gpio_free(dev
, &priv
->ec_claim
);
129 static const struct i2c_mux_ops i2c_arbitrator_ops
= {
130 .select
= i2c_arbitrator_select
,
131 .deselect
= i2c_arbitrator_deselect
,
134 static const struct udevice_id i2c_arbitrator_ids
[] = {
135 { .compatible
= "i2c-arb-gpio-challenge" },
139 U_BOOT_DRIVER(i2c_arbitrator
) = {
140 .name
= "i2c_arbitrator",
141 .id
= UCLASS_I2C_MUX
,
142 .of_match
= i2c_arbitrator_ids
,
143 .probe
= i2c_arbitrator_probe
,
144 .remove
= i2c_arbitrator_remove
,
145 .ops
= &i2c_arbitrator_ops
,
146 .priv_auto_alloc_size
= sizeof(struct i2c_arbitrator_priv
),