blob: 3a6ef3b01d530688b1b6dfda14dcfaff5715bb1f [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glasse821d182014-02-26 15:59:24 -07002/*
3 * Copyright (c) 2013 Google, Inc
Simon Glasse821d182014-02-26 15:59:24 -07004 */
5
Simon Glasse43eae22021-02-04 21:22:08 -07006#define LOG_CATEGORY UCLASS_GPIO
7
Simon Glasse821d182014-02-26 15:59:24 -07008#include <common.h>
9#include <dm.h>
Simon Glass2149e112021-08-07 07:24:12 -060010#include <dt-structs.h>
Simon Glass0f2af882020-05-10 11:40:05 -060011#include <log.h>
Jean-Jacques Hiblot775d6a22020-09-11 13:43:34 +053012#include <dm/devres.h>
13#include <dm/device_compat.h>
Heiko Schocher39cb3402019-06-12 06:11:46 +020014#include <dm/device-internal.h>
15#include <dm/lists.h>
16#include <dm/uclass-internal.h>
Eric Nelson786e98d2016-04-24 16:32:40 -070017#include <dt-bindings/gpio/gpio.h>
Simon Glasse821d182014-02-26 15:59:24 -070018#include <errno.h>
Simon Glassd3322bb2015-01-05 20:05:28 -070019#include <fdtdec.h>
Simon Glass0f4517d2014-10-04 11:29:42 -060020#include <malloc.h>
Simon Glass3176b6c2020-07-07 13:11:44 -060021#include <acpi/acpi_device.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060022#include <asm/global_data.h>
Simon Glasse821d182014-02-26 15:59:24 -070023#include <asm/gpio.h>
Simon Glass0f2af882020-05-10 11:40:05 -060024#include <dm/device_compat.h>
Masahiro Yamada78eeb912016-01-24 23:27:48 +090025#include <linux/bug.h>
Simon Glass43b2e1a2014-10-22 21:37:01 -060026#include <linux/ctype.h>
Simon Glass247ccf22021-02-04 21:22:09 -070027#include <linux/delay.h>
Simon Glasse821d182014-02-26 15:59:24 -070028
Simon Glass16e10402015-01-05 20:05:29 -070029DECLARE_GLOBAL_DATA_PTR;
30
Simon Glasse821d182014-02-26 15:59:24 -070031/**
Patrick Delaunay758bba92020-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 Glasse821d182014-02-26 15:59:24 -070048 * gpio_to_device() - Convert global GPIO number to device, number
Simon Glasse821d182014-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 Glassce555292015-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 Schuchardt47b4c022022-01-19 18:05:50 +010056 * Return: 0 if found, -ENOENT if not found
Simon Glasse821d182014-02-26 15:59:24 -070057 */
Simon Glassce555292015-01-05 20:05:27 -070058static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
Simon Glasse821d182014-02-26 15:59:24 -070059{
60 struct gpio_dev_priv *uc_priv;
Heiko Schocherb74fcb42014-05-22 12:43:05 +020061 struct udevice *dev;
Simon Glasse821d182014-02-26 15:59:24 -070062
Michal Suchanek91c96fe2022-10-12 21:58:08 +020063 for (uclass_first_device(UCLASS_GPIO, &dev);
Simon Glasse821d182014-02-26 15:59:24 -070064 dev;
Michal Suchanek91c96fe2022-10-12 21:58:08 +020065 uclass_next_device(&dev)) {
Simon Glassde0977b2015-03-05 12:25:20 -070066 uc_priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -070067 if (gpio >= uc_priv->gpio_base &&
68 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
Patrick Delaunay758bba92020-01-13 11:35:01 +010069 gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
Simon Glasse821d182014-02-26 15:59:24 -070070 return 0;
71 }
72 }
73
74 /* No such GPIO */
Michal Suchanek91c96fe2022-10-12 21:58:08 +020075 return -ENOENT;
Simon Glasse821d182014-02-26 15:59:24 -070076}
77
Heiko Schochera3e793c2020-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 Schochera3e793c2020-05-22 11:08:59 +020093 int i;
94
95 *offset = -1;
Heiko Schochera3e793c2020-05-22 11:08:59 +020096 for (i = 0; i < uc_priv->gpio_count; i++) {
97 if (!uc_priv->name[i])
98 continue;
Rasmus Villemoes48828082022-10-03 11:02:45 +020099 if (!strcmp(name, uc_priv->name[i])) {
Heiko Schochera3e793c2020-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 Glass215bcc72015-06-23 15:38:40 -0600115int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
Simon Glasse821d182014-02-26 15:59:24 -0700116{
Simon Glass43b2e1a2014-10-22 21:37:01 -0600117 struct gpio_dev_priv *uc_priv = NULL;
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200118 struct udevice *dev;
Simon Glass43b2e1a2014-10-22 21:37:01 -0600119 ulong offset;
120 int numeric;
Simon Glasse821d182014-02-26 15:59:24 -0700121
Simon Glassff9b9032021-07-24 09:03:30 -0600122 numeric = isdigit(*name) ? dectoul(name, NULL) : -1;
Michal Suchanek91c96fe2022-10-12 21:58:08 +0200123 for (uclass_first_device(UCLASS_GPIO, &dev);
Simon Glasse821d182014-02-26 15:59:24 -0700124 dev;
Michal Suchanek91c96fe2022-10-12 21:58:08 +0200125 uclass_next_device(&dev)) {
Simon Glasse821d182014-02-26 15:59:24 -0700126 int len;
127
Simon Glassde0977b2015-03-05 12:25:20 -0700128 uc_priv = dev_get_uclass_priv(dev);
Simon Glass43b2e1a2014-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 Rini26fd9682017-05-10 15:20:15 -0400132 if (offset < uc_priv->gpio_count)
Simon Glass43b2e1a2014-10-22 21:37:01 -0600133 break;
134 }
135
Simon Glasse821d182014-02-26 15:59:24 -0700136 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
137
Simon Glassd4acf632014-06-11 23:29:47 -0600138 if (!strncasecmp(name, uc_priv->bank_name, len)) {
Simon Glass43b2e1a2014-10-22 21:37:01 -0600139 if (!strict_strtoul(name + len, 10, &offset))
Samuel Holland8f53a332021-09-11 17:05:51 -0500140 if (offset < uc_priv->gpio_count)
141 break;
Simon Glasse821d182014-02-26 15:59:24 -0700142 }
Heiko Schochera3e793c2020-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 Glasse821d182014-02-26 15:59:24 -0700150 }
151
Simon Glass43b2e1a2014-10-22 21:37:01 -0600152 if (!dev)
Michal Suchanek91c96fe2022-10-12 21:58:08 +0200153 return -EINVAL;
Simon Glass43b2e1a2014-10-22 21:37:01 -0600154
Patrick Delaunay758bba92020-01-13 11:35:01 +0100155 gpio_desc_init(desc, dev, offset);
Simon Glass215bcc72015-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
166 if (devp)
167 *devp = NULL;
168 ret = dm_gpio_lookup_name(name, &desc);
169 if (ret)
170 return ret;
171
Simon Glass43b2e1a2014-10-22 21:37:01 -0600172 if (devp)
Simon Glass215bcc72015-06-23 15:38:40 -0600173 *devp = desc.dev;
Simon Glass43b2e1a2014-10-22 21:37:01 -0600174 if (offsetp)
Simon Glass215bcc72015-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 Glass43b2e1a2014-10-22 21:37:01 -0600181
182 return 0;
Simon Glasse821d182014-02-26 15:59:24 -0700183}
184
Samuel Holland8e10c712021-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 Glass12faa022017-05-18 20:09:18 -0600213int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
214 struct ofnode_phandle_args *args)
Eric Nelson786e98d2016-04-24 16:32:40 -0700215{
Samuel Holland78acb922021-09-11 17:05:52 -0500216 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
217
Eric Nelson786e98d2016-04-24 16:32:40 -0700218 if (args->args_count < 1)
219 return -EINVAL;
220
221 desc->offset = args->args[0];
Samuel Holland78acb922021-09-11 17:05:52 -0500222 if (desc->offset >= uc_priv->gpio_count)
223 return -EINVAL;
Eric Nelson786e98d2016-04-24 16:32:40 -0700224
225 if (args->args_count < 2)
226 return 0;
227
Samuel Holland8e10c712021-09-11 17:05:53 -0500228 desc->flags = gpio_flags_xlate(args->args[1]);
Patrick Delaunay5c1c06e2020-01-13 11:35:07 +0100229
Eric Nelson786e98d2016-04-24 16:32:40 -0700230 return 0;
231}
232
Simon Glass16e10402015-01-05 20:05:29 -0700233static int gpio_find_and_xlate(struct gpio_desc *desc,
Simon Glass12faa022017-05-18 20:09:18 -0600234 struct ofnode_phandle_args *args)
Simon Glassd3322bb2015-01-05 20:05:28 -0700235{
Simon Glass49f315a2021-02-04 21:22:05 -0700236 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glassd3322bb2015-01-05 20:05:28 -0700237
Eric Nelson786e98d2016-04-24 16:32:40 -0700238 if (ops->xlate)
239 return ops->xlate(desc->dev, desc, args);
Simon Glassd3322bb2015-01-05 20:05:28 -0700240 else
Eric Nelson786e98d2016-04-24 16:32:40 -0700241 return gpio_xlate_offs_flags(desc->dev, desc, args);
Simon Glassd3322bb2015-01-05 20:05:28 -0700242}
243
Simon Glass2149e112021-08-07 07:24:12 -0600244#if CONFIG_IS_ENABLED(GPIO_HOG)
Heiko Schocher39cb3402019-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 Glassaad29ae2020-12-03 16:55:21 -0700256static int gpio_hog_of_to_plat(struct udevice *dev)
Heiko Schocher39cb3402019-06-12 06:11:46 +0200257{
Simon Glassfa20e932020-12-03 16:55:20 -0700258 struct gpio_hog_data *plat = dev_get_plat(dev);
Heiko Schocher39cb3402019-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 Schocher58e4c382019-07-17 06:59:51 +0200281 if (nodename)
282 device_set_name(dev, nodename);
Heiko Schocher39cb3402019-06-12 06:11:46 +0200283
284 return 0;
285}
286
287static int gpio_hog_probe(struct udevice *dev)
288{
Simon Glassfa20e932020-12-03 16:55:20 -0700289 struct gpio_hog_data *plat = dev_get_plat(dev);
Heiko Schocher39cb3402019-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 Schocher58e4c382019-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 Schocher39cb3402019-06-12 06:11:46 +0200310
311 return 0;
312}
313
314int gpio_hog_probe_all(void)
315{
316 struct udevice *dev;
317 int ret;
Heiko Schocher58e4c382019-07-17 06:59:51 +0200318 int retval = 0;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200319
320 for (uclass_first_device(UCLASS_NOP, &dev);
321 dev;
322 uclass_find_next_device(&dev)) {
Simon Glass65130cd2020-12-28 20:34:56 -0700323 if (dev->driver == DM_DRIVER_GET(gpio_hog)) {
Heiko Schocher39cb3402019-06-12 06:11:46 +0200324 ret = device_probe(dev);
Heiko Schocher58e4c382019-07-17 06:59:51 +0200325 if (ret) {
326 printf("Failed to probe device %s err: %d\n",
327 dev->name, ret);
328 retval = ret;
329 }
Heiko Schocher39cb3402019-06-12 06:11:46 +0200330 }
331 }
332
Heiko Schocher58e4c382019-07-17 06:59:51 +0200333 return retval;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200334}
335
Heiko Schocher58e4c382019-07-17 06:59:51 +0200336int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher39cb3402019-06-12 06:11:46 +0200337{
338 struct udevice *dev;
339
Heiko Schocher58e4c382019-07-17 06:59:51 +0200340 *desc = NULL;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200341 gpio_hog_probe_all();
342 if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
343 struct gpio_hog_priv *priv = dev_get_priv(dev);
344
Heiko Schocher58e4c382019-07-17 06:59:51 +0200345 *desc = &priv->gpiod;
346 return 0;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200347 }
348
Heiko Schocher58e4c382019-07-17 06:59:51 +0200349 return -ENODEV;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200350}
351
352U_BOOT_DRIVER(gpio_hog) = {
353 .name = "gpio_hog",
354 .id = UCLASS_NOP,
Simon Glassaad29ae2020-12-03 16:55:21 -0700355 .of_to_plat = gpio_hog_of_to_plat,
Heiko Schocher39cb3402019-06-12 06:11:46 +0200356 .probe = gpio_hog_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700357 .priv_auto = sizeof(struct gpio_hog_priv),
Simon Glass71fa5b42020-12-03 16:55:18 -0700358 .plat_auto = sizeof(struct gpio_hog_data),
Heiko Schocher39cb3402019-06-12 06:11:46 +0200359};
360#else
Heiko Schocher58e4c382019-07-17 06:59:51 +0200361int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher39cb3402019-06-12 06:11:46 +0200362{
Heiko Schocher58e4c382019-07-17 06:59:51 +0200363 return 0;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200364}
365#endif
366
Simon Glass047cdb32015-06-23 15:38:41 -0600367int dm_gpio_request(struct gpio_desc *desc, const char *label)
Simon Glassce555292015-01-05 20:05:27 -0700368{
Simon Glass49f315a2021-02-04 21:22:05 -0700369 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glassce555292015-01-05 20:05:27 -0700370 struct udevice *dev = desc->dev;
371 struct gpio_dev_priv *uc_priv;
372 char *str;
373 int ret;
374
Simon Glassde0977b2015-03-05 12:25:20 -0700375 uc_priv = dev_get_uclass_priv(dev);
Simon Glassce555292015-01-05 20:05:27 -0700376 if (uc_priv->name[desc->offset])
377 return -EBUSY;
378 str = strdup(label);
379 if (!str)
380 return -ENOMEM;
Simon Glass49f315a2021-02-04 21:22:05 -0700381 if (ops->request) {
382 ret = ops->request(dev, desc->offset, label);
Simon Glassce555292015-01-05 20:05:27 -0700383 if (ret) {
384 free(str);
385 return ret;
386 }
387 }
388 uc_priv->name[desc->offset] = str;
389
390 return 0;
391}
392
Simon Glass16e10402015-01-05 20:05:29 -0700393static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
394{
Simon Glass7611ac62019-09-25 08:56:27 -0600395#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass16e10402015-01-05 20:05:29 -0700396 va_list args;
397 char buf[40];
398
399 va_start(args, fmt);
400 vscnprintf(buf, sizeof(buf), fmt, args);
401 va_end(args);
402 return dm_gpio_request(desc, buf);
Simon Glassee8a3d92015-12-29 05:22:48 -0700403#else
404 return dm_gpio_request(desc, fmt);
405#endif
Simon Glass16e10402015-01-05 20:05:29 -0700406}
407
Simon Glasse821d182014-02-26 15:59:24 -0700408/**
409 * gpio_request() - [COMPAT] Request GPIO
410 * gpio: GPIO number
411 * label: Name for the requested GPIO
412 *
Simon Glass0f4517d2014-10-04 11:29:42 -0600413 * The label is copied and allocated so the caller does not need to keep
414 * the pointer around.
415 *
Simon Glasse821d182014-02-26 15:59:24 -0700416 * This function implements the API that's compatible with current
417 * GPIO API used in U-Boot. The request is forwarded to particular
418 * GPIO driver. Returns 0 on success, negative value on error.
419 */
420int gpio_request(unsigned gpio, const char *label)
421{
Simon Glassce555292015-01-05 20:05:27 -0700422 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700423 int ret;
424
Simon Glassce555292015-01-05 20:05:27 -0700425 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700426 if (ret)
427 return ret;
428
Simon Glassce555292015-01-05 20:05:27 -0700429 return dm_gpio_request(&desc, label);
Simon Glasse821d182014-02-26 15:59:24 -0700430}
431
432/**
Simon Glass1b27d602014-10-04 11:29:49 -0600433 * gpio_requestf() - [COMPAT] Request GPIO
434 * @gpio: GPIO number
435 * @fmt: Format string for the requested GPIO
436 * @...: Arguments for the printf() format string
437 *
438 * This function implements the API that's compatible with current
439 * GPIO API used in U-Boot. The request is forwarded to particular
440 * GPIO driver. Returns 0 on success, negative value on error.
441 */
442int gpio_requestf(unsigned gpio, const char *fmt, ...)
443{
Simon Glass7611ac62019-09-25 08:56:27 -0600444#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass1b27d602014-10-04 11:29:49 -0600445 va_list args;
446 char buf[40];
447
448 va_start(args, fmt);
449 vscnprintf(buf, sizeof(buf), fmt, args);
450 va_end(args);
451 return gpio_request(gpio, buf);
Simon Glassee8a3d92015-12-29 05:22:48 -0700452#else
453 return gpio_request(gpio, fmt);
454#endif
Simon Glass1b27d602014-10-04 11:29:49 -0600455}
456
Simon Glassce555292015-01-05 20:05:27 -0700457int _dm_gpio_free(struct udevice *dev, uint offset)
Simon Glasse821d182014-02-26 15:59:24 -0700458{
Simon Glass49f315a2021-02-04 21:22:05 -0700459 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -0600460 struct gpio_dev_priv *uc_priv;
Simon Glasse821d182014-02-26 15:59:24 -0700461 int ret;
462
Simon Glassde0977b2015-03-05 12:25:20 -0700463 uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -0600464 if (!uc_priv->name[offset])
465 return -ENXIO;
Simon Glass49f315a2021-02-04 21:22:05 -0700466 if (ops->rfree) {
467 ret = ops->rfree(dev, offset);
Simon Glass0f4517d2014-10-04 11:29:42 -0600468 if (ret)
469 return ret;
470 }
471
472 free(uc_priv->name[offset]);
473 uc_priv->name[offset] = NULL;
474
475 return 0;
476}
477
Simon Glassce555292015-01-05 20:05:27 -0700478/**
479 * gpio_free() - [COMPAT] Relinquish GPIO
480 * gpio: GPIO number
481 *
482 * This function implements the API that's compatible with current
483 * GPIO API used in U-Boot. The request is forwarded to particular
484 * GPIO driver. Returns 0 on success, negative value on error.
485 */
486int gpio_free(unsigned gpio)
487{
488 struct gpio_desc desc;
489 int ret;
490
491 ret = gpio_to_device(gpio, &desc);
492 if (ret)
493 return ret;
494
495 return _dm_gpio_free(desc.dev, desc.offset);
496}
497
Simon Glassfd838972016-03-06 19:27:51 -0700498static int check_reserved(const struct gpio_desc *desc, const char *func)
Simon Glass0f4517d2014-10-04 11:29:42 -0600499{
Simon Glass230c1432015-07-02 18:16:16 -0600500 struct gpio_dev_priv *uc_priv;
501
502 if (!dm_gpio_is_valid(desc))
503 return -ENOENT;
Simon Glass0f4517d2014-10-04 11:29:42 -0600504
Simon Glass230c1432015-07-02 18:16:16 -0600505 uc_priv = dev_get_uclass_priv(desc->dev);
Simon Glassce555292015-01-05 20:05:27 -0700506 if (!uc_priv->name[desc->offset]) {
Simon Glass0f4517d2014-10-04 11:29:42 -0600507 printf("%s: %s: error: gpio %s%d not reserved\n",
Simon Glassce555292015-01-05 20:05:27 -0700508 desc->dev->name, func,
509 uc_priv->bank_name ? uc_priv->bank_name : "",
510 desc->offset);
Simon Glass0f4517d2014-10-04 11:29:42 -0600511 return -EBUSY;
512 }
513
514 return 0;
Simon Glasse821d182014-02-26 15:59:24 -0700515}
516
517/**
518 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
519 * gpio: GPIO number
520 *
521 * This function implements the API that's compatible with current
522 * GPIO API used in U-Boot. The request is forwarded to particular
523 * GPIO driver. Returns 0 on success, negative value on error.
524 */
525int gpio_direction_input(unsigned gpio)
526{
Simon Glassce555292015-01-05 20:05:27 -0700527 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700528 int ret;
529
Simon Glassce555292015-01-05 20:05:27 -0700530 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700531 if (ret)
532 return ret;
533
Simon Glass722f9682021-02-04 21:22:04 -0700534 return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN);
Simon Glasse821d182014-02-26 15:59:24 -0700535}
536
537/**
538 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
539 * gpio: GPIO number
540 * value: Logical value to be set on the GPIO pin
541 *
542 * This function implements the API that's compatible with current
543 * GPIO API used in U-Boot. The request is forwarded to particular
544 * GPIO driver. Returns 0 on success, negative value on error.
545 */
546int gpio_direction_output(unsigned gpio, int value)
547{
Simon Glassce555292015-01-05 20:05:27 -0700548 struct gpio_desc desc;
Simon Glass722f9682021-02-04 21:22:04 -0700549 ulong flags;
Simon Glassce555292015-01-05 20:05:27 -0700550 int ret;
551
552 ret = gpio_to_device(gpio, &desc);
553 if (ret)
554 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700555
Simon Glass722f9682021-02-04 21:22:04 -0700556 flags = GPIOD_IS_OUT;
557 if (value)
558 flags |= GPIOD_IS_OUT_ACTIVE;
559 return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, flags);
Simon Glassce555292015-01-05 20:05:27 -0700560}
561
Patrick Delaunay4c2c96f2020-01-13 11:35:02 +0100562static int _gpio_get_value(const struct gpio_desc *desc)
Simon Glassce555292015-01-05 20:05:27 -0700563{
Simon Glass49f315a2021-02-04 21:22:05 -0700564 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glassce555292015-01-05 20:05:27 -0700565 int value;
Patrick Delaunay4c2c96f2020-01-13 11:35:02 +0100566
Simon Glass49f315a2021-02-04 21:22:05 -0700567 value = ops->get_value(desc->dev, desc->offset);
Patrick Delaunay4c2c96f2020-01-13 11:35:02 +0100568
569 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
570}
571
572int dm_gpio_get_value(const struct gpio_desc *desc)
573{
Simon Glassce555292015-01-05 20:05:27 -0700574 int ret;
575
576 ret = check_reserved(desc, "get_value");
577 if (ret)
578 return ret;
579
Patrick Delaunay4c2c96f2020-01-13 11:35:02 +0100580 return _gpio_get_value(desc);
Simon Glassce555292015-01-05 20:05:27 -0700581}
582
Simon Glassfd838972016-03-06 19:27:51 -0700583int dm_gpio_set_value(const struct gpio_desc *desc, int value)
Simon Glassce555292015-01-05 20:05:27 -0700584{
Simon Glass7b893f92021-02-04 21:22:03 -0700585 const struct dm_gpio_ops *ops;
Simon Glassce555292015-01-05 20:05:27 -0700586 int ret;
587
588 ret = check_reserved(desc, "set_value");
589 if (ret)
590 return ret;
591
592 if (desc->flags & GPIOD_ACTIVE_LOW)
593 value = !value;
Neil Armstrongf51b8da2020-05-05 10:43:17 +0200594
Simon Glass7b893f92021-02-04 21:22:03 -0700595 /* GPIOD_ are directly managed by driver in set_flags */
596 ops = gpio_get_ops(desc->dev);
597 if (ops->set_flags) {
598 ulong flags = desc->flags;
599
600 if (value)
601 flags |= GPIOD_IS_OUT_ACTIVE;
602 else
603 flags &= ~GPIOD_IS_OUT_ACTIVE;
604 return ops->set_flags(desc->dev, desc->offset, flags);
605 }
606
Neil Armstrongf51b8da2020-05-05 10:43:17 +0200607 /*
608 * Emulate open drain by not actively driving the line high or
609 * Emulate open source by not actively driving the line low
610 */
611 if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
612 (desc->flags & GPIOD_OPEN_SOURCE && !value))
Simon Glass7b893f92021-02-04 21:22:03 -0700613 return ops->direction_input(desc->dev, desc->offset);
Neil Armstrongf51b8da2020-05-05 10:43:17 +0200614 else if (desc->flags & GPIOD_OPEN_DRAIN ||
615 desc->flags & GPIOD_OPEN_SOURCE)
Simon Glass7b893f92021-02-04 21:22:03 -0700616 return ops->direction_output(desc->dev, desc->offset, value);
617
618 ret = ops->set_value(desc->dev, desc->offset, value);
619 if (ret)
620 return ret;
Neil Armstrongf51b8da2020-05-05 10:43:17 +0200621
Simon Glassce555292015-01-05 20:05:27 -0700622 return 0;
623}
624
Patrick Delaunay187c45f2020-01-13 11:35:04 +0100625/* check dir flags invalid configuration */
626static int check_dir_flags(ulong flags)
627{
628 if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
629 log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
630 __func__, flags);
631 return -EINVAL;
632 }
633
Patrick Delaunay5c1c06e2020-01-13 11:35:07 +0100634 if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
635 log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
636 __func__, flags);
637 return -EINVAL;
638 }
639
640 if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
641 log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
642 __func__, flags);
643 return -EINVAL;
644 }
645
Patrick Delaunay187c45f2020-01-13 11:35:04 +0100646 return 0;
647}
648
Simon Glass7b893f92021-02-04 21:22:03 -0700649/**
650 * _dm_gpio_set_flags() - Send flags to the driver
651 *
652 * This uses the best available method to send the given flags to the driver.
653 * Note that if flags & GPIOD_ACTIVE_LOW, the driver sees the opposite value
654 * of GPIOD_IS_OUT_ACTIVE.
655 *
656 * @desc: GPIO description
657 * @flags: flags value to set
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100658 * Return: 0 if OK, -ve on error
Simon Glass7b893f92021-02-04 21:22:03 -0700659 */
Simon Glass54befdd2021-02-04 21:21:55 -0700660static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
Simon Glassce555292015-01-05 20:05:27 -0700661{
662 struct udevice *dev = desc->dev;
Simon Glass49f315a2021-02-04 21:22:05 -0700663 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunay187c45f2020-01-13 11:35:04 +0100664 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100665 int ret = 0;
Simon Glasse821d182014-02-26 15:59:24 -0700666
Patrick Delaunay187c45f2020-01-13 11:35:04 +0100667 ret = check_dir_flags(flags);
668 if (ret) {
669 dev_dbg(dev,
670 "%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
671 desc->dev->name,
672 uc_priv->bank_name ? uc_priv->bank_name : "",
673 desc->offset, flags);
674
675 return ret;
676 }
677
Simon Glass7b893f92021-02-04 21:22:03 -0700678 /* If active low, invert the output state */
679 if ((flags & (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW)) ==
680 (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW))
681 flags ^= GPIOD_IS_OUT_ACTIVE;
682
Simon Glass54befdd2021-02-04 21:21:55 -0700683 /* GPIOD_ are directly managed by driver in set_flags */
684 if (ops->set_flags) {
685 ret = ops->set_flags(dev, desc->offset, flags);
Patrick Delaunay684326f2020-01-13 11:35:09 +0100686 } else {
687 if (flags & GPIOD_IS_OUT) {
Simon Glass7b893f92021-02-04 21:22:03 -0700688 bool value = flags & GPIOD_IS_OUT_ACTIVE;
689
690 ret = ops->direction_output(dev, desc->offset, value);
Patrick Delaunay684326f2020-01-13 11:35:09 +0100691 } else if (flags & GPIOD_IS_IN) {
692 ret = ops->direction_input(dev, desc->offset);
693 }
Simon Glassce555292015-01-05 20:05:27 -0700694 }
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100695
696 return ret;
697}
698
Simon Glass7b893f92021-02-04 21:22:03 -0700699int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set)
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100700{
Simon Glass7b893f92021-02-04 21:22:03 -0700701 ulong flags;
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100702 int ret;
703
704 ret = check_reserved(desc, "set_dir_flags");
Simon Glassce555292015-01-05 20:05:27 -0700705 if (ret)
706 return ret;
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100707
Simon Glass7b893f92021-02-04 21:22:03 -0700708 flags = (desc->flags & ~clr) | set;
709
Simon Glass54befdd2021-02-04 21:21:55 -0700710 ret = _dm_gpio_set_flags(desc, flags);
Simon Glass7b893f92021-02-04 21:22:03 -0700711 if (ret)
712 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700713
Simon Glass7b893f92021-02-04 21:22:03 -0700714 /* save the flags also in descriptor */
715 desc->flags = flags;
716
717 return 0;
718}
719
720int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
721{
722 /* combine the requested flags (for IN/OUT) and the descriptor flags */
723 return dm_gpio_clrset_flags(desc, GPIOD_MASK_DIR, flags);
Simon Glassce555292015-01-05 20:05:27 -0700724}
725
Simon Glass247ccf22021-02-04 21:22:09 -0700726int dm_gpios_clrset_flags(struct gpio_desc *desc, int count, ulong clr,
727 ulong set)
728{
729 int ret;
730 int i;
731
732 for (i = 0; i < count; i++) {
733 ret = dm_gpio_clrset_flags(&desc[i], clr, set);
734 if (ret)
735 return log_ret(ret);
736 }
737
738 return 0;
739}
740
Simon Glass909bee32021-02-04 21:21:57 -0700741int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100742{
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100743 struct udevice *dev = desc->dev;
744 int ret, value;
Simon Glass49f315a2021-02-04 21:22:05 -0700745 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glassd063ce92021-02-04 21:21:56 -0700746 ulong flags;
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100747
Simon Glassd063ce92021-02-04 21:21:56 -0700748 ret = check_reserved(desc, "get_flags");
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100749 if (ret)
750 return ret;
751
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100752 /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
Simon Glassd063ce92021-02-04 21:21:56 -0700753 if (ops->get_flags) {
754 ret = ops->get_flags(dev, desc->offset, &flags);
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100755 if (ret)
756 return ret;
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100757
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100758 /* GPIOD_ACTIVE_LOW is saved in desc->flags */
Simon Glassd063ce92021-02-04 21:21:56 -0700759 value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100760 if (desc->flags & GPIOD_ACTIVE_LOW)
761 value = !value;
Simon Glassd063ce92021-02-04 21:21:56 -0700762 flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
763 flags |= (desc->flags & GPIOD_ACTIVE_LOW);
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100764 if (value)
Simon Glassd063ce92021-02-04 21:21:56 -0700765 flags |= GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100766 } else {
Simon Glassd063ce92021-02-04 21:21:56 -0700767 flags = desc->flags;
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100768 /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
Simon Glassd063ce92021-02-04 21:21:56 -0700769 flags &= ~GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100770 if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
Simon Glassd063ce92021-02-04 21:21:56 -0700771 flags |= GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100772 }
Simon Glassd063ce92021-02-04 21:21:56 -0700773 *flagsp = flags;
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100774
775 return 0;
776}
777
Simon Glasse821d182014-02-26 15:59:24 -0700778/**
779 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
780 * gpio: GPIO number
781 *
782 * This function implements the API that's compatible with current
783 * GPIO API used in U-Boot. The request is forwarded to particular
784 * GPIO driver. Returns the value of the GPIO pin, or negative value
785 * on error.
786 */
787int gpio_get_value(unsigned gpio)
788{
Simon Glasse821d182014-02-26 15:59:24 -0700789 int ret;
790
Simon Glassce555292015-01-05 20:05:27 -0700791 struct gpio_desc desc;
792
793 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700794 if (ret)
795 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700796 return dm_gpio_get_value(&desc);
Simon Glasse821d182014-02-26 15:59:24 -0700797}
798
799/**
800 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
801 * gpio: GPIO number
802 * value: Logical value to be set on the GPIO pin.
803 *
804 * This function implements the API that's compatible with current
805 * GPIO API used in U-Boot. The request is forwarded to particular
806 * GPIO driver. Returns 0 on success, negative value on error.
807 */
808int gpio_set_value(unsigned gpio, int value)
809{
Simon Glassce555292015-01-05 20:05:27 -0700810 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700811 int ret;
812
Simon Glassce555292015-01-05 20:05:27 -0700813 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700814 if (ret)
815 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700816 return dm_gpio_set_value(&desc, value);
Simon Glasse821d182014-02-26 15:59:24 -0700817}
818
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200819const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
Simon Glasse821d182014-02-26 15:59:24 -0700820{
821 struct gpio_dev_priv *priv;
822
823 /* Must be called on an active device */
Simon Glassde0977b2015-03-05 12:25:20 -0700824 priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -0700825 assert(priv);
826
827 *bit_count = priv->gpio_count;
828 return priv->bank_name;
829}
830
Simon Glass6e5e6dd2014-10-04 11:29:43 -0600831static const char * const gpio_function[GPIOF_COUNT] = {
832 "input",
833 "output",
834 "unused",
835 "unknown",
836 "func",
837};
838
Masahiro Yamada286c2522017-06-22 16:50:25 +0900839static int get_function(struct udevice *dev, int offset, bool skip_unused,
840 const char **namep)
Simon Glass6e5e6dd2014-10-04 11:29:43 -0600841{
Simon Glassde0977b2015-03-05 12:25:20 -0700842 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass49f315a2021-02-04 21:22:05 -0700843 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass6e5e6dd2014-10-04 11:29:43 -0600844
845 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
846 if (!device_active(dev))
847 return -ENODEV;
848 if (offset < 0 || offset >= uc_priv->gpio_count)
849 return -EINVAL;
850 if (namep)
851 *namep = uc_priv->name[offset];
852 if (skip_unused && !uc_priv->name[offset])
853 return GPIOF_UNUSED;
854 if (ops->get_function) {
855 int ret;
856
857 ret = ops->get_function(dev, offset);
858 if (ret < 0)
859 return ret;
860 if (ret >= ARRAY_SIZE(gpio_function))
861 return -ENODATA;
862 return ret;
863 }
864
865 return GPIOF_UNKNOWN;
866}
867
868int gpio_get_function(struct udevice *dev, int offset, const char **namep)
869{
870 return get_function(dev, offset, true, namep);
871}
872
873int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
874{
875 return get_function(dev, offset, false, namep);
876}
877
Simon Glass6b1ef592014-10-04 11:29:44 -0600878int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
879{
Simon Glass49f315a2021-02-04 21:22:05 -0700880 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass6b1ef592014-10-04 11:29:44 -0600881 struct gpio_dev_priv *priv;
882 char *str = buf;
Patrice Chotard8b1310e2022-08-30 14:09:11 +0200883 const char *label;
Simon Glass6b1ef592014-10-04 11:29:44 -0600884 int func;
885 int ret;
886 int len;
Patrice Chotard8b1310e2022-08-30 14:09:11 +0200887 bool used;
Simon Glass6b1ef592014-10-04 11:29:44 -0600888
889 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
890
891 *buf = 0;
Simon Glassde0977b2015-03-05 12:25:20 -0700892 priv = dev_get_uclass_priv(dev);
Patrice Chotard8b1310e2022-08-30 14:09:11 +0200893 ret = gpio_get_raw_function(dev, offset, &label);
Simon Glass6b1ef592014-10-04 11:29:44 -0600894 if (ret < 0)
895 return ret;
896 func = ret;
897 len = snprintf(str, buffsize, "%s%d: %s",
898 priv->bank_name ? priv->bank_name : "",
899 offset, gpio_function[func]);
Simon Glass6b1ef592014-10-04 11:29:44 -0600900
Patrice Chotard8b1310e2022-08-30 14:09:11 +0200901 switch (func) {
902 case GPIOF_FUNC:
903 snprintf(str + len, buffsize - len, " %s", label ? label : "");
904 break;
905 case GPIOF_INPUT:
906 case GPIOF_OUTPUT:
907 case GPIOF_UNUSED:
Simon Glass6b1ef592014-10-04 11:29:44 -0600908 ret = ops->get_value(dev, offset);
909 if (ret < 0)
910 return ret;
911 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
912 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
913 ret,
914 used ? 'x' : ' ',
Patrice Chotardeb8f3a72022-08-30 14:09:12 +0200915 label ? " " : "",
Simon Glass6b1ef592014-10-04 11:29:44 -0600916 label ? label : "");
Patrice Chotard8b1310e2022-08-30 14:09:11 +0200917 break;
Simon Glass6b1ef592014-10-04 11:29:44 -0600918 }
919
920 return 0;
921}
922
Simon Glass3176b6c2020-07-07 13:11:44 -0600923#if CONFIG_IS_ENABLED(ACPIGEN)
924int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
925{
Simon Glass49f315a2021-02-04 21:22:05 -0700926 const struct dm_gpio_ops *ops;
Simon Glass3176b6c2020-07-07 13:11:44 -0600927
928 memset(gpio, '\0', sizeof(*gpio));
929 if (!dm_gpio_is_valid(desc)) {
930 /* Indicate that the GPIO is not valid */
931 gpio->pin_count = 0;
932 gpio->pins[0] = 0;
933 return -EINVAL;
934 }
935
936 ops = gpio_get_ops(desc->dev);
937 if (!ops->get_acpi)
938 return -ENOSYS;
939
940 return ops->get_acpi(desc, gpio);
941}
942#endif
943
Simon Glassbef54db2015-04-14 21:03:20 -0600944int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
945{
946 int i, ret;
947 int gpio;
948
949 for (i = 0; i < 32; i++) {
950 gpio = gpio_num_array[i];
951 if (gpio == -1)
952 break;
953 ret = gpio_requestf(gpio, fmt, i);
954 if (ret)
955 goto err;
956 ret = gpio_direction_input(gpio);
957 if (ret) {
958 gpio_free(gpio);
959 goto err;
960 }
961 }
962
963 return 0;
964err:
965 for (i--; i >= 0; i--)
966 gpio_free(gpio_num_array[i]);
967
968 return ret;
969}
970
Simon Glass2c97a8f2014-11-10 18:00:21 -0700971/*
972 * get a number comprised of multiple GPIO values. gpio_num_array points to
973 * the array of gpio pin numbers to scan, terminated by -1.
974 */
Simon Glassbef54db2015-04-14 21:03:20 -0600975int gpio_get_values_as_int(const int *gpio_list)
Simon Glass2c97a8f2014-11-10 18:00:21 -0700976{
977 int gpio;
978 unsigned bitmask = 1;
979 unsigned vector = 0;
Simon Glassbef54db2015-04-14 21:03:20 -0600980 int ret;
Simon Glass2c97a8f2014-11-10 18:00:21 -0700981
982 while (bitmask &&
Simon Glassbef54db2015-04-14 21:03:20 -0600983 ((gpio = *gpio_list++) != -1)) {
984 ret = gpio_get_value(gpio);
985 if (ret < 0)
986 return ret;
987 else if (ret)
Simon Glass2c97a8f2014-11-10 18:00:21 -0700988 vector |= bitmask;
989 bitmask <<= 1;
990 }
Simon Glassbef54db2015-04-14 21:03:20 -0600991
Simon Glass2c97a8f2014-11-10 18:00:21 -0700992 return vector;
993}
994
Simon Glassfd838972016-03-06 19:27:51 -0700995int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
Simon Glassdf1687d2016-03-06 19:27:50 -0700996{
997 unsigned bitmask = 1;
998 unsigned vector = 0;
999 int ret, i;
1000
1001 for (i = 0; i < count; i++) {
1002 ret = dm_gpio_get_value(&desc_list[i]);
1003 if (ret < 0)
1004 return ret;
1005 else if (ret)
1006 vector |= bitmask;
1007 bitmask <<= 1;
1008 }
Simon Glass247ccf22021-02-04 21:22:09 -07001009
1010 return vector;
1011}
1012
1013int dm_gpio_get_values_as_int_base3(struct gpio_desc *desc_list,
1014 int count)
1015{
1016 static const char tristate[] = "01z";
1017 enum {
1018 PULLUP,
1019 PULLDOWN,
1020
1021 NUM_OPTIONS,
1022 };
1023 int vals[NUM_OPTIONS];
1024 uint mask;
1025 uint vector = 0;
1026 int ret, i;
1027
1028 /*
1029 * Limit to 19 digits which should be plenty. This avoids overflow of a
1030 * 32-bit int
1031 */
1032 assert(count < 20);
1033
1034 for (i = 0; i < NUM_OPTIONS; i++) {
1035 uint flags = GPIOD_IS_IN;
1036
1037 flags |= (i == PULLDOWN) ? GPIOD_PULL_DOWN : GPIOD_PULL_UP;
1038 ret = dm_gpios_clrset_flags(desc_list, count, GPIOD_MASK_PULL,
1039 flags);
1040 if (ret)
1041 return log_msg_ret("pu", ret);
1042
1043 /* Give the lines time to settle */
1044 udelay(10);
1045
1046 ret = dm_gpio_get_values_as_int(desc_list, count);
1047 if (ret < 0)
1048 return log_msg_ret("get1", ret);
1049 vals[i] = ret;
1050 }
1051
1052 log_debug("values: %x %x, count = %d\n", vals[0], vals[1], count);
1053 for (i = count - 1, mask = 1 << i; i >= 0; i--, mask >>= 1) {
1054 uint pd = vals[PULLDOWN] & mask ? 1 : 0;
1055 uint pu = vals[PULLUP] & mask ? 1 : 0;
1056 uint digit;
1057
1058 /*
1059 * Get value with internal pulldown active. If this is 1 then
1060 * there is a stronger external pullup, which we call 1. If not
1061 * then call it 0.
1062 *
1063 * If the values differ then the pin is floating so we call
1064 * this a 2.
1065 */
1066 if (pu == pd)
1067 digit = pd;
1068 else
1069 digit = 2;
1070 log_debug("%c ", tristate[digit]);
1071 vector = 3 * vector + digit;
1072 }
1073 log_debug("vector=%d\n", vector);
Simon Glassdf1687d2016-03-06 19:27:50 -07001074
1075 return vector;
1076}
1077
Heiko Schocher58e4c382019-07-17 06:59:51 +02001078/**
1079 * gpio_request_tail: common work for requesting a gpio.
1080 *
1081 * ret: return value from previous work in function which calls
1082 * this function.
1083 * This seems bogus (why calling this function instead not
1084 * calling it and end caller function instead?).
1085 * Because on error in caller function we want to set some
1086 * default values in gpio desc and have a common error
1087 * debug message, which provides this function.
1088 * nodename: Name of node for which gpio gets requested
1089 * used for gpio label name.
1090 * args: pointer to output arguments structure
1091 * list_name: Name of GPIO list
1092 * used for gpio label name.
1093 * index: gpio index in gpio list
1094 * used for gpio label name.
1095 * desc: pointer to gpio descriptor, filled from this
1096 * function.
1097 * flags: gpio flags to use.
1098 * add_index: should index added to gpio label name
1099 * gpio_dev: pointer to gpio device from which the gpio
1100 * will be requested. If NULL try to get the
1101 * gpio device with uclass_get_device_by_ofnode()
1102 *
1103 * return: In error case this function sets default values in
1104 * gpio descriptor, also emmits a debug message.
1105 * On success it returns 0 else the error code from
1106 * function calls, or the error code passed through
1107 * ret to this function.
1108 *
1109 */
Heiko Schocher39cb3402019-06-12 06:11:46 +02001110static int gpio_request_tail(int ret, const char *nodename,
Simon Glass12faa022017-05-18 20:09:18 -06001111 struct ofnode_phandle_args *args,
1112 const char *list_name, int index,
Heiko Schocher39cb3402019-06-12 06:11:46 +02001113 struct gpio_desc *desc, int flags,
Heiko Schocher58e4c382019-07-17 06:59:51 +02001114 bool add_index, struct udevice *gpio_dev)
Simon Glass16e10402015-01-05 20:05:29 -07001115{
Patrick Delaunay758bba92020-01-13 11:35:01 +01001116 gpio_desc_init(desc, gpio_dev, 0);
Simon Glass12faa022017-05-18 20:09:18 -06001117 if (ret)
Simon Glass16e10402015-01-05 20:05:29 -07001118 goto err;
Simon Glass16e10402015-01-05 20:05:29 -07001119
Heiko Schocher39cb3402019-06-12 06:11:46 +02001120 if (!desc->dev) {
1121 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
1122 &desc->dev);
1123 if (ret) {
Heiko Schocher58e4c382019-07-17 06:59:51 +02001124 debug("%s: uclass_get_device_by_ofnode failed\n",
1125 __func__);
Heiko Schocher39cb3402019-06-12 06:11:46 +02001126 goto err;
1127 }
Simon Glass16e10402015-01-05 20:05:29 -07001128 }
Simon Glass12faa022017-05-18 20:09:18 -06001129 ret = gpio_find_and_xlate(desc, args);
Simon Glass16e10402015-01-05 20:05:29 -07001130 if (ret) {
1131 debug("%s: gpio_find_and_xlate failed\n", __func__);
1132 goto err;
1133 }
1134 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
Heiko Schocher39cb3402019-06-12 06:11:46 +02001135 nodename, list_name, index);
Simon Glass16e10402015-01-05 20:05:29 -07001136 if (ret) {
1137 debug("%s: dm_gpio_requestf failed\n", __func__);
1138 goto err;
1139 }
Simon Glass7b893f92021-02-04 21:22:03 -07001140
1141 /* Keep any direction flags provided by the devicetree */
1142 ret = dm_gpio_set_dir_flags(desc,
1143 flags | (desc->flags & GPIOD_MASK_DIR));
Simon Glass16e10402015-01-05 20:05:29 -07001144 if (ret) {
1145 debug("%s: dm_gpio_set_dir failed\n", __func__);
1146 goto err;
1147 }
1148
1149 return 0;
1150err:
1151 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
Heiko Schocher39cb3402019-06-12 06:11:46 +02001152 __func__, nodename, list_name, index, ret);
Simon Glass16e10402015-01-05 20:05:29 -07001153 return ret;
1154}
1155
Simon Glass92882652021-08-07 07:24:04 -06001156#if CONFIG_IS_ENABLED(OF_REAL)
Simon Glass1d9af1f2017-05-30 21:47:09 -06001157static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
1158 int index, struct gpio_desc *desc,
1159 int flags, bool add_index)
Simon Glass12faa022017-05-18 20:09:18 -06001160{
1161 struct ofnode_phandle_args args;
1162 int ret;
1163
Simon Glass1d9af1f2017-05-30 21:47:09 -06001164 ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
1165 index, &args);
Simon Glass12faa022017-05-18 20:09:18 -06001166
Heiko Schocher39cb3402019-06-12 06:11:46 +02001167 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1168 index, desc, flags, add_index, NULL);
Simon Glass12faa022017-05-18 20:09:18 -06001169}
1170
Simon Glass1d9af1f2017-05-30 21:47:09 -06001171int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
Simon Glass16e10402015-01-05 20:05:29 -07001172 struct gpio_desc *desc, int flags)
1173{
Simon Glass1d9af1f2017-05-30 21:47:09 -06001174 return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
1175 index > 0);
Simon Glass16e10402015-01-05 20:05:29 -07001176}
1177
Simon Glass1d9af1f2017-05-30 21:47:09 -06001178int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
Simon Glass16e10402015-01-05 20:05:29 -07001179 struct gpio_desc *desc, int flags)
1180{
Simon Glass1d9af1f2017-05-30 21:47:09 -06001181 struct ofnode_phandle_args args;
Heiko Schocher39cb3402019-06-12 06:11:46 +02001182 ofnode node;
Simon Glass1d9af1f2017-05-30 21:47:09 -06001183 int ret;
1184
1185 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
1186 index, &args);
Heiko Schocher39cb3402019-06-12 06:11:46 +02001187 node = dev_ofnode(dev);
1188 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1189 index, desc, flags, index > 0, NULL);
Simon Glass16e10402015-01-05 20:05:29 -07001190}
1191
Andrew Jeffery2e62c6b2022-01-31 13:54:05 +10301192int gpio_request_by_line_name(struct udevice *dev, const char *line_name,
1193 struct gpio_desc *desc, int flags)
1194{
1195 int ret;
1196
1197 ret = dev_read_stringlist_search(dev, "gpio-line-names", line_name);
1198 if (ret < 0)
1199 return ret;
1200
1201 desc->dev = dev;
1202 desc->offset = ret;
1203 desc->flags = 0;
1204
1205 ret = dm_gpio_request(desc, line_name);
1206 if (ret) {
1207 debug("%s: dm_gpio_requestf failed\n", __func__);
1208 return ret;
1209 }
1210
1211 ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
1212 if (ret)
1213 debug("%s: dm_gpio_set_dir failed\n", __func__);
1214
1215 return ret;
1216}
1217
Simon Glass1d9af1f2017-05-30 21:47:09 -06001218int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
Simon Glass16e10402015-01-05 20:05:29 -07001219 struct gpio_desc *desc, int max_count,
1220 int flags)
1221{
1222 int count;
1223 int ret;
1224
Przemyslaw Marczak44fc5362015-03-31 18:57:16 +02001225 for (count = 0; count < max_count; count++) {
Simon Glass1d9af1f2017-05-30 21:47:09 -06001226 ret = _gpio_request_by_name_nodev(node, list_name, count,
Simon Glass16e10402015-01-05 20:05:29 -07001227 &desc[count], flags, true);
1228 if (ret == -ENOENT)
1229 break;
1230 else if (ret)
1231 goto err;
1232 }
1233
1234 /* We ran out of GPIOs in the list */
1235 return count;
1236
1237err:
1238 gpio_free_list_nodev(desc, count - 1);
1239
1240 return ret;
1241}
1242
1243int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
1244 struct gpio_desc *desc, int max_count,
1245 int flags)
1246{
1247 /*
1248 * This isn't ideal since we don't use dev->name in the debug()
1249 * calls in gpio_request_by_name(), but we can do this until
1250 * gpio_request_list_by_name_nodev() can be dropped.
1251 */
Simon Glass1d9af1f2017-05-30 21:47:09 -06001252 return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
1253 max_count, flags);
Simon Glass16e10402015-01-05 20:05:29 -07001254}
1255
1256int gpio_get_list_count(struct udevice *dev, const char *list_name)
1257{
1258 int ret;
1259
Sean Anderson8ad66c52021-04-20 10:50:54 -04001260 ret = dev_count_phandle_with_args(dev, list_name, "#gpio-cells",
1261 -ENOENT);
1262 if (ret < 0) {
Simon Glass16e10402015-01-05 20:05:29 -07001263 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
1264 __func__, dev->name, list_name, ret);
1265 }
1266
1267 return ret;
1268}
Simon Glassea383722021-02-04 21:21:54 -07001269#endif /* OF_PLATDATA */
Simon Glass16e10402015-01-05 20:05:29 -07001270
Simon Glass2149e112021-08-07 07:24:12 -06001271#if CONFIG_IS_ENABLED(OF_PLATDATA)
1272int gpio_request_by_phandle(struct udevice *dev,
1273 const struct phandle_2_arg *cells,
1274 struct gpio_desc *desc, int flags)
1275{
1276 struct ofnode_phandle_args args;
1277 struct udevice *gpio_dev;
1278 const int index = 0;
1279 int ret;
1280
1281 ret = device_get_by_ofplat_idx(cells->idx, &gpio_dev);
1282 if (ret)
1283 return ret;
1284 args.args[0] = cells->arg[0];
1285 args.args[1] = cells->arg[1];
1286
1287 return gpio_request_tail(ret, NULL, &args, NULL, index, desc, flags,
1288 index > 0, gpio_dev);
1289}
1290#endif
1291
Simon Glass16e10402015-01-05 20:05:29 -07001292int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
1293{
1294 /* For now, we don't do any checking of dev */
1295 return _dm_gpio_free(desc->dev, desc->offset);
1296}
1297
1298int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
1299{
1300 int i;
1301
1302 /* For now, we don't do any checking of dev */
1303 for (i = 0; i < count; i++)
1304 dm_gpio_free(dev, &desc[i]);
1305
1306 return 0;
1307}
1308
1309int gpio_free_list_nodev(struct gpio_desc *desc, int count)
1310{
1311 return gpio_free_list(NULL, desc, count);
1312}
1313
Simon Glasse821d182014-02-26 15:59:24 -07001314/* We need to renumber the GPIOs when any driver is probed/removed */
Simon Glass0f4517d2014-10-04 11:29:42 -06001315static int gpio_renumber(struct udevice *removed_dev)
Simon Glasse821d182014-02-26 15:59:24 -07001316{
1317 struct gpio_dev_priv *uc_priv;
Heiko Schocherb74fcb42014-05-22 12:43:05 +02001318 struct udevice *dev;
Simon Glasse821d182014-02-26 15:59:24 -07001319 struct uclass *uc;
1320 unsigned base;
1321 int ret;
1322
1323 ret = uclass_get(UCLASS_GPIO, &uc);
1324 if (ret)
1325 return ret;
1326
1327 /* Ensure that we have a base for each bank */
1328 base = 0;
1329 uclass_foreach_dev(dev, uc) {
Simon Glass0f4517d2014-10-04 11:29:42 -06001330 if (device_active(dev) && dev != removed_dev) {
Simon Glassde0977b2015-03-05 12:25:20 -07001331 uc_priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -07001332 uc_priv->gpio_base = base;
1333 base += uc_priv->gpio_count;
1334 }
1335 }
1336
1337 return 0;
1338}
1339
Simon Glassfd838972016-03-06 19:27:51 -07001340int gpio_get_number(const struct gpio_desc *desc)
Simon Glass94f54d12015-03-25 12:21:58 -06001341{
1342 struct udevice *dev = desc->dev;
1343 struct gpio_dev_priv *uc_priv;
1344
1345 if (!dev)
1346 return -1;
Simon Glass95588622020-12-22 19:30:28 -07001347 uc_priv = dev_get_uclass_priv(dev);
Simon Glass94f54d12015-03-25 12:21:58 -06001348
1349 return uc_priv->gpio_base + desc->offset;
1350}
1351
Heiko Schocherb74fcb42014-05-22 12:43:05 +02001352static int gpio_post_probe(struct udevice *dev)
Simon Glasse821d182014-02-26 15:59:24 -07001353{
Simon Glassde0977b2015-03-05 12:25:20 -07001354 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -06001355
1356 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
1357 if (!uc_priv->name)
1358 return -ENOMEM;
1359
1360 return gpio_renumber(NULL);
Simon Glasse821d182014-02-26 15:59:24 -07001361}
1362
Heiko Schocherb74fcb42014-05-22 12:43:05 +02001363static int gpio_pre_remove(struct udevice *dev)
Simon Glasse821d182014-02-26 15:59:24 -07001364{
Simon Glassde0977b2015-03-05 12:25:20 -07001365 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -06001366 int i;
1367
1368 for (i = 0; i < uc_priv->gpio_count; i++) {
1369 if (uc_priv->name[i])
1370 free(uc_priv->name[i]);
1371 }
1372 free(uc_priv->name);
1373
1374 return gpio_renumber(dev);
Simon Glasse821d182014-02-26 15:59:24 -07001375}
1376
Heiko Schocher39cb3402019-06-12 06:11:46 +02001377int gpio_dev_request_index(struct udevice *dev, const char *nodename,
1378 char *list_name, int index, int flags,
1379 int dtflags, struct gpio_desc *desc)
1380{
1381 struct ofnode_phandle_args args;
1382
1383 args.node = ofnode_null();
1384 args.args_count = 2;
1385 args.args[0] = index;
1386 args.args[1] = dtflags;
1387
1388 return gpio_request_tail(0, nodename, &args, list_name, index, desc,
1389 flags, 0, dev);
1390}
1391
Jean-Jacques Hiblot775d6a22020-09-11 13:43:34 +05301392static void devm_gpiod_release(struct udevice *dev, void *res)
1393{
1394 dm_gpio_free(dev, res);
1395}
1396
1397static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
1398{
1399 return res == data;
1400}
1401
1402struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
1403 unsigned int index, int flags)
1404{
1405 int rc;
1406 struct gpio_desc *desc;
1407 char *propname;
1408 static const char suffix[] = "-gpios";
1409
1410 propname = malloc(strlen(id) + sizeof(suffix));
1411 if (!propname) {
1412 rc = -ENOMEM;
1413 goto end;
1414 }
1415
1416 strcpy(propname, id);
1417 strcat(propname, suffix);
1418
1419 desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
1420 __GFP_ZERO);
1421 if (unlikely(!desc)) {
1422 rc = -ENOMEM;
1423 goto end;
1424 }
1425
1426 rc = gpio_request_by_name(dev, propname, index, desc, flags);
1427
1428end:
1429 if (propname)
1430 free(propname);
1431
1432 if (rc)
1433 return ERR_PTR(rc);
1434
1435 devres_add(dev, desc);
1436
1437 return desc;
1438}
1439
1440struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
1441 const char *id,
1442 unsigned int index,
1443 int flags)
1444{
1445 struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);
1446
1447 if (IS_ERR(desc))
1448 return NULL;
1449
1450 return desc;
1451}
1452
1453void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
1454{
1455 int rc;
1456
1457 rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
1458 WARN_ON(rc);
1459}
1460
Michal Simek5f7202c2018-07-12 12:42:27 +02001461static int gpio_post_bind(struct udevice *dev)
1462{
1463#if defined(CONFIG_NEEDS_MANUAL_RELOC)
1464 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
1465 static int reloc_done;
1466
1467 if (!reloc_done) {
1468 if (ops->request)
1469 ops->request += gd->reloc_off;
Simon Glassb3a47542020-02-04 20:15:17 -07001470 if (ops->rfree)
1471 ops->rfree += gd->reloc_off;
Michal Simek5f7202c2018-07-12 12:42:27 +02001472 if (ops->direction_input)
1473 ops->direction_input += gd->reloc_off;
1474 if (ops->direction_output)
1475 ops->direction_output += gd->reloc_off;
1476 if (ops->get_value)
1477 ops->get_value += gd->reloc_off;
1478 if (ops->set_value)
1479 ops->set_value += gd->reloc_off;
Michal Simek5f7202c2018-07-12 12:42:27 +02001480 if (ops->get_function)
1481 ops->get_function += gd->reloc_off;
1482 if (ops->xlate)
1483 ops->xlate += gd->reloc_off;
Simon Glass54befdd2021-02-04 21:21:55 -07001484 if (ops->set_flags)
1485 ops->set_flags += gd->reloc_off;
Simon Glassd063ce92021-02-04 21:21:56 -07001486 if (ops->get_flags)
1487 ops->get_flags += gd->reloc_off;
Michal Simek5f7202c2018-07-12 12:42:27 +02001488
1489 reloc_done++;
1490 }
1491#endif
Heiko Schocher39cb3402019-06-12 06:11:46 +02001492
Eddie James652b8692022-02-07 17:09:01 -06001493 if (CONFIG_IS_ENABLED(GPIO_HOG)) {
1494 struct udevice *child;
1495 ofnode node;
1496
Heiko Schocher58e4c382019-07-17 06:59:51 +02001497 dev_for_each_subnode(node, dev) {
1498 if (ofnode_read_bool(node, "gpio-hog")) {
1499 const char *name = ofnode_get_name(node);
1500 int ret;
Heiko Schocher39cb3402019-06-12 06:11:46 +02001501
Heiko Schocher58e4c382019-07-17 06:59:51 +02001502 ret = device_bind_driver_to_node(dev,
1503 "gpio_hog",
1504 name, node,
1505 &child);
1506 if (ret)
1507 return ret;
1508 }
Heiko Schocher39cb3402019-06-12 06:11:46 +02001509 }
1510 }
Michal Simek5f7202c2018-07-12 12:42:27 +02001511 return 0;
1512}
1513
Simon Glasse821d182014-02-26 15:59:24 -07001514UCLASS_DRIVER(gpio) = {
1515 .id = UCLASS_GPIO,
1516 .name = "gpio",
Bhuvanchandra DVb1a1fc92015-06-01 18:37:15 +05301517 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glasse821d182014-02-26 15:59:24 -07001518 .post_probe = gpio_post_probe,
Michal Simek5f7202c2018-07-12 12:42:27 +02001519 .post_bind = gpio_post_bind,
Simon Glasse821d182014-02-26 15:59:24 -07001520 .pre_remove = gpio_pre_remove,
Simon Glass8a2b47f2020-12-03 16:55:17 -07001521 .per_device_auto = sizeof(struct gpio_dev_priv),
Simon Glasse821d182014-02-26 15:59:24 -07001522};