blob: 9c53299b6a3b65aed0ba1292e093440a56e85cfc [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass96495d92014-02-26 15:59:24 -07002/*
3 * Copyright (c) 2013 Google, Inc
Simon Glass96495d92014-02-26 15:59:24 -07004 */
5
6#include <common.h>
7#include <dm.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -06008#include <log.h>
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02009#include <dm/device-internal.h>
10#include <dm/lists.h>
11#include <dm/uclass-internal.h>
Eric Nelson6c880b72016-04-24 16:32:40 -070012#include <dt-bindings/gpio/gpio.h>
Simon Glass96495d92014-02-26 15:59:24 -070013#include <errno.h>
Simon Glass0dac4d52015-01-05 20:05:28 -070014#include <fdtdec.h>
Simon Glassb892d122014-10-04 11:29:42 -060015#include <malloc.h>
Simon Glass29126862020-07-07 13:11:44 -060016#include <acpi/acpi_device.h>
Simon Glass96495d92014-02-26 15:59:24 -070017#include <asm/gpio.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060018#include <dm/device_compat.h>
Masahiro Yamada84b8bf62016-01-24 23:27:48 +090019#include <linux/bug.h>
Simon Glassfe1ef502014-10-22 21:37:01 -060020#include <linux/ctype.h>
Simon Glass96495d92014-02-26 15:59:24 -070021
Simon Glass3669e0e2015-01-05 20:05:29 -070022DECLARE_GLOBAL_DATA_PTR;
23
Simon Glass96495d92014-02-26 15:59:24 -070024/**
Patrick Delaunay9f2b0662020-01-13 11:35:01 +010025 * gpio_desc_init() - Initialize the GPIO descriptor
26 *
27 * @desc: GPIO descriptor to initialize
28 * @dev: GPIO device
29 * @offset: Offset of device GPIO
30 */
31static void gpio_desc_init(struct gpio_desc *desc,
32 struct udevice *dev,
33 uint offset)
34{
35 desc->dev = dev;
36 desc->offset = offset;
37 desc->flags = 0;
38}
39
40/**
Simon Glass96495d92014-02-26 15:59:24 -070041 * gpio_to_device() - Convert global GPIO number to device, number
Simon Glass96495d92014-02-26 15:59:24 -070042 *
43 * Convert the GPIO number to an entry in the list of GPIOs
44 * or GPIO blocks registered with the GPIO controller. Returns
45 * entry on success, NULL on error.
Simon Glassae7123f2015-01-05 20:05:27 -070046 *
47 * @gpio: The numeric representation of the GPIO
48 * @desc: Returns description (desc->flags will always be 0)
49 * @return 0 if found, -ENOENT if not found
Simon Glass96495d92014-02-26 15:59:24 -070050 */
Simon Glassae7123f2015-01-05 20:05:27 -070051static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
Simon Glass96495d92014-02-26 15:59:24 -070052{
53 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +020054 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -070055 int ret;
56
57 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
58 dev;
59 ret = uclass_next_device(&dev)) {
Simon Glasse564f052015-03-05 12:25:20 -070060 uc_priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -070061 if (gpio >= uc_priv->gpio_base &&
62 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
Patrick Delaunay9f2b0662020-01-13 11:35:01 +010063 gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
Simon Glass96495d92014-02-26 15:59:24 -070064 return 0;
65 }
66 }
67
68 /* No such GPIO */
Simon Glassae7123f2015-01-05 20:05:27 -070069 return ret ? ret : -ENOENT;
Simon Glass96495d92014-02-26 15:59:24 -070070}
71
Heiko Schocher2bd261d2020-05-22 11:08:59 +020072#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL)
73/**
74 * dm_gpio_lookup_label() - look for name in gpio device
75 *
76 * search in uc_priv, if there is a gpio with labelname same
77 * as name.
78 *
79 * @name: name which is searched
80 * @uc_priv: gpio_dev_priv pointer.
81 * @offset: gpio offset within the device
82 * @return: 0 if found, -ENOENT if not.
83 */
84static int dm_gpio_lookup_label(const char *name,
85 struct gpio_dev_priv *uc_priv, ulong *offset)
86{
87 int len;
88 int i;
89
90 *offset = -1;
91 len = strlen(name);
92 for (i = 0; i < uc_priv->gpio_count; i++) {
93 if (!uc_priv->name[i])
94 continue;
95 if (!strncmp(name, uc_priv->name[i], len)) {
96 *offset = i;
97 return 0;
98 }
99 }
100 return -ENOENT;
101}
102#else
103static int
104dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv,
105 ulong *offset)
106{
107 return -ENOENT;
108}
109#endif
110
Simon Glass32ec1592015-06-23 15:38:40 -0600111int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
Simon Glass96495d92014-02-26 15:59:24 -0700112{
Simon Glassfe1ef502014-10-22 21:37:01 -0600113 struct gpio_dev_priv *uc_priv = NULL;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200114 struct udevice *dev;
Simon Glassfe1ef502014-10-22 21:37:01 -0600115 ulong offset;
116 int numeric;
Simon Glass96495d92014-02-26 15:59:24 -0700117 int ret;
118
Simon Glassfe1ef502014-10-22 21:37:01 -0600119 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
Simon Glass96495d92014-02-26 15:59:24 -0700120 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
121 dev;
122 ret = uclass_next_device(&dev)) {
Simon Glass96495d92014-02-26 15:59:24 -0700123 int len;
124
Simon Glasse564f052015-03-05 12:25:20 -0700125 uc_priv = dev_get_uclass_priv(dev);
Simon Glassfe1ef502014-10-22 21:37:01 -0600126 if (numeric != -1) {
127 offset = numeric - uc_priv->gpio_base;
128 /* Allow GPIOs to be numbered from 0 */
Tom Rini75897912017-05-10 15:20:15 -0400129 if (offset < uc_priv->gpio_count)
Simon Glassfe1ef502014-10-22 21:37:01 -0600130 break;
131 }
132
Simon Glass96495d92014-02-26 15:59:24 -0700133 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
134
Simon Glass939cda52014-06-11 23:29:47 -0600135 if (!strncasecmp(name, uc_priv->bank_name, len)) {
Simon Glassfe1ef502014-10-22 21:37:01 -0600136 if (!strict_strtoul(name + len, 10, &offset))
137 break;
Simon Glass96495d92014-02-26 15:59:24 -0700138 }
Heiko Schocher2bd261d2020-05-22 11:08:59 +0200139
140 /*
141 * if we did not found a gpio through its bank
142 * name, we search for a valid gpio label.
143 */
144 if (!dm_gpio_lookup_label(name, uc_priv, &offset))
145 break;
Simon Glass96495d92014-02-26 15:59:24 -0700146 }
147
Simon Glassfe1ef502014-10-22 21:37:01 -0600148 if (!dev)
149 return ret ? ret : -EINVAL;
150
Patrick Delaunay9f2b0662020-01-13 11:35:01 +0100151 gpio_desc_init(desc, dev, offset);
Simon Glass32ec1592015-06-23 15:38:40 -0600152
153 return 0;
154}
155
156int gpio_lookup_name(const char *name, struct udevice **devp,
157 unsigned int *offsetp, unsigned int *gpiop)
158{
159 struct gpio_desc desc;
160 int ret;
161
Simon Glassfe1ef502014-10-22 21:37:01 -0600162 if (devp)
Simon Glass32ec1592015-06-23 15:38:40 -0600163 *devp = NULL;
164 ret = dm_gpio_lookup_name(name, &desc);
165 if (ret)
166 return ret;
167
168 if (devp)
169 *devp = desc.dev;
Simon Glassfe1ef502014-10-22 21:37:01 -0600170 if (offsetp)
Simon Glass32ec1592015-06-23 15:38:40 -0600171 *offsetp = desc.offset;
172 if (gpiop) {
173 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
174
175 *gpiop = uc_priv->gpio_base + desc.offset;
176 }
Simon Glassfe1ef502014-10-22 21:37:01 -0600177
178 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700179}
180
Simon Glass3a571232017-05-18 20:09:18 -0600181int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
182 struct ofnode_phandle_args *args)
Eric Nelson6c880b72016-04-24 16:32:40 -0700183{
184 if (args->args_count < 1)
185 return -EINVAL;
186
187 desc->offset = args->args[0];
188
189 if (args->args_count < 2)
190 return 0;
191
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100192 desc->flags = 0;
Eric Nelson6c880b72016-04-24 16:32:40 -0700193 if (args->args[1] & GPIO_ACTIVE_LOW)
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100194 desc->flags |= GPIOD_ACTIVE_LOW;
Eric Nelson6c880b72016-04-24 16:32:40 -0700195
Patrick Delaunay477ca572020-01-13 11:35:07 +0100196 /*
197 * need to test 2 bits for gpio output binding:
198 * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
199 * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
200 */
201 if (args->args[1] & GPIO_SINGLE_ENDED) {
202 if (args->args[1] & GPIO_LINE_OPEN_DRAIN)
203 desc->flags |= GPIOD_OPEN_DRAIN;
204 else
205 desc->flags |= GPIOD_OPEN_SOURCE;
206 }
207
208 if (args->args[1] & GPIO_PULL_UP)
209 desc->flags |= GPIOD_PULL_UP;
210
211 if (args->args[1] & GPIO_PULL_DOWN)
212 desc->flags |= GPIOD_PULL_DOWN;
213
Eric Nelson6c880b72016-04-24 16:32:40 -0700214 return 0;
215}
216
Simon Glass3669e0e2015-01-05 20:05:29 -0700217static int gpio_find_and_xlate(struct gpio_desc *desc,
Simon Glass3a571232017-05-18 20:09:18 -0600218 struct ofnode_phandle_args *args)
Simon Glass0dac4d52015-01-05 20:05:28 -0700219{
220 struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
221
Eric Nelson6c880b72016-04-24 16:32:40 -0700222 if (ops->xlate)
223 return ops->xlate(desc->dev, desc, args);
Simon Glass0dac4d52015-01-05 20:05:28 -0700224 else
Eric Nelson6c880b72016-04-24 16:32:40 -0700225 return gpio_xlate_offs_flags(desc->dev, desc, args);
Simon Glass0dac4d52015-01-05 20:05:28 -0700226}
227
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200228#if defined(CONFIG_GPIO_HOG)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200229
230struct gpio_hog_priv {
231 struct gpio_desc gpiod;
232};
233
234struct gpio_hog_data {
235 int gpiod_flags;
236 int value;
237 u32 val[2];
238};
239
240static int gpio_hog_ofdata_to_platdata(struct udevice *dev)
241{
242 struct gpio_hog_data *plat = dev_get_platdata(dev);
243 const char *nodename;
244 int ret;
245
246 plat->value = 0;
247 if (dev_read_bool(dev, "input")) {
248 plat->gpiod_flags = GPIOD_IS_IN;
249 } else if (dev_read_bool(dev, "output-high")) {
250 plat->value = 1;
251 plat->gpiod_flags = GPIOD_IS_OUT;
252 } else if (dev_read_bool(dev, "output-low")) {
253 plat->gpiod_flags = GPIOD_IS_OUT;
254 } else {
255 printf("%s: missing gpio-hog state.\n", __func__);
256 return -EINVAL;
257 }
258 ret = dev_read_u32_array(dev, "gpios", plat->val, 2);
259 if (ret) {
260 printf("%s: wrong gpios property, 2 values needed %d\n",
261 __func__, ret);
262 return ret;
263 }
264 nodename = dev_read_string(dev, "line-name");
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200265 if (nodename)
266 device_set_name(dev, nodename);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200267
268 return 0;
269}
270
271static int gpio_hog_probe(struct udevice *dev)
272{
273 struct gpio_hog_data *plat = dev_get_platdata(dev);
274 struct gpio_hog_priv *priv = dev_get_priv(dev);
275 int ret;
276
277 ret = gpio_dev_request_index(dev->parent, dev->name, "gpio-hog",
278 plat->val[0], plat->gpiod_flags,
279 plat->val[1], &priv->gpiod);
280 if (ret < 0) {
281 debug("%s: node %s could not get gpio.\n", __func__,
282 dev->name);
283 return ret;
284 }
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200285
286 if (plat->gpiod_flags == GPIOD_IS_OUT) {
287 ret = dm_gpio_set_value(&priv->gpiod, plat->value);
288 if (ret < 0) {
289 debug("%s: node %s could not set gpio.\n", __func__,
290 dev->name);
291 return ret;
292 }
293 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200294
295 return 0;
296}
297
298int gpio_hog_probe_all(void)
299{
300 struct udevice *dev;
301 int ret;
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200302 int retval = 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200303
304 for (uclass_first_device(UCLASS_NOP, &dev);
305 dev;
306 uclass_find_next_device(&dev)) {
307 if (dev->driver == DM_GET_DRIVER(gpio_hog)) {
308 ret = device_probe(dev);
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200309 if (ret) {
310 printf("Failed to probe device %s err: %d\n",
311 dev->name, ret);
312 retval = ret;
313 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200314 }
315 }
316
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200317 return retval;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200318}
319
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200320int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200321{
322 struct udevice *dev;
323
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200324 *desc = NULL;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200325 gpio_hog_probe_all();
326 if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
327 struct gpio_hog_priv *priv = dev_get_priv(dev);
328
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200329 *desc = &priv->gpiod;
330 return 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200331 }
332
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200333 return -ENODEV;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200334}
335
336U_BOOT_DRIVER(gpio_hog) = {
337 .name = "gpio_hog",
338 .id = UCLASS_NOP,
339 .ofdata_to_platdata = gpio_hog_ofdata_to_platdata,
340 .probe = gpio_hog_probe,
341 .priv_auto_alloc_size = sizeof(struct gpio_hog_priv),
342 .platdata_auto_alloc_size = sizeof(struct gpio_hog_data),
343};
344#else
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200345int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200346{
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200347 return 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200348}
349#endif
350
Simon Glassefa677f2015-06-23 15:38:41 -0600351int dm_gpio_request(struct gpio_desc *desc, const char *label)
Simon Glassae7123f2015-01-05 20:05:27 -0700352{
353 struct udevice *dev = desc->dev;
354 struct gpio_dev_priv *uc_priv;
355 char *str;
356 int ret;
357
Simon Glasse564f052015-03-05 12:25:20 -0700358 uc_priv = dev_get_uclass_priv(dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700359 if (uc_priv->name[desc->offset])
360 return -EBUSY;
361 str = strdup(label);
362 if (!str)
363 return -ENOMEM;
364 if (gpio_get_ops(dev)->request) {
365 ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
366 if (ret) {
367 free(str);
368 return ret;
369 }
370 }
371 uc_priv->name[desc->offset] = str;
372
373 return 0;
374}
375
Simon Glass3669e0e2015-01-05 20:05:29 -0700376static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
377{
Simon Glass27084c02019-09-25 08:56:27 -0600378#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass3669e0e2015-01-05 20:05:29 -0700379 va_list args;
380 char buf[40];
381
382 va_start(args, fmt);
383 vscnprintf(buf, sizeof(buf), fmt, args);
384 va_end(args);
385 return dm_gpio_request(desc, buf);
Simon Glass4dc52592015-12-29 05:22:48 -0700386#else
387 return dm_gpio_request(desc, fmt);
388#endif
Simon Glass3669e0e2015-01-05 20:05:29 -0700389}
390
Simon Glass96495d92014-02-26 15:59:24 -0700391/**
392 * gpio_request() - [COMPAT] Request GPIO
393 * gpio: GPIO number
394 * label: Name for the requested GPIO
395 *
Simon Glassb892d122014-10-04 11:29:42 -0600396 * The label is copied and allocated so the caller does not need to keep
397 * the pointer around.
398 *
Simon Glass96495d92014-02-26 15:59:24 -0700399 * This function implements the API that's compatible with current
400 * GPIO API used in U-Boot. The request is forwarded to particular
401 * GPIO driver. Returns 0 on success, negative value on error.
402 */
403int gpio_request(unsigned gpio, const char *label)
404{
Simon Glassae7123f2015-01-05 20:05:27 -0700405 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700406 int ret;
407
Simon Glassae7123f2015-01-05 20:05:27 -0700408 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700409 if (ret)
410 return ret;
411
Simon Glassae7123f2015-01-05 20:05:27 -0700412 return dm_gpio_request(&desc, label);
Simon Glass96495d92014-02-26 15:59:24 -0700413}
414
415/**
Simon Glassd44f5972014-10-04 11:29:49 -0600416 * gpio_requestf() - [COMPAT] Request GPIO
417 * @gpio: GPIO number
418 * @fmt: Format string for the requested GPIO
419 * @...: Arguments for the printf() format string
420 *
421 * This function implements the API that's compatible with current
422 * GPIO API used in U-Boot. The request is forwarded to particular
423 * GPIO driver. Returns 0 on success, negative value on error.
424 */
425int gpio_requestf(unsigned gpio, const char *fmt, ...)
426{
Simon Glass27084c02019-09-25 08:56:27 -0600427#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glassd44f5972014-10-04 11:29:49 -0600428 va_list args;
429 char buf[40];
430
431 va_start(args, fmt);
432 vscnprintf(buf, sizeof(buf), fmt, args);
433 va_end(args);
434 return gpio_request(gpio, buf);
Simon Glass4dc52592015-12-29 05:22:48 -0700435#else
436 return gpio_request(gpio, fmt);
437#endif
Simon Glassd44f5972014-10-04 11:29:49 -0600438}
439
Simon Glassae7123f2015-01-05 20:05:27 -0700440int _dm_gpio_free(struct udevice *dev, uint offset)
Simon Glass96495d92014-02-26 15:59:24 -0700441{
Simon Glassb892d122014-10-04 11:29:42 -0600442 struct gpio_dev_priv *uc_priv;
Simon Glass96495d92014-02-26 15:59:24 -0700443 int ret;
444
Simon Glasse564f052015-03-05 12:25:20 -0700445 uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -0600446 if (!uc_priv->name[offset])
447 return -ENXIO;
Simon Glass093152f2020-02-04 20:15:17 -0700448 if (gpio_get_ops(dev)->rfree) {
449 ret = gpio_get_ops(dev)->rfree(dev, offset);
Simon Glassb892d122014-10-04 11:29:42 -0600450 if (ret)
451 return ret;
452 }
453
454 free(uc_priv->name[offset]);
455 uc_priv->name[offset] = NULL;
456
457 return 0;
458}
459
Simon Glassae7123f2015-01-05 20:05:27 -0700460/**
461 * gpio_free() - [COMPAT] Relinquish GPIO
462 * gpio: GPIO number
463 *
464 * This function implements the API that's compatible with current
465 * GPIO API used in U-Boot. The request is forwarded to particular
466 * GPIO driver. Returns 0 on success, negative value on error.
467 */
468int gpio_free(unsigned gpio)
Simon Glassb892d122014-10-04 11:29:42 -0600469{
Simon Glassae7123f2015-01-05 20:05:27 -0700470 struct gpio_desc desc;
471 int ret;
Simon Glassb892d122014-10-04 11:29:42 -0600472
Simon Glassae7123f2015-01-05 20:05:27 -0700473 ret = gpio_to_device(gpio, &desc);
474 if (ret)
475 return ret;
476
477 return _dm_gpio_free(desc.dev, desc.offset);
478}
479
Simon Glass17c43f12016-03-06 19:27:51 -0700480static int check_reserved(const struct gpio_desc *desc, const char *func)
Simon Glassae7123f2015-01-05 20:05:27 -0700481{
Simon Glasseca48662015-07-02 18:16:16 -0600482 struct gpio_dev_priv *uc_priv;
Simon Glassae7123f2015-01-05 20:05:27 -0700483
Simon Glasseca48662015-07-02 18:16:16 -0600484 if (!dm_gpio_is_valid(desc))
485 return -ENOENT;
486
487 uc_priv = dev_get_uclass_priv(desc->dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700488 if (!uc_priv->name[desc->offset]) {
Simon Glassb892d122014-10-04 11:29:42 -0600489 printf("%s: %s: error: gpio %s%d not reserved\n",
Simon Glassae7123f2015-01-05 20:05:27 -0700490 desc->dev->name, func,
491 uc_priv->bank_name ? uc_priv->bank_name : "",
492 desc->offset);
Simon Glassb892d122014-10-04 11:29:42 -0600493 return -EBUSY;
494 }
495
496 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700497}
498
499/**
500 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
501 * gpio: GPIO number
502 *
503 * This function implements the API that's compatible with current
504 * GPIO API used in U-Boot. The request is forwarded to particular
505 * GPIO driver. Returns 0 on success, negative value on error.
506 */
507int gpio_direction_input(unsigned gpio)
508{
Simon Glassae7123f2015-01-05 20:05:27 -0700509 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700510 int ret;
511
Simon Glassae7123f2015-01-05 20:05:27 -0700512 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700513 if (ret)
514 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700515 ret = check_reserved(&desc, "dir_input");
516 if (ret)
517 return ret;
Simon Glass96495d92014-02-26 15:59:24 -0700518
Simon Glassae7123f2015-01-05 20:05:27 -0700519 return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
Simon Glass96495d92014-02-26 15:59:24 -0700520}
521
522/**
523 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
524 * gpio: GPIO number
525 * value: Logical value to be set on the GPIO pin
526 *
527 * This function implements the API that's compatible with current
528 * GPIO API used in U-Boot. The request is forwarded to particular
529 * GPIO driver. Returns 0 on success, negative value on error.
530 */
531int gpio_direction_output(unsigned gpio, int value)
532{
Simon Glassae7123f2015-01-05 20:05:27 -0700533 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700534 int ret;
535
Simon Glassae7123f2015-01-05 20:05:27 -0700536 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700537 if (ret)
538 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700539 ret = check_reserved(&desc, "dir_output");
540 if (ret)
541 return ret;
Simon Glass96495d92014-02-26 15:59:24 -0700542
Simon Glassae7123f2015-01-05 20:05:27 -0700543 return gpio_get_ops(desc.dev)->direction_output(desc.dev,
544 desc.offset, value);
545}
546
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100547static int _gpio_get_value(const struct gpio_desc *desc)
Simon Glassae7123f2015-01-05 20:05:27 -0700548{
549 int value;
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100550
551 value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
552
553 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
554}
555
556int dm_gpio_get_value(const struct gpio_desc *desc)
557{
Simon Glassae7123f2015-01-05 20:05:27 -0700558 int ret;
559
560 ret = check_reserved(desc, "get_value");
561 if (ret)
562 return ret;
563
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100564 return _gpio_get_value(desc);
Simon Glassae7123f2015-01-05 20:05:27 -0700565}
566
Simon Glass17c43f12016-03-06 19:27:51 -0700567int dm_gpio_set_value(const struct gpio_desc *desc, int value)
Simon Glassae7123f2015-01-05 20:05:27 -0700568{
569 int ret;
570
571 ret = check_reserved(desc, "set_value");
572 if (ret)
573 return ret;
574
575 if (desc->flags & GPIOD_ACTIVE_LOW)
576 value = !value;
Neil Armstrong47bd5332020-05-05 10:43:17 +0200577
578 /*
579 * Emulate open drain by not actively driving the line high or
580 * Emulate open source by not actively driving the line low
581 */
582 if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
583 (desc->flags & GPIOD_OPEN_SOURCE && !value))
584 return gpio_get_ops(desc->dev)->direction_input(desc->dev,
585 desc->offset);
586 else if (desc->flags & GPIOD_OPEN_DRAIN ||
587 desc->flags & GPIOD_OPEN_SOURCE)
588 return gpio_get_ops(desc->dev)->direction_output(desc->dev,
589 desc->offset,
590 value);
591
Simon Glassae7123f2015-01-05 20:05:27 -0700592 gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
593 return 0;
594}
595
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100596/* check dir flags invalid configuration */
597static int check_dir_flags(ulong flags)
598{
599 if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
600 log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
601 __func__, flags);
602 return -EINVAL;
603 }
604
Patrick Delaunay477ca572020-01-13 11:35:07 +0100605 if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
606 log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
607 __func__, flags);
608 return -EINVAL;
609 }
610
611 if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
612 log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
613 __func__, flags);
614 return -EINVAL;
615 }
616
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100617 return 0;
618}
619
Patrick Delaunay788ea832020-01-13 11:35:03 +0100620static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
Simon Glassae7123f2015-01-05 20:05:27 -0700621{
622 struct udevice *dev = desc->dev;
623 struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100624 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Patrick Delaunay788ea832020-01-13 11:35:03 +0100625 int ret = 0;
Simon Glassae7123f2015-01-05 20:05:27 -0700626
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100627 ret = check_dir_flags(flags);
628 if (ret) {
629 dev_dbg(dev,
630 "%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
631 desc->dev->name,
632 uc_priv->bank_name ? uc_priv->bank_name : "",
633 desc->offset, flags);
634
635 return ret;
636 }
637
Patrick Delaunay8fd9daf2020-01-13 11:35:09 +0100638 /* GPIOD_ are directly managed by driver in set_dir_flags*/
639 if (ops->set_dir_flags) {
640 ret = ops->set_dir_flags(dev, desc->offset, flags);
641 } else {
642 if (flags & GPIOD_IS_OUT) {
643 ret = ops->direction_output(dev, desc->offset,
644 GPIOD_FLAGS_OUTPUT(flags));
645 } else if (flags & GPIOD_IS_IN) {
646 ret = ops->direction_input(dev, desc->offset);
647 }
Simon Glassae7123f2015-01-05 20:05:27 -0700648 }
Patrick Delaunay788ea832020-01-13 11:35:03 +0100649
Heiko Schochercd2faeb2020-05-22 11:08:56 +0200650 /* save the flags also in descriptor */
651 if (!ret)
652 desc->flags = flags;
653
Patrick Delaunay788ea832020-01-13 11:35:03 +0100654 return ret;
655}
656
657int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
658{
659 int ret;
660
661 ret = check_reserved(desc, "set_dir_flags");
Simon Glassae7123f2015-01-05 20:05:27 -0700662 if (ret)
663 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700664
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100665 /* combine the requested flags (for IN/OUT) and the descriptor flags */
666 flags |= desc->flags;
Patrick Delaunay788ea832020-01-13 11:35:03 +0100667 ret = _dm_gpio_set_dir_flags(desc, flags);
668
Patrick Delaunay788ea832020-01-13 11:35:03 +0100669 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700670}
671
672int dm_gpio_set_dir(struct gpio_desc *desc)
673{
Patrick Delaunay788ea832020-01-13 11:35:03 +0100674 int ret;
675
676 ret = check_reserved(desc, "set_dir");
677 if (ret)
678 return ret;
679
680 return _dm_gpio_set_dir_flags(desc, desc->flags);
Simon Glass96495d92014-02-26 15:59:24 -0700681}
682
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100683int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
684{
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100685 struct udevice *dev = desc->dev;
686 int ret, value;
687 struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100688 ulong dir_flags;
689
690 ret = check_reserved(desc, "get_dir_flags");
691 if (ret)
692 return ret;
693
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100694 /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
695 if (ops->get_dir_flags) {
696 ret = ops->get_dir_flags(dev, desc->offset, &dir_flags);
697 if (ret)
698 return ret;
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100699
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100700 /* GPIOD_ACTIVE_LOW is saved in desc->flags */
701 value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
702 if (desc->flags & GPIOD_ACTIVE_LOW)
703 value = !value;
704 dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
705 dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW);
706 if (value)
707 dir_flags |= GPIOD_IS_OUT_ACTIVE;
708 } else {
709 dir_flags = desc->flags;
710 /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
711 dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
712 if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
713 dir_flags |= GPIOD_IS_OUT_ACTIVE;
714 }
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100715 *flags = dir_flags;
716
717 return 0;
718}
719
Simon Glass96495d92014-02-26 15:59:24 -0700720/**
721 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
722 * gpio: GPIO number
723 *
724 * This function implements the API that's compatible with current
725 * GPIO API used in U-Boot. The request is forwarded to particular
726 * GPIO driver. Returns the value of the GPIO pin, or negative value
727 * on error.
728 */
729int gpio_get_value(unsigned gpio)
730{
Simon Glass96495d92014-02-26 15:59:24 -0700731 int ret;
732
Simon Glassae7123f2015-01-05 20:05:27 -0700733 struct gpio_desc desc;
734
735 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700736 if (ret)
737 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700738 return dm_gpio_get_value(&desc);
Simon Glass96495d92014-02-26 15:59:24 -0700739}
740
741/**
742 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
743 * gpio: GPIO number
744 * value: Logical value to be set on the GPIO pin.
745 *
746 * This function implements the API that's compatible with current
747 * GPIO API used in U-Boot. The request is forwarded to particular
748 * GPIO driver. Returns 0 on success, negative value on error.
749 */
750int gpio_set_value(unsigned gpio, int value)
751{
Simon Glassae7123f2015-01-05 20:05:27 -0700752 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700753 int ret;
754
Simon Glassae7123f2015-01-05 20:05:27 -0700755 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700756 if (ret)
757 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700758 return dm_gpio_set_value(&desc, value);
Simon Glass96495d92014-02-26 15:59:24 -0700759}
760
Heiko Schocher54c5d082014-05-22 12:43:05 +0200761const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
Simon Glass96495d92014-02-26 15:59:24 -0700762{
763 struct gpio_dev_priv *priv;
764
765 /* Must be called on an active device */
Simon Glasse564f052015-03-05 12:25:20 -0700766 priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -0700767 assert(priv);
768
769 *bit_count = priv->gpio_count;
770 return priv->bank_name;
771}
772
Simon Glass6449a502014-10-04 11:29:43 -0600773static const char * const gpio_function[GPIOF_COUNT] = {
774 "input",
775 "output",
776 "unused",
777 "unknown",
778 "func",
779};
780
Masahiro Yamadafb07f972017-06-22 16:50:25 +0900781static int get_function(struct udevice *dev, int offset, bool skip_unused,
782 const char **namep)
Simon Glass6449a502014-10-04 11:29:43 -0600783{
Simon Glasse564f052015-03-05 12:25:20 -0700784 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass6449a502014-10-04 11:29:43 -0600785 struct dm_gpio_ops *ops = gpio_get_ops(dev);
786
787 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
788 if (!device_active(dev))
789 return -ENODEV;
790 if (offset < 0 || offset >= uc_priv->gpio_count)
791 return -EINVAL;
792 if (namep)
793 *namep = uc_priv->name[offset];
794 if (skip_unused && !uc_priv->name[offset])
795 return GPIOF_UNUSED;
796 if (ops->get_function) {
797 int ret;
798
799 ret = ops->get_function(dev, offset);
800 if (ret < 0)
801 return ret;
802 if (ret >= ARRAY_SIZE(gpio_function))
803 return -ENODATA;
804 return ret;
805 }
806
807 return GPIOF_UNKNOWN;
808}
809
810int gpio_get_function(struct udevice *dev, int offset, const char **namep)
811{
812 return get_function(dev, offset, true, namep);
813}
814
815int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
816{
817 return get_function(dev, offset, false, namep);
818}
819
Simon Glass07575352014-10-04 11:29:44 -0600820int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
821{
822 struct dm_gpio_ops *ops = gpio_get_ops(dev);
823 struct gpio_dev_priv *priv;
824 char *str = buf;
825 int func;
826 int ret;
827 int len;
828
829 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
830
831 *buf = 0;
Simon Glasse564f052015-03-05 12:25:20 -0700832 priv = dev_get_uclass_priv(dev);
Simon Glass07575352014-10-04 11:29:44 -0600833 ret = gpio_get_raw_function(dev, offset, NULL);
834 if (ret < 0)
835 return ret;
836 func = ret;
837 len = snprintf(str, buffsize, "%s%d: %s",
838 priv->bank_name ? priv->bank_name : "",
839 offset, gpio_function[func]);
840 if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
841 func == GPIOF_UNUSED) {
842 const char *label;
843 bool used;
844
845 ret = ops->get_value(dev, offset);
846 if (ret < 0)
847 return ret;
848 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
849 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
850 ret,
851 used ? 'x' : ' ',
852 used ? " " : "",
853 label ? label : "");
854 }
855
856 return 0;
857}
858
Simon Glass29126862020-07-07 13:11:44 -0600859#if CONFIG_IS_ENABLED(ACPIGEN)
860int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
861{
862 struct dm_gpio_ops *ops;
863
864 memset(gpio, '\0', sizeof(*gpio));
865 if (!dm_gpio_is_valid(desc)) {
866 /* Indicate that the GPIO is not valid */
867 gpio->pin_count = 0;
868 gpio->pins[0] = 0;
869 return -EINVAL;
870 }
871
872 ops = gpio_get_ops(desc->dev);
873 if (!ops->get_acpi)
874 return -ENOSYS;
875
876 return ops->get_acpi(desc, gpio);
877}
878#endif
879
Simon Glass962f5ca2015-04-14 21:03:20 -0600880int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
881{
882 int i, ret;
883 int gpio;
884
885 for (i = 0; i < 32; i++) {
886 gpio = gpio_num_array[i];
887 if (gpio == -1)
888 break;
889 ret = gpio_requestf(gpio, fmt, i);
890 if (ret)
891 goto err;
892 ret = gpio_direction_input(gpio);
893 if (ret) {
894 gpio_free(gpio);
895 goto err;
896 }
897 }
898
899 return 0;
900err:
901 for (i--; i >= 0; i--)
902 gpio_free(gpio_num_array[i]);
903
904 return ret;
905}
906
Simon Glasse5901c92014-11-10 18:00:21 -0700907/*
908 * get a number comprised of multiple GPIO values. gpio_num_array points to
909 * the array of gpio pin numbers to scan, terminated by -1.
910 */
Simon Glass962f5ca2015-04-14 21:03:20 -0600911int gpio_get_values_as_int(const int *gpio_list)
Simon Glasse5901c92014-11-10 18:00:21 -0700912{
913 int gpio;
914 unsigned bitmask = 1;
915 unsigned vector = 0;
Simon Glass962f5ca2015-04-14 21:03:20 -0600916 int ret;
Simon Glasse5901c92014-11-10 18:00:21 -0700917
918 while (bitmask &&
Simon Glass962f5ca2015-04-14 21:03:20 -0600919 ((gpio = *gpio_list++) != -1)) {
920 ret = gpio_get_value(gpio);
921 if (ret < 0)
922 return ret;
923 else if (ret)
Simon Glasse5901c92014-11-10 18:00:21 -0700924 vector |= bitmask;
925 bitmask <<= 1;
926 }
Simon Glass962f5ca2015-04-14 21:03:20 -0600927
Simon Glasse5901c92014-11-10 18:00:21 -0700928 return vector;
929}
930
Simon Glass17c43f12016-03-06 19:27:51 -0700931int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
Simon Glassbbf24782016-03-06 19:27:50 -0700932{
933 unsigned bitmask = 1;
934 unsigned vector = 0;
935 int ret, i;
936
937 for (i = 0; i < count; i++) {
938 ret = dm_gpio_get_value(&desc_list[i]);
939 if (ret < 0)
940 return ret;
941 else if (ret)
942 vector |= bitmask;
943 bitmask <<= 1;
944 }
945
946 return vector;
947}
948
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200949/**
950 * gpio_request_tail: common work for requesting a gpio.
951 *
952 * ret: return value from previous work in function which calls
953 * this function.
954 * This seems bogus (why calling this function instead not
955 * calling it and end caller function instead?).
956 * Because on error in caller function we want to set some
957 * default values in gpio desc and have a common error
958 * debug message, which provides this function.
959 * nodename: Name of node for which gpio gets requested
960 * used for gpio label name.
961 * args: pointer to output arguments structure
962 * list_name: Name of GPIO list
963 * used for gpio label name.
964 * index: gpio index in gpio list
965 * used for gpio label name.
966 * desc: pointer to gpio descriptor, filled from this
967 * function.
968 * flags: gpio flags to use.
969 * add_index: should index added to gpio label name
970 * gpio_dev: pointer to gpio device from which the gpio
971 * will be requested. If NULL try to get the
972 * gpio device with uclass_get_device_by_ofnode()
973 *
974 * return: In error case this function sets default values in
975 * gpio descriptor, also emmits a debug message.
976 * On success it returns 0 else the error code from
977 * function calls, or the error code passed through
978 * ret to this function.
979 *
980 */
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200981static int gpio_request_tail(int ret, const char *nodename,
Simon Glass3a571232017-05-18 20:09:18 -0600982 struct ofnode_phandle_args *args,
983 const char *list_name, int index,
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200984 struct gpio_desc *desc, int flags,
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200985 bool add_index, struct udevice *gpio_dev)
Simon Glass3669e0e2015-01-05 20:05:29 -0700986{
Patrick Delaunay9f2b0662020-01-13 11:35:01 +0100987 gpio_desc_init(desc, gpio_dev, 0);
Simon Glass3a571232017-05-18 20:09:18 -0600988 if (ret)
Simon Glass3669e0e2015-01-05 20:05:29 -0700989 goto err;
Simon Glass3669e0e2015-01-05 20:05:29 -0700990
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200991 if (!desc->dev) {
992 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
993 &desc->dev);
994 if (ret) {
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200995 debug("%s: uclass_get_device_by_ofnode failed\n",
996 __func__);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200997 goto err;
998 }
Simon Glass3669e0e2015-01-05 20:05:29 -0700999 }
Simon Glass3a571232017-05-18 20:09:18 -06001000 ret = gpio_find_and_xlate(desc, args);
Simon Glass3669e0e2015-01-05 20:05:29 -07001001 if (ret) {
1002 debug("%s: gpio_find_and_xlate failed\n", __func__);
1003 goto err;
1004 }
1005 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001006 nodename, list_name, index);
Simon Glass3669e0e2015-01-05 20:05:29 -07001007 if (ret) {
1008 debug("%s: dm_gpio_requestf failed\n", __func__);
1009 goto err;
1010 }
Patrick Delaunay695e5fd2020-01-13 11:35:06 +01001011 ret = dm_gpio_set_dir_flags(desc, flags);
Simon Glass3669e0e2015-01-05 20:05:29 -07001012 if (ret) {
1013 debug("%s: dm_gpio_set_dir failed\n", __func__);
1014 goto err;
1015 }
1016
1017 return 0;
1018err:
1019 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001020 __func__, nodename, list_name, index, ret);
Simon Glass3669e0e2015-01-05 20:05:29 -07001021 return ret;
1022}
1023
Simon Glass150c5af2017-05-30 21:47:09 -06001024static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
1025 int index, struct gpio_desc *desc,
1026 int flags, bool add_index)
Simon Glass3a571232017-05-18 20:09:18 -06001027{
1028 struct ofnode_phandle_args args;
1029 int ret;
1030
Simon Glass150c5af2017-05-30 21:47:09 -06001031 ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
1032 index, &args);
Simon Glass3a571232017-05-18 20:09:18 -06001033
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001034 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1035 index, desc, flags, add_index, NULL);
Simon Glass3a571232017-05-18 20:09:18 -06001036}
1037
Simon Glass150c5af2017-05-30 21:47:09 -06001038int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
Simon Glass3669e0e2015-01-05 20:05:29 -07001039 struct gpio_desc *desc, int flags)
1040{
Simon Glass150c5af2017-05-30 21:47:09 -06001041 return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
1042 index > 0);
Simon Glass3669e0e2015-01-05 20:05:29 -07001043}
1044
Simon Glass150c5af2017-05-30 21:47:09 -06001045int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
Simon Glass3669e0e2015-01-05 20:05:29 -07001046 struct gpio_desc *desc, int flags)
1047{
Simon Glass150c5af2017-05-30 21:47:09 -06001048 struct ofnode_phandle_args args;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001049 ofnode node;
Simon Glass150c5af2017-05-30 21:47:09 -06001050 int ret;
1051
1052 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
1053 index, &args);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001054 node = dev_ofnode(dev);
1055 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1056 index, desc, flags, index > 0, NULL);
Simon Glass3669e0e2015-01-05 20:05:29 -07001057}
1058
Simon Glass150c5af2017-05-30 21:47:09 -06001059int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
Simon Glass3669e0e2015-01-05 20:05:29 -07001060 struct gpio_desc *desc, int max_count,
1061 int flags)
1062{
1063 int count;
1064 int ret;
1065
Przemyslaw Marczak2984e7a2015-03-31 18:57:16 +02001066 for (count = 0; count < max_count; count++) {
Simon Glass150c5af2017-05-30 21:47:09 -06001067 ret = _gpio_request_by_name_nodev(node, list_name, count,
Simon Glass3669e0e2015-01-05 20:05:29 -07001068 &desc[count], flags, true);
1069 if (ret == -ENOENT)
1070 break;
1071 else if (ret)
1072 goto err;
1073 }
1074
1075 /* We ran out of GPIOs in the list */
1076 return count;
1077
1078err:
1079 gpio_free_list_nodev(desc, count - 1);
1080
1081 return ret;
1082}
1083
1084int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
1085 struct gpio_desc *desc, int max_count,
1086 int flags)
1087{
1088 /*
1089 * This isn't ideal since we don't use dev->name in the debug()
1090 * calls in gpio_request_by_name(), but we can do this until
1091 * gpio_request_list_by_name_nodev() can be dropped.
1092 */
Simon Glass150c5af2017-05-30 21:47:09 -06001093 return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
1094 max_count, flags);
Simon Glass3669e0e2015-01-05 20:05:29 -07001095}
1096
1097int gpio_get_list_count(struct udevice *dev, const char *list_name)
1098{
1099 int ret;
1100
Simon Glasse160f7d2017-01-17 16:52:55 -07001101 ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
Simon Glass3669e0e2015-01-05 20:05:29 -07001102 list_name, "#gpio-cells", 0, -1,
1103 NULL);
1104 if (ret) {
1105 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
1106 __func__, dev->name, list_name, ret);
1107 }
1108
1109 return ret;
1110}
1111
1112int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
1113{
1114 /* For now, we don't do any checking of dev */
1115 return _dm_gpio_free(desc->dev, desc->offset);
1116}
1117
1118int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
1119{
1120 int i;
1121
1122 /* For now, we don't do any checking of dev */
1123 for (i = 0; i < count; i++)
1124 dm_gpio_free(dev, &desc[i]);
1125
1126 return 0;
1127}
1128
1129int gpio_free_list_nodev(struct gpio_desc *desc, int count)
1130{
1131 return gpio_free_list(NULL, desc, count);
1132}
1133
Simon Glass96495d92014-02-26 15:59:24 -07001134/* We need to renumber the GPIOs when any driver is probed/removed */
Simon Glassb892d122014-10-04 11:29:42 -06001135static int gpio_renumber(struct udevice *removed_dev)
Simon Glass96495d92014-02-26 15:59:24 -07001136{
1137 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +02001138 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -07001139 struct uclass *uc;
1140 unsigned base;
1141 int ret;
1142
1143 ret = uclass_get(UCLASS_GPIO, &uc);
1144 if (ret)
1145 return ret;
1146
1147 /* Ensure that we have a base for each bank */
1148 base = 0;
1149 uclass_foreach_dev(dev, uc) {
Simon Glassb892d122014-10-04 11:29:42 -06001150 if (device_active(dev) && dev != removed_dev) {
Simon Glasse564f052015-03-05 12:25:20 -07001151 uc_priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -07001152 uc_priv->gpio_base = base;
1153 base += uc_priv->gpio_count;
1154 }
1155 }
1156
1157 return 0;
1158}
1159
Simon Glass17c43f12016-03-06 19:27:51 -07001160int gpio_get_number(const struct gpio_desc *desc)
Simon Glass56a71f82015-03-25 12:21:58 -06001161{
1162 struct udevice *dev = desc->dev;
1163 struct gpio_dev_priv *uc_priv;
1164
1165 if (!dev)
1166 return -1;
1167 uc_priv = dev->uclass_priv;
1168
1169 return uc_priv->gpio_base + desc->offset;
1170}
1171
Heiko Schocher54c5d082014-05-22 12:43:05 +02001172static int gpio_post_probe(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -07001173{
Simon Glasse564f052015-03-05 12:25:20 -07001174 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -06001175
1176 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
1177 if (!uc_priv->name)
1178 return -ENOMEM;
1179
1180 return gpio_renumber(NULL);
Simon Glass96495d92014-02-26 15:59:24 -07001181}
1182
Heiko Schocher54c5d082014-05-22 12:43:05 +02001183static int gpio_pre_remove(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -07001184{
Simon Glasse564f052015-03-05 12:25:20 -07001185 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -06001186 int i;
1187
1188 for (i = 0; i < uc_priv->gpio_count; i++) {
1189 if (uc_priv->name[i])
1190 free(uc_priv->name[i]);
1191 }
1192 free(uc_priv->name);
1193
1194 return gpio_renumber(dev);
Simon Glass96495d92014-02-26 15:59:24 -07001195}
1196
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001197int gpio_dev_request_index(struct udevice *dev, const char *nodename,
1198 char *list_name, int index, int flags,
1199 int dtflags, struct gpio_desc *desc)
1200{
1201 struct ofnode_phandle_args args;
1202
1203 args.node = ofnode_null();
1204 args.args_count = 2;
1205 args.args[0] = index;
1206 args.args[1] = dtflags;
1207
1208 return gpio_request_tail(0, nodename, &args, list_name, index, desc,
1209 flags, 0, dev);
1210}
1211
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001212static int gpio_post_bind(struct udevice *dev)
1213{
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001214 struct udevice *child;
1215 ofnode node;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001216
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001217#if defined(CONFIG_NEEDS_MANUAL_RELOC)
1218 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
1219 static int reloc_done;
1220
1221 if (!reloc_done) {
1222 if (ops->request)
1223 ops->request += gd->reloc_off;
Simon Glass093152f2020-02-04 20:15:17 -07001224 if (ops->rfree)
1225 ops->rfree += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001226 if (ops->direction_input)
1227 ops->direction_input += gd->reloc_off;
1228 if (ops->direction_output)
1229 ops->direction_output += gd->reloc_off;
1230 if (ops->get_value)
1231 ops->get_value += gd->reloc_off;
1232 if (ops->set_value)
1233 ops->set_value += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001234 if (ops->get_function)
1235 ops->get_function += gd->reloc_off;
1236 if (ops->xlate)
1237 ops->xlate += gd->reloc_off;
Patrick Delaunay8fd9daf2020-01-13 11:35:09 +01001238 if (ops->set_dir_flags)
1239 ops->set_dir_flags += gd->reloc_off;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +01001240 if (ops->get_dir_flags)
1241 ops->get_dir_flags += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001242
1243 reloc_done++;
1244 }
1245#endif
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001246
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001247 if (IS_ENABLED(CONFIG_GPIO_HOG)) {
1248 dev_for_each_subnode(node, dev) {
1249 if (ofnode_read_bool(node, "gpio-hog")) {
1250 const char *name = ofnode_get_name(node);
1251 int ret;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001252
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001253 ret = device_bind_driver_to_node(dev,
1254 "gpio_hog",
1255 name, node,
1256 &child);
1257 if (ret)
1258 return ret;
1259 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001260 }
1261 }
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001262 return 0;
1263}
1264
Simon Glass96495d92014-02-26 15:59:24 -07001265UCLASS_DRIVER(gpio) = {
1266 .id = UCLASS_GPIO,
1267 .name = "gpio",
Bhuvanchandra DVae89bb02015-06-01 18:37:15 +05301268 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass96495d92014-02-26 15:59:24 -07001269 .post_probe = gpio_post_probe,
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001270 .post_bind = gpio_post_bind,
Simon Glass96495d92014-02-26 15:59:24 -07001271 .pre_remove = gpio_pre_remove,
1272 .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
1273};