blob: 729e41033bb4dfcf42fa5629ee3089109bc98e5e [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 Glassf7ae49f2020-05-10 11:40:05 -060010#include <log.h>
Jean-Jacques Hiblotd4b722e2020-09-11 13:43:34 +053011#include <dm/devres.h>
12#include <dm/device_compat.h>
Heiko Schocher5fc7cf82019-06-12 06:11:46 +020013#include <dm/device-internal.h>
14#include <dm/lists.h>
15#include <dm/uclass-internal.h>
Eric Nelson6c880b72016-04-24 16:32:40 -070016#include <dt-bindings/gpio/gpio.h>
Simon Glass96495d92014-02-26 15:59:24 -070017#include <errno.h>
Simon Glass0dac4d52015-01-05 20:05:28 -070018#include <fdtdec.h>
Simon Glassb892d122014-10-04 11:29:42 -060019#include <malloc.h>
Simon Glass29126862020-07-07 13:11:44 -060020#include <acpi/acpi_device.h>
Simon Glass401d1c42020-10-30 21:38:53 -060021#include <asm/global_data.h>
Simon Glass96495d92014-02-26 15:59:24 -070022#include <asm/gpio.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060023#include <dm/device_compat.h>
Masahiro Yamada84b8bf62016-01-24 23:27:48 +090024#include <linux/bug.h>
Simon Glassfe1ef502014-10-22 21:37:01 -060025#include <linux/ctype.h>
Simon Glass96495d92014-02-26 15:59:24 -070026
Simon Glass3669e0e2015-01-05 20:05:29 -070027DECLARE_GLOBAL_DATA_PTR;
28
Simon Glass96495d92014-02-26 15:59:24 -070029/**
Patrick Delaunay9f2b0662020-01-13 11:35:01 +010030 * gpio_desc_init() - Initialize the GPIO descriptor
31 *
32 * @desc: GPIO descriptor to initialize
33 * @dev: GPIO device
34 * @offset: Offset of device GPIO
35 */
36static void gpio_desc_init(struct gpio_desc *desc,
37 struct udevice *dev,
38 uint offset)
39{
40 desc->dev = dev;
41 desc->offset = offset;
42 desc->flags = 0;
43}
44
45/**
Simon Glass96495d92014-02-26 15:59:24 -070046 * gpio_to_device() - Convert global GPIO number to device, number
Simon Glass96495d92014-02-26 15:59:24 -070047 *
48 * Convert the GPIO number to an entry in the list of GPIOs
49 * or GPIO blocks registered with the GPIO controller. Returns
50 * entry on success, NULL on error.
Simon Glassae7123f2015-01-05 20:05:27 -070051 *
52 * @gpio: The numeric representation of the GPIO
53 * @desc: Returns description (desc->flags will always be 0)
54 * @return 0 if found, -ENOENT if not found
Simon Glass96495d92014-02-26 15:59:24 -070055 */
Simon Glassae7123f2015-01-05 20:05:27 -070056static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
Simon Glass96495d92014-02-26 15:59:24 -070057{
58 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +020059 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -070060 int ret;
61
62 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
63 dev;
64 ret = uclass_next_device(&dev)) {
Simon Glasse564f052015-03-05 12:25:20 -070065 uc_priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -070066 if (gpio >= uc_priv->gpio_base &&
67 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
Patrick Delaunay9f2b0662020-01-13 11:35:01 +010068 gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
Simon Glass96495d92014-02-26 15:59:24 -070069 return 0;
70 }
71 }
72
73 /* No such GPIO */
Simon Glassae7123f2015-01-05 20:05:27 -070074 return ret ? ret : -ENOENT;
Simon Glass96495d92014-02-26 15:59:24 -070075}
76
Heiko Schocher2bd261d2020-05-22 11:08:59 +020077#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL)
78/**
79 * dm_gpio_lookup_label() - look for name in gpio device
80 *
81 * search in uc_priv, if there is a gpio with labelname same
82 * as name.
83 *
84 * @name: name which is searched
85 * @uc_priv: gpio_dev_priv pointer.
86 * @offset: gpio offset within the device
87 * @return: 0 if found, -ENOENT if not.
88 */
89static int dm_gpio_lookup_label(const char *name,
90 struct gpio_dev_priv *uc_priv, ulong *offset)
91{
92 int len;
93 int i;
94
95 *offset = -1;
96 len = strlen(name);
97 for (i = 0; i < uc_priv->gpio_count; i++) {
98 if (!uc_priv->name[i])
99 continue;
100 if (!strncmp(name, uc_priv->name[i], len)) {
101 *offset = i;
102 return 0;
103 }
104 }
105 return -ENOENT;
106}
107#else
108static int
109dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv,
110 ulong *offset)
111{
112 return -ENOENT;
113}
114#endif
115
Simon Glass32ec1592015-06-23 15:38:40 -0600116int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
Simon Glass96495d92014-02-26 15:59:24 -0700117{
Simon Glassfe1ef502014-10-22 21:37:01 -0600118 struct gpio_dev_priv *uc_priv = NULL;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200119 struct udevice *dev;
Simon Glassfe1ef502014-10-22 21:37:01 -0600120 ulong offset;
121 int numeric;
Simon Glass96495d92014-02-26 15:59:24 -0700122 int ret;
123
Simon Glassfe1ef502014-10-22 21:37:01 -0600124 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
Simon Glass96495d92014-02-26 15:59:24 -0700125 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
126 dev;
127 ret = uclass_next_device(&dev)) {
Simon Glass96495d92014-02-26 15:59:24 -0700128 int len;
129
Simon Glasse564f052015-03-05 12:25:20 -0700130 uc_priv = dev_get_uclass_priv(dev);
Simon Glassfe1ef502014-10-22 21:37:01 -0600131 if (numeric != -1) {
132 offset = numeric - uc_priv->gpio_base;
133 /* Allow GPIOs to be numbered from 0 */
Tom Rini75897912017-05-10 15:20:15 -0400134 if (offset < uc_priv->gpio_count)
Simon Glassfe1ef502014-10-22 21:37:01 -0600135 break;
136 }
137
Simon Glass96495d92014-02-26 15:59:24 -0700138 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
139
Simon Glass939cda52014-06-11 23:29:47 -0600140 if (!strncasecmp(name, uc_priv->bank_name, len)) {
Simon Glassfe1ef502014-10-22 21:37:01 -0600141 if (!strict_strtoul(name + len, 10, &offset))
142 break;
Simon Glass96495d92014-02-26 15:59:24 -0700143 }
Heiko Schocher2bd261d2020-05-22 11:08:59 +0200144
145 /*
146 * if we did not found a gpio through its bank
147 * name, we search for a valid gpio label.
148 */
149 if (!dm_gpio_lookup_label(name, uc_priv, &offset))
150 break;
Simon Glass96495d92014-02-26 15:59:24 -0700151 }
152
Simon Glassfe1ef502014-10-22 21:37:01 -0600153 if (!dev)
154 return ret ? ret : -EINVAL;
155
Patrick Delaunay9f2b0662020-01-13 11:35:01 +0100156 gpio_desc_init(desc, dev, offset);
Simon Glass32ec1592015-06-23 15:38:40 -0600157
158 return 0;
159}
160
161int gpio_lookup_name(const char *name, struct udevice **devp,
162 unsigned int *offsetp, unsigned int *gpiop)
163{
164 struct gpio_desc desc;
165 int ret;
166
Simon Glassfe1ef502014-10-22 21:37:01 -0600167 if (devp)
Simon Glass32ec1592015-06-23 15:38:40 -0600168 *devp = NULL;
169 ret = dm_gpio_lookup_name(name, &desc);
170 if (ret)
171 return ret;
172
173 if (devp)
174 *devp = desc.dev;
Simon Glassfe1ef502014-10-22 21:37:01 -0600175 if (offsetp)
Simon Glass32ec1592015-06-23 15:38:40 -0600176 *offsetp = desc.offset;
177 if (gpiop) {
178 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
179
180 *gpiop = uc_priv->gpio_base + desc.offset;
181 }
Simon Glassfe1ef502014-10-22 21:37:01 -0600182
183 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700184}
185
Simon Glass3a571232017-05-18 20:09:18 -0600186int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
187 struct ofnode_phandle_args *args)
Eric Nelson6c880b72016-04-24 16:32:40 -0700188{
189 if (args->args_count < 1)
190 return -EINVAL;
191
192 desc->offset = args->args[0];
193
194 if (args->args_count < 2)
195 return 0;
196
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100197 desc->flags = 0;
Eric Nelson6c880b72016-04-24 16:32:40 -0700198 if (args->args[1] & GPIO_ACTIVE_LOW)
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100199 desc->flags |= GPIOD_ACTIVE_LOW;
Eric Nelson6c880b72016-04-24 16:32:40 -0700200
Patrick Delaunay477ca572020-01-13 11:35:07 +0100201 /*
202 * need to test 2 bits for gpio output binding:
203 * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
204 * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
205 */
206 if (args->args[1] & GPIO_SINGLE_ENDED) {
207 if (args->args[1] & GPIO_LINE_OPEN_DRAIN)
208 desc->flags |= GPIOD_OPEN_DRAIN;
209 else
210 desc->flags |= GPIOD_OPEN_SOURCE;
211 }
212
213 if (args->args[1] & GPIO_PULL_UP)
214 desc->flags |= GPIOD_PULL_UP;
215
216 if (args->args[1] & GPIO_PULL_DOWN)
217 desc->flags |= GPIOD_PULL_DOWN;
218
Eric Nelson6c880b72016-04-24 16:32:40 -0700219 return 0;
220}
221
Simon Glass3669e0e2015-01-05 20:05:29 -0700222static int gpio_find_and_xlate(struct gpio_desc *desc,
Simon Glass3a571232017-05-18 20:09:18 -0600223 struct ofnode_phandle_args *args)
Simon Glass0dac4d52015-01-05 20:05:28 -0700224{
Simon Glass3d647742021-02-04 21:22:05 -0700225 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glass0dac4d52015-01-05 20:05:28 -0700226
Eric Nelson6c880b72016-04-24 16:32:40 -0700227 if (ops->xlate)
228 return ops->xlate(desc->dev, desc, args);
Simon Glass0dac4d52015-01-05 20:05:28 -0700229 else
Eric Nelson6c880b72016-04-24 16:32:40 -0700230 return gpio_xlate_offs_flags(desc->dev, desc, args);
Simon Glass0dac4d52015-01-05 20:05:28 -0700231}
232
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200233#if defined(CONFIG_GPIO_HOG)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200234
235struct gpio_hog_priv {
236 struct gpio_desc gpiod;
237};
238
239struct gpio_hog_data {
240 int gpiod_flags;
241 int value;
242 u32 val[2];
243};
244
Simon Glassd1998a92020-12-03 16:55:21 -0700245static int gpio_hog_of_to_plat(struct udevice *dev)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200246{
Simon Glassc69cda22020-12-03 16:55:20 -0700247 struct gpio_hog_data *plat = dev_get_plat(dev);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200248 const char *nodename;
249 int ret;
250
251 plat->value = 0;
252 if (dev_read_bool(dev, "input")) {
253 plat->gpiod_flags = GPIOD_IS_IN;
254 } else if (dev_read_bool(dev, "output-high")) {
255 plat->value = 1;
256 plat->gpiod_flags = GPIOD_IS_OUT;
257 } else if (dev_read_bool(dev, "output-low")) {
258 plat->gpiod_flags = GPIOD_IS_OUT;
259 } else {
260 printf("%s: missing gpio-hog state.\n", __func__);
261 return -EINVAL;
262 }
263 ret = dev_read_u32_array(dev, "gpios", plat->val, 2);
264 if (ret) {
265 printf("%s: wrong gpios property, 2 values needed %d\n",
266 __func__, ret);
267 return ret;
268 }
269 nodename = dev_read_string(dev, "line-name");
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200270 if (nodename)
271 device_set_name(dev, nodename);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200272
273 return 0;
274}
275
276static int gpio_hog_probe(struct udevice *dev)
277{
Simon Glassc69cda22020-12-03 16:55:20 -0700278 struct gpio_hog_data *plat = dev_get_plat(dev);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200279 struct gpio_hog_priv *priv = dev_get_priv(dev);
280 int ret;
281
282 ret = gpio_dev_request_index(dev->parent, dev->name, "gpio-hog",
283 plat->val[0], plat->gpiod_flags,
284 plat->val[1], &priv->gpiod);
285 if (ret < 0) {
286 debug("%s: node %s could not get gpio.\n", __func__,
287 dev->name);
288 return ret;
289 }
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200290
291 if (plat->gpiod_flags == GPIOD_IS_OUT) {
292 ret = dm_gpio_set_value(&priv->gpiod, plat->value);
293 if (ret < 0) {
294 debug("%s: node %s could not set gpio.\n", __func__,
295 dev->name);
296 return ret;
297 }
298 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200299
300 return 0;
301}
302
303int gpio_hog_probe_all(void)
304{
305 struct udevice *dev;
306 int ret;
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200307 int retval = 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200308
309 for (uclass_first_device(UCLASS_NOP, &dev);
310 dev;
311 uclass_find_next_device(&dev)) {
Simon Glass65e25be2020-12-28 20:34:56 -0700312 if (dev->driver == DM_DRIVER_GET(gpio_hog)) {
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200313 ret = device_probe(dev);
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200314 if (ret) {
315 printf("Failed to probe device %s err: %d\n",
316 dev->name, ret);
317 retval = ret;
318 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200319 }
320 }
321
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200322 return retval;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200323}
324
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200325int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200326{
327 struct udevice *dev;
328
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200329 *desc = NULL;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200330 gpio_hog_probe_all();
331 if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
332 struct gpio_hog_priv *priv = dev_get_priv(dev);
333
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200334 *desc = &priv->gpiod;
335 return 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200336 }
337
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200338 return -ENODEV;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200339}
340
341U_BOOT_DRIVER(gpio_hog) = {
342 .name = "gpio_hog",
343 .id = UCLASS_NOP,
Simon Glassd1998a92020-12-03 16:55:21 -0700344 .of_to_plat = gpio_hog_of_to_plat,
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200345 .probe = gpio_hog_probe,
Simon Glass41575d82020-12-03 16:55:17 -0700346 .priv_auto = sizeof(struct gpio_hog_priv),
Simon Glasscaa4daa2020-12-03 16:55:18 -0700347 .plat_auto = sizeof(struct gpio_hog_data),
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200348};
349#else
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200350int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200351{
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200352 return 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200353}
354#endif
355
Simon Glassefa677f2015-06-23 15:38:41 -0600356int dm_gpio_request(struct gpio_desc *desc, const char *label)
Simon Glassae7123f2015-01-05 20:05:27 -0700357{
Simon Glass3d647742021-02-04 21:22:05 -0700358 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700359 struct udevice *dev = desc->dev;
360 struct gpio_dev_priv *uc_priv;
361 char *str;
362 int ret;
363
Simon Glasse564f052015-03-05 12:25:20 -0700364 uc_priv = dev_get_uclass_priv(dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700365 if (uc_priv->name[desc->offset])
366 return -EBUSY;
367 str = strdup(label);
368 if (!str)
369 return -ENOMEM;
Simon Glass3d647742021-02-04 21:22:05 -0700370 if (ops->request) {
371 ret = ops->request(dev, desc->offset, label);
Simon Glassae7123f2015-01-05 20:05:27 -0700372 if (ret) {
373 free(str);
374 return ret;
375 }
376 }
377 uc_priv->name[desc->offset] = str;
378
379 return 0;
380}
381
Simon Glass3669e0e2015-01-05 20:05:29 -0700382static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
383{
Simon Glass27084c02019-09-25 08:56:27 -0600384#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass3669e0e2015-01-05 20:05:29 -0700385 va_list args;
386 char buf[40];
387
388 va_start(args, fmt);
389 vscnprintf(buf, sizeof(buf), fmt, args);
390 va_end(args);
391 return dm_gpio_request(desc, buf);
Simon Glass4dc52592015-12-29 05:22:48 -0700392#else
393 return dm_gpio_request(desc, fmt);
394#endif
Simon Glass3669e0e2015-01-05 20:05:29 -0700395}
396
Simon Glass96495d92014-02-26 15:59:24 -0700397/**
398 * gpio_request() - [COMPAT] Request GPIO
399 * gpio: GPIO number
400 * label: Name for the requested GPIO
401 *
Simon Glassb892d122014-10-04 11:29:42 -0600402 * The label is copied and allocated so the caller does not need to keep
403 * the pointer around.
404 *
Simon Glass96495d92014-02-26 15:59:24 -0700405 * This function implements the API that's compatible with current
406 * GPIO API used in U-Boot. The request is forwarded to particular
407 * GPIO driver. Returns 0 on success, negative value on error.
408 */
409int gpio_request(unsigned gpio, const char *label)
410{
Simon Glassae7123f2015-01-05 20:05:27 -0700411 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700412 int ret;
413
Simon Glassae7123f2015-01-05 20:05:27 -0700414 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700415 if (ret)
416 return ret;
417
Simon Glassae7123f2015-01-05 20:05:27 -0700418 return dm_gpio_request(&desc, label);
Simon Glass96495d92014-02-26 15:59:24 -0700419}
420
421/**
Simon Glassd44f5972014-10-04 11:29:49 -0600422 * gpio_requestf() - [COMPAT] Request GPIO
423 * @gpio: GPIO number
424 * @fmt: Format string for the requested GPIO
425 * @...: Arguments for the printf() format string
426 *
427 * This function implements the API that's compatible with current
428 * GPIO API used in U-Boot. The request is forwarded to particular
429 * GPIO driver. Returns 0 on success, negative value on error.
430 */
431int gpio_requestf(unsigned gpio, const char *fmt, ...)
432{
Simon Glass27084c02019-09-25 08:56:27 -0600433#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glassd44f5972014-10-04 11:29:49 -0600434 va_list args;
435 char buf[40];
436
437 va_start(args, fmt);
438 vscnprintf(buf, sizeof(buf), fmt, args);
439 va_end(args);
440 return gpio_request(gpio, buf);
Simon Glass4dc52592015-12-29 05:22:48 -0700441#else
442 return gpio_request(gpio, fmt);
443#endif
Simon Glassd44f5972014-10-04 11:29:49 -0600444}
445
Simon Glassae7123f2015-01-05 20:05:27 -0700446int _dm_gpio_free(struct udevice *dev, uint offset)
Simon Glass96495d92014-02-26 15:59:24 -0700447{
Simon Glass3d647742021-02-04 21:22:05 -0700448 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glassb892d122014-10-04 11:29:42 -0600449 struct gpio_dev_priv *uc_priv;
Simon Glass96495d92014-02-26 15:59:24 -0700450 int ret;
451
Simon Glasse564f052015-03-05 12:25:20 -0700452 uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -0600453 if (!uc_priv->name[offset])
454 return -ENXIO;
Simon Glass3d647742021-02-04 21:22:05 -0700455 if (ops->rfree) {
456 ret = ops->rfree(dev, offset);
Simon Glassb892d122014-10-04 11:29:42 -0600457 if (ret)
458 return ret;
459 }
460
461 free(uc_priv->name[offset]);
462 uc_priv->name[offset] = NULL;
463
464 return 0;
465}
466
Simon Glassae7123f2015-01-05 20:05:27 -0700467/**
468 * gpio_free() - [COMPAT] Relinquish GPIO
469 * gpio: GPIO number
470 *
471 * This function implements the API that's compatible with current
472 * GPIO API used in U-Boot. The request is forwarded to particular
473 * GPIO driver. Returns 0 on success, negative value on error.
474 */
475int gpio_free(unsigned gpio)
Simon Glassb892d122014-10-04 11:29:42 -0600476{
Simon Glassae7123f2015-01-05 20:05:27 -0700477 struct gpio_desc desc;
478 int ret;
Simon Glassb892d122014-10-04 11:29:42 -0600479
Simon Glassae7123f2015-01-05 20:05:27 -0700480 ret = gpio_to_device(gpio, &desc);
481 if (ret)
482 return ret;
483
484 return _dm_gpio_free(desc.dev, desc.offset);
485}
486
Simon Glass17c43f12016-03-06 19:27:51 -0700487static int check_reserved(const struct gpio_desc *desc, const char *func)
Simon Glassae7123f2015-01-05 20:05:27 -0700488{
Simon Glasseca48662015-07-02 18:16:16 -0600489 struct gpio_dev_priv *uc_priv;
Simon Glassae7123f2015-01-05 20:05:27 -0700490
Simon Glasseca48662015-07-02 18:16:16 -0600491 if (!dm_gpio_is_valid(desc))
492 return -ENOENT;
493
494 uc_priv = dev_get_uclass_priv(desc->dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700495 if (!uc_priv->name[desc->offset]) {
Simon Glassb892d122014-10-04 11:29:42 -0600496 printf("%s: %s: error: gpio %s%d not reserved\n",
Simon Glassae7123f2015-01-05 20:05:27 -0700497 desc->dev->name, func,
498 uc_priv->bank_name ? uc_priv->bank_name : "",
499 desc->offset);
Simon Glassb892d122014-10-04 11:29:42 -0600500 return -EBUSY;
501 }
502
503 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700504}
505
506/**
507 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
508 * gpio: GPIO number
509 *
510 * This function implements the API that's compatible with current
511 * GPIO API used in U-Boot. The request is forwarded to particular
512 * GPIO driver. Returns 0 on success, negative value on error.
513 */
514int gpio_direction_input(unsigned gpio)
515{
Simon Glassae7123f2015-01-05 20:05:27 -0700516 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700517 int ret;
518
Simon Glassae7123f2015-01-05 20:05:27 -0700519 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700520 if (ret)
521 return ret;
522
Simon Glassca1e1f52021-02-04 21:22:04 -0700523 return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN);
Simon Glass96495d92014-02-26 15:59:24 -0700524}
525
526/**
527 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
528 * gpio: GPIO number
529 * value: Logical value to be set on the GPIO pin
530 *
531 * This function implements the API that's compatible with current
532 * GPIO API used in U-Boot. The request is forwarded to particular
533 * GPIO driver. Returns 0 on success, negative value on error.
534 */
535int gpio_direction_output(unsigned gpio, int value)
536{
Simon Glassae7123f2015-01-05 20:05:27 -0700537 struct gpio_desc desc;
Simon Glassca1e1f52021-02-04 21:22:04 -0700538 ulong flags;
Simon Glass96495d92014-02-26 15:59:24 -0700539 int ret;
540
Simon Glassae7123f2015-01-05 20:05:27 -0700541 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700542 if (ret)
543 return ret;
544
Simon Glassca1e1f52021-02-04 21:22:04 -0700545 flags = GPIOD_IS_OUT;
546 if (value)
547 flags |= GPIOD_IS_OUT_ACTIVE;
548 return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, flags);
Simon Glassae7123f2015-01-05 20:05:27 -0700549}
550
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100551static int _gpio_get_value(const struct gpio_desc *desc)
Simon Glassae7123f2015-01-05 20:05:27 -0700552{
Simon Glass3d647742021-02-04 21:22:05 -0700553 const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700554 int value;
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100555
Simon Glass3d647742021-02-04 21:22:05 -0700556 value = ops->get_value(desc->dev, desc->offset);
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100557
558 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
559}
560
561int dm_gpio_get_value(const struct gpio_desc *desc)
562{
Simon Glassae7123f2015-01-05 20:05:27 -0700563 int ret;
564
565 ret = check_reserved(desc, "get_value");
566 if (ret)
567 return ret;
568
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100569 return _gpio_get_value(desc);
Simon Glassae7123f2015-01-05 20:05:27 -0700570}
571
Simon Glass17c43f12016-03-06 19:27:51 -0700572int dm_gpio_set_value(const struct gpio_desc *desc, int value)
Simon Glassae7123f2015-01-05 20:05:27 -0700573{
Simon Glass7e0a96d2021-02-04 21:22:03 -0700574 const struct dm_gpio_ops *ops;
Simon Glassae7123f2015-01-05 20:05:27 -0700575 int ret;
576
577 ret = check_reserved(desc, "set_value");
578 if (ret)
579 return ret;
580
581 if (desc->flags & GPIOD_ACTIVE_LOW)
582 value = !value;
Neil Armstrong47bd5332020-05-05 10:43:17 +0200583
Simon Glass7e0a96d2021-02-04 21:22:03 -0700584 /* GPIOD_ are directly managed by driver in set_flags */
585 ops = gpio_get_ops(desc->dev);
586 if (ops->set_flags) {
587 ulong flags = desc->flags;
588
589 if (value)
590 flags |= GPIOD_IS_OUT_ACTIVE;
591 else
592 flags &= ~GPIOD_IS_OUT_ACTIVE;
593 return ops->set_flags(desc->dev, desc->offset, flags);
594 }
595
Neil Armstrong47bd5332020-05-05 10:43:17 +0200596 /*
597 * Emulate open drain by not actively driving the line high or
598 * Emulate open source by not actively driving the line low
599 */
600 if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
601 (desc->flags & GPIOD_OPEN_SOURCE && !value))
Simon Glass7e0a96d2021-02-04 21:22:03 -0700602 return ops->direction_input(desc->dev, desc->offset);
Neil Armstrong47bd5332020-05-05 10:43:17 +0200603 else if (desc->flags & GPIOD_OPEN_DRAIN ||
604 desc->flags & GPIOD_OPEN_SOURCE)
Simon Glass7e0a96d2021-02-04 21:22:03 -0700605 return ops->direction_output(desc->dev, desc->offset, value);
Neil Armstrong47bd5332020-05-05 10:43:17 +0200606
Simon Glass7e0a96d2021-02-04 21:22:03 -0700607 ret = ops->set_value(desc->dev, desc->offset, value);
608 if (ret)
609 return ret;
610
Simon Glassae7123f2015-01-05 20:05:27 -0700611 return 0;
612}
613
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100614/* check dir flags invalid configuration */
615static int check_dir_flags(ulong flags)
616{
617 if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
618 log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
619 __func__, flags);
620 return -EINVAL;
621 }
622
Patrick Delaunay477ca572020-01-13 11:35:07 +0100623 if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
624 log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
625 __func__, flags);
626 return -EINVAL;
627 }
628
629 if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
630 log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
631 __func__, flags);
632 return -EINVAL;
633 }
634
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100635 return 0;
636}
637
Simon Glass7e0a96d2021-02-04 21:22:03 -0700638/**
639 * _dm_gpio_set_flags() - Send flags to the driver
640 *
641 * This uses the best available method to send the given flags to the driver.
642 * Note that if flags & GPIOD_ACTIVE_LOW, the driver sees the opposite value
643 * of GPIOD_IS_OUT_ACTIVE.
644 *
645 * @desc: GPIO description
646 * @flags: flags value to set
647 * @return 0 if OK, -ve on error
648 */
Simon Glass13979fc2021-02-04 21:21:55 -0700649static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
Simon Glassae7123f2015-01-05 20:05:27 -0700650{
651 struct udevice *dev = desc->dev;
Simon Glass3d647742021-02-04 21:22:05 -0700652 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100653 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Patrick Delaunay788ea832020-01-13 11:35:03 +0100654 int ret = 0;
Simon Glassae7123f2015-01-05 20:05:27 -0700655
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100656 ret = check_dir_flags(flags);
657 if (ret) {
658 dev_dbg(dev,
659 "%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
660 desc->dev->name,
661 uc_priv->bank_name ? uc_priv->bank_name : "",
662 desc->offset, flags);
663
664 return ret;
665 }
666
Simon Glass7e0a96d2021-02-04 21:22:03 -0700667 /* If active low, invert the output state */
668 if ((flags & (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW)) ==
669 (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW))
670 flags ^= GPIOD_IS_OUT_ACTIVE;
671
Simon Glass13979fc2021-02-04 21:21:55 -0700672 /* GPIOD_ are directly managed by driver in set_flags */
673 if (ops->set_flags) {
674 ret = ops->set_flags(dev, desc->offset, flags);
Patrick Delaunay8fd9daf2020-01-13 11:35:09 +0100675 } else {
676 if (flags & GPIOD_IS_OUT) {
Simon Glass7e0a96d2021-02-04 21:22:03 -0700677 bool value = flags & GPIOD_IS_OUT_ACTIVE;
678
679 ret = ops->direction_output(dev, desc->offset, value);
Patrick Delaunay8fd9daf2020-01-13 11:35:09 +0100680 } else if (flags & GPIOD_IS_IN) {
681 ret = ops->direction_input(dev, desc->offset);
682 }
Simon Glassae7123f2015-01-05 20:05:27 -0700683 }
Patrick Delaunay788ea832020-01-13 11:35:03 +0100684
685 return ret;
686}
687
Simon Glass7e0a96d2021-02-04 21:22:03 -0700688int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set)
Patrick Delaunay788ea832020-01-13 11:35:03 +0100689{
Simon Glass7e0a96d2021-02-04 21:22:03 -0700690 ulong flags;
Patrick Delaunay788ea832020-01-13 11:35:03 +0100691 int ret;
692
693 ret = check_reserved(desc, "set_dir_flags");
Simon Glassae7123f2015-01-05 20:05:27 -0700694 if (ret)
695 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700696
Simon Glass7e0a96d2021-02-04 21:22:03 -0700697 flags = (desc->flags & ~clr) | set;
Patrick Delaunay788ea832020-01-13 11:35:03 +0100698
Simon Glass7e0a96d2021-02-04 21:22:03 -0700699 ret = _dm_gpio_set_flags(desc, flags);
700 if (ret)
701 return ret;
702
703 /* save the flags also in descriptor */
704 desc->flags = flags;
705
706 return 0;
707}
708
709int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
710{
711 /* combine the requested flags (for IN/OUT) and the descriptor flags */
712 return dm_gpio_clrset_flags(desc, GPIOD_MASK_DIR, flags);
Simon Glassae7123f2015-01-05 20:05:27 -0700713}
714
715int dm_gpio_set_dir(struct gpio_desc *desc)
716{
Patrick Delaunay788ea832020-01-13 11:35:03 +0100717 int ret;
718
719 ret = check_reserved(desc, "set_dir");
720 if (ret)
721 return ret;
722
Simon Glass13979fc2021-02-04 21:21:55 -0700723 return _dm_gpio_set_flags(desc, desc->flags);
Simon Glass96495d92014-02-26 15:59:24 -0700724}
725
Simon Glassc0c1e622021-02-04 21:21:57 -0700726int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100727{
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100728 struct udevice *dev = desc->dev;
729 int ret, value;
Simon Glass3d647742021-02-04 21:22:05 -0700730 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass96487892021-02-04 21:21:56 -0700731 ulong flags;
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100732
Simon Glass96487892021-02-04 21:21:56 -0700733 ret = check_reserved(desc, "get_flags");
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100734 if (ret)
735 return ret;
736
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100737 /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
Simon Glass96487892021-02-04 21:21:56 -0700738 if (ops->get_flags) {
739 ret = ops->get_flags(dev, desc->offset, &flags);
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100740 if (ret)
741 return ret;
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100742
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100743 /* GPIOD_ACTIVE_LOW is saved in desc->flags */
Simon Glass96487892021-02-04 21:21:56 -0700744 value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100745 if (desc->flags & GPIOD_ACTIVE_LOW)
746 value = !value;
Simon Glass96487892021-02-04 21:21:56 -0700747 flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
748 flags |= (desc->flags & GPIOD_ACTIVE_LOW);
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100749 if (value)
Simon Glass96487892021-02-04 21:21:56 -0700750 flags |= GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100751 } else {
Simon Glass96487892021-02-04 21:21:56 -0700752 flags = desc->flags;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100753 /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
Simon Glass96487892021-02-04 21:21:56 -0700754 flags &= ~GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100755 if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
Simon Glass96487892021-02-04 21:21:56 -0700756 flags |= GPIOD_IS_OUT_ACTIVE;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100757 }
Simon Glass96487892021-02-04 21:21:56 -0700758 *flagsp = flags;
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100759
760 return 0;
761}
762
Simon Glass96495d92014-02-26 15:59:24 -0700763/**
764 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
765 * gpio: GPIO number
766 *
767 * This function implements the API that's compatible with current
768 * GPIO API used in U-Boot. The request is forwarded to particular
769 * GPIO driver. Returns the value of the GPIO pin, or negative value
770 * on error.
771 */
772int gpio_get_value(unsigned gpio)
773{
Simon Glass96495d92014-02-26 15:59:24 -0700774 int ret;
775
Simon Glassae7123f2015-01-05 20:05:27 -0700776 struct gpio_desc desc;
777
778 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700779 if (ret)
780 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700781 return dm_gpio_get_value(&desc);
Simon Glass96495d92014-02-26 15:59:24 -0700782}
783
784/**
785 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
786 * gpio: GPIO number
787 * value: Logical value to be set on the GPIO pin.
788 *
789 * This function implements the API that's compatible with current
790 * GPIO API used in U-Boot. The request is forwarded to particular
791 * GPIO driver. Returns 0 on success, negative value on error.
792 */
793int gpio_set_value(unsigned gpio, int value)
794{
Simon Glassae7123f2015-01-05 20:05:27 -0700795 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700796 int ret;
797
Simon Glassae7123f2015-01-05 20:05:27 -0700798 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700799 if (ret)
800 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700801 return dm_gpio_set_value(&desc, value);
Simon Glass96495d92014-02-26 15:59:24 -0700802}
803
Heiko Schocher54c5d082014-05-22 12:43:05 +0200804const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
Simon Glass96495d92014-02-26 15:59:24 -0700805{
806 struct gpio_dev_priv *priv;
807
808 /* Must be called on an active device */
Simon Glasse564f052015-03-05 12:25:20 -0700809 priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -0700810 assert(priv);
811
812 *bit_count = priv->gpio_count;
813 return priv->bank_name;
814}
815
Simon Glass6449a502014-10-04 11:29:43 -0600816static const char * const gpio_function[GPIOF_COUNT] = {
817 "input",
818 "output",
819 "unused",
820 "unknown",
821 "func",
822};
823
Masahiro Yamadafb07f972017-06-22 16:50:25 +0900824static int get_function(struct udevice *dev, int offset, bool skip_unused,
825 const char **namep)
Simon Glass6449a502014-10-04 11:29:43 -0600826{
Simon Glasse564f052015-03-05 12:25:20 -0700827 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass3d647742021-02-04 21:22:05 -0700828 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass6449a502014-10-04 11:29:43 -0600829
830 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
831 if (!device_active(dev))
832 return -ENODEV;
833 if (offset < 0 || offset >= uc_priv->gpio_count)
834 return -EINVAL;
835 if (namep)
836 *namep = uc_priv->name[offset];
837 if (skip_unused && !uc_priv->name[offset])
838 return GPIOF_UNUSED;
839 if (ops->get_function) {
840 int ret;
841
842 ret = ops->get_function(dev, offset);
843 if (ret < 0)
844 return ret;
845 if (ret >= ARRAY_SIZE(gpio_function))
846 return -ENODATA;
847 return ret;
848 }
849
850 return GPIOF_UNKNOWN;
851}
852
853int gpio_get_function(struct udevice *dev, int offset, const char **namep)
854{
855 return get_function(dev, offset, true, namep);
856}
857
858int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
859{
860 return get_function(dev, offset, false, namep);
861}
862
Simon Glass07575352014-10-04 11:29:44 -0600863int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
864{
Simon Glass3d647742021-02-04 21:22:05 -0700865 const struct dm_gpio_ops *ops = gpio_get_ops(dev);
Simon Glass07575352014-10-04 11:29:44 -0600866 struct gpio_dev_priv *priv;
867 char *str = buf;
868 int func;
869 int ret;
870 int len;
871
872 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
873
874 *buf = 0;
Simon Glasse564f052015-03-05 12:25:20 -0700875 priv = dev_get_uclass_priv(dev);
Simon Glass07575352014-10-04 11:29:44 -0600876 ret = gpio_get_raw_function(dev, offset, NULL);
877 if (ret < 0)
878 return ret;
879 func = ret;
880 len = snprintf(str, buffsize, "%s%d: %s",
881 priv->bank_name ? priv->bank_name : "",
882 offset, gpio_function[func]);
883 if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
884 func == GPIOF_UNUSED) {
885 const char *label;
886 bool used;
887
888 ret = ops->get_value(dev, offset);
889 if (ret < 0)
890 return ret;
891 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
892 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
893 ret,
894 used ? 'x' : ' ',
895 used ? " " : "",
896 label ? label : "");
897 }
898
899 return 0;
900}
901
Simon Glass29126862020-07-07 13:11:44 -0600902#if CONFIG_IS_ENABLED(ACPIGEN)
903int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
904{
Simon Glass3d647742021-02-04 21:22:05 -0700905 const struct dm_gpio_ops *ops;
Simon Glass29126862020-07-07 13:11:44 -0600906
907 memset(gpio, '\0', sizeof(*gpio));
908 if (!dm_gpio_is_valid(desc)) {
909 /* Indicate that the GPIO is not valid */
910 gpio->pin_count = 0;
911 gpio->pins[0] = 0;
912 return -EINVAL;
913 }
914
915 ops = gpio_get_ops(desc->dev);
916 if (!ops->get_acpi)
917 return -ENOSYS;
918
919 return ops->get_acpi(desc, gpio);
920}
921#endif
922
Simon Glass962f5ca2015-04-14 21:03:20 -0600923int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
924{
925 int i, ret;
926 int gpio;
927
928 for (i = 0; i < 32; i++) {
929 gpio = gpio_num_array[i];
930 if (gpio == -1)
931 break;
932 ret = gpio_requestf(gpio, fmt, i);
933 if (ret)
934 goto err;
935 ret = gpio_direction_input(gpio);
936 if (ret) {
937 gpio_free(gpio);
938 goto err;
939 }
940 }
941
942 return 0;
943err:
944 for (i--; i >= 0; i--)
945 gpio_free(gpio_num_array[i]);
946
947 return ret;
948}
949
Simon Glasse5901c92014-11-10 18:00:21 -0700950/*
951 * get a number comprised of multiple GPIO values. gpio_num_array points to
952 * the array of gpio pin numbers to scan, terminated by -1.
953 */
Simon Glass962f5ca2015-04-14 21:03:20 -0600954int gpio_get_values_as_int(const int *gpio_list)
Simon Glasse5901c92014-11-10 18:00:21 -0700955{
956 int gpio;
957 unsigned bitmask = 1;
958 unsigned vector = 0;
Simon Glass962f5ca2015-04-14 21:03:20 -0600959 int ret;
Simon Glasse5901c92014-11-10 18:00:21 -0700960
961 while (bitmask &&
Simon Glass962f5ca2015-04-14 21:03:20 -0600962 ((gpio = *gpio_list++) != -1)) {
963 ret = gpio_get_value(gpio);
964 if (ret < 0)
965 return ret;
966 else if (ret)
Simon Glasse5901c92014-11-10 18:00:21 -0700967 vector |= bitmask;
968 bitmask <<= 1;
969 }
Simon Glass962f5ca2015-04-14 21:03:20 -0600970
Simon Glasse5901c92014-11-10 18:00:21 -0700971 return vector;
972}
973
Simon Glass17c43f12016-03-06 19:27:51 -0700974int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
Simon Glassbbf24782016-03-06 19:27:50 -0700975{
976 unsigned bitmask = 1;
977 unsigned vector = 0;
978 int ret, i;
979
980 for (i = 0; i < count; i++) {
981 ret = dm_gpio_get_value(&desc_list[i]);
982 if (ret < 0)
983 return ret;
984 else if (ret)
985 vector |= bitmask;
986 bitmask <<= 1;
987 }
988
989 return vector;
990}
991
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200992/**
993 * gpio_request_tail: common work for requesting a gpio.
994 *
995 * ret: return value from previous work in function which calls
996 * this function.
997 * This seems bogus (why calling this function instead not
998 * calling it and end caller function instead?).
999 * Because on error in caller function we want to set some
1000 * default values in gpio desc and have a common error
1001 * debug message, which provides this function.
1002 * nodename: Name of node for which gpio gets requested
1003 * used for gpio label name.
1004 * args: pointer to output arguments structure
1005 * list_name: Name of GPIO list
1006 * used for gpio label name.
1007 * index: gpio index in gpio list
1008 * used for gpio label name.
1009 * desc: pointer to gpio descriptor, filled from this
1010 * function.
1011 * flags: gpio flags to use.
1012 * add_index: should index added to gpio label name
1013 * gpio_dev: pointer to gpio device from which the gpio
1014 * will be requested. If NULL try to get the
1015 * gpio device with uclass_get_device_by_ofnode()
1016 *
1017 * return: In error case this function sets default values in
1018 * gpio descriptor, also emmits a debug message.
1019 * On success it returns 0 else the error code from
1020 * function calls, or the error code passed through
1021 * ret to this function.
1022 *
1023 */
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001024static int gpio_request_tail(int ret, const char *nodename,
Simon Glass3a571232017-05-18 20:09:18 -06001025 struct ofnode_phandle_args *args,
1026 const char *list_name, int index,
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001027 struct gpio_desc *desc, int flags,
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001028 bool add_index, struct udevice *gpio_dev)
Simon Glass3669e0e2015-01-05 20:05:29 -07001029{
Patrick Delaunay9f2b0662020-01-13 11:35:01 +01001030 gpio_desc_init(desc, gpio_dev, 0);
Simon Glass3a571232017-05-18 20:09:18 -06001031 if (ret)
Simon Glass3669e0e2015-01-05 20:05:29 -07001032 goto err;
Simon Glass3669e0e2015-01-05 20:05:29 -07001033
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001034 if (!desc->dev) {
1035 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
1036 &desc->dev);
1037 if (ret) {
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001038 debug("%s: uclass_get_device_by_ofnode failed\n",
1039 __func__);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001040 goto err;
1041 }
Simon Glass3669e0e2015-01-05 20:05:29 -07001042 }
Simon Glass3a571232017-05-18 20:09:18 -06001043 ret = gpio_find_and_xlate(desc, args);
Simon Glass3669e0e2015-01-05 20:05:29 -07001044 if (ret) {
1045 debug("%s: gpio_find_and_xlate failed\n", __func__);
1046 goto err;
1047 }
1048 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001049 nodename, list_name, index);
Simon Glass3669e0e2015-01-05 20:05:29 -07001050 if (ret) {
1051 debug("%s: dm_gpio_requestf failed\n", __func__);
1052 goto err;
1053 }
Simon Glass7e0a96d2021-02-04 21:22:03 -07001054
1055 /* Keep any direction flags provided by the devicetree */
1056 ret = dm_gpio_set_dir_flags(desc,
1057 flags | (desc->flags & GPIOD_MASK_DIR));
Simon Glass3669e0e2015-01-05 20:05:29 -07001058 if (ret) {
1059 debug("%s: dm_gpio_set_dir failed\n", __func__);
1060 goto err;
1061 }
1062
1063 return 0;
1064err:
1065 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001066 __func__, nodename, list_name, index, ret);
Simon Glass3669e0e2015-01-05 20:05:29 -07001067 return ret;
1068}
1069
Simon Glass4fe40672021-02-04 21:21:54 -07001070#if !CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glass150c5af2017-05-30 21:47:09 -06001071static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
1072 int index, struct gpio_desc *desc,
1073 int flags, bool add_index)
Simon Glass3a571232017-05-18 20:09:18 -06001074{
1075 struct ofnode_phandle_args args;
1076 int ret;
1077
Simon Glass150c5af2017-05-30 21:47:09 -06001078 ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
1079 index, &args);
Simon Glass3a571232017-05-18 20:09:18 -06001080
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001081 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1082 index, desc, flags, add_index, NULL);
Simon Glass3a571232017-05-18 20:09:18 -06001083}
1084
Simon Glass150c5af2017-05-30 21:47:09 -06001085int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
Simon Glass3669e0e2015-01-05 20:05:29 -07001086 struct gpio_desc *desc, int flags)
1087{
Simon Glass150c5af2017-05-30 21:47:09 -06001088 return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
1089 index > 0);
Simon Glass3669e0e2015-01-05 20:05:29 -07001090}
1091
Simon Glass150c5af2017-05-30 21:47:09 -06001092int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
Simon Glass3669e0e2015-01-05 20:05:29 -07001093 struct gpio_desc *desc, int flags)
1094{
Simon Glass150c5af2017-05-30 21:47:09 -06001095 struct ofnode_phandle_args args;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001096 ofnode node;
Simon Glass150c5af2017-05-30 21:47:09 -06001097 int ret;
1098
1099 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
1100 index, &args);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001101 node = dev_ofnode(dev);
1102 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1103 index, desc, flags, index > 0, NULL);
Simon Glass3669e0e2015-01-05 20:05:29 -07001104}
1105
Simon Glass150c5af2017-05-30 21:47:09 -06001106int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
Simon Glass3669e0e2015-01-05 20:05:29 -07001107 struct gpio_desc *desc, int max_count,
1108 int flags)
1109{
1110 int count;
1111 int ret;
1112
Przemyslaw Marczak2984e7a2015-03-31 18:57:16 +02001113 for (count = 0; count < max_count; count++) {
Simon Glass150c5af2017-05-30 21:47:09 -06001114 ret = _gpio_request_by_name_nodev(node, list_name, count,
Simon Glass3669e0e2015-01-05 20:05:29 -07001115 &desc[count], flags, true);
1116 if (ret == -ENOENT)
1117 break;
1118 else if (ret)
1119 goto err;
1120 }
1121
1122 /* We ran out of GPIOs in the list */
1123 return count;
1124
1125err:
1126 gpio_free_list_nodev(desc, count - 1);
1127
1128 return ret;
1129}
1130
1131int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
1132 struct gpio_desc *desc, int max_count,
1133 int flags)
1134{
1135 /*
1136 * This isn't ideal since we don't use dev->name in the debug()
1137 * calls in gpio_request_by_name(), but we can do this until
1138 * gpio_request_list_by_name_nodev() can be dropped.
1139 */
Simon Glass150c5af2017-05-30 21:47:09 -06001140 return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
1141 max_count, flags);
Simon Glass3669e0e2015-01-05 20:05:29 -07001142}
1143
1144int gpio_get_list_count(struct udevice *dev, const char *list_name)
1145{
1146 int ret;
1147
Patrick Delaunay85582172020-09-09 18:26:16 +02001148 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0, -1,
1149 NULL);
Simon Glass3669e0e2015-01-05 20:05:29 -07001150 if (ret) {
1151 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
1152 __func__, dev->name, list_name, ret);
1153 }
1154
1155 return ret;
1156}
Simon Glass4fe40672021-02-04 21:21:54 -07001157#endif /* OF_PLATDATA */
Simon Glass3669e0e2015-01-05 20:05:29 -07001158
1159int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
1160{
1161 /* For now, we don't do any checking of dev */
1162 return _dm_gpio_free(desc->dev, desc->offset);
1163}
1164
1165int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
1166{
1167 int i;
1168
1169 /* For now, we don't do any checking of dev */
1170 for (i = 0; i < count; i++)
1171 dm_gpio_free(dev, &desc[i]);
1172
1173 return 0;
1174}
1175
1176int gpio_free_list_nodev(struct gpio_desc *desc, int count)
1177{
1178 return gpio_free_list(NULL, desc, count);
1179}
1180
Simon Glass96495d92014-02-26 15:59:24 -07001181/* We need to renumber the GPIOs when any driver is probed/removed */
Simon Glassb892d122014-10-04 11:29:42 -06001182static int gpio_renumber(struct udevice *removed_dev)
Simon Glass96495d92014-02-26 15:59:24 -07001183{
1184 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +02001185 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -07001186 struct uclass *uc;
1187 unsigned base;
1188 int ret;
1189
1190 ret = uclass_get(UCLASS_GPIO, &uc);
1191 if (ret)
1192 return ret;
1193
1194 /* Ensure that we have a base for each bank */
1195 base = 0;
1196 uclass_foreach_dev(dev, uc) {
Simon Glassb892d122014-10-04 11:29:42 -06001197 if (device_active(dev) && dev != removed_dev) {
Simon Glasse564f052015-03-05 12:25:20 -07001198 uc_priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -07001199 uc_priv->gpio_base = base;
1200 base += uc_priv->gpio_count;
1201 }
1202 }
1203
1204 return 0;
1205}
1206
Simon Glass17c43f12016-03-06 19:27:51 -07001207int gpio_get_number(const struct gpio_desc *desc)
Simon Glass56a71f82015-03-25 12:21:58 -06001208{
1209 struct udevice *dev = desc->dev;
1210 struct gpio_dev_priv *uc_priv;
1211
1212 if (!dev)
1213 return -1;
Simon Glass0fd3d912020-12-22 19:30:28 -07001214 uc_priv = dev_get_uclass_priv(dev);
Simon Glass56a71f82015-03-25 12:21:58 -06001215
1216 return uc_priv->gpio_base + desc->offset;
1217}
1218
Heiko Schocher54c5d082014-05-22 12:43:05 +02001219static int gpio_post_probe(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -07001220{
Simon Glasse564f052015-03-05 12:25:20 -07001221 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -06001222
1223 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
1224 if (!uc_priv->name)
1225 return -ENOMEM;
1226
1227 return gpio_renumber(NULL);
Simon Glass96495d92014-02-26 15:59:24 -07001228}
1229
Heiko Schocher54c5d082014-05-22 12:43:05 +02001230static int gpio_pre_remove(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -07001231{
Simon Glasse564f052015-03-05 12:25:20 -07001232 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -06001233 int i;
1234
1235 for (i = 0; i < uc_priv->gpio_count; i++) {
1236 if (uc_priv->name[i])
1237 free(uc_priv->name[i]);
1238 }
1239 free(uc_priv->name);
1240
1241 return gpio_renumber(dev);
Simon Glass96495d92014-02-26 15:59:24 -07001242}
1243
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001244int gpio_dev_request_index(struct udevice *dev, const char *nodename,
1245 char *list_name, int index, int flags,
1246 int dtflags, struct gpio_desc *desc)
1247{
1248 struct ofnode_phandle_args args;
1249
1250 args.node = ofnode_null();
1251 args.args_count = 2;
1252 args.args[0] = index;
1253 args.args[1] = dtflags;
1254
1255 return gpio_request_tail(0, nodename, &args, list_name, index, desc,
1256 flags, 0, dev);
1257}
1258
Jean-Jacques Hiblotd4b722e2020-09-11 13:43:34 +05301259static void devm_gpiod_release(struct udevice *dev, void *res)
1260{
1261 dm_gpio_free(dev, res);
1262}
1263
1264static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
1265{
1266 return res == data;
1267}
1268
1269struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
1270 unsigned int index, int flags)
1271{
1272 int rc;
1273 struct gpio_desc *desc;
1274 char *propname;
1275 static const char suffix[] = "-gpios";
1276
1277 propname = malloc(strlen(id) + sizeof(suffix));
1278 if (!propname) {
1279 rc = -ENOMEM;
1280 goto end;
1281 }
1282
1283 strcpy(propname, id);
1284 strcat(propname, suffix);
1285
1286 desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
1287 __GFP_ZERO);
1288 if (unlikely(!desc)) {
1289 rc = -ENOMEM;
1290 goto end;
1291 }
1292
1293 rc = gpio_request_by_name(dev, propname, index, desc, flags);
1294
1295end:
1296 if (propname)
1297 free(propname);
1298
1299 if (rc)
1300 return ERR_PTR(rc);
1301
1302 devres_add(dev, desc);
1303
1304 return desc;
1305}
1306
1307struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
1308 const char *id,
1309 unsigned int index,
1310 int flags)
1311{
1312 struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);
1313
1314 if (IS_ERR(desc))
1315 return NULL;
1316
1317 return desc;
1318}
1319
1320void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
1321{
1322 int rc;
1323
1324 rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
1325 WARN_ON(rc);
1326}
1327
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001328static int gpio_post_bind(struct udevice *dev)
1329{
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001330 struct udevice *child;
1331 ofnode node;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001332
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001333#if defined(CONFIG_NEEDS_MANUAL_RELOC)
1334 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
1335 static int reloc_done;
1336
1337 if (!reloc_done) {
1338 if (ops->request)
1339 ops->request += gd->reloc_off;
Simon Glass093152f2020-02-04 20:15:17 -07001340 if (ops->rfree)
1341 ops->rfree += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001342 if (ops->direction_input)
1343 ops->direction_input += gd->reloc_off;
1344 if (ops->direction_output)
1345 ops->direction_output += gd->reloc_off;
1346 if (ops->get_value)
1347 ops->get_value += gd->reloc_off;
1348 if (ops->set_value)
1349 ops->set_value += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001350 if (ops->get_function)
1351 ops->get_function += gd->reloc_off;
1352 if (ops->xlate)
1353 ops->xlate += gd->reloc_off;
Simon Glass13979fc2021-02-04 21:21:55 -07001354 if (ops->set_flags)
1355 ops->set_flags += gd->reloc_off;
Simon Glass96487892021-02-04 21:21:56 -07001356 if (ops->get_flags)
1357 ops->get_flags += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001358
1359 reloc_done++;
1360 }
1361#endif
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001362
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001363 if (IS_ENABLED(CONFIG_GPIO_HOG)) {
1364 dev_for_each_subnode(node, dev) {
1365 if (ofnode_read_bool(node, "gpio-hog")) {
1366 const char *name = ofnode_get_name(node);
1367 int ret;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001368
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001369 ret = device_bind_driver_to_node(dev,
1370 "gpio_hog",
1371 name, node,
1372 &child);
1373 if (ret)
1374 return ret;
1375 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001376 }
1377 }
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001378 return 0;
1379}
1380
Simon Glass96495d92014-02-26 15:59:24 -07001381UCLASS_DRIVER(gpio) = {
1382 .id = UCLASS_GPIO,
1383 .name = "gpio",
Bhuvanchandra DVae89bb02015-06-01 18:37:15 +05301384 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass96495d92014-02-26 15:59:24 -07001385 .post_probe = gpio_post_probe,
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001386 .post_bind = gpio_post_bind,
Simon Glass96495d92014-02-26 15:59:24 -07001387 .pre_remove = gpio_pre_remove,
Simon Glass41575d82020-12-03 16:55:17 -07001388 .per_device_auto = sizeof(struct gpio_dev_priv),
Simon Glass96495d92014-02-26 15:59:24 -07001389};