common: Drop linux/delay.h from common header
[oweals/u-boot.git] / drivers / i2c / muxes / i2c-arb-gpio-challenge.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2015 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <i2c.h>
11 #include <log.h>
12 #include <malloc.h>
13 #include <asm/gpio.h>
14 #include <linux/delay.h>
15
16 DECLARE_GLOBAL_DATA_PTR;
17
18 struct i2c_arbitrator_priv {
19         struct gpio_desc ap_claim;
20         struct gpio_desc ec_claim;
21         uint slew_delay_us;
22         uint wait_retry_ms;
23         uint wait_free_ms;
24 };
25
26 int i2c_arbitrator_deselect(struct udevice *mux, struct udevice *bus,
27                             uint channel)
28 {
29         struct i2c_arbitrator_priv *priv = dev_get_priv(mux);
30         int ret;
31
32         debug("%s: %s\n", __func__, mux->name);
33         ret = dm_gpio_set_value(&priv->ap_claim, 0);
34         udelay(priv->slew_delay_us);
35
36         return ret;
37 }
38
39 int i2c_arbitrator_select(struct udevice *mux, struct udevice *bus,
40                           uint channel)
41 {
42         struct i2c_arbitrator_priv *priv = dev_get_priv(mux);
43         unsigned start;
44         int ret;
45
46         debug("%s: %s\n", __func__, mux->name);
47         /* Start a round of trying to claim the bus */
48         start = get_timer(0);
49         do {
50                 unsigned start_retry;
51                 int waiting = 0;
52
53                 /* Indicate that we want to claim the bus */
54                 ret = dm_gpio_set_value(&priv->ap_claim, 1);
55                 if (ret)
56                         goto err;
57                 udelay(priv->slew_delay_us);
58
59                 /* Wait for the EC to release it */
60                 start_retry = get_timer(0);
61                 while (get_timer(start_retry) < priv->wait_retry_ms) {
62                         ret = dm_gpio_get_value(&priv->ec_claim);
63                         if (ret < 0) {
64                                 goto err;
65                         } else if (!ret) {
66                                 /* We got it, so return */
67                                 return 0;
68                         }
69
70                         if (!waiting)
71                                 waiting = 1;
72                 }
73
74                 /* It didn't release, so give up, wait, and try again */
75                 ret = dm_gpio_set_value(&priv->ap_claim, 0);
76                 if (ret)
77                         goto err;
78
79                 mdelay(priv->wait_retry_ms);
80         } while (get_timer(start) < priv->wait_free_ms);
81
82         /* Give up, release our claim */
83         printf("I2C: Could not claim bus, timeout %lu\n", get_timer(start));
84         ret = -ETIMEDOUT;
85         ret = 0;
86 err:
87         return ret;
88 }
89
90 static int i2c_arbitrator_probe(struct udevice *dev)
91 {
92         struct i2c_arbitrator_priv *priv = dev_get_priv(dev);
93         const void *blob = gd->fdt_blob;
94         int node = dev_of_offset(dev);
95         int ret;
96
97         debug("%s: %s\n", __func__, dev->name);
98         priv->slew_delay_us = fdtdec_get_int(blob, node, "slew-delay-us", 0);
99         priv->wait_retry_ms = fdtdec_get_int(blob, node, "wait-retry-us", 0) /
100                 1000;
101         priv->wait_free_ms = fdtdec_get_int(blob, node, "wait-free-us", 0) /
102                 1000;
103         ret = gpio_request_by_name(dev, "our-claim-gpio", 0, &priv->ap_claim,
104                                    GPIOD_IS_OUT);
105         if (ret)
106                 goto err;
107         ret = gpio_request_by_name(dev, "their-claim-gpios", 0, &priv->ec_claim,
108                                    GPIOD_IS_IN);
109         if (ret)
110                 goto err_ec_gpio;
111
112         return 0;
113
114 err_ec_gpio:
115         dm_gpio_free(dev, &priv->ap_claim);
116 err:
117         debug("%s: ret=%d\n", __func__, ret);
118         return ret;
119 }
120
121 static int i2c_arbitrator_remove(struct udevice *dev)
122 {
123         struct i2c_arbitrator_priv *priv = dev_get_priv(dev);
124
125         dm_gpio_free(dev, &priv->ap_claim);
126         dm_gpio_free(dev, &priv->ec_claim);
127
128         return 0;
129 }
130
131 static const struct i2c_mux_ops i2c_arbitrator_ops = {
132         .select         = i2c_arbitrator_select,
133         .deselect       = i2c_arbitrator_deselect,
134 };
135
136 static const struct udevice_id i2c_arbitrator_ids[] = {
137         { .compatible = "i2c-arb-gpio-challenge" },
138         { }
139 };
140
141 U_BOOT_DRIVER(i2c_arbitrator) = {
142         .name = "i2c_arbitrator",
143         .id = UCLASS_I2C_MUX,
144         .of_match = i2c_arbitrator_ids,
145         .probe = i2c_arbitrator_probe,
146         .remove = i2c_arbitrator_remove,
147         .ops = &i2c_arbitrator_ops,
148         .priv_auto_alloc_size = sizeof(struct i2c_arbitrator_priv),
149 };