dm: Move the function for getting GPIO status into the uclass
[platform/kernel/u-boot.git] / drivers / gpio / gpio-uclass.c
1 /*
2  * Copyright (c) 2013 Google, Inc
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <malloc.h>
11 #include <asm/gpio.h>
12 #include <linux/ctype.h>
13
14 /**
15  * gpio_to_device() - Convert global GPIO number to device, number
16  * gpio:        The numeric representation of the GPIO
17  *
18  * Convert the GPIO number to an entry in the list of GPIOs
19  * or GPIO blocks registered with the GPIO controller. Returns
20  * entry on success, NULL on error.
21  */
22 static int gpio_to_device(unsigned int gpio, struct udevice **devp,
23                           unsigned int *offset)
24 {
25         struct gpio_dev_priv *uc_priv;
26         struct udevice *dev;
27         int ret;
28
29         for (ret = uclass_first_device(UCLASS_GPIO, &dev);
30              dev;
31              ret = uclass_next_device(&dev)) {
32                 uc_priv = dev->uclass_priv;
33                 if (gpio >= uc_priv->gpio_base &&
34                     gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
35                         *devp = dev;
36                         *offset = gpio - uc_priv->gpio_base;
37                         return 0;
38                 }
39         }
40
41         /* No such GPIO */
42         return ret ? ret : -EINVAL;
43 }
44
45 int gpio_lookup_name(const char *name, struct udevice **devp,
46                      unsigned int *offsetp, unsigned int *gpiop)
47 {
48         struct gpio_dev_priv *uc_priv = NULL;
49         struct udevice *dev;
50         ulong offset;
51         int numeric;
52         int ret;
53
54         if (devp)
55                 *devp = NULL;
56         numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
57         for (ret = uclass_first_device(UCLASS_GPIO, &dev);
58              dev;
59              ret = uclass_next_device(&dev)) {
60                 int len;
61
62                 uc_priv = dev->uclass_priv;
63                 if (numeric != -1) {
64                         offset = numeric - uc_priv->gpio_base;
65                         /* Allow GPIOs to be numbered from 0 */
66                         if (offset >= 0 && offset < uc_priv->gpio_count)
67                                 break;
68                 }
69
70                 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
71
72                 if (!strncasecmp(name, uc_priv->bank_name, len)) {
73                         if (!strict_strtoul(name + len, 10, &offset))
74                                 break;
75                 }
76         }
77
78         if (!dev)
79                 return ret ? ret : -EINVAL;
80
81         if (devp)
82                 *devp = dev;
83         if (offsetp)
84                 *offsetp = offset;
85         if (gpiop)
86                 *gpiop = uc_priv->gpio_base + offset;
87
88         return 0;
89 }
90
91 /**
92  * gpio_request() - [COMPAT] Request GPIO
93  * gpio:        GPIO number
94  * label:       Name for the requested GPIO
95  *
96  * The label is copied and allocated so the caller does not need to keep
97  * the pointer around.
98  *
99  * This function implements the API that's compatible with current
100  * GPIO API used in U-Boot. The request is forwarded to particular
101  * GPIO driver. Returns 0 on success, negative value on error.
102  */
103 int gpio_request(unsigned gpio, const char *label)
104 {
105         struct gpio_dev_priv *uc_priv;
106         unsigned int offset;
107         struct udevice *dev;
108         char *str;
109         int ret;
110
111         ret = gpio_to_device(gpio, &dev, &offset);
112         if (ret)
113                 return ret;
114
115         uc_priv = dev->uclass_priv;
116         if (uc_priv->name[offset])
117                 return -EBUSY;
118         str = strdup(label);
119         if (!str)
120                 return -ENOMEM;
121         if (gpio_get_ops(dev)->request) {
122                 ret = gpio_get_ops(dev)->request(dev, offset, label);
123                 if (ret) {
124                         free(str);
125                         return ret;
126                 }
127         }
128         uc_priv->name[offset] = str;
129
130         return 0;
131 }
132
133 /**
134  * gpio_free() - [COMPAT] Relinquish GPIO
135  * gpio:        GPIO number
136  *
137  * This function implements the API that's compatible with current
138  * GPIO API used in U-Boot. The request is forwarded to particular
139  * GPIO driver. Returns 0 on success, negative value on error.
140  */
141 int gpio_free(unsigned gpio)
142 {
143         struct gpio_dev_priv *uc_priv;
144         unsigned int offset;
145         struct udevice *dev;
146         int ret;
147
148         ret = gpio_to_device(gpio, &dev, &offset);
149         if (ret)
150                 return ret;
151
152         uc_priv = dev->uclass_priv;
153         if (!uc_priv->name[offset])
154                 return -ENXIO;
155         if (gpio_get_ops(dev)->free) {
156                 ret = gpio_get_ops(dev)->free(dev, offset);
157                 if (ret)
158                         return ret;
159         }
160
161         free(uc_priv->name[offset]);
162         uc_priv->name[offset] = NULL;
163
164         return 0;
165 }
166
167 static int check_reserved(struct udevice *dev, unsigned offset,
168                           const char *func)
169 {
170         struct gpio_dev_priv *uc_priv = dev->uclass_priv;
171
172         if (!uc_priv->name[offset]) {
173                 printf("%s: %s: error: gpio %s%d not reserved\n",
174                        dev->name, func,
175                        uc_priv->bank_name ? uc_priv->bank_name : "", offset);
176                 return -EBUSY;
177         }
178
179         return 0;
180 }
181
182 /**
183  * gpio_direction_input() - [COMPAT] Set GPIO direction to input
184  * gpio:        GPIO number
185  *
186  * This function implements the API that's compatible with current
187  * GPIO API used in U-Boot. The request is forwarded to particular
188  * GPIO driver. Returns 0 on success, negative value on error.
189  */
190 int gpio_direction_input(unsigned gpio)
191 {
192         unsigned int offset;
193         struct udevice *dev;
194         int ret;
195
196         ret = gpio_to_device(gpio, &dev, &offset);
197         if (ret)
198                 return ret;
199         ret = check_reserved(dev, offset, "dir_input");
200
201         return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
202 }
203
204 /**
205  * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
206  * gpio:        GPIO number
207  * value:       Logical value to be set on the GPIO pin
208  *
209  * This function implements the API that's compatible with current
210  * GPIO API used in U-Boot. The request is forwarded to particular
211  * GPIO driver. Returns 0 on success, negative value on error.
212  */
213 int gpio_direction_output(unsigned gpio, int value)
214 {
215         unsigned int offset;
216         struct udevice *dev;
217         int ret;
218
219         ret = gpio_to_device(gpio, &dev, &offset);
220         if (ret)
221                 return ret;
222         ret = check_reserved(dev, offset, "dir_output");
223
224         return ret ? ret :
225                 gpio_get_ops(dev)->direction_output(dev, offset, value);
226 }
227
228 /**
229  * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
230  * gpio:        GPIO number
231  *
232  * This function implements the API that's compatible with current
233  * GPIO API used in U-Boot. The request is forwarded to particular
234  * GPIO driver. Returns the value of the GPIO pin, or negative value
235  * on error.
236  */
237 int gpio_get_value(unsigned gpio)
238 {
239         unsigned int offset;
240         struct udevice *dev;
241         int ret;
242
243         ret = gpio_to_device(gpio, &dev, &offset);
244         if (ret)
245                 return ret;
246         ret = check_reserved(dev, offset, "get_value");
247
248         return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
249 }
250
251 /**
252  * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
253  * gpio:        GPIO number
254  * value:       Logical value to be set on the GPIO pin.
255  *
256  * This function implements the API that's compatible with current
257  * GPIO API used in U-Boot. The request is forwarded to particular
258  * GPIO driver. Returns 0 on success, negative value on error.
259  */
260 int gpio_set_value(unsigned gpio, int value)
261 {
262         unsigned int offset;
263         struct udevice *dev;
264         int ret;
265
266         ret = gpio_to_device(gpio, &dev, &offset);
267         if (ret)
268                 return ret;
269         ret = check_reserved(dev, offset, "set_value");
270
271         return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
272 }
273
274 const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
275 {
276         struct gpio_dev_priv *priv;
277
278         /* Must be called on an active device */
279         priv = dev->uclass_priv;
280         assert(priv);
281
282         *bit_count = priv->gpio_count;
283         return priv->bank_name;
284 }
285
286 static const char * const gpio_function[GPIOF_COUNT] = {
287         "input",
288         "output",
289         "unused",
290         "unknown",
291         "func",
292 };
293
294 int get_function(struct udevice *dev, int offset, bool skip_unused,
295                  const char **namep)
296 {
297         struct gpio_dev_priv *uc_priv = dev->uclass_priv;
298         struct dm_gpio_ops *ops = gpio_get_ops(dev);
299
300         BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
301         if (!device_active(dev))
302                 return -ENODEV;
303         if (offset < 0 || offset >= uc_priv->gpio_count)
304                 return -EINVAL;
305         if (namep)
306                 *namep = uc_priv->name[offset];
307         if (skip_unused && !uc_priv->name[offset])
308                 return GPIOF_UNUSED;
309         if (ops->get_function) {
310                 int ret;
311
312                 ret = ops->get_function(dev, offset);
313                 if (ret < 0)
314                         return ret;
315                 if (ret >= ARRAY_SIZE(gpio_function))
316                         return -ENODATA;
317                 return ret;
318         }
319
320         return GPIOF_UNKNOWN;
321 }
322
323 int gpio_get_function(struct udevice *dev, int offset, const char **namep)
324 {
325         return get_function(dev, offset, true, namep);
326 }
327
328 int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
329 {
330         return get_function(dev, offset, false, namep);
331 }
332
333 int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
334 {
335         struct dm_gpio_ops *ops = gpio_get_ops(dev);
336         struct gpio_dev_priv *priv;
337         char *str = buf;
338         int func;
339         int ret;
340         int len;
341
342         BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
343
344         *buf = 0;
345         priv = dev->uclass_priv;
346         ret = gpio_get_raw_function(dev, offset, NULL);
347         if (ret < 0)
348                 return ret;
349         func = ret;
350         len = snprintf(str, buffsize, "%s%d: %s",
351                        priv->bank_name ? priv->bank_name : "",
352                        offset, gpio_function[func]);
353         if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
354             func == GPIOF_UNUSED) {
355                 const char *label;
356                 bool used;
357
358                 ret = ops->get_value(dev, offset);
359                 if (ret < 0)
360                         return ret;
361                 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
362                 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
363                          ret,
364                          used ? 'x' : ' ',
365                          used ? " " : "",
366                          label ? label : "");
367         }
368
369         return 0;
370 }
371
372 /* We need to renumber the GPIOs when any driver is probed/removed */
373 static int gpio_renumber(struct udevice *removed_dev)
374 {
375         struct gpio_dev_priv *uc_priv;
376         struct udevice *dev;
377         struct uclass *uc;
378         unsigned base;
379         int ret;
380
381         ret = uclass_get(UCLASS_GPIO, &uc);
382         if (ret)
383                 return ret;
384
385         /* Ensure that we have a base for each bank */
386         base = 0;
387         uclass_foreach_dev(dev, uc) {
388                 if (device_active(dev) && dev != removed_dev) {
389                         uc_priv = dev->uclass_priv;
390                         uc_priv->gpio_base = base;
391                         base += uc_priv->gpio_count;
392                 }
393         }
394
395         return 0;
396 }
397
398 static int gpio_post_probe(struct udevice *dev)
399 {
400         struct gpio_dev_priv *uc_priv = dev->uclass_priv;
401
402         uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
403         if (!uc_priv->name)
404                 return -ENOMEM;
405
406         return gpio_renumber(NULL);
407 }
408
409 static int gpio_pre_remove(struct udevice *dev)
410 {
411         struct gpio_dev_priv *uc_priv = dev->uclass_priv;
412         int i;
413
414         for (i = 0; i < uc_priv->gpio_count; i++) {
415                 if (uc_priv->name[i])
416                         free(uc_priv->name[i]);
417         }
418         free(uc_priv->name);
419
420         return gpio_renumber(dev);
421 }
422
423 UCLASS_DRIVER(gpio) = {
424         .id             = UCLASS_GPIO,
425         .name           = "gpio",
426         .post_probe     = gpio_post_probe,
427         .pre_remove     = gpio_pre_remove,
428         .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
429 };