blob: d603b55902790abe87a6aef154bec77747de6c45 [file] [log] [blame]
Simon Glasse821d182014-02-26 15:59:24 -07001/*
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>
Simon Glassd3322bb2015-01-05 20:05:28 -070010#include <fdtdec.h>
Simon Glass0f4517d2014-10-04 11:29:42 -060011#include <malloc.h>
Simon Glasse821d182014-02-26 15:59:24 -070012#include <asm/gpio.h>
Masahiro Yamada78eeb912016-01-24 23:27:48 +090013#include <linux/bug.h>
Simon Glass43b2e1a2014-10-22 21:37:01 -060014#include <linux/ctype.h>
Simon Glasse821d182014-02-26 15:59:24 -070015
Simon Glass16e10402015-01-05 20:05:29 -070016DECLARE_GLOBAL_DATA_PTR;
17
Simon Glasse821d182014-02-26 15:59:24 -070018/**
19 * gpio_to_device() - Convert global GPIO number to device, number
Simon Glasse821d182014-02-26 15:59:24 -070020 *
21 * Convert the GPIO number to an entry in the list of GPIOs
22 * or GPIO blocks registered with the GPIO controller. Returns
23 * entry on success, NULL on error.
Simon Glassce555292015-01-05 20:05:27 -070024 *
25 * @gpio: The numeric representation of the GPIO
26 * @desc: Returns description (desc->flags will always be 0)
27 * @return 0 if found, -ENOENT if not found
Simon Glasse821d182014-02-26 15:59:24 -070028 */
Simon Glassce555292015-01-05 20:05:27 -070029static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
Simon Glasse821d182014-02-26 15:59:24 -070030{
31 struct gpio_dev_priv *uc_priv;
Heiko Schocherb74fcb42014-05-22 12:43:05 +020032 struct udevice *dev;
Simon Glasse821d182014-02-26 15:59:24 -070033 int ret;
34
35 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
36 dev;
37 ret = uclass_next_device(&dev)) {
Simon Glassde0977b2015-03-05 12:25:20 -070038 uc_priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -070039 if (gpio >= uc_priv->gpio_base &&
40 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
Simon Glassce555292015-01-05 20:05:27 -070041 desc->dev = dev;
42 desc->offset = gpio - uc_priv->gpio_base;
43 desc->flags = 0;
Simon Glasse821d182014-02-26 15:59:24 -070044 return 0;
45 }
46 }
47
48 /* No such GPIO */
Simon Glassce555292015-01-05 20:05:27 -070049 return ret ? ret : -ENOENT;
Simon Glasse821d182014-02-26 15:59:24 -070050}
51
Simon Glass215bcc72015-06-23 15:38:40 -060052int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
Simon Glasse821d182014-02-26 15:59:24 -070053{
Simon Glass43b2e1a2014-10-22 21:37:01 -060054 struct gpio_dev_priv *uc_priv = NULL;
Heiko Schocherb74fcb42014-05-22 12:43:05 +020055 struct udevice *dev;
Simon Glass43b2e1a2014-10-22 21:37:01 -060056 ulong offset;
57 int numeric;
Simon Glasse821d182014-02-26 15:59:24 -070058 int ret;
59
Simon Glass43b2e1a2014-10-22 21:37:01 -060060 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
Simon Glasse821d182014-02-26 15:59:24 -070061 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
62 dev;
63 ret = uclass_next_device(&dev)) {
Simon Glasse821d182014-02-26 15:59:24 -070064 int len;
65
Simon Glassde0977b2015-03-05 12:25:20 -070066 uc_priv = dev_get_uclass_priv(dev);
Simon Glass43b2e1a2014-10-22 21:37:01 -060067 if (numeric != -1) {
68 offset = numeric - uc_priv->gpio_base;
69 /* Allow GPIOs to be numbered from 0 */
70 if (offset >= 0 && offset < uc_priv->gpio_count)
71 break;
72 }
73
Simon Glasse821d182014-02-26 15:59:24 -070074 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
75
Simon Glassd4acf632014-06-11 23:29:47 -060076 if (!strncasecmp(name, uc_priv->bank_name, len)) {
Simon Glass43b2e1a2014-10-22 21:37:01 -060077 if (!strict_strtoul(name + len, 10, &offset))
78 break;
Simon Glasse821d182014-02-26 15:59:24 -070079 }
80 }
81
Simon Glass43b2e1a2014-10-22 21:37:01 -060082 if (!dev)
83 return ret ? ret : -EINVAL;
84
Simon Glass215bcc72015-06-23 15:38:40 -060085 desc->dev = dev;
86 desc->offset = offset;
87
88 return 0;
89}
90
91int gpio_lookup_name(const char *name, struct udevice **devp,
92 unsigned int *offsetp, unsigned int *gpiop)
93{
94 struct gpio_desc desc;
95 int ret;
96
97 if (devp)
98 *devp = NULL;
99 ret = dm_gpio_lookup_name(name, &desc);
100 if (ret)
101 return ret;
102
Simon Glass43b2e1a2014-10-22 21:37:01 -0600103 if (devp)
Simon Glass215bcc72015-06-23 15:38:40 -0600104 *devp = desc.dev;
Simon Glass43b2e1a2014-10-22 21:37:01 -0600105 if (offsetp)
Simon Glass215bcc72015-06-23 15:38:40 -0600106 *offsetp = desc.offset;
107 if (gpiop) {
108 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
109
110 *gpiop = uc_priv->gpio_base + desc.offset;
111 }
Simon Glass43b2e1a2014-10-22 21:37:01 -0600112
113 return 0;
Simon Glasse821d182014-02-26 15:59:24 -0700114}
115
Simon Glass16e10402015-01-05 20:05:29 -0700116static int gpio_find_and_xlate(struct gpio_desc *desc,
117 struct fdtdec_phandle_args *args)
Simon Glassd3322bb2015-01-05 20:05:28 -0700118{
119 struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
120
121 /* Use the first argument as the offset by default */
122 if (args->args_count > 0)
123 desc->offset = args->args[0];
124 else
125 desc->offset = -1;
126 desc->flags = 0;
127
128 return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
129}
130
Simon Glass047cdb32015-06-23 15:38:41 -0600131int dm_gpio_request(struct gpio_desc *desc, const char *label)
Simon Glassce555292015-01-05 20:05:27 -0700132{
133 struct udevice *dev = desc->dev;
134 struct gpio_dev_priv *uc_priv;
135 char *str;
136 int ret;
137
Simon Glassde0977b2015-03-05 12:25:20 -0700138 uc_priv = dev_get_uclass_priv(dev);
Simon Glassce555292015-01-05 20:05:27 -0700139 if (uc_priv->name[desc->offset])
140 return -EBUSY;
141 str = strdup(label);
142 if (!str)
143 return -ENOMEM;
144 if (gpio_get_ops(dev)->request) {
145 ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
146 if (ret) {
147 free(str);
148 return ret;
149 }
150 }
151 uc_priv->name[desc->offset] = str;
152
153 return 0;
154}
155
Simon Glass16e10402015-01-05 20:05:29 -0700156static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
157{
Simon Glassee8a3d92015-12-29 05:22:48 -0700158#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_USE_TINY_PRINTF)
Simon Glass16e10402015-01-05 20:05:29 -0700159 va_list args;
160 char buf[40];
161
162 va_start(args, fmt);
163 vscnprintf(buf, sizeof(buf), fmt, args);
164 va_end(args);
165 return dm_gpio_request(desc, buf);
Simon Glassee8a3d92015-12-29 05:22:48 -0700166#else
167 return dm_gpio_request(desc, fmt);
168#endif
Simon Glass16e10402015-01-05 20:05:29 -0700169}
170
Simon Glasse821d182014-02-26 15:59:24 -0700171/**
172 * gpio_request() - [COMPAT] Request GPIO
173 * gpio: GPIO number
174 * label: Name for the requested GPIO
175 *
Simon Glass0f4517d2014-10-04 11:29:42 -0600176 * The label is copied and allocated so the caller does not need to keep
177 * the pointer around.
178 *
Simon Glasse821d182014-02-26 15:59:24 -0700179 * This function implements the API that's compatible with current
180 * GPIO API used in U-Boot. The request is forwarded to particular
181 * GPIO driver. Returns 0 on success, negative value on error.
182 */
183int gpio_request(unsigned gpio, const char *label)
184{
Simon Glassce555292015-01-05 20:05:27 -0700185 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700186 int ret;
187
Simon Glassce555292015-01-05 20:05:27 -0700188 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700189 if (ret)
190 return ret;
191
Simon Glassce555292015-01-05 20:05:27 -0700192 return dm_gpio_request(&desc, label);
Simon Glasse821d182014-02-26 15:59:24 -0700193}
194
195/**
Simon Glass1b27d602014-10-04 11:29:49 -0600196 * gpio_requestf() - [COMPAT] Request GPIO
197 * @gpio: GPIO number
198 * @fmt: Format string for the requested GPIO
199 * @...: Arguments for the printf() format string
200 *
201 * This function implements the API that's compatible with current
202 * GPIO API used in U-Boot. The request is forwarded to particular
203 * GPIO driver. Returns 0 on success, negative value on error.
204 */
205int gpio_requestf(unsigned gpio, const char *fmt, ...)
206{
Simon Glassee8a3d92015-12-29 05:22:48 -0700207#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_USE_TINY_PRINTF)
Simon Glass1b27d602014-10-04 11:29:49 -0600208 va_list args;
209 char buf[40];
210
211 va_start(args, fmt);
212 vscnprintf(buf, sizeof(buf), fmt, args);
213 va_end(args);
214 return gpio_request(gpio, buf);
Simon Glassee8a3d92015-12-29 05:22:48 -0700215#else
216 return gpio_request(gpio, fmt);
217#endif
Simon Glass1b27d602014-10-04 11:29:49 -0600218}
219
Simon Glassce555292015-01-05 20:05:27 -0700220int _dm_gpio_free(struct udevice *dev, uint offset)
Simon Glasse821d182014-02-26 15:59:24 -0700221{
Simon Glass0f4517d2014-10-04 11:29:42 -0600222 struct gpio_dev_priv *uc_priv;
Simon Glasse821d182014-02-26 15:59:24 -0700223 int ret;
224
Simon Glassde0977b2015-03-05 12:25:20 -0700225 uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -0600226 if (!uc_priv->name[offset])
227 return -ENXIO;
228 if (gpio_get_ops(dev)->free) {
229 ret = gpio_get_ops(dev)->free(dev, offset);
230 if (ret)
231 return ret;
232 }
233
234 free(uc_priv->name[offset]);
235 uc_priv->name[offset] = NULL;
236
237 return 0;
238}
239
Simon Glassce555292015-01-05 20:05:27 -0700240/**
241 * gpio_free() - [COMPAT] Relinquish GPIO
242 * gpio: GPIO number
243 *
244 * This function implements the API that's compatible with current
245 * GPIO API used in U-Boot. The request is forwarded to particular
246 * GPIO driver. Returns 0 on success, negative value on error.
247 */
248int gpio_free(unsigned gpio)
249{
250 struct gpio_desc desc;
251 int ret;
252
253 ret = gpio_to_device(gpio, &desc);
254 if (ret)
255 return ret;
256
257 return _dm_gpio_free(desc.dev, desc.offset);
258}
259
260static int check_reserved(struct gpio_desc *desc, const char *func)
Simon Glass0f4517d2014-10-04 11:29:42 -0600261{
Simon Glass230c1432015-07-02 18:16:16 -0600262 struct gpio_dev_priv *uc_priv;
263
264 if (!dm_gpio_is_valid(desc))
265 return -ENOENT;
Simon Glass0f4517d2014-10-04 11:29:42 -0600266
Simon Glass230c1432015-07-02 18:16:16 -0600267 uc_priv = dev_get_uclass_priv(desc->dev);
Simon Glassce555292015-01-05 20:05:27 -0700268 if (!uc_priv->name[desc->offset]) {
Simon Glass0f4517d2014-10-04 11:29:42 -0600269 printf("%s: %s: error: gpio %s%d not reserved\n",
Simon Glassce555292015-01-05 20:05:27 -0700270 desc->dev->name, func,
271 uc_priv->bank_name ? uc_priv->bank_name : "",
272 desc->offset);
Simon Glass0f4517d2014-10-04 11:29:42 -0600273 return -EBUSY;
274 }
275
276 return 0;
Simon Glasse821d182014-02-26 15:59:24 -0700277}
278
279/**
280 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
281 * gpio: GPIO number
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 */
287int gpio_direction_input(unsigned gpio)
288{
Simon Glassce555292015-01-05 20:05:27 -0700289 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700290 int ret;
291
Simon Glassce555292015-01-05 20:05:27 -0700292 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700293 if (ret)
294 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700295 ret = check_reserved(&desc, "dir_input");
296 if (ret)
297 return ret;
Simon Glasse821d182014-02-26 15:59:24 -0700298
Simon Glassce555292015-01-05 20:05:27 -0700299 return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
Simon Glasse821d182014-02-26 15:59:24 -0700300}
301
302/**
303 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
304 * gpio: GPIO number
305 * value: Logical value to be set on the GPIO pin
306 *
307 * This function implements the API that's compatible with current
308 * GPIO API used in U-Boot. The request is forwarded to particular
309 * GPIO driver. Returns 0 on success, negative value on error.
310 */
311int gpio_direction_output(unsigned gpio, int value)
312{
Simon Glassce555292015-01-05 20:05:27 -0700313 struct gpio_desc desc;
314 int ret;
315
316 ret = gpio_to_device(gpio, &desc);
317 if (ret)
318 return ret;
319 ret = check_reserved(&desc, "dir_output");
320 if (ret)
321 return ret;
322
323 return gpio_get_ops(desc.dev)->direction_output(desc.dev,
324 desc.offset, value);
325}
326
327int dm_gpio_get_value(struct gpio_desc *desc)
328{
329 int value;
330 int ret;
331
332 ret = check_reserved(desc, "get_value");
333 if (ret)
334 return ret;
335
336 value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
337
338 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
339}
340
341int dm_gpio_set_value(struct gpio_desc *desc, int value)
342{
343 int ret;
344
345 ret = check_reserved(desc, "set_value");
346 if (ret)
347 return ret;
348
349 if (desc->flags & GPIOD_ACTIVE_LOW)
350 value = !value;
351 gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
352 return 0;
353}
354
355int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
356{
357 struct udevice *dev = desc->dev;
358 struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glasse821d182014-02-26 15:59:24 -0700359 int ret;
360
Simon Glassce555292015-01-05 20:05:27 -0700361 ret = check_reserved(desc, "set_dir");
Simon Glasse821d182014-02-26 15:59:24 -0700362 if (ret)
363 return ret;
364
Simon Glassce555292015-01-05 20:05:27 -0700365 if (flags & GPIOD_IS_OUT) {
366 int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
367
368 if (flags & GPIOD_ACTIVE_LOW)
369 value = !value;
370 ret = ops->direction_output(dev, desc->offset, value);
371 } else if (flags & GPIOD_IS_IN) {
372 ret = ops->direction_input(dev, desc->offset);
373 }
374 if (ret)
375 return ret;
376 /*
377 * Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in
378 * futures
379 */
380 desc->flags = flags;
381
382 return 0;
383}
384
385int dm_gpio_set_dir(struct gpio_desc *desc)
386{
387 return dm_gpio_set_dir_flags(desc, desc->flags);
Simon Glasse821d182014-02-26 15:59:24 -0700388}
389
390/**
391 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
392 * gpio: GPIO number
393 *
394 * This function implements the API that's compatible with current
395 * GPIO API used in U-Boot. The request is forwarded to particular
396 * GPIO driver. Returns the value of the GPIO pin, or negative value
397 * on error.
398 */
399int gpio_get_value(unsigned gpio)
400{
Simon Glasse821d182014-02-26 15:59:24 -0700401 int ret;
402
Simon Glassce555292015-01-05 20:05:27 -0700403 struct gpio_desc desc;
404
405 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700406 if (ret)
407 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700408 return dm_gpio_get_value(&desc);
Simon Glasse821d182014-02-26 15:59:24 -0700409}
410
411/**
412 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
413 * gpio: GPIO number
414 * value: Logical value to be set on the GPIO pin.
415 *
416 * This function implements the API that's compatible with current
417 * GPIO API used in U-Boot. The request is forwarded to particular
418 * GPIO driver. Returns 0 on success, negative value on error.
419 */
420int gpio_set_value(unsigned gpio, int value)
421{
Simon Glassce555292015-01-05 20:05:27 -0700422 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700423 int ret;
424
Simon Glassce555292015-01-05 20:05:27 -0700425 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700426 if (ret)
427 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700428 return dm_gpio_set_value(&desc, value);
Simon Glasse821d182014-02-26 15:59:24 -0700429}
430
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200431const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
Simon Glasse821d182014-02-26 15:59:24 -0700432{
433 struct gpio_dev_priv *priv;
434
435 /* Must be called on an active device */
Simon Glassde0977b2015-03-05 12:25:20 -0700436 priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -0700437 assert(priv);
438
439 *bit_count = priv->gpio_count;
440 return priv->bank_name;
441}
442
Simon Glass6e5e6dd2014-10-04 11:29:43 -0600443static const char * const gpio_function[GPIOF_COUNT] = {
444 "input",
445 "output",
446 "unused",
447 "unknown",
448 "func",
449};
450
451int get_function(struct udevice *dev, int offset, bool skip_unused,
452 const char **namep)
453{
Simon Glassde0977b2015-03-05 12:25:20 -0700454 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass6e5e6dd2014-10-04 11:29:43 -0600455 struct dm_gpio_ops *ops = gpio_get_ops(dev);
456
457 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
458 if (!device_active(dev))
459 return -ENODEV;
460 if (offset < 0 || offset >= uc_priv->gpio_count)
461 return -EINVAL;
462 if (namep)
463 *namep = uc_priv->name[offset];
464 if (skip_unused && !uc_priv->name[offset])
465 return GPIOF_UNUSED;
466 if (ops->get_function) {
467 int ret;
468
469 ret = ops->get_function(dev, offset);
470 if (ret < 0)
471 return ret;
472 if (ret >= ARRAY_SIZE(gpio_function))
473 return -ENODATA;
474 return ret;
475 }
476
477 return GPIOF_UNKNOWN;
478}
479
480int gpio_get_function(struct udevice *dev, int offset, const char **namep)
481{
482 return get_function(dev, offset, true, namep);
483}
484
485int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
486{
487 return get_function(dev, offset, false, namep);
488}
489
Simon Glass6b1ef592014-10-04 11:29:44 -0600490int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
491{
492 struct dm_gpio_ops *ops = gpio_get_ops(dev);
493 struct gpio_dev_priv *priv;
494 char *str = buf;
495 int func;
496 int ret;
497 int len;
498
499 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
500
501 *buf = 0;
Simon Glassde0977b2015-03-05 12:25:20 -0700502 priv = dev_get_uclass_priv(dev);
Simon Glass6b1ef592014-10-04 11:29:44 -0600503 ret = gpio_get_raw_function(dev, offset, NULL);
504 if (ret < 0)
505 return ret;
506 func = ret;
507 len = snprintf(str, buffsize, "%s%d: %s",
508 priv->bank_name ? priv->bank_name : "",
509 offset, gpio_function[func]);
510 if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
511 func == GPIOF_UNUSED) {
512 const char *label;
513 bool used;
514
515 ret = ops->get_value(dev, offset);
516 if (ret < 0)
517 return ret;
518 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
519 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
520 ret,
521 used ? 'x' : ' ',
522 used ? " " : "",
523 label ? label : "");
524 }
525
526 return 0;
527}
528
Simon Glassbef54db2015-04-14 21:03:20 -0600529int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
530{
531 int i, ret;
532 int gpio;
533
534 for (i = 0; i < 32; i++) {
535 gpio = gpio_num_array[i];
536 if (gpio == -1)
537 break;
538 ret = gpio_requestf(gpio, fmt, i);
539 if (ret)
540 goto err;
541 ret = gpio_direction_input(gpio);
542 if (ret) {
543 gpio_free(gpio);
544 goto err;
545 }
546 }
547
548 return 0;
549err:
550 for (i--; i >= 0; i--)
551 gpio_free(gpio_num_array[i]);
552
553 return ret;
554}
555
Simon Glass2c97a8f2014-11-10 18:00:21 -0700556/*
557 * get a number comprised of multiple GPIO values. gpio_num_array points to
558 * the array of gpio pin numbers to scan, terminated by -1.
559 */
Simon Glassbef54db2015-04-14 21:03:20 -0600560int gpio_get_values_as_int(const int *gpio_list)
Simon Glass2c97a8f2014-11-10 18:00:21 -0700561{
562 int gpio;
563 unsigned bitmask = 1;
564 unsigned vector = 0;
Simon Glassbef54db2015-04-14 21:03:20 -0600565 int ret;
Simon Glass2c97a8f2014-11-10 18:00:21 -0700566
567 while (bitmask &&
Simon Glassbef54db2015-04-14 21:03:20 -0600568 ((gpio = *gpio_list++) != -1)) {
569 ret = gpio_get_value(gpio);
570 if (ret < 0)
571 return ret;
572 else if (ret)
Simon Glass2c97a8f2014-11-10 18:00:21 -0700573 vector |= bitmask;
574 bitmask <<= 1;
575 }
Simon Glassbef54db2015-04-14 21:03:20 -0600576
Simon Glass2c97a8f2014-11-10 18:00:21 -0700577 return vector;
578}
579
Simon Glass16e10402015-01-05 20:05:29 -0700580static int _gpio_request_by_name_nodev(const void *blob, int node,
581 const char *list_name, int index,
582 struct gpio_desc *desc, int flags,
583 bool add_index)
584{
585 struct fdtdec_phandle_args args;
586 int ret;
587
588 desc->dev = NULL;
589 desc->offset = 0;
590 ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
591 "#gpio-cells", 0, index, &args);
592 if (ret) {
593 debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
594 goto err;
595 }
596
597 ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
598 &desc->dev);
599 if (ret) {
600 debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
601 goto err;
602 }
603 ret = gpio_find_and_xlate(desc, &args);
604 if (ret) {
605 debug("%s: gpio_find_and_xlate failed\n", __func__);
606 goto err;
607 }
608 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
609 fdt_get_name(blob, node, NULL),
610 list_name, index);
611 if (ret) {
612 debug("%s: dm_gpio_requestf failed\n", __func__);
613 goto err;
614 }
615 ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
616 if (ret) {
617 debug("%s: dm_gpio_set_dir failed\n", __func__);
618 goto err;
619 }
620
621 return 0;
622err:
623 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
624 __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
625 return ret;
626}
627
628int gpio_request_by_name_nodev(const void *blob, int node,
629 const char *list_name, int index,
630 struct gpio_desc *desc, int flags)
631{
632 return _gpio_request_by_name_nodev(blob, node, list_name, index, desc,
633 flags, index > 0);
634}
635
636int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
637 struct gpio_desc *desc, int flags)
638{
639 /*
640 * This isn't ideal since we don't use dev->name in the debug()
641 * calls in gpio_request_by_name(), but we can do this until
642 * gpio_request_by_name_nodev() can be dropped.
643 */
644 return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
645 list_name, index, desc, flags);
646}
647
648int gpio_request_list_by_name_nodev(const void *blob, int node,
649 const char *list_name,
650 struct gpio_desc *desc, int max_count,
651 int flags)
652{
653 int count;
654 int ret;
655
Przemyslaw Marczak44fc5362015-03-31 18:57:16 +0200656 for (count = 0; count < max_count; count++) {
Simon Glass16e10402015-01-05 20:05:29 -0700657 ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
658 &desc[count], flags, true);
659 if (ret == -ENOENT)
660 break;
661 else if (ret)
662 goto err;
663 }
664
665 /* We ran out of GPIOs in the list */
666 return count;
667
668err:
669 gpio_free_list_nodev(desc, count - 1);
670
671 return ret;
672}
673
674int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
675 struct gpio_desc *desc, int max_count,
676 int flags)
677{
678 /*
679 * This isn't ideal since we don't use dev->name in the debug()
680 * calls in gpio_request_by_name(), but we can do this until
681 * gpio_request_list_by_name_nodev() can be dropped.
682 */
683 return gpio_request_list_by_name_nodev(gd->fdt_blob, dev->of_offset,
684 list_name, desc, max_count,
685 flags);
686}
687
688int gpio_get_list_count(struct udevice *dev, const char *list_name)
689{
690 int ret;
691
692 ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
693 list_name, "#gpio-cells", 0, -1,
694 NULL);
695 if (ret) {
696 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
697 __func__, dev->name, list_name, ret);
698 }
699
700 return ret;
701}
702
703int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
704{
705 /* For now, we don't do any checking of dev */
706 return _dm_gpio_free(desc->dev, desc->offset);
707}
708
709int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
710{
711 int i;
712
713 /* For now, we don't do any checking of dev */
714 for (i = 0; i < count; i++)
715 dm_gpio_free(dev, &desc[i]);
716
717 return 0;
718}
719
720int gpio_free_list_nodev(struct gpio_desc *desc, int count)
721{
722 return gpio_free_list(NULL, desc, count);
723}
724
Simon Glasse821d182014-02-26 15:59:24 -0700725/* We need to renumber the GPIOs when any driver is probed/removed */
Simon Glass0f4517d2014-10-04 11:29:42 -0600726static int gpio_renumber(struct udevice *removed_dev)
Simon Glasse821d182014-02-26 15:59:24 -0700727{
728 struct gpio_dev_priv *uc_priv;
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200729 struct udevice *dev;
Simon Glasse821d182014-02-26 15:59:24 -0700730 struct uclass *uc;
731 unsigned base;
732 int ret;
733
734 ret = uclass_get(UCLASS_GPIO, &uc);
735 if (ret)
736 return ret;
737
738 /* Ensure that we have a base for each bank */
739 base = 0;
740 uclass_foreach_dev(dev, uc) {
Simon Glass0f4517d2014-10-04 11:29:42 -0600741 if (device_active(dev) && dev != removed_dev) {
Simon Glassde0977b2015-03-05 12:25:20 -0700742 uc_priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -0700743 uc_priv->gpio_base = base;
744 base += uc_priv->gpio_count;
745 }
746 }
747
748 return 0;
749}
750
Simon Glass94f54d12015-03-25 12:21:58 -0600751int gpio_get_number(struct gpio_desc *desc)
752{
753 struct udevice *dev = desc->dev;
754 struct gpio_dev_priv *uc_priv;
755
756 if (!dev)
757 return -1;
758 uc_priv = dev->uclass_priv;
759
760 return uc_priv->gpio_base + desc->offset;
761}
762
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200763static int gpio_post_probe(struct udevice *dev)
Simon Glasse821d182014-02-26 15:59:24 -0700764{
Simon Glassde0977b2015-03-05 12:25:20 -0700765 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -0600766
767 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
768 if (!uc_priv->name)
769 return -ENOMEM;
770
771 return gpio_renumber(NULL);
Simon Glasse821d182014-02-26 15:59:24 -0700772}
773
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200774static int gpio_pre_remove(struct udevice *dev)
Simon Glasse821d182014-02-26 15:59:24 -0700775{
Simon Glassde0977b2015-03-05 12:25:20 -0700776 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -0600777 int i;
778
779 for (i = 0; i < uc_priv->gpio_count; i++) {
780 if (uc_priv->name[i])
781 free(uc_priv->name[i]);
782 }
783 free(uc_priv->name);
784
785 return gpio_renumber(dev);
Simon Glasse821d182014-02-26 15:59:24 -0700786}
787
788UCLASS_DRIVER(gpio) = {
789 .id = UCLASS_GPIO,
790 .name = "gpio",
Bhuvanchandra DVb1a1fc92015-06-01 18:37:15 +0530791 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glasse821d182014-02-26 15:59:24 -0700792 .post_probe = gpio_post_probe,
793 .pre_remove = gpio_pre_remove,
794 .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
795};