]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/gpio-uclass.c
karo: merge with Ka-Ro specific tree for secure boot support
[karo-tx-uboot.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_requestf() - [COMPAT] Request GPIO
135  * @gpio:       GPIO number
136  * @fmt:        Format string for the requested GPIO
137  * @...:        Arguments for the printf() format string
138  *
139  * This function implements the API that's compatible with current
140  * GPIO API used in U-Boot. The request is forwarded to particular
141  * GPIO driver. Returns 0 on success, negative value on error.
142  */
143 int gpio_requestf(unsigned gpio, const char *fmt, ...)
144 {
145         va_list args;
146         char buf[40];
147
148         va_start(args, fmt);
149         vscnprintf(buf, sizeof(buf), fmt, args);
150         va_end(args);
151         return gpio_request(gpio, buf);
152 }
153
154 int gpio_request_one(unsigned int gpio, enum gpio_flags flags,
155                 const char *label)
156 {
157         int ret;
158
159         ret = gpio_request(gpio, label);
160         if (ret)
161                 return ret;
162
163         if (flags == GPIOFLAG_INPUT)
164                 gpio_direction_input(gpio);
165         else if (flags == GPIOFLAG_OUTPUT_INIT_LOW)
166                 gpio_direction_output(gpio, 0);
167         else if (flags == GPIOFLAG_OUTPUT_INIT_HIGH)
168                 gpio_direction_output(gpio, 1);
169
170         return ret;
171 }
172
173 int gpio_request_array(const struct gpio *gpios, int count)
174 {
175         int ret;
176         int i;
177
178         for (i = 0; i < count; i++) {
179                 ret = gpio_request_one(gpios[i].gpio, gpios[i].flags,
180                                 gpios[i].label);
181                 if (ret) {
182                         printf("Failed to request GPIO%d (%u of %u): %d\n",
183                                 gpios[i].gpio, i, count, ret);
184                         goto error;
185                 }
186         }
187         return 0;
188
189 error:
190         while (--i >= 0)
191                 gpio_free(gpios[i].gpio);
192
193         return ret;
194 }
195
196 /**
197  * gpio_free() - [COMPAT] Relinquish GPIO
198  * gpio:        GPIO number
199  *
200  * This function implements the API that's compatible with current
201  * GPIO API used in U-Boot. The request is forwarded to particular
202  * GPIO driver. Returns 0 on success, negative value on error.
203  */
204 int gpio_free(unsigned gpio)
205 {
206         struct gpio_dev_priv *uc_priv;
207         unsigned int offset;
208         struct udevice *dev;
209         int ret;
210
211         ret = gpio_to_device(gpio, &dev, &offset);
212         if (ret)
213                 return ret;
214
215         uc_priv = dev->uclass_priv;
216         if (!uc_priv->name[offset])
217                 return -ENXIO;
218         if (gpio_get_ops(dev)->free) {
219                 ret = gpio_get_ops(dev)->free(dev, offset);
220                 if (ret)
221                         return ret;
222         }
223
224         free(uc_priv->name[offset]);
225         uc_priv->name[offset] = NULL;
226
227         return 0;
228 }
229
230 int gpio_free_array(const struct gpio *gpios, int count)
231 {
232         int ret = 0;
233         int i;
234
235         for (i = 0; i < count; i++)
236                 ret |= gpio_free(gpios[i].gpio);
237
238         return ret;
239 }
240
241 static int check_reserved(struct udevice *dev, unsigned offset,
242                           const char *func)
243 {
244         struct gpio_dev_priv *uc_priv = dev->uclass_priv;
245
246         if (!uc_priv->name[offset]) {
247                 printf("%s: %s: error: gpio %s%d not reserved\n",
248                        dev->name, func,
249                        uc_priv->bank_name ? uc_priv->bank_name : "", offset);
250                 return -EBUSY;
251         }
252
253         return 0;
254 }
255
256 /**
257  * gpio_direction_input() - [COMPAT] Set GPIO direction to input
258  * gpio:        GPIO number
259  *
260  * This function implements the API that's compatible with current
261  * GPIO API used in U-Boot. The request is forwarded to particular
262  * GPIO driver. Returns 0 on success, negative value on error.
263  */
264 int gpio_direction_input(unsigned gpio)
265 {
266         unsigned int offset;
267         struct udevice *dev;
268         int ret;
269
270         ret = gpio_to_device(gpio, &dev, &offset);
271         if (ret)
272                 return ret;
273         ret = check_reserved(dev, offset, "dir_input");
274
275         return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
276 }
277
278 /**
279  * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
280  * gpio:        GPIO number
281  * value:       Logical value to be set on the GPIO pin
282  *
283  * This function implements the API that's compatible with current
284  * GPIO API used in U-Boot. The request is forwarded to particular
285  * GPIO driver. Returns 0 on success, negative value on error.
286  */
287 int gpio_direction_output(unsigned gpio, int value)
288 {
289         unsigned int offset;
290         struct udevice *dev;
291         int ret;
292
293         ret = gpio_to_device(gpio, &dev, &offset);
294         if (ret)
295                 return ret;
296         ret = check_reserved(dev, offset, "dir_output");
297
298         return ret ? ret :
299                 gpio_get_ops(dev)->direction_output(dev, offset, value);
300 }
301
302 /**
303  * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
304  * gpio:        GPIO number
305  *
306  * This function implements the API that's compatible with current
307  * GPIO API used in U-Boot. The request is forwarded to particular
308  * GPIO driver. Returns the value of the GPIO pin, or negative value
309  * on error.
310  */
311 int gpio_get_value(unsigned gpio)
312 {
313         unsigned int offset;
314         struct udevice *dev;
315         int ret;
316
317         ret = gpio_to_device(gpio, &dev, &offset);
318         if (ret)
319                 return ret;
320         ret = check_reserved(dev, offset, "get_value");
321
322         return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
323 }
324
325 /**
326  * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
327  * gpio:        GPIO number
328  * value:       Logical value to be set on the GPIO pin.
329  *
330  * This function implements the API that's compatible with current
331  * GPIO API used in U-Boot. The request is forwarded to particular
332  * GPIO driver. Returns 0 on success, negative value on error.
333  */
334 int gpio_set_value(unsigned gpio, int value)
335 {
336         unsigned int offset;
337         struct udevice *dev;
338         int ret;
339
340         ret = gpio_to_device(gpio, &dev, &offset);
341         if (ret)
342                 return ret;
343         ret = check_reserved(dev, offset, "set_value");
344
345         return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
346 }
347
348 const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
349 {
350         struct gpio_dev_priv *priv;
351
352         /* Must be called on an active device */
353         priv = dev->uclass_priv;
354         assert(priv);
355
356         *bit_count = priv->gpio_count;
357         return priv->bank_name;
358 }
359
360 static const char * const gpio_function[GPIOF_COUNT] = {
361         "input",
362         "output",
363         "unused",
364         "unknown",
365         "func",
366 };
367
368 int get_function(struct udevice *dev, int offset, bool skip_unused,
369                  const char **namep)
370 {
371         struct gpio_dev_priv *uc_priv = dev->uclass_priv;
372         struct dm_gpio_ops *ops = gpio_get_ops(dev);
373
374         BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
375         if (!device_active(dev))
376                 return -ENODEV;
377         if (offset < 0 || offset >= uc_priv->gpio_count)
378                 return -EINVAL;
379         if (namep)
380                 *namep = uc_priv->name[offset];
381         if (skip_unused && !uc_priv->name[offset])
382                 return GPIOF_UNUSED;
383         if (ops->get_function) {
384                 int ret;
385
386                 ret = ops->get_function(dev, offset);
387                 if (ret < 0)
388                         return ret;
389                 if (ret >= ARRAY_SIZE(gpio_function))
390                         return -ENODATA;
391                 return ret;
392         }
393
394         return GPIOF_UNKNOWN;
395 }
396
397 int gpio_get_function(struct udevice *dev, int offset, const char **namep)
398 {
399         return get_function(dev, offset, true, namep);
400 }
401
402 int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
403 {
404         return get_function(dev, offset, false, namep);
405 }
406
407 int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
408 {
409         struct dm_gpio_ops *ops = gpio_get_ops(dev);
410         struct gpio_dev_priv *priv;
411         char *str = buf;
412         int func;
413         int ret;
414         int len;
415
416         BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
417
418         *buf = 0;
419         priv = dev->uclass_priv;
420         ret = gpio_get_raw_function(dev, offset, NULL);
421         if (ret < 0)
422                 return ret;
423         func = ret;
424         len = snprintf(str, buffsize, "%s%d: %s",
425                        priv->bank_name ? priv->bank_name : "",
426                        offset, gpio_function[func]);
427         if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
428             func == GPIOF_UNUSED) {
429                 const char *label;
430                 bool used;
431
432                 ret = ops->get_value(dev, offset);
433                 if (ret < 0)
434                         return ret;
435                 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
436                 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
437                          ret,
438                          used ? 'x' : ' ',
439                          used ? " " : "",
440                          label ? label : "");
441         }
442
443         return 0;
444 }
445
446 /*
447  * get a number comprised of multiple GPIO values. gpio_num_array points to
448  * the array of gpio pin numbers to scan, terminated by -1.
449  */
450 unsigned gpio_get_values_as_int(const int *gpio_num_array)
451 {
452         int gpio;
453         unsigned bitmask = 1;
454         unsigned vector = 0;
455
456         while (bitmask &&
457                ((gpio = *gpio_num_array++) != -1)) {
458                 if (gpio_get_value(gpio))
459                         vector |= bitmask;
460                 bitmask <<= 1;
461         }
462         return vector;
463 }
464
465 /* We need to renumber the GPIOs when any driver is probed/removed */
466 static int gpio_renumber(struct udevice *removed_dev)
467 {
468         struct gpio_dev_priv *uc_priv;
469         struct udevice *dev;
470         struct uclass *uc;
471         unsigned base;
472         int ret;
473
474         ret = uclass_get(UCLASS_GPIO, &uc);
475         if (ret)
476                 return ret;
477
478         /* Ensure that we have a base for each bank */
479         base = 0;
480         uclass_foreach_dev(dev, uc) {
481                 if (device_active(dev) && dev != removed_dev) {
482                         uc_priv = dev->uclass_priv;
483                         uc_priv->gpio_base = base;
484                         base += uc_priv->gpio_count;
485                 }
486         }
487
488         return 0;
489 }
490
491 static int gpio_post_probe(struct udevice *dev)
492 {
493         struct gpio_dev_priv *uc_priv = dev->uclass_priv;
494
495         uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
496         if (!uc_priv->name)
497                 return -ENOMEM;
498
499         return gpio_renumber(NULL);
500 }
501
502 static int gpio_pre_remove(struct udevice *dev)
503 {
504         struct gpio_dev_priv *uc_priv = dev->uclass_priv;
505         int i;
506
507         for (i = 0; i < uc_priv->gpio_count; i++) {
508                 if (uc_priv->name[i])
509                         free(uc_priv->name[i]);
510         }
511         free(uc_priv->name);
512
513         return gpio_renumber(dev);
514 }
515
516 UCLASS_DRIVER(gpio) = {
517         .id             = UCLASS_GPIO,
518         .name           = "gpio",
519         .post_probe     = gpio_post_probe,
520         .pre_remove     = gpio_pre_remove,
521         .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
522 };