Merge branch 'i2c/for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
[linux-2.6-microblaze.git] / drivers / i2c / muxes / i2c-mux-gpio.c
1 /*
2  * I2C multiplexer using GPIO API
3  *
4  * Peter Korsgaard <peter.korsgaard@barco.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/i2c.h>
12 #include <linux/i2c-mux.h>
13 #include <linux/platform_data/i2c-mux-gpio.h>
14 #include <linux/platform_device.h>
15 #include <linux/module.h>
16 #include <linux/slab.h>
17 #include <linux/gpio.h>
18 #include "../../gpio/gpiolib.h"
19 #include <linux/of_gpio.h>
20
21 struct gpiomux {
22         struct i2c_mux_gpio_platform_data data;
23         unsigned gpio_base;
24         struct gpio_desc **gpios;
25         int *values;
26 };
27
28 static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
29 {
30         int i;
31
32         for (i = 0; i < mux->data.n_gpios; i++)
33                 mux->values[i] = (val >> i) & 1;
34
35         gpiod_set_array_value_cansleep(mux->data.n_gpios,
36                                        mux->gpios, mux->values);
37 }
38
39 static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
40 {
41         struct gpiomux *mux = i2c_mux_priv(muxc);
42
43         i2c_mux_gpio_set(mux, chan);
44
45         return 0;
46 }
47
48 static int i2c_mux_gpio_deselect(struct i2c_mux_core *muxc, u32 chan)
49 {
50         struct gpiomux *mux = i2c_mux_priv(muxc);
51
52         i2c_mux_gpio_set(mux, mux->data.idle);
53
54         return 0;
55 }
56
57 static int match_gpio_chip_by_label(struct gpio_chip *chip,
58                                               void *data)
59 {
60         return !strcmp(chip->label, data);
61 }
62
63 #ifdef CONFIG_OF
64 static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
65                                         struct platform_device *pdev)
66 {
67         struct device_node *np = pdev->dev.of_node;
68         struct device_node *adapter_np, *child;
69         struct i2c_adapter *adapter;
70         unsigned *values, *gpios;
71         int i = 0, ret;
72
73         if (!np)
74                 return -ENODEV;
75
76         adapter_np = of_parse_phandle(np, "i2c-parent", 0);
77         if (!adapter_np) {
78                 dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
79                 return -ENODEV;
80         }
81         adapter = of_find_i2c_adapter_by_node(adapter_np);
82         of_node_put(adapter_np);
83         if (!adapter)
84                 return -EPROBE_DEFER;
85
86         mux->data.parent = i2c_adapter_id(adapter);
87         put_device(&adapter->dev);
88
89         mux->data.n_values = of_get_child_count(np);
90
91         values = devm_kcalloc(&pdev->dev,
92                               mux->data.n_values, sizeof(*mux->data.values),
93                               GFP_KERNEL);
94         if (!values) {
95                 dev_err(&pdev->dev, "Cannot allocate values array");
96                 return -ENOMEM;
97         }
98
99         for_each_child_of_node(np, child) {
100                 of_property_read_u32(child, "reg", values + i);
101                 i++;
102         }
103         mux->data.values = values;
104
105         if (of_property_read_u32(np, "idle-state", &mux->data.idle))
106                 mux->data.idle = I2C_MUX_GPIO_NO_IDLE;
107
108         mux->data.n_gpios = of_gpio_named_count(np, "mux-gpios");
109         if (mux->data.n_gpios < 0) {
110                 dev_err(&pdev->dev, "Missing mux-gpios property in the DT.\n");
111                 return -EINVAL;
112         }
113
114         gpios = devm_kcalloc(&pdev->dev,
115                              mux->data.n_gpios, sizeof(*mux->data.gpios),
116                              GFP_KERNEL);
117         if (!gpios) {
118                 dev_err(&pdev->dev, "Cannot allocate gpios array");
119                 return -ENOMEM;
120         }
121
122         for (i = 0; i < mux->data.n_gpios; i++) {
123                 ret = of_get_named_gpio(np, "mux-gpios", i);
124                 if (ret < 0)
125                         return ret;
126                 gpios[i] = ret;
127         }
128
129         mux->data.gpios = gpios;
130
131         return 0;
132 }
133 #else
134 static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
135                                         struct platform_device *pdev)
136 {
137         return 0;
138 }
139 #endif
140
141 static int i2c_mux_gpio_probe(struct platform_device *pdev)
142 {
143         struct i2c_mux_core *muxc;
144         struct gpiomux *mux;
145         struct i2c_adapter *parent;
146         struct i2c_adapter *root;
147         unsigned initial_state, gpio_base;
148         int i, ret;
149
150         mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
151         if (!mux)
152                 return -ENOMEM;
153
154         if (!dev_get_platdata(&pdev->dev)) {
155                 ret = i2c_mux_gpio_probe_dt(mux, pdev);
156                 if (ret < 0)
157                         return ret;
158         } else {
159                 memcpy(&mux->data, dev_get_platdata(&pdev->dev),
160                         sizeof(mux->data));
161         }
162
163         /*
164          * If a GPIO chip name is provided, the GPIO pin numbers provided are
165          * relative to its base GPIO number. Otherwise they are absolute.
166          */
167         if (mux->data.gpio_chip) {
168                 struct gpio_chip *gpio;
169
170                 gpio = gpiochip_find(mux->data.gpio_chip,
171                                      match_gpio_chip_by_label);
172                 if (!gpio)
173                         return -EPROBE_DEFER;
174
175                 gpio_base = gpio->base;
176         } else {
177                 gpio_base = 0;
178         }
179
180         parent = i2c_get_adapter(mux->data.parent);
181         if (!parent)
182                 return -EPROBE_DEFER;
183
184         muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values,
185                              mux->data.n_gpios * sizeof(*mux->gpios) +
186                              mux->data.n_gpios * sizeof(*mux->values), 0,
187                              i2c_mux_gpio_select, NULL);
188         if (!muxc) {
189                 ret = -ENOMEM;
190                 goto alloc_failed;
191         }
192         mux->gpios = muxc->priv;
193         mux->values = (int *)(mux->gpios + mux->data.n_gpios);
194         muxc->priv = mux;
195
196         platform_set_drvdata(pdev, muxc);
197
198         root = i2c_root_adapter(&parent->dev);
199
200         muxc->mux_locked = true;
201         mux->gpio_base = gpio_base;
202
203         if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) {
204                 initial_state = mux->data.idle;
205                 muxc->deselect = i2c_mux_gpio_deselect;
206         } else {
207                 initial_state = mux->data.values[0];
208         }
209
210         for (i = 0; i < mux->data.n_gpios; i++) {
211                 struct device *gpio_dev;
212                 struct gpio_desc *gpio_desc;
213
214                 ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio");
215                 if (ret) {
216                         dev_err(&pdev->dev, "Failed to request GPIO %d\n",
217                                 mux->data.gpios[i]);
218                         goto err_request_gpio;
219                 }
220
221                 ret = gpio_direction_output(gpio_base + mux->data.gpios[i],
222                                             initial_state & (1 << i));
223                 if (ret) {
224                         dev_err(&pdev->dev,
225                                 "Failed to set direction of GPIO %d to output\n",
226                                 mux->data.gpios[i]);
227                         i++;    /* gpio_request above succeeded, so must free */
228                         goto err_request_gpio;
229                 }
230
231                 gpio_desc = gpio_to_desc(gpio_base + mux->data.gpios[i]);
232                 mux->gpios[i] = gpio_desc;
233
234                 if (!muxc->mux_locked)
235                         continue;
236
237                 gpio_dev = &gpio_desc->gdev->dev;
238                 muxc->mux_locked = i2c_root_adapter(gpio_dev) == root;
239         }
240
241         if (muxc->mux_locked)
242                 dev_info(&pdev->dev, "mux-locked i2c mux\n");
243
244         for (i = 0; i < mux->data.n_values; i++) {
245                 u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
246                 unsigned int class = mux->data.classes ? mux->data.classes[i] : 0;
247
248                 ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class);
249                 if (ret)
250                         goto add_adapter_failed;
251         }
252
253         dev_info(&pdev->dev, "%d port mux on %s adapter\n",
254                  mux->data.n_values, parent->name);
255
256         return 0;
257
258 add_adapter_failed:
259         i2c_mux_del_adapters(muxc);
260         i = mux->data.n_gpios;
261 err_request_gpio:
262         for (; i > 0; i--)
263                 gpio_free(gpio_base + mux->data.gpios[i - 1]);
264 alloc_failed:
265         i2c_put_adapter(parent);
266
267         return ret;
268 }
269
270 static int i2c_mux_gpio_remove(struct platform_device *pdev)
271 {
272         struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
273         struct gpiomux *mux = i2c_mux_priv(muxc);
274         int i;
275
276         i2c_mux_del_adapters(muxc);
277
278         for (i = 0; i < mux->data.n_gpios; i++)
279                 gpio_free(mux->gpio_base + mux->data.gpios[i]);
280
281         i2c_put_adapter(muxc->parent);
282
283         return 0;
284 }
285
286 static const struct of_device_id i2c_mux_gpio_of_match[] = {
287         { .compatible = "i2c-mux-gpio", },
288         {},
289 };
290 MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match);
291
292 static struct platform_driver i2c_mux_gpio_driver = {
293         .probe  = i2c_mux_gpio_probe,
294         .remove = i2c_mux_gpio_remove,
295         .driver = {
296                 .name   = "i2c-mux-gpio",
297                 .of_match_table = i2c_mux_gpio_of_match,
298         },
299 };
300
301 module_platform_driver(i2c_mux_gpio_driver);
302
303 MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver");
304 MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>");
305 MODULE_LICENSE("GPL");
306 MODULE_ALIAS("platform:i2c-mux-gpio");