Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/egtvedt...
[cascardo/linux.git] / drivers / i2c / muxes / i2c-arb-gpio-challenge.c
1 /*
2  * GPIO-based I2C Arbitration Using a Challenge & Response Mechanism
3  *
4  * Copyright (C) 2012 Google, Inc
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/delay.h>
18 #include <linux/gpio.h>
19 #include <linux/kernel.h>
20 #include <linux/i2c.h>
21 #include <linux/i2c-mux.h>
22 #include <linux/module.h>
23 #include <linux/of_gpio.h>
24 #include <linux/platform_device.h>
25 #include <linux/slab.h>
26
27
28 /**
29  * struct i2c_arbitrator_data - Driver data for I2C arbitrator
30  *
31  * @our_gpio: GPIO we'll use to claim.
32  * @our_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO ==
33  *   this then consider it released.
34  * @their_gpio: GPIO that the other side will use to claim.
35  * @their_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO ==
36  *   this then consider it released.
37  * @slew_delay_us: microseconds to wait for a GPIO to go high.
38  * @wait_retry_us: we'll attempt another claim after this many microseconds.
39  * @wait_free_us: we'll give up after this many microseconds.
40  */
41
42 struct i2c_arbitrator_data {
43         int our_gpio;
44         int our_gpio_release;
45         int their_gpio;
46         int their_gpio_release;
47         unsigned int slew_delay_us;
48         unsigned int wait_retry_us;
49         unsigned int wait_free_us;
50 };
51
52
53 /**
54  * i2c_arbitrator_select - claim the I2C bus
55  *
56  * Use the GPIO-based signalling protocol; return -EBUSY if we fail.
57  */
58 static int i2c_arbitrator_select(struct i2c_mux_core *muxc, u32 chan)
59 {
60         const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc);
61         unsigned long stop_retry, stop_time;
62
63         /* Start a round of trying to claim the bus */
64         stop_time = jiffies + usecs_to_jiffies(arb->wait_free_us) + 1;
65         do {
66                 /* Indicate that we want to claim the bus */
67                 gpio_set_value(arb->our_gpio, !arb->our_gpio_release);
68                 udelay(arb->slew_delay_us);
69
70                 /* Wait for the other master to release it */
71                 stop_retry = jiffies + usecs_to_jiffies(arb->wait_retry_us) + 1;
72                 while (time_before(jiffies, stop_retry)) {
73                         int gpio_val = !!gpio_get_value(arb->their_gpio);
74
75                         if (gpio_val == arb->their_gpio_release) {
76                                 /* We got it, so return */
77                                 return 0;
78                         }
79
80                         usleep_range(50, 200);
81                 }
82
83                 /* It didn't release, so give up, wait, and try again */
84                 gpio_set_value(arb->our_gpio, arb->our_gpio_release);
85
86                 usleep_range(arb->wait_retry_us, arb->wait_retry_us * 2);
87         } while (time_before(jiffies, stop_time));
88
89         /* Give up, release our claim */
90         gpio_set_value(arb->our_gpio, arb->our_gpio_release);
91         udelay(arb->slew_delay_us);
92         dev_err(muxc->dev, "Could not claim bus, timeout\n");
93         return -EBUSY;
94 }
95
96 /**
97  * i2c_arbitrator_deselect - release the I2C bus
98  *
99  * Release the I2C bus using the GPIO-based signalling protocol.
100  */
101 static int i2c_arbitrator_deselect(struct i2c_mux_core *muxc, u32 chan)
102 {
103         const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc);
104
105         /* Release the bus and wait for the other master to notice */
106         gpio_set_value(arb->our_gpio, arb->our_gpio_release);
107         udelay(arb->slew_delay_us);
108
109         return 0;
110 }
111
112 static int i2c_arbitrator_probe(struct platform_device *pdev)
113 {
114         struct device *dev = &pdev->dev;
115         struct device_node *np = dev->of_node;
116         struct device_node *parent_np;
117         struct i2c_mux_core *muxc;
118         struct i2c_arbitrator_data *arb;
119         enum of_gpio_flags gpio_flags;
120         unsigned long out_init;
121         int ret;
122
123         /* We only support probing from device tree; no platform_data */
124         if (!np) {
125                 dev_err(dev, "Cannot find device tree node\n");
126                 return -ENODEV;
127         }
128         if (dev_get_platdata(dev)) {
129                 dev_err(dev, "Platform data is not supported\n");
130                 return -EINVAL;
131         }
132
133         muxc = i2c_mux_alloc(NULL, dev, 1, sizeof(*arb), I2C_MUX_ARBITRATOR,
134                              i2c_arbitrator_select, i2c_arbitrator_deselect);
135         if (!muxc)
136                 return -ENOMEM;
137         arb = i2c_mux_priv(muxc);
138
139         platform_set_drvdata(pdev, muxc);
140
141         /* Request GPIOs */
142         ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags);
143         if (!gpio_is_valid(ret)) {
144                 if (ret != -EPROBE_DEFER)
145                         dev_err(dev, "Error getting our-claim-gpio\n");
146                 return ret;
147         }
148         arb->our_gpio = ret;
149         arb->our_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
150         out_init = (gpio_flags & OF_GPIO_ACTIVE_LOW) ?
151                 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
152         ret = devm_gpio_request_one(dev, arb->our_gpio, out_init,
153                                     "our-claim-gpio");
154         if (ret) {
155                 if (ret != -EPROBE_DEFER)
156                         dev_err(dev, "Error requesting our-claim-gpio\n");
157                 return ret;
158         }
159
160         ret = of_get_named_gpio_flags(np, "their-claim-gpios", 0, &gpio_flags);
161         if (!gpio_is_valid(ret)) {
162                 if (ret != -EPROBE_DEFER)
163                         dev_err(dev, "Error getting their-claim-gpio\n");
164                 return ret;
165         }
166         arb->their_gpio = ret;
167         arb->their_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
168         ret = devm_gpio_request_one(dev, arb->their_gpio, GPIOF_IN,
169                                     "their-claim-gpio");
170         if (ret) {
171                 if (ret != -EPROBE_DEFER)
172                         dev_err(dev, "Error requesting their-claim-gpio\n");
173                 return ret;
174         }
175
176         /* At the moment we only support a single two master (us + 1 other) */
177         if (gpio_is_valid(of_get_named_gpio(np, "their-claim-gpios", 1))) {
178                 dev_err(dev, "Only one other master is supported\n");
179                 return -EINVAL;
180         }
181
182         /* Arbitration parameters */
183         if (of_property_read_u32(np, "slew-delay-us", &arb->slew_delay_us))
184                 arb->slew_delay_us = 10;
185         if (of_property_read_u32(np, "wait-retry-us", &arb->wait_retry_us))
186                 arb->wait_retry_us = 3000;
187         if (of_property_read_u32(np, "wait-free-us", &arb->wait_free_us))
188                 arb->wait_free_us = 50000;
189
190         /* Find our parent */
191         parent_np = of_parse_phandle(np, "i2c-parent", 0);
192         if (!parent_np) {
193                 dev_err(dev, "Cannot parse i2c-parent\n");
194                 return -EINVAL;
195         }
196         muxc->parent = of_get_i2c_adapter_by_node(parent_np);
197         of_node_put(parent_np);
198         if (!muxc->parent) {
199                 dev_err(dev, "Cannot find parent bus\n");
200                 return -EPROBE_DEFER;
201         }
202
203         /* Actually add the mux adapter */
204         ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
205         if (ret) {
206                 dev_err(dev, "Failed to add adapter\n");
207                 i2c_put_adapter(muxc->parent);
208         }
209
210         return ret;
211 }
212
213 static int i2c_arbitrator_remove(struct platform_device *pdev)
214 {
215         struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
216
217         i2c_mux_del_adapters(muxc);
218         i2c_put_adapter(muxc->parent);
219         return 0;
220 }
221
222 static const struct of_device_id i2c_arbitrator_of_match[] = {
223         { .compatible = "i2c-arb-gpio-challenge", },
224         {},
225 };
226 MODULE_DEVICE_TABLE(of, i2c_arbitrator_of_match);
227
228 static struct platform_driver i2c_arbitrator_driver = {
229         .probe  = i2c_arbitrator_probe,
230         .remove = i2c_arbitrator_remove,
231         .driver = {
232                 .name   = "i2c-arb-gpio-challenge",
233                 .of_match_table = i2c_arbitrator_of_match,
234         },
235 };
236
237 module_platform_driver(i2c_arbitrator_driver);
238
239 MODULE_DESCRIPTION("GPIO-based I2C Arbitration");
240 MODULE_AUTHOR("Doug Anderson <dianders@chromium.org>");
241 MODULE_LICENSE("GPL v2");
242 MODULE_ALIAS("platform:i2c-arb-gpio-challenge");