blob: 712119c3415b8fb9bbf410d4da30ae07bdf3095a [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
Simon Glassbe04f1a2021-02-04 21:22:08 -07006#define LOG_CATEGORY UCLASS_GPIO
7
Simon Glass96495d92014-02-26 15:59:24 -07008#include <common.h>
9#include <dm.h>
Simon Glass48609d02021-08-07 07:24:12 -060010#include <dt-structs.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060011#include <log.h>
Jean-Jacques Hiblotd4b722e2020-09-11 13:43:34 +053012#include <dm/devres.h>
13#include <dm/device_compat.h>
Heiko Schocher5fc7cf82019-06-12 06:11:46 +020014#include <dm/device-internal.h>
15#include <dm/lists.h>
16#include <dm/uclass-internal.h>
Eric Nelson6c880b72016-04-24 16:32:40 -070017#include <dt-bindings/gpio/gpio.h>
Simon Glass96495d92014-02-26 15:59:24 -070018#include <errno.h>
Simon Glass0dac4d52015-01-05 20:05:28 -070019#include <fdtdec.h>
Simon Glassb892d122014-10-04 11:29:42 -060020#include <malloc.h>
Simon Glass29126862020-07-07 13:11:44 -060021#include <acpi/acpi_device.h>
Simon Glass401d1c42020-10-30 21:38:53 -060022#include <asm/global_data.h>
Simon Glass96495d92014-02-26 15:59:24 -070023#include <asm/gpio.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060024#include <dm/device_compat.h>
Masahiro Yamada84b8bf62016-01-24 23:27:48 +090025#include <linux/bug.h>
Simon Glassfe1ef502014-10-22 21:37:01 -060026#include <linux/ctype.h>
Simon Glass8a45b222021-02-04 21:22:09 -070027#include <linux/delay.h>
Simon Glass96495d92014-02-26 15:59:24 -070028
Simon Glass3669e0e2015-01-05 20:05:29 -070029DECLARE_GLOBAL_DATA_PTR;
30
Simon Glass96495d92014-02-26 15:59:24 -070031/**
Patrick Delaunay9f2b0662020-01-13 11:35:01 +010032 * gpio_desc_init() - Initialize the GPIO descriptor
33 *
34 * @desc: GPIO descriptor to initialize
35 * @dev: GPIO device
36 * @offset: Offset of device GPIO
37 */
38static void gpio_desc_init(struct gpio_desc *desc,
39 struct udevice *dev,
40 uint offset)
41{
42 desc->dev = dev;
43 desc->offset = offset;
44 desc->flags = 0;
45}
46
47/**
Simon Glass96495d92014-02-26 15:59:24 -070048 * gpio_to_device() - Convert global GPIO number to device, number
Simon Glass96495d92014-02-26 15:59:24 -070049 *
50 * Convert the GPIO number to an entry in the list of GPIOs
51 * or GPIO blocks registered with the GPIO controller. Returns
52 * entry on success, NULL on error.
Simon Glassae7123f2015-01-05 20:05:27 -070053 *
54 * @gpio: The numeric representation of the GPIO
55 * @desc: Returns description (desc->flags will always be 0)
Heinrich Schuchardt185f8122022-01-19 18:05:50 +010056 * Return: 0 if found, -ENOENT if not found
Simon Glass96495d92014-02-26 15:59:24 -070057 */
Simon Glassae7123f2015-01-05 20:05:27 -070058static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
Simon Glass96495d92014-02-26 15:59:24 -070059{
60 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +020061 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -070062
Michal Suchanek49549372022-10-12 21:58:08 +020063 for (uclass_first_device(UCLASS_GPIO, &dev);
Simon Glass96495d92014-02-26 15:59:24 -070064 dev;
Michal Suchanek49549372022-10-12 21:58:08 +020065 uclass_next_device(&dev)) {
Simon Glasse564f052015-03-05 12:25:20 -070066 uc_priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -070067 if (gpio >= uc_priv->gpio_base &&
68 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
Patrick Delaunay9f2b0662020-01-13 11:35:01 +010069 gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
Simon Glass96495d92014-02-26 15:59:24 -070070 return 0;
71 }
72 }
73
74 /* No such GPIO */
Michal Suchanek49549372022-10-12 21:58:08 +020075 return -ENOENT;
Simon Glass96495d92014-02-26 15:59:24 -070076}
77
Heiko Schocher2bd261d2020-05-22 11:08:59 +020078#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL)
79/**
80 * dm_gpio_lookup_label() - look for name in gpio device
81 *
82 * search in uc_priv, if there is a gpio with labelname same
83 * as name.
84 *
85 * @name: name which is searched
86 * @uc_priv: gpio_dev_priv pointer.
87 * @offset: gpio offset within the device
88 * @return: 0 if found, -ENOENT if not.
89 */
90static int dm_gpio_lookup_label(const char *name,
91 struct gpio_dev_priv *uc_priv, ulong *offset)
92{
Heiko Schocher2bd261d2020-05-22 11:08:59 +020093 int i;
94
95 *offset = -1;
Heiko Schocher2bd261d2020-05-22 11:08:59 +020096 for (i = 0; i < uc_priv->gpio_count; i++) {
97 if (!uc_priv->name[i])
98 continue;
Rasmus Villemoes10e66442022-10-03 11:02:45 +020099 if (!strcmp(name, uc_priv->name[i])) {
Heiko Schocher2bd261d2020-05-22 11:08:59 +0200100 *offset = i;
101 return 0;
102 }
103 }
104 return -ENOENT;
105}
106#else
107static int
108dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv,
109 ulong *offset)
110{
111 return -ENOENT;
112}
113#endif
114
Simon Glass32ec1592015-06-23 15:38:40 -0600115int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
Simon Glass96495d92014-02-26 15:59:24 -0700116{
Simon Glassfe1ef502014-10-22 21:37:01 -0600117 struct gpio_dev_priv *uc_priv = NULL;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200118 struct udevice *dev;
Simon Glassfe1ef502014-10-22 21:37:01 -0600119 ulong offset;
120 int numeric;
Simon Glass96495d92014-02-26 15:59:24 -0700121
Simon Glass0b1284e2021-07-24 09:03:30 -0600122 numeric = isdigit(*name) ? dectoul(name, NULL) : -1;
Michal Suchanek49549372022-10-12 21:58:08 +0200123 for (uclass_first_device(UCLASS_GPIO, &dev);
Simon Glass96495d92014-02-26 15:59:24 -0700124 dev;
Michal Suchanek49549372022-10-12 21:58:08 +0200125 uclass_next_device(&dev)) {
Simon Glass96495d92014-02-26 15:59:24 -0700126 int len;
127
Simon Glasse564f052015-03-05 12:25:20 -0700128 uc_priv = dev_get_uclass_priv(dev);
Simon Glassfe1ef502014-10-22 21:37:01 -0600129 if (numeric != -1) {
130 offset = numeric - uc_priv->gpio_base;
131 /* Allow GPIOs to be numbered from 0 */
Tom Rini75897912017-05-10 15:20:15 -0400132 if (offset < uc_priv->gpio_count)
Simon Glassfe1ef502014-10-22 21:37:01 -0600133 break;
134 }
135
Simon Glass96495d92014-02-26 15:59:24 -0700136 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
137
Simon Glass939cda52014-06-11 23:29:47 -0600138 if (!strncasecmp(name, uc_priv->bank_name, len)) {
Simon Glassfe1ef502014-10-22 21:37:01 -0600139 if (!strict_strtoul(name + len, 10, &offset))
Samuel Holland390ccff2021-09-11 17:05:51 -0500140 if (offset < uc_priv->gpio_count)
141 break;
Simon Glass96495d92014-02-26 15:59:24 -0700142 }
Heiko Schocher2bd261d2020-05-22 11:08:59 +0200143
144 /*
145 * if we did not found a gpio through its bank
146 * name, we search for a valid gpio label.
147 */
148 if (!dm_gpio_lookup_label(name, uc_priv, &offset))
149 break;
Simon Glass96495d92014-02-26 15:59:24 -0700150 }
151
Simon Glassfe1ef502014-10-22 21:37:01 -0600152 if (!dev)
Michal Suchanek49549372022-10-12 21:58:08 +0200153 return -EINVAL;
Simon Glassfe1ef502014-10-22 21:37:01 -0600154
Patrick Delaunay9f2b0662020-01-13 11:35:01 +0100155 gpio_desc_init(desc, dev, offset);
Simon Glass32ec1592015-06-23 15:38:40 -0600156
157 return 0;
158}
159
160int gpio_lookup_name(const char *name, struct udevice **devp,
161 unsigned int *offsetp, unsigned int *gpiop)
162{
163 struct gpio_desc desc;
164 int ret;
165
Simon Glassfe1ef502014-10-22 21:37:01 -0600166 if (devp)
Simon Glass32ec1592015-06-23 15:38:40 -0600167 *devp = NULL;
168 ret = dm_gpio_lookup_name(name, &desc);
169 if (ret)
170 return ret;
171
172 if (devp)
173 *devp = desc.dev;
Simon Glassfe1ef502014-10-22 21:37:01 -0600174 if (offsetp)
Simon Glass32ec1592015-06-23 15:38:40 -0600175 *offsetp = desc.offset;
176 if (gpiop) {
177 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
178
179 *gpiop = uc_priv->gpio_base + desc.offset;
180 }
Simon Glassfe1ef502014-10-22 21:37:01 -0600181
182 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700183}
184
Samuel Holland8a479822021-09-11 17:05:53 -0500185unsigned long gpio_flags_xlate(uint32_t arg)
186{
187 unsigned long flags = 0;
188
189 if (arg & GPIO_ACTIVE_LOW)
190 flags |= GPIOD_ACTIVE_LOW;
191
192 /*
193 * need to test 2 bits for gpio output binding:
194 * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
195 * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
196 */
197 if (arg & GPIO_SINGLE_ENDED) {
198 if (arg & GPIO_LINE_OPEN_DRAIN)
199 flags |= GPIOD_OPEN_DRAIN;
200 else
201 flags |= GPIOD_OPEN_SOURCE;
202 }
203
204 if (arg & GPIO_PULL_UP)
205 flags |= GPIOD_PULL_UP;
206
207 if (arg & GPIO_PULL_DOWN)
208 flags |= GPIOD_PULL_DOWN;
209
210 return flags;
211}
212
Simon Glass3a571232017-05-18 20:09:18 -0600213int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
214 struct ofnode_phandle_args *args)
Eric Nelson6c880b72016-04-24 16:32:40 -0700215{
Samuel Holland37c10bf2021-09-11 17:05:52 -0500216 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
217
Eric Nelson6c880b72016-04-24 16:32:40 -0700218 if (args->args_count < 1)
219 return -EINVAL;
220
221 desc->offset = args->args[0];
Samuel Holland37c10bf2021-09-11 17:05:52 -0500222 if (desc->offset >= uc_priv->gpio_count)
223 return -EINVAL;
Eric Nelson6c880b72016-04-24 16:32:40 -0700224
225 if (args->args_count < 2)
226 return 0;
227
Samuel Holland8a479822021-09-11 17:05:53 -0500228 desc->flags = gpio_flags_xlate(args->args[1]);
Patrick Delaunay477ca572020-01-13 11:35:07 +0100229
Eric Nelson6c880b72016-04-24 16:32:40 -0700230 return 0;
231}
232
Simon Glass3669e0e2015-01-05 20:05:29 -0700233static int gpio_find_and_xlate(struct gpio_desc *desc,
Simon Glass3a571232017-05-18 20:09:18 -0600234 struct ofnode_phandle_args *args)
Simon Glass0dac4d52015-01-05 20:05:28 -0700235{
Simon Glass3d647742021-02-04 21:22:05 -0700236 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glass0dac4d52015-01-05 20:05:28 -0700237
Eric Nelson6c880b72016-04-24 16:32:40 -0700238 if (ops->xlate)
239 return ops->xlate(desc->dev, desc, args);
Simon Glass0dac4d52015-01-05 20:05:28 -0700240 else
Eric Nelson6c880b72016-04-24 16:32:40 -0700241 return gpio_xlate_offs_flags(desc->dev, desc, args);
Simon Glass0dac4d52015-01-05 20:05:28 -0700242}
243
Simon Glass48609d02021-08-07 07:24:12 -0600244#if CONFIG_IS_ENABLED(GPIO_HOG)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200245
246struct gpio_hog_priv {
247 struct gpio_desc gpiod;
248};
249
250struct gpio_hog_data {
251 int gpiod_flags;
252 int value;
253 u32 val[2];
254};
255
Simon Glassd1998a92020-12-03 16:55:21 -0700256static int gpio_hog_of_to_plat(struct udevice *dev)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200257{
Simon Glassc69cda22020-12-03 16:55:20 -0700258 struct gpio_hog_data *plat = dev_get_plat(dev);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200259 const char *nodename;
260 int ret;
261
262 plat->value = 0;
263 if (dev_read_bool(dev, "input")) {
264 plat->gpiod_flags = GPIOD_IS_IN;
265 } else if (dev_read_bool(dev, "output-high")) {
266 plat->value = 1;
267 plat->gpiod_flags = GPIOD_IS_OUT;
268 } else if (dev_read_bool(dev, "output-low")) {
269 plat->gpiod_flags = GPIOD_IS_OUT;
270 } else {
271 printf("%s: missing gpio-hog state.\n", __func__);
272 return -EINVAL;
273 }
274 ret = dev_read_u32_array(dev, "gpios", plat->val, 2);
275 if (ret) {
276 printf("%s: wrong gpios property, 2 values needed %d\n",
277 __func__, ret);
278 return ret;
279 }
280 nodename = dev_read_string(dev, "line-name");
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200281 if (nodename)
282 device_set_name(dev, nodename);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200283
284 return 0;
285}
286
287static int gpio_hog_probe(struct udevice *dev)
288{
Simon Glassc69cda22020-12-03 16:55:20 -0700289 struct gpio_hog_data *plat = dev_get_plat(dev);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200290 struct gpio_hog_priv *priv = dev_get_priv(dev);
291 int ret;
292
293 ret = gpio_dev_request_index(dev->parent, dev->name, "gpio-hog",
294 plat->val[0], plat->gpiod_flags,
295 plat->val[1], &priv->gpiod);
296 if (ret < 0) {
297 debug("%s: node %s could not get gpio.\n", __func__,
298 dev->name);
299 return ret;
300 }
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200301
302 if (plat->gpiod_flags == GPIOD_IS_OUT) {
303 ret = dm_gpio_set_value(&priv->gpiod, plat->value);
304 if (ret < 0) {
305 debug("%s: node %s could not set gpio.\n", __func__,
306 dev->name);
307 return ret;
308 }
309 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200310
311 return 0;
312}
313
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200314int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200315{
316 struct udevice *dev;
317
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200318 *desc = NULL;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200319 if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
320 struct gpio_hog_priv *priv = dev_get_priv(dev);
321
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200322 *desc = &priv->gpiod;
323 return 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200324 }
325
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200326 return -ENODEV;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200327}
328
329U_BOOT_DRIVER(gpio_hog) = {
330 .name = "gpio_hog",
331 .id = UCLASS_NOP,
Simon Glassd1998a92020-12-03 16:55:21 -0700332 .of_to_plat = gpio_hog_of_to_plat,
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200333 .probe = gpio_hog_probe,
Simon Glass41575d82020-12-03 16:55:17 -0700334 .priv_auto = sizeof(struct gpio_hog_priv),
Simon Glasscaa4daa2020-12-03 16:55:18 -0700335 .plat_auto = sizeof(struct gpio_hog_data),
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200336};
337#else
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200338int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200339{
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200340 return 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200341}
342#endif
343
Simon Glassefa677f2015-06-23 15:38:41 -0600344int dm_gpio_request(struct gpio_desc *desc, const char *label)
Simon Glassae7123f2015-01-05 20:05:27 -0700345{
Simon Glass3d647742021-02-04 21:22:05 -0700346 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700347 struct udevice *dev = desc->dev;
348 struct gpio_dev_priv *uc_priv;
349 char *str;
350 int ret;
351
Simon Glasse564f052015-03-05 12:25:20 -0700352 uc_priv = dev_get_uclass_priv(dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700353 if (uc_priv->name[desc->offset])
354 return -EBUSY;
355 str = strdup(label);
356 if (!str)
357 return -ENOMEM;
Simon Glass3d647742021-02-04 21:22:05 -0700358 if (ops->request) {
359 ret = ops->request(dev, desc->offset, label);
Simon Glassae7123f2015-01-05 20:05:27 -0700360 if (ret) {
361 free(str);
362 return ret;
363 }
364 }
365 uc_priv->name[desc->offset] = str;
366
367 return 0;
368}
369
Simon Glass3669e0e2015-01-05 20:05:29 -0700370static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
371{
Simon Glass27084c02019-09-25 08:56:27 -0600372#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass3669e0e2015-01-05 20:05:29 -0700373 va_list args;
374 char buf[40];
375
376 va_start(args, fmt);
377 vscnprintf(buf, sizeof(buf), fmt, args);
378 va_end(args);
379 return dm_gpio_request(desc, buf);
Simon Glass4dc52592015-12-29 05:22:48 -0700380#else
381 return dm_gpio_request(desc, fmt);
382#endif
Simon Glass3669e0e2015-01-05 20:05:29 -0700383}
384
Simon Glass96495d92014-02-26 15:59:24 -0700385/**
386 * gpio_request() - [COMPAT] Request GPIO
387 * gpio: GPIO number
388 * label: Name for the requested GPIO
389 *
Simon Glassb892d122014-10-04 11:29:42 -0600390 * The label is copied and allocated so the caller does not need to keep
391 * the pointer around.
392 *
Simon Glass96495d92014-02-26 15:59:24 -0700393 * This function implements the API that's compatible with current
394 * GPIO API used in U-Boot. The request is forwarded to particular
395 * GPIO driver. Returns 0 on success, negative value on error.
396 */
397int gpio_request(unsigned gpio, const char *label)
398{
Simon Glassae7123f2015-01-05 20:05:27 -0700399 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700400 int ret;
401
Simon Glassae7123f2015-01-05 20:05:27 -0700402 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700403 if (ret)
404 return ret;
405
Simon Glassae7123f2015-01-05 20:05:27 -0700406 return dm_gpio_request(&desc, label);
Simon Glass96495d92014-02-26 15:59:24 -0700407}
408
409/**
Simon Glassd44f5972014-10-04 11:29:49 -0600410 * gpio_requestf() - [COMPAT] Request GPIO
411 * @gpio: GPIO number
412 * @fmt: Format string for the requested GPIO
413 * @...: Arguments for the printf() format string
414 *
415 * This function implements the API that's compatible with current
416 * GPIO API used in U-Boot. The request is forwarded to particular
417 * GPIO driver. Returns 0 on success, negative value on error.
418 */
419int gpio_requestf(unsigned gpio, const char *fmt, ...)
420{
Simon Glass27084c02019-09-25 08:56:27 -0600421#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glassd44f5972014-10-04 11:29:49 -0600422 va_list args;
423 char buf[40];
424
425 va_start(args, fmt);
426 vscnprintf(buf, sizeof(buf), fmt, args);
427 va_end(args);
428 return gpio_request(gpio, buf);
Simon Glass4dc52592015-12-29 05:22:48 -0700429#else
430 return gpio_request(gpio, fmt);
431#endif
Simon Glassd44f5972014-10-04 11:29:49 -0600432}
433
Simon Glassae7123f2015-01-05 20:05:27 -0700434int _dm_gpio_free(struct udevice *dev, uint offset)
Simon Glass96495d92014-02-26 15:59:24 -0700435{
Simon Glass3d647742021-02-04 21:22:05 -0700436 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glassb892d122014-10-04 11:29:42 -0600437 struct gpio_dev_priv *uc_priv;
Simon Glass96495d92014-02-26 15:59:24 -0700438 int ret;
439
Simon Glasse564f052015-03-05 12:25:20 -0700440 uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -0600441 if (!uc_priv->name[offset])
442 return -ENXIO;
Simon Glass3d647742021-02-04 21:22:05 -0700443 if (ops->rfree) {
444 ret = ops->rfree(dev, offset);
Simon Glassb892d122014-10-04 11:29:42 -0600445 if (ret)
446 return ret;
447 }
448
449 free(uc_priv->name[offset]);
450 uc_priv->name[offset] = NULL;
451
452 return 0;
453}
454
Simon Glassae7123f2015-01-05 20:05:27 -0700455/**
456 * gpio_free() - [COMPAT] Relinquish GPIO
457 * gpio: GPIO number
458 *
459 * This function implements the API that's compatible with current
460 * GPIO API used in U-Boot. The request is forwarded to particular
461 * GPIO driver. Returns 0 on success, negative value on error.
462 */
463int gpio_free(unsigned gpio)
Simon Glassb892d122014-10-04 11:29:42 -0600464{
Simon Glassae7123f2015-01-05 20:05:27 -0700465 struct gpio_desc desc;
466 int ret;
Simon Glassb892d122014-10-04 11:29:42 -0600467
Simon Glassae7123f2015-01-05 20:05:27 -0700468 ret = gpio_to_device(gpio, &desc);
469 if (ret)
470 return ret;
471
472 return _dm_gpio_free(desc.dev, desc.offset);
473}
474
Simon Glass17c43f12016-03-06 19:27:51 -0700475static int check_reserved(const struct gpio_desc *desc, const char *func)
Simon Glassae7123f2015-01-05 20:05:27 -0700476{
Simon Glasseca48662015-07-02 18:16:16 -0600477 struct gpio_dev_priv *uc_priv;
Simon Glassae7123f2015-01-05 20:05:27 -0700478
Simon Glasseca48662015-07-02 18:16:16 -0600479 if (!dm_gpio_is_valid(desc))
480 return -ENOENT;
481
482 uc_priv = dev_get_uclass_priv(desc->dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700483 if (!uc_priv->name[desc->offset]) {
Simon Glassb892d122014-10-04 11:29:42 -0600484 printf("%s: %s: error: gpio %s%d not reserved\n",
Simon Glassae7123f2015-01-05 20:05:27 -0700485 desc->dev->name, func,
486 uc_priv->bank_name ? uc_priv->bank_name : "",
487 desc->offset);
Simon Glassb892d122014-10-04 11:29:42 -0600488 return -EBUSY;
489 }
490
491 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700492}
493
494/**
495 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
496 * gpio: GPIO number
497 *
498 * This function implements the API that's compatible with current
499 * GPIO API used in U-Boot. The request is forwarded to particular
500 * GPIO driver. Returns 0 on success, negative value on error.
501 */
502int gpio_direction_input(unsigned gpio)
503{
Simon Glassae7123f2015-01-05 20:05:27 -0700504 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700505 int ret;
506
Simon Glassae7123f2015-01-05 20:05:27 -0700507 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700508 if (ret)
509 return ret;
510
Simon Glassca1e1f52021-02-04 21:22:04 -0700511 return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN);
Simon Glass96495d92014-02-26 15:59:24 -0700512}
513
514/**
515 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
516 * gpio: GPIO number
517 * value: Logical value to be set on the GPIO pin
518 *
519 * This function implements the API that's compatible with current
520 * GPIO API used in U-Boot. The request is forwarded to particular
521 * GPIO driver. Returns 0 on success, negative value on error.
522 */
523int gpio_direction_output(unsigned gpio, int value)
524{
Simon Glassae7123f2015-01-05 20:05:27 -0700525 struct gpio_desc desc;
Simon Glassca1e1f52021-02-04 21:22:04 -0700526 ulong flags;
Simon Glass96495d92014-02-26 15:59:24 -0700527 int ret;
528
Simon Glassae7123f2015-01-05 20:05:27 -0700529 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700530 if (ret)
531 return ret;
532
Simon Glassca1e1f52021-02-04 21:22:04 -0700533 flags = GPIOD_IS_OUT;
534 if (value)
535 flags |= GPIOD_IS_OUT_ACTIVE;
536 return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, flags);
Simon Glassae7123f2015-01-05 20:05:27 -0700537}
538
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100539static int _gpio_get_value(const struct gpio_desc *desc)
Simon Glassae7123f2015-01-05 20:05:27 -0700540{
Simon Glass3d647742021-02-04 21:22:05 -0700541 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700542 int value;
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100543
Simon Glass3d647742021-02-04 21:22:05 -0700544 value = ops->get_value(desc->dev, desc->offset);
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100545
546 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
547}
548
549int dm_gpio_get_value(const struct gpio_desc *desc)
550{
Simon Glassae7123f2015-01-05 20:05:27 -0700551 int ret;
552
553 ret = check_reserved(desc, "get_value");
554 if (ret)
555 return ret;
556
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100557 return _gpio_get_value(desc);
Simon Glassae7123f2015-01-05 20:05:27 -0700558}
559
Simon Glass17c43f12016-03-06 19:27:51 -0700560int dm_gpio_set_value(const struct gpio_desc *desc, int value)
Simon Glassae7123f2015-01-05 20:05:27 -0700561{
Simon Glass7e0a96d2021-02-04 21:22:03 -0700562 const struct dm_gpio_ops *ops;
Simon Glassae7123f2015-01-05 20:05:27 -0700563 int ret;
564
565 ret = check_reserved(desc, "set_value");
566 if (ret)
567 return ret;
568
569 if (desc->flags & GPIOD_ACTIVE_LOW)
570 value = !value;
Neil Armstrong47bd5332020-05-05 10:43:17 +0200571
Simon Glass7e0a96d2021-02-04 21:22:03 -0700572 /* GPIOD_ are directly managed by driver in set_flags */
573 ops = gpio_get_ops(desc->dev);
574 if (ops->set_flags) {
575 ulong flags = desc->flags;
576
577 if (value)
578 flags |= GPIOD_IS_OUT_ACTIVE;
579 else
580 flags &= ~GPIOD_IS_OUT_ACTIVE;
581 return ops->set_flags(desc->dev, desc->offset, flags);
582 }
583
Neil Armstrong47bd5332020-05-05 10:43:17 +0200584 /*
585 * Emulate open drain by not actively driving the line high or
586 * Emulate open source by not actively driving the line low
587 */
588 if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
589 (desc->flags & GPIOD_OPEN_SOURCE && !value))
Simon Glass7e0a96d2021-02-04 21:22:03 -0700590 return ops->direction_input(desc->dev, desc->offset);
Neil Armstrong47bd5332020-05-05 10:43:17 +0200591 else if (desc->flags & GPIOD_OPEN_DRAIN ||
592 desc->flags & GPIOD_OPEN_SOURCE)
Simon Glass7e0a96d2021-02-04 21:22:03 -0700593 return ops->direction_output(desc->dev, desc->offset, value);
Neil Armstrong47bd5332020-05-05 10:43:17 +0200594
Simon Glass7e0a96d2021-02-04 21:22:03 -0700595 ret = ops->set_value(desc->dev, desc->offset, value);
596 if (ret)
597 return ret;
598
Simon Glassae7123f2015-01-05 20:05:27 -0700599 return 0;
600}
601
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100602/* check dir flags invalid configuration */
603static int check_dir_flags(ulong flags)
604{
605 if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
606 log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
607 __func__, flags);
608 return -EINVAL;
609 }
610
Patrick Delaunay477ca572020-01-13 11:35:07 +0100611 if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
612 log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
613 __func__, flags);
614 return -EINVAL;
615 }
616
617 if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
618 log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
619 __func__, flags);
620 return -EINVAL;
621 }
622
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100623 return 0;
624}
625
Simon Glass7e0a96d2021-02-04 21:22:03 -0700626/**
627 * _dm_gpio_set_flags() - Send flags to the driver
628 *
629 * This uses the best available method to send the given flags to the driver.
630 * Note that if flags & GPIOD_ACTIVE_LOW, the driver sees the opposite value
631 * of GPIOD_IS_OUT_ACTIVE.
632 *
633 * @desc: GPIO description
634 * @flags: flags value to set
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100635 * Return: 0 if OK, -ve on error
Simon Glass7e0a96d2021-02-04 21:22:03 -0700636 */
Simon Glass13979fc2021-02-04 21:21:55 -0700637static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
Simon Glassae7123f2015-01-05 20:05:27 -0700638{
639 struct udevice *dev = desc->dev;
Simon Glass3d647742021-02-04 21:22:05 -0700640 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100641 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Patrick Delaunay788ea832020-01-13 11:35:03 +0100642 int ret = 0;
Simon Glassae7123f2015-01-05 20:05:27 -0700643
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100644 ret = check_dir_flags(flags);
645 if (ret) {
646 dev_dbg(dev,
647 "%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
648 desc->dev->name,
649 uc_priv->bank_name ? uc_priv->bank_name : "",
650 desc->offset, flags);
651
652 return ret;
653 }
654
Simon Glass7e0a96d2021-02-04 21:22:03 -0700655 /* If active low, invert the output state */
656 if ((flags & (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW)) ==
657 (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW))
658 flags ^= GPIOD_IS_OUT_ACTIVE;
659
Simon Glass13979fc2021-02-04 21:21:55 -0700660 /* GPIOD_ are directly managed by driver in set_flags */
661 if (ops->set_flags) {
662 ret = ops->set_flags(dev, desc->offset, flags);
Patrick Delaunay8fd9daf2020-01-13 11:35:09 +0100663 } else {
664 if (flags & GPIOD_IS_OUT) {
Simon Glass7e0a96d2021-02-04 21:22:03 -0700665 bool value = flags & GPIOD_IS_OUT_ACTIVE;
666
667 ret = ops->direction_output(dev, desc->offset, value);
Patrick Delaunay8fd9daf2020-01-13 11:35:09 +0100668 } else if (flags & GPIOD_IS_IN) {
669 ret = ops->direction_input(dev, desc->offset);
670 }
Simon Glassae7123f2015-01-05 20:05:27 -0700671 }
Patrick Delaunay788ea832020-01-13 11:35:03 +0100672
673 return ret;
674}
675
Simon Glass7e0a96d2021-02-04 21:22:03 -0700676int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set)
Patrick Delaunay788ea832020-01-13 11:35:03 +0100677{
Simon Glass7e0a96d2021-02-04 21:22:03 -0700678 ulong flags;
Patrick Delaunay788ea832020-01-13 11:35:03 +0100679 int ret;
680
681 ret = check_reserved(desc, "set_dir_flags");
Simon Glassae7123f2015-01-05 20:05:27 -0700682 if (ret)
683 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700684
Simon Glass7e0a96d2021-02-04 21:22:03 -0700685 flags = (desc->flags & ~clr) | set;
Patrick Delaunay788ea832020-01-13 11:35:03 +0100686
Simon Glass7e0a96d2021-02-04 21:22:03 -0700687 ret = _dm_gpio_set_flags(desc, flags);
688 if (ret)
689 return ret;
690
691 /* save the flags also in descriptor */
692 desc->flags = flags;
693
694 return 0;
695}
696
697int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
698{
699 /* combine the requested flags (for IN/OUT) and the descriptor flags */
700 return dm_gpio_clrset_flags(desc, GPIOD_MASK_DIR, flags);
Simon Glassae7123f2015-01-05 20:05:27 -0700701}
702
Simon Glass8a45b222021-02-04 21:22:09 -0700703int dm_gpios_clrset_flags(struct gpio_desc *desc, int count, ulong clr,
704 ulong set)
705{
706 int ret;
707 int i;
708
709 for (i = 0; i < count; i++) {
710 ret = dm_gpio_clrset_flags(&desc[i], clr, set);
711 if (ret)
712 return log_ret(ret);
713 }
714
715 return 0;
716}
717
Simon Glassc0c1e622021-02-04 21:21:57 -0700718int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100719{
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100720 struct udevice *dev = desc->dev;
721 int ret, value;
Simon Glass3d647742021-02-04 21:22:05 -0700722 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass96487892021-02-04 21:21:56 -0700723 ulong flags;
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100724
Simon Glass96487892021-02-04 21:21:56 -0700725 ret = check_reserved(desc, "get_flags");
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100726 if (ret)
727 return ret;
728
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100729 /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
Simon Glass96487892021-02-04 21:21:56 -0700730 if (ops->get_flags) {
731 ret = ops->get_flags(dev, desc->offset, &flags);
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100732 if (ret)
733 return ret;
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100734
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100735 /* GPIOD_ACTIVE_LOW is saved in desc->flags */
Simon Glass96487892021-02-04 21:21:56 -0700736 value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100737 if (desc->flags & GPIOD_ACTIVE_LOW)
738 value = !value;
Simon Glass96487892021-02-04 21:21:56 -0700739 flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
740 flags |= (desc->flags & GPIOD_ACTIVE_LOW);
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100741 if (value)
Simon Glass96487892021-02-04 21:21:56 -0700742 flags |= GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100743 } else {
Simon Glass96487892021-02-04 21:21:56 -0700744 flags = desc->flags;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100745 /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
Simon Glass96487892021-02-04 21:21:56 -0700746 flags &= ~GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100747 if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
Simon Glass96487892021-02-04 21:21:56 -0700748 flags |= GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100749 }
Simon Glass96487892021-02-04 21:21:56 -0700750 *flagsp = flags;
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100751
752 return 0;
753}
754
Simon Glass96495d92014-02-26 15:59:24 -0700755/**
756 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
757 * gpio: GPIO number
758 *
759 * This function implements the API that's compatible with current
760 * GPIO API used in U-Boot. The request is forwarded to particular
761 * GPIO driver. Returns the value of the GPIO pin, or negative value
762 * on error.
763 */
764int gpio_get_value(unsigned gpio)
765{
Simon Glass96495d92014-02-26 15:59:24 -0700766 int ret;
767
Simon Glassae7123f2015-01-05 20:05:27 -0700768 struct gpio_desc desc;
769
770 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700771 if (ret)
772 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700773 return dm_gpio_get_value(&desc);
Simon Glass96495d92014-02-26 15:59:24 -0700774}
775
776/**
777 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
778 * gpio: GPIO number
779 * value: Logical value to be set on the GPIO pin.
780 *
781 * This function implements the API that's compatible with current
782 * GPIO API used in U-Boot. The request is forwarded to particular
783 * GPIO driver. Returns 0 on success, negative value on error.
784 */
785int gpio_set_value(unsigned gpio, int value)
786{
Simon Glassae7123f2015-01-05 20:05:27 -0700787 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700788 int ret;
789
Simon Glassae7123f2015-01-05 20:05:27 -0700790 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700791 if (ret)
792 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700793 return dm_gpio_set_value(&desc, value);
Simon Glass96495d92014-02-26 15:59:24 -0700794}
795
Heiko Schocher54c5d082014-05-22 12:43:05 +0200796const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
Simon Glass96495d92014-02-26 15:59:24 -0700797{
798 struct gpio_dev_priv *priv;
799
800 /* Must be called on an active device */
Simon Glasse564f052015-03-05 12:25:20 -0700801 priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -0700802 assert(priv);
803
804 *bit_count = priv->gpio_count;
805 return priv->bank_name;
806}
807
Simon Glass6449a502014-10-04 11:29:43 -0600808static const char * const gpio_function[GPIOF_COUNT] = {
809 "input",
810 "output",
811 "unused",
812 "unknown",
813 "func",
814};
815
Masahiro Yamadafb07f972017-06-22 16:50:25 +0900816static int get_function(struct udevice *dev, int offset, bool skip_unused,
817 const char **namep)
Simon Glass6449a502014-10-04 11:29:43 -0600818{
Simon Glasse564f052015-03-05 12:25:20 -0700819 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass3d647742021-02-04 21:22:05 -0700820 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass6449a502014-10-04 11:29:43 -0600821
822 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
823 if (!device_active(dev))
824 return -ENODEV;
825 if (offset < 0 || offset >= uc_priv->gpio_count)
826 return -EINVAL;
827 if (namep)
828 *namep = uc_priv->name[offset];
829 if (skip_unused && !uc_priv->name[offset])
830 return GPIOF_UNUSED;
831 if (ops->get_function) {
832 int ret;
833
834 ret = ops->get_function(dev, offset);
835 if (ret < 0)
836 return ret;
837 if (ret >= ARRAY_SIZE(gpio_function))
838 return -ENODATA;
839 return ret;
840 }
841
842 return GPIOF_UNKNOWN;
843}
844
845int gpio_get_function(struct udevice *dev, int offset, const char **namep)
846{
847 return get_function(dev, offset, true, namep);
848}
849
850int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
851{
852 return get_function(dev, offset, false, namep);
853}
854
Simon Glass07575352014-10-04 11:29:44 -0600855int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
856{
Simon Glass3d647742021-02-04 21:22:05 -0700857 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass07575352014-10-04 11:29:44 -0600858 struct gpio_dev_priv *priv;
859 char *str = buf;
Patrice Chotardd7124f02022-08-30 14:09:11 +0200860 const char *label;
Simon Glass07575352014-10-04 11:29:44 -0600861 int func;
862 int ret;
863 int len;
Patrice Chotardd7124f02022-08-30 14:09:11 +0200864 bool used;
Simon Glass07575352014-10-04 11:29:44 -0600865
866 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
867
868 *buf = 0;
Simon Glasse564f052015-03-05 12:25:20 -0700869 priv = dev_get_uclass_priv(dev);
Patrice Chotardd7124f02022-08-30 14:09:11 +0200870 ret = gpio_get_raw_function(dev, offset, &label);
Simon Glass07575352014-10-04 11:29:44 -0600871 if (ret < 0)
872 return ret;
873 func = ret;
874 len = snprintf(str, buffsize, "%s%d: %s",
875 priv->bank_name ? priv->bank_name : "",
876 offset, gpio_function[func]);
Simon Glass07575352014-10-04 11:29:44 -0600877
Patrice Chotardd7124f02022-08-30 14:09:11 +0200878 switch (func) {
879 case GPIOF_FUNC:
880 snprintf(str + len, buffsize - len, " %s", label ? label : "");
881 break;
882 case GPIOF_INPUT:
883 case GPIOF_OUTPUT:
884 case GPIOF_UNUSED:
Simon Glass07575352014-10-04 11:29:44 -0600885 ret = ops->get_value(dev, offset);
886 if (ret < 0)
887 return ret;
888 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
889 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
890 ret,
891 used ? 'x' : ' ',
Patrice Chotarda3292082022-08-30 14:09:12 +0200892 label ? " " : "",
Simon Glass07575352014-10-04 11:29:44 -0600893 label ? label : "");
Patrice Chotardd7124f02022-08-30 14:09:11 +0200894 break;
Simon Glass07575352014-10-04 11:29:44 -0600895 }
896
897 return 0;
898}
899
Simon Glass29126862020-07-07 13:11:44 -0600900#if CONFIG_IS_ENABLED(ACPIGEN)
901int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
902{
Simon Glass3d647742021-02-04 21:22:05 -0700903 const struct dm_gpio_ops *ops;
Simon Glass29126862020-07-07 13:11:44 -0600904
905 memset(gpio, '\0', sizeof(*gpio));
906 if (!dm_gpio_is_valid(desc)) {
907 /* Indicate that the GPIO is not valid */
908 gpio->pin_count = 0;
909 gpio->pins[0] = 0;
910 return -EINVAL;
911 }
912
913 ops = gpio_get_ops(desc->dev);
914 if (!ops->get_acpi)
915 return -ENOSYS;
916
917 return ops->get_acpi(desc, gpio);
918}
919#endif
920
Simon Glass962f5ca2015-04-14 21:03:20 -0600921int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
922{
923 int i, ret;
924 int gpio;
925
926 for (i = 0; i < 32; i++) {
927 gpio = gpio_num_array[i];
928 if (gpio == -1)
929 break;
930 ret = gpio_requestf(gpio, fmt, i);
931 if (ret)
932 goto err;
933 ret = gpio_direction_input(gpio);
934 if (ret) {
935 gpio_free(gpio);
936 goto err;
937 }
938 }
939
940 return 0;
941err:
942 for (i--; i >= 0; i--)
943 gpio_free(gpio_num_array[i]);
944
945 return ret;
946}
947
Simon Glasse5901c92014-11-10 18:00:21 -0700948/*
949 * get a number comprised of multiple GPIO values. gpio_num_array points to
950 * the array of gpio pin numbers to scan, terminated by -1.
951 */
Simon Glass962f5ca2015-04-14 21:03:20 -0600952int gpio_get_values_as_int(const int *gpio_list)
Simon Glasse5901c92014-11-10 18:00:21 -0700953{
954 int gpio;
955 unsigned bitmask = 1;
956 unsigned vector = 0;
Simon Glass962f5ca2015-04-14 21:03:20 -0600957 int ret;
Simon Glasse5901c92014-11-10 18:00:21 -0700958
959 while (bitmask &&
Simon Glass962f5ca2015-04-14 21:03:20 -0600960 ((gpio = *gpio_list++) != -1)) {
961 ret = gpio_get_value(gpio);
962 if (ret < 0)
963 return ret;
964 else if (ret)
Simon Glasse5901c92014-11-10 18:00:21 -0700965 vector |= bitmask;
966 bitmask <<= 1;
967 }
Simon Glass962f5ca2015-04-14 21:03:20 -0600968
Simon Glasse5901c92014-11-10 18:00:21 -0700969 return vector;
970}
971
Simon Glass17c43f12016-03-06 19:27:51 -0700972int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
Simon Glassbbf24782016-03-06 19:27:50 -0700973{
974 unsigned bitmask = 1;
975 unsigned vector = 0;
976 int ret, i;
977
978 for (i = 0; i < count; i++) {
979 ret = dm_gpio_get_value(&desc_list[i]);
980 if (ret < 0)
981 return ret;
982 else if (ret)
983 vector |= bitmask;
984 bitmask <<= 1;
985 }
986
987 return vector;
988}
989
Simon Glass8a45b222021-02-04 21:22:09 -0700990int dm_gpio_get_values_as_int_base3(struct gpio_desc *desc_list,
991 int count)
992{
993 static const char tristate[] = "01z";
994 enum {
995 PULLUP,
996 PULLDOWN,
997
998 NUM_OPTIONS,
999 };
1000 int vals[NUM_OPTIONS];
1001 uint mask;
1002 uint vector = 0;
1003 int ret, i;
1004
1005 /*
1006 * Limit to 19 digits which should be plenty. This avoids overflow of a
1007 * 32-bit int
1008 */
1009 assert(count < 20);
1010
1011 for (i = 0; i < NUM_OPTIONS; i++) {
1012 uint flags = GPIOD_IS_IN;
1013
1014 flags |= (i == PULLDOWN) ? GPIOD_PULL_DOWN : GPIOD_PULL_UP;
1015 ret = dm_gpios_clrset_flags(desc_list, count, GPIOD_MASK_PULL,
1016 flags);
1017 if (ret)
1018 return log_msg_ret("pu", ret);
1019
1020 /* Give the lines time to settle */
1021 udelay(10);
1022
1023 ret = dm_gpio_get_values_as_int(desc_list, count);
1024 if (ret < 0)
1025 return log_msg_ret("get1", ret);
1026 vals[i] = ret;
1027 }
1028
1029 log_debug("values: %x %x, count = %d\n", vals[0], vals[1], count);
1030 for (i = count - 1, mask = 1 << i; i >= 0; i--, mask >>= 1) {
1031 uint pd = vals[PULLDOWN] & mask ? 1 : 0;
1032 uint pu = vals[PULLUP] & mask ? 1 : 0;
1033 uint digit;
1034
1035 /*
1036 * Get value with internal pulldown active. If this is 1 then
1037 * there is a stronger external pullup, which we call 1. If not
1038 * then call it 0.
1039 *
1040 * If the values differ then the pin is floating so we call
1041 * this a 2.
1042 */
1043 if (pu == pd)
1044 digit = pd;
1045 else
1046 digit = 2;
1047 log_debug("%c ", tristate[digit]);
1048 vector = 3 * vector + digit;
1049 }
1050 log_debug("vector=%d\n", vector);
1051
1052 return vector;
1053}
1054
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001055/**
1056 * gpio_request_tail: common work for requesting a gpio.
1057 *
1058 * ret: return value from previous work in function which calls
1059 * this function.
1060 * This seems bogus (why calling this function instead not
1061 * calling it and end caller function instead?).
1062 * Because on error in caller function we want to set some
1063 * default values in gpio desc and have a common error
1064 * debug message, which provides this function.
1065 * nodename: Name of node for which gpio gets requested
1066 * used for gpio label name.
1067 * args: pointer to output arguments structure
1068 * list_name: Name of GPIO list
1069 * used for gpio label name.
1070 * index: gpio index in gpio list
1071 * used for gpio label name.
1072 * desc: pointer to gpio descriptor, filled from this
1073 * function.
1074 * flags: gpio flags to use.
1075 * add_index: should index added to gpio label name
1076 * gpio_dev: pointer to gpio device from which the gpio
1077 * will be requested. If NULL try to get the
1078 * gpio device with uclass_get_device_by_ofnode()
1079 *
1080 * return: In error case this function sets default values in
1081 * gpio descriptor, also emmits a debug message.
1082 * On success it returns 0 else the error code from
1083 * function calls, or the error code passed through
1084 * ret to this function.
1085 *
1086 */
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001087static int gpio_request_tail(int ret, const char *nodename,
Simon Glass3a571232017-05-18 20:09:18 -06001088 struct ofnode_phandle_args *args,
1089 const char *list_name, int index,
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001090 struct gpio_desc *desc, int flags,
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001091 bool add_index, struct udevice *gpio_dev)
Simon Glass3669e0e2015-01-05 20:05:29 -07001092{
Patrick Delaunay9f2b0662020-01-13 11:35:01 +01001093 gpio_desc_init(desc, gpio_dev, 0);
Simon Glass3a571232017-05-18 20:09:18 -06001094 if (ret)
Simon Glass3669e0e2015-01-05 20:05:29 -07001095 goto err;
Simon Glass3669e0e2015-01-05 20:05:29 -07001096
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001097 if (!desc->dev) {
1098 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
1099 &desc->dev);
1100 if (ret) {
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001101 debug("%s: uclass_get_device_by_ofnode failed\n",
1102 __func__);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001103 goto err;
1104 }
Simon Glass3669e0e2015-01-05 20:05:29 -07001105 }
Simon Glass3a571232017-05-18 20:09:18 -06001106 ret = gpio_find_and_xlate(desc, args);
Simon Glass3669e0e2015-01-05 20:05:29 -07001107 if (ret) {
1108 debug("%s: gpio_find_and_xlate failed\n", __func__);
1109 goto err;
1110 }
1111 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001112 nodename, list_name, index);
Simon Glass3669e0e2015-01-05 20:05:29 -07001113 if (ret) {
1114 debug("%s: dm_gpio_requestf failed\n", __func__);
1115 goto err;
1116 }
Simon Glass7e0a96d2021-02-04 21:22:03 -07001117
1118 /* Keep any direction flags provided by the devicetree */
1119 ret = dm_gpio_set_dir_flags(desc,
1120 flags | (desc->flags & GPIOD_MASK_DIR));
Simon Glass3669e0e2015-01-05 20:05:29 -07001121 if (ret) {
1122 debug("%s: dm_gpio_set_dir failed\n", __func__);
1123 goto err;
1124 }
1125
1126 return 0;
1127err:
1128 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001129 __func__, nodename, list_name, index, ret);
Simon Glass3669e0e2015-01-05 20:05:29 -07001130 return ret;
1131}
1132
Simon Glass95397382021-08-07 07:24:04 -06001133#if CONFIG_IS_ENABLED(OF_REAL)
Simon Glass150c5af2017-05-30 21:47:09 -06001134static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
1135 int index, struct gpio_desc *desc,
1136 int flags, bool add_index)
Simon Glass3a571232017-05-18 20:09:18 -06001137{
1138 struct ofnode_phandle_args args;
1139 int ret;
1140
Simon Glass150c5af2017-05-30 21:47:09 -06001141 ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
1142 index, &args);
Simon Glass3a571232017-05-18 20:09:18 -06001143
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001144 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1145 index, desc, flags, add_index, NULL);
Simon Glass3a571232017-05-18 20:09:18 -06001146}
1147
Simon Glass150c5af2017-05-30 21:47:09 -06001148int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
Simon Glass3669e0e2015-01-05 20:05:29 -07001149 struct gpio_desc *desc, int flags)
1150{
Simon Glass150c5af2017-05-30 21:47:09 -06001151 return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
1152 index > 0);
Simon Glass3669e0e2015-01-05 20:05:29 -07001153}
1154
Simon Glass150c5af2017-05-30 21:47:09 -06001155int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
Simon Glass3669e0e2015-01-05 20:05:29 -07001156 struct gpio_desc *desc, int flags)
1157{
Simon Glass150c5af2017-05-30 21:47:09 -06001158 struct ofnode_phandle_args args;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001159 ofnode node;
Simon Glass150c5af2017-05-30 21:47:09 -06001160 int ret;
1161
1162 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
1163 index, &args);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001164 node = dev_ofnode(dev);
1165 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1166 index, desc, flags, index > 0, NULL);
Simon Glass3669e0e2015-01-05 20:05:29 -07001167}
1168
Andrew Jeffery34be6962022-01-31 13:54:05 +10301169int gpio_request_by_line_name(struct udevice *dev, const char *line_name,
1170 struct gpio_desc *desc, int flags)
1171{
1172 int ret;
1173
Rasmus Villemoese1c97942023-03-17 21:12:22 +01001174 if (!dev) {
1175 uclass_foreach_dev_probe(UCLASS_GPIO, dev)
1176 if (!gpio_request_by_line_name(dev, line_name, desc, flags))
1177 return 0;
1178 return -ENOENT;
1179 }
1180
Andrew Jeffery34be6962022-01-31 13:54:05 +10301181 ret = dev_read_stringlist_search(dev, "gpio-line-names", line_name);
1182 if (ret < 0)
1183 return ret;
1184
1185 desc->dev = dev;
1186 desc->offset = ret;
1187 desc->flags = 0;
1188
1189 ret = dm_gpio_request(desc, line_name);
1190 if (ret) {
1191 debug("%s: dm_gpio_requestf failed\n", __func__);
1192 return ret;
1193 }
1194
1195 ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
1196 if (ret)
1197 debug("%s: dm_gpio_set_dir failed\n", __func__);
1198
1199 return ret;
1200}
1201
Simon Glass150c5af2017-05-30 21:47:09 -06001202int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
Simon Glass3669e0e2015-01-05 20:05:29 -07001203 struct gpio_desc *desc, int max_count,
1204 int flags)
1205{
1206 int count;
1207 int ret;
1208
Przemyslaw Marczak2984e7a2015-03-31 18:57:16 +02001209 for (count = 0; count < max_count; count++) {
Simon Glass150c5af2017-05-30 21:47:09 -06001210 ret = _gpio_request_by_name_nodev(node, list_name, count,
Simon Glass3669e0e2015-01-05 20:05:29 -07001211 &desc[count], flags, true);
1212 if (ret == -ENOENT)
1213 break;
1214 else if (ret)
1215 goto err;
1216 }
1217
1218 /* We ran out of GPIOs in the list */
1219 return count;
1220
1221err:
Rasmus Villemoes0fac5c42023-04-19 12:10:13 +02001222 gpio_free_list_nodev(desc, count);
Simon Glass3669e0e2015-01-05 20:05:29 -07001223
1224 return ret;
1225}
1226
1227int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
1228 struct gpio_desc *desc, int max_count,
1229 int flags)
1230{
1231 /*
1232 * This isn't ideal since we don't use dev->name in the debug()
1233 * calls in gpio_request_by_name(), but we can do this until
1234 * gpio_request_list_by_name_nodev() can be dropped.
1235 */
Simon Glass150c5af2017-05-30 21:47:09 -06001236 return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
1237 max_count, flags);
Simon Glass3669e0e2015-01-05 20:05:29 -07001238}
1239
1240int gpio_get_list_count(struct udevice *dev, const char *list_name)
1241{
1242 int ret;
1243
Sean Anderson430e1362021-04-20 10:50:54 -04001244 ret = dev_count_phandle_with_args(dev, list_name, "#gpio-cells",
1245 -ENOENT);
1246 if (ret < 0) {
Simon Glass3669e0e2015-01-05 20:05:29 -07001247 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
1248 __func__, dev->name, list_name, ret);
1249 }
1250
1251 return ret;
1252}
Simon Glass4fe40672021-02-04 21:21:54 -07001253#endif /* OF_PLATDATA */
Simon Glass3669e0e2015-01-05 20:05:29 -07001254
Simon Glass48609d02021-08-07 07:24:12 -06001255#if CONFIG_IS_ENABLED(OF_PLATDATA)
1256int gpio_request_by_phandle(struct udevice *dev,
1257 const struct phandle_2_arg *cells,
1258 struct gpio_desc *desc, int flags)
1259{
1260 struct ofnode_phandle_args args;
1261 struct udevice *gpio_dev;
1262 const int index = 0;
1263 int ret;
1264
1265 ret = device_get_by_ofplat_idx(cells->idx, &gpio_dev);
1266 if (ret)
1267 return ret;
1268 args.args[0] = cells->arg[0];
1269 args.args[1] = cells->arg[1];
1270
1271 return gpio_request_tail(ret, NULL, &args, NULL, index, desc, flags,
1272 index > 0, gpio_dev);
1273}
1274#endif
1275
Simon Glass3669e0e2015-01-05 20:05:29 -07001276int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
1277{
1278 /* For now, we don't do any checking of dev */
1279 return _dm_gpio_free(desc->dev, desc->offset);
1280}
1281
1282int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
1283{
1284 int i;
1285
1286 /* For now, we don't do any checking of dev */
1287 for (i = 0; i < count; i++)
1288 dm_gpio_free(dev, &desc[i]);
1289
1290 return 0;
1291}
1292
1293int gpio_free_list_nodev(struct gpio_desc *desc, int count)
1294{
1295 return gpio_free_list(NULL, desc, count);
1296}
1297
Simon Glass96495d92014-02-26 15:59:24 -07001298/* We need to renumber the GPIOs when any driver is probed/removed */
Simon Glassb892d122014-10-04 11:29:42 -06001299static int gpio_renumber(struct udevice *removed_dev)
Simon Glass96495d92014-02-26 15:59:24 -07001300{
1301 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +02001302 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -07001303 struct uclass *uc;
1304 unsigned base;
1305 int ret;
1306
1307 ret = uclass_get(UCLASS_GPIO, &uc);
1308 if (ret)
1309 return ret;
1310
1311 /* Ensure that we have a base for each bank */
1312 base = 0;
1313 uclass_foreach_dev(dev, uc) {
Simon Glassb892d122014-10-04 11:29:42 -06001314 if (device_active(dev) && dev != removed_dev) {
Simon Glasse564f052015-03-05 12:25:20 -07001315 uc_priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -07001316 uc_priv->gpio_base = base;
1317 base += uc_priv->gpio_count;
1318 }
1319 }
1320
1321 return 0;
1322}
1323
Simon Glass17c43f12016-03-06 19:27:51 -07001324int gpio_get_number(const struct gpio_desc *desc)
Simon Glass56a71f82015-03-25 12:21:58 -06001325{
1326 struct udevice *dev = desc->dev;
1327 struct gpio_dev_priv *uc_priv;
1328
1329 if (!dev)
1330 return -1;
Simon Glass0fd3d912020-12-22 19:30:28 -07001331 uc_priv = dev_get_uclass_priv(dev);
Simon Glass56a71f82015-03-25 12:21:58 -06001332
1333 return uc_priv->gpio_base + desc->offset;
1334}
1335
Heiko Schocher54c5d082014-05-22 12:43:05 +02001336static int gpio_post_probe(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -07001337{
Simon Glasse564f052015-03-05 12:25:20 -07001338 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -06001339
1340 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
1341 if (!uc_priv->name)
1342 return -ENOMEM;
1343
1344 return gpio_renumber(NULL);
Simon Glass96495d92014-02-26 15:59:24 -07001345}
1346
Heiko Schocher54c5d082014-05-22 12:43:05 +02001347static int gpio_pre_remove(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -07001348{
Simon Glasse564f052015-03-05 12:25:20 -07001349 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -06001350 int i;
1351
1352 for (i = 0; i < uc_priv->gpio_count; i++) {
1353 if (uc_priv->name[i])
1354 free(uc_priv->name[i]);
1355 }
1356 free(uc_priv->name);
1357
1358 return gpio_renumber(dev);
Simon Glass96495d92014-02-26 15:59:24 -07001359}
1360
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001361int gpio_dev_request_index(struct udevice *dev, const char *nodename,
1362 char *list_name, int index, int flags,
1363 int dtflags, struct gpio_desc *desc)
1364{
1365 struct ofnode_phandle_args args;
1366
1367 args.node = ofnode_null();
1368 args.args_count = 2;
1369 args.args[0] = index;
1370 args.args[1] = dtflags;
1371
1372 return gpio_request_tail(0, nodename, &args, list_name, index, desc,
1373 flags, 0, dev);
1374}
1375
Jean-Jacques Hiblotd4b722e2020-09-11 13:43:34 +05301376static void devm_gpiod_release(struct udevice *dev, void *res)
1377{
1378 dm_gpio_free(dev, res);
1379}
1380
1381static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
1382{
1383 return res == data;
1384}
1385
1386struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
1387 unsigned int index, int flags)
1388{
1389 int rc;
1390 struct gpio_desc *desc;
1391 char *propname;
1392 static const char suffix[] = "-gpios";
1393
1394 propname = malloc(strlen(id) + sizeof(suffix));
1395 if (!propname) {
1396 rc = -ENOMEM;
1397 goto end;
1398 }
1399
1400 strcpy(propname, id);
1401 strcat(propname, suffix);
1402
1403 desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
1404 __GFP_ZERO);
1405 if (unlikely(!desc)) {
1406 rc = -ENOMEM;
1407 goto end;
1408 }
1409
1410 rc = gpio_request_by_name(dev, propname, index, desc, flags);
1411
1412end:
1413 if (propname)
1414 free(propname);
1415
1416 if (rc)
1417 return ERR_PTR(rc);
1418
1419 devres_add(dev, desc);
1420
1421 return desc;
1422}
1423
1424struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
1425 const char *id,
1426 unsigned int index,
1427 int flags)
1428{
1429 struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);
1430
1431 if (IS_ERR(desc))
1432 return NULL;
1433
1434 return desc;
1435}
1436
1437void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
1438{
1439 int rc;
1440
1441 rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
1442 WARN_ON(rc);
1443}
1444
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001445static int gpio_post_bind(struct udevice *dev)
1446{
1447#if defined(CONFIG_NEEDS_MANUAL_RELOC)
1448 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
1449 static int reloc_done;
1450
1451 if (!reloc_done) {
1452 if (ops->request)
1453 ops->request += gd->reloc_off;
Simon Glass093152f2020-02-04 20:15:17 -07001454 if (ops->rfree)
1455 ops->rfree += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001456 if (ops->direction_input)
1457 ops->direction_input += gd->reloc_off;
1458 if (ops->direction_output)
1459 ops->direction_output += gd->reloc_off;
1460 if (ops->get_value)
1461 ops->get_value += gd->reloc_off;
1462 if (ops->set_value)
1463 ops->set_value += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001464 if (ops->get_function)
1465 ops->get_function += gd->reloc_off;
1466 if (ops->xlate)
1467 ops->xlate += gd->reloc_off;
Simon Glass13979fc2021-02-04 21:21:55 -07001468 if (ops->set_flags)
1469 ops->set_flags += gd->reloc_off;
Simon Glass96487892021-02-04 21:21:56 -07001470 if (ops->get_flags)
1471 ops->get_flags += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001472
1473 reloc_done++;
1474 }
1475#endif
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001476
Eddie James1d99e672022-02-07 17:09:01 -06001477 if (CONFIG_IS_ENABLED(GPIO_HOG)) {
1478 struct udevice *child;
1479 ofnode node;
1480
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001481 dev_for_each_subnode(node, dev) {
1482 if (ofnode_read_bool(node, "gpio-hog")) {
1483 const char *name = ofnode_get_name(node);
1484 int ret;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001485
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001486 ret = device_bind_driver_to_node(dev,
1487 "gpio_hog",
1488 name, node,
1489 &child);
1490 if (ret)
1491 return ret;
Marek Vasut48b3ecb2022-09-22 17:53:26 +02001492
1493 /*
1494 * Make sure gpio-hogs are probed after bind
1495 * since hogs can be essential to the hardware
1496 * system.
1497 */
1498 dev_or_flags(child, DM_FLAG_PROBE_AFTER_BIND);
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001499 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001500 }
1501 }
Marek Vasut48b3ecb2022-09-22 17:53:26 +02001502
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001503 return 0;
1504}
1505
Simon Glass96495d92014-02-26 15:59:24 -07001506UCLASS_DRIVER(gpio) = {
1507 .id = UCLASS_GPIO,
1508 .name = "gpio",
Bhuvanchandra DVae89bb02015-06-01 18:37:15 +05301509 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass96495d92014-02-26 15:59:24 -07001510 .post_probe = gpio_post_probe,
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001511 .post_bind = gpio_post_bind,
Simon Glass96495d92014-02-26 15:59:24 -07001512 .pre_remove = gpio_pre_remove,
Simon Glass41575d82020-12-03 16:55:17 -07001513 .per_device_auto = sizeof(struct gpio_dev_priv),
Simon Glass96495d92014-02-26 15:59:24 -07001514};