blob: bad6b71e0c38b78d1c115ad09085808aa95aacbe [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
6#include <common.h>
7#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -06008#include <log.h>
Jean-Jacques Hiblot775d6a22020-09-11 13:43:34 +05309#include <dm/devres.h>
10#include <dm/device_compat.h>
Heiko Schocher39cb3402019-06-12 06:11:46 +020011#include <dm/device-internal.h>
12#include <dm/lists.h>
13#include <dm/uclass-internal.h>
Eric Nelson786e98d2016-04-24 16:32:40 -070014#include <dt-bindings/gpio/gpio.h>
Simon Glasse821d182014-02-26 15:59:24 -070015#include <errno.h>
Simon Glassd3322bb2015-01-05 20:05:28 -070016#include <fdtdec.h>
Simon Glass0f4517d2014-10-04 11:29:42 -060017#include <malloc.h>
Simon Glass3176b6c2020-07-07 13:11:44 -060018#include <acpi/acpi_device.h>
Simon Glasse821d182014-02-26 15:59:24 -070019#include <asm/gpio.h>
Simon Glass0f2af882020-05-10 11:40:05 -060020#include <dm/device_compat.h>
Masahiro Yamada78eeb912016-01-24 23:27:48 +090021#include <linux/bug.h>
Simon Glass43b2e1a2014-10-22 21:37:01 -060022#include <linux/ctype.h>
Simon Glasse821d182014-02-26 15:59:24 -070023
Simon Glass16e10402015-01-05 20:05:29 -070024DECLARE_GLOBAL_DATA_PTR;
25
Simon Glasse821d182014-02-26 15:59:24 -070026/**
Patrick Delaunay758bba92020-01-13 11:35:01 +010027 * gpio_desc_init() - Initialize the GPIO descriptor
28 *
29 * @desc: GPIO descriptor to initialize
30 * @dev: GPIO device
31 * @offset: Offset of device GPIO
32 */
33static void gpio_desc_init(struct gpio_desc *desc,
34 struct udevice *dev,
35 uint offset)
36{
37 desc->dev = dev;
38 desc->offset = offset;
39 desc->flags = 0;
40}
41
42/**
Simon Glasse821d182014-02-26 15:59:24 -070043 * gpio_to_device() - Convert global GPIO number to device, number
Simon Glasse821d182014-02-26 15:59:24 -070044 *
45 * Convert the GPIO number to an entry in the list of GPIOs
46 * or GPIO blocks registered with the GPIO controller. Returns
47 * entry on success, NULL on error.
Simon Glassce555292015-01-05 20:05:27 -070048 *
49 * @gpio: The numeric representation of the GPIO
50 * @desc: Returns description (desc->flags will always be 0)
51 * @return 0 if found, -ENOENT if not found
Simon Glasse821d182014-02-26 15:59:24 -070052 */
Simon Glassce555292015-01-05 20:05:27 -070053static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
Simon Glasse821d182014-02-26 15:59:24 -070054{
55 struct gpio_dev_priv *uc_priv;
Heiko Schocherb74fcb42014-05-22 12:43:05 +020056 struct udevice *dev;
Simon Glasse821d182014-02-26 15:59:24 -070057 int ret;
58
59 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
60 dev;
61 ret = uclass_next_device(&dev)) {
Simon Glassde0977b2015-03-05 12:25:20 -070062 uc_priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -070063 if (gpio >= uc_priv->gpio_base &&
64 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
Patrick Delaunay758bba92020-01-13 11:35:01 +010065 gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
Simon Glasse821d182014-02-26 15:59:24 -070066 return 0;
67 }
68 }
69
70 /* No such GPIO */
Simon Glassce555292015-01-05 20:05:27 -070071 return ret ? ret : -ENOENT;
Simon Glasse821d182014-02-26 15:59:24 -070072}
73
Heiko Schochera3e793c2020-05-22 11:08:59 +020074#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL)
75/**
76 * dm_gpio_lookup_label() - look for name in gpio device
77 *
78 * search in uc_priv, if there is a gpio with labelname same
79 * as name.
80 *
81 * @name: name which is searched
82 * @uc_priv: gpio_dev_priv pointer.
83 * @offset: gpio offset within the device
84 * @return: 0 if found, -ENOENT if not.
85 */
86static int dm_gpio_lookup_label(const char *name,
87 struct gpio_dev_priv *uc_priv, ulong *offset)
88{
89 int len;
90 int i;
91
92 *offset = -1;
93 len = strlen(name);
94 for (i = 0; i < uc_priv->gpio_count; i++) {
95 if (!uc_priv->name[i])
96 continue;
97 if (!strncmp(name, uc_priv->name[i], len)) {
98 *offset = i;
99 return 0;
100 }
101 }
102 return -ENOENT;
103}
104#else
105static int
106dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv,
107 ulong *offset)
108{
109 return -ENOENT;
110}
111#endif
112
Simon Glass215bcc72015-06-23 15:38:40 -0600113int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
Simon Glasse821d182014-02-26 15:59:24 -0700114{
Simon Glass43b2e1a2014-10-22 21:37:01 -0600115 struct gpio_dev_priv *uc_priv = NULL;
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200116 struct udevice *dev;
Simon Glass43b2e1a2014-10-22 21:37:01 -0600117 ulong offset;
118 int numeric;
Simon Glasse821d182014-02-26 15:59:24 -0700119 int ret;
120
Simon Glass43b2e1a2014-10-22 21:37:01 -0600121 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
Simon Glasse821d182014-02-26 15:59:24 -0700122 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
123 dev;
124 ret = uclass_next_device(&dev)) {
Simon Glasse821d182014-02-26 15:59:24 -0700125 int len;
126
Simon Glassde0977b2015-03-05 12:25:20 -0700127 uc_priv = dev_get_uclass_priv(dev);
Simon Glass43b2e1a2014-10-22 21:37:01 -0600128 if (numeric != -1) {
129 offset = numeric - uc_priv->gpio_base;
130 /* Allow GPIOs to be numbered from 0 */
Tom Rini26fd9682017-05-10 15:20:15 -0400131 if (offset < uc_priv->gpio_count)
Simon Glass43b2e1a2014-10-22 21:37:01 -0600132 break;
133 }
134
Simon Glasse821d182014-02-26 15:59:24 -0700135 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
136
Simon Glassd4acf632014-06-11 23:29:47 -0600137 if (!strncasecmp(name, uc_priv->bank_name, len)) {
Simon Glass43b2e1a2014-10-22 21:37:01 -0600138 if (!strict_strtoul(name + len, 10, &offset))
139 break;
Simon Glasse821d182014-02-26 15:59:24 -0700140 }
Heiko Schochera3e793c2020-05-22 11:08:59 +0200141
142 /*
143 * if we did not found a gpio through its bank
144 * name, we search for a valid gpio label.
145 */
146 if (!dm_gpio_lookup_label(name, uc_priv, &offset))
147 break;
Simon Glasse821d182014-02-26 15:59:24 -0700148 }
149
Simon Glass43b2e1a2014-10-22 21:37:01 -0600150 if (!dev)
151 return ret ? ret : -EINVAL;
152
Patrick Delaunay758bba92020-01-13 11:35:01 +0100153 gpio_desc_init(desc, dev, offset);
Simon Glass215bcc72015-06-23 15:38:40 -0600154
155 return 0;
156}
157
158int gpio_lookup_name(const char *name, struct udevice **devp,
159 unsigned int *offsetp, unsigned int *gpiop)
160{
161 struct gpio_desc desc;
162 int ret;
163
164 if (devp)
165 *devp = NULL;
166 ret = dm_gpio_lookup_name(name, &desc);
167 if (ret)
168 return ret;
169
Simon Glass43b2e1a2014-10-22 21:37:01 -0600170 if (devp)
Simon Glass215bcc72015-06-23 15:38:40 -0600171 *devp = desc.dev;
Simon Glass43b2e1a2014-10-22 21:37:01 -0600172 if (offsetp)
Simon Glass215bcc72015-06-23 15:38:40 -0600173 *offsetp = desc.offset;
174 if (gpiop) {
175 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
176
177 *gpiop = uc_priv->gpio_base + desc.offset;
178 }
Simon Glass43b2e1a2014-10-22 21:37:01 -0600179
180 return 0;
Simon Glasse821d182014-02-26 15:59:24 -0700181}
182
Simon Glass12faa022017-05-18 20:09:18 -0600183int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
184 struct ofnode_phandle_args *args)
Eric Nelson786e98d2016-04-24 16:32:40 -0700185{
186 if (args->args_count < 1)
187 return -EINVAL;
188
189 desc->offset = args->args[0];
190
191 if (args->args_count < 2)
192 return 0;
193
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100194 desc->flags = 0;
Eric Nelson786e98d2016-04-24 16:32:40 -0700195 if (args->args[1] & GPIO_ACTIVE_LOW)
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100196 desc->flags |= GPIOD_ACTIVE_LOW;
Eric Nelson786e98d2016-04-24 16:32:40 -0700197
Patrick Delaunay5c1c06e2020-01-13 11:35:07 +0100198 /*
199 * need to test 2 bits for gpio output binding:
200 * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
201 * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
202 */
203 if (args->args[1] & GPIO_SINGLE_ENDED) {
204 if (args->args[1] & GPIO_LINE_OPEN_DRAIN)
205 desc->flags |= GPIOD_OPEN_DRAIN;
206 else
207 desc->flags |= GPIOD_OPEN_SOURCE;
208 }
209
210 if (args->args[1] & GPIO_PULL_UP)
211 desc->flags |= GPIOD_PULL_UP;
212
213 if (args->args[1] & GPIO_PULL_DOWN)
214 desc->flags |= GPIOD_PULL_DOWN;
215
Eric Nelson786e98d2016-04-24 16:32:40 -0700216 return 0;
217}
218
Simon Glass16e10402015-01-05 20:05:29 -0700219static int gpio_find_and_xlate(struct gpio_desc *desc,
Simon Glass12faa022017-05-18 20:09:18 -0600220 struct ofnode_phandle_args *args)
Simon Glassd3322bb2015-01-05 20:05:28 -0700221{
222 struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
223
Eric Nelson786e98d2016-04-24 16:32:40 -0700224 if (ops->xlate)
225 return ops->xlate(desc->dev, desc, args);
Simon Glassd3322bb2015-01-05 20:05:28 -0700226 else
Eric Nelson786e98d2016-04-24 16:32:40 -0700227 return gpio_xlate_offs_flags(desc->dev, desc, args);
Simon Glassd3322bb2015-01-05 20:05:28 -0700228}
229
Heiko Schocher58e4c382019-07-17 06:59:51 +0200230#if defined(CONFIG_GPIO_HOG)
Heiko Schocher39cb3402019-06-12 06:11:46 +0200231
232struct gpio_hog_priv {
233 struct gpio_desc gpiod;
234};
235
236struct gpio_hog_data {
237 int gpiod_flags;
238 int value;
239 u32 val[2];
240};
241
Simon Glassaad29ae2020-12-03 16:55:21 -0700242static int gpio_hog_of_to_plat(struct udevice *dev)
Heiko Schocher39cb3402019-06-12 06:11:46 +0200243{
Simon Glassfa20e932020-12-03 16:55:20 -0700244 struct gpio_hog_data *plat = dev_get_plat(dev);
Heiko Schocher39cb3402019-06-12 06:11:46 +0200245 const char *nodename;
246 int ret;
247
248 plat->value = 0;
249 if (dev_read_bool(dev, "input")) {
250 plat->gpiod_flags = GPIOD_IS_IN;
251 } else if (dev_read_bool(dev, "output-high")) {
252 plat->value = 1;
253 plat->gpiod_flags = GPIOD_IS_OUT;
254 } else if (dev_read_bool(dev, "output-low")) {
255 plat->gpiod_flags = GPIOD_IS_OUT;
256 } else {
257 printf("%s: missing gpio-hog state.\n", __func__);
258 return -EINVAL;
259 }
260 ret = dev_read_u32_array(dev, "gpios", plat->val, 2);
261 if (ret) {
262 printf("%s: wrong gpios property, 2 values needed %d\n",
263 __func__, ret);
264 return ret;
265 }
266 nodename = dev_read_string(dev, "line-name");
Heiko Schocher58e4c382019-07-17 06:59:51 +0200267 if (nodename)
268 device_set_name(dev, nodename);
Heiko Schocher39cb3402019-06-12 06:11:46 +0200269
270 return 0;
271}
272
273static int gpio_hog_probe(struct udevice *dev)
274{
Simon Glassfa20e932020-12-03 16:55:20 -0700275 struct gpio_hog_data *plat = dev_get_plat(dev);
Heiko Schocher39cb3402019-06-12 06:11:46 +0200276 struct gpio_hog_priv *priv = dev_get_priv(dev);
277 int ret;
278
279 ret = gpio_dev_request_index(dev->parent, dev->name, "gpio-hog",
280 plat->val[0], plat->gpiod_flags,
281 plat->val[1], &priv->gpiod);
282 if (ret < 0) {
283 debug("%s: node %s could not get gpio.\n", __func__,
284 dev->name);
285 return ret;
286 }
Heiko Schocher58e4c382019-07-17 06:59:51 +0200287
288 if (plat->gpiod_flags == GPIOD_IS_OUT) {
289 ret = dm_gpio_set_value(&priv->gpiod, plat->value);
290 if (ret < 0) {
291 debug("%s: node %s could not set gpio.\n", __func__,
292 dev->name);
293 return ret;
294 }
295 }
Heiko Schocher39cb3402019-06-12 06:11:46 +0200296
297 return 0;
298}
299
300int gpio_hog_probe_all(void)
301{
302 struct udevice *dev;
303 int ret;
Heiko Schocher58e4c382019-07-17 06:59:51 +0200304 int retval = 0;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200305
306 for (uclass_first_device(UCLASS_NOP, &dev);
307 dev;
308 uclass_find_next_device(&dev)) {
Simon Glass65130cd2020-12-28 20:34:56 -0700309 if (dev->driver == DM_DRIVER_GET(gpio_hog)) {
Heiko Schocher39cb3402019-06-12 06:11:46 +0200310 ret = device_probe(dev);
Heiko Schocher58e4c382019-07-17 06:59:51 +0200311 if (ret) {
312 printf("Failed to probe device %s err: %d\n",
313 dev->name, ret);
314 retval = ret;
315 }
Heiko Schocher39cb3402019-06-12 06:11:46 +0200316 }
317 }
318
Heiko Schocher58e4c382019-07-17 06:59:51 +0200319 return retval;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200320}
321
Heiko Schocher58e4c382019-07-17 06:59:51 +0200322int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher39cb3402019-06-12 06:11:46 +0200323{
324 struct udevice *dev;
325
Heiko Schocher58e4c382019-07-17 06:59:51 +0200326 *desc = NULL;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200327 gpio_hog_probe_all();
328 if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
329 struct gpio_hog_priv *priv = dev_get_priv(dev);
330
Heiko Schocher58e4c382019-07-17 06:59:51 +0200331 *desc = &priv->gpiod;
332 return 0;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200333 }
334
Heiko Schocher58e4c382019-07-17 06:59:51 +0200335 return -ENODEV;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200336}
337
338U_BOOT_DRIVER(gpio_hog) = {
339 .name = "gpio_hog",
340 .id = UCLASS_NOP,
Simon Glassaad29ae2020-12-03 16:55:21 -0700341 .of_to_plat = gpio_hog_of_to_plat,
Heiko Schocher39cb3402019-06-12 06:11:46 +0200342 .probe = gpio_hog_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700343 .priv_auto = sizeof(struct gpio_hog_priv),
Simon Glass71fa5b42020-12-03 16:55:18 -0700344 .plat_auto = sizeof(struct gpio_hog_data),
Heiko Schocher39cb3402019-06-12 06:11:46 +0200345};
346#else
Heiko Schocher58e4c382019-07-17 06:59:51 +0200347int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher39cb3402019-06-12 06:11:46 +0200348{
Heiko Schocher58e4c382019-07-17 06:59:51 +0200349 return 0;
Heiko Schocher39cb3402019-06-12 06:11:46 +0200350}
351#endif
352
Simon Glass047cdb32015-06-23 15:38:41 -0600353int dm_gpio_request(struct gpio_desc *desc, const char *label)
Simon Glassce555292015-01-05 20:05:27 -0700354{
355 struct udevice *dev = desc->dev;
356 struct gpio_dev_priv *uc_priv;
357 char *str;
358 int ret;
359
Simon Glassde0977b2015-03-05 12:25:20 -0700360 uc_priv = dev_get_uclass_priv(dev);
Simon Glassce555292015-01-05 20:05:27 -0700361 if (uc_priv->name[desc->offset])
362 return -EBUSY;
363 str = strdup(label);
364 if (!str)
365 return -ENOMEM;
366 if (gpio_get_ops(dev)->request) {
367 ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
368 if (ret) {
369 free(str);
370 return ret;
371 }
372 }
373 uc_priv->name[desc->offset] = str;
374
375 return 0;
376}
377
Simon Glass16e10402015-01-05 20:05:29 -0700378static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
379{
Simon Glass7611ac62019-09-25 08:56:27 -0600380#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass16e10402015-01-05 20:05:29 -0700381 va_list args;
382 char buf[40];
383
384 va_start(args, fmt);
385 vscnprintf(buf, sizeof(buf), fmt, args);
386 va_end(args);
387 return dm_gpio_request(desc, buf);
Simon Glassee8a3d92015-12-29 05:22:48 -0700388#else
389 return dm_gpio_request(desc, fmt);
390#endif
Simon Glass16e10402015-01-05 20:05:29 -0700391}
392
Simon Glasse821d182014-02-26 15:59:24 -0700393/**
394 * gpio_request() - [COMPAT] Request GPIO
395 * gpio: GPIO number
396 * label: Name for the requested GPIO
397 *
Simon Glass0f4517d2014-10-04 11:29:42 -0600398 * The label is copied and allocated so the caller does not need to keep
399 * the pointer around.
400 *
Simon Glasse821d182014-02-26 15:59:24 -0700401 * This function implements the API that's compatible with current
402 * GPIO API used in U-Boot. The request is forwarded to particular
403 * GPIO driver. Returns 0 on success, negative value on error.
404 */
405int gpio_request(unsigned gpio, const char *label)
406{
Simon Glassce555292015-01-05 20:05:27 -0700407 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700408 int ret;
409
Simon Glassce555292015-01-05 20:05:27 -0700410 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700411 if (ret)
412 return ret;
413
Simon Glassce555292015-01-05 20:05:27 -0700414 return dm_gpio_request(&desc, label);
Simon Glasse821d182014-02-26 15:59:24 -0700415}
416
417/**
Simon Glass1b27d602014-10-04 11:29:49 -0600418 * gpio_requestf() - [COMPAT] Request GPIO
419 * @gpio: GPIO number
420 * @fmt: Format string for the requested GPIO
421 * @...: Arguments for the printf() format string
422 *
423 * This function implements the API that's compatible with current
424 * GPIO API used in U-Boot. The request is forwarded to particular
425 * GPIO driver. Returns 0 on success, negative value on error.
426 */
427int gpio_requestf(unsigned gpio, const char *fmt, ...)
428{
Simon Glass7611ac62019-09-25 08:56:27 -0600429#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass1b27d602014-10-04 11:29:49 -0600430 va_list args;
431 char buf[40];
432
433 va_start(args, fmt);
434 vscnprintf(buf, sizeof(buf), fmt, args);
435 va_end(args);
436 return gpio_request(gpio, buf);
Simon Glassee8a3d92015-12-29 05:22:48 -0700437#else
438 return gpio_request(gpio, fmt);
439#endif
Simon Glass1b27d602014-10-04 11:29:49 -0600440}
441
Simon Glassce555292015-01-05 20:05:27 -0700442int _dm_gpio_free(struct udevice *dev, uint offset)
Simon Glasse821d182014-02-26 15:59:24 -0700443{
Simon Glass0f4517d2014-10-04 11:29:42 -0600444 struct gpio_dev_priv *uc_priv;
Simon Glasse821d182014-02-26 15:59:24 -0700445 int ret;
446
Simon Glassde0977b2015-03-05 12:25:20 -0700447 uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -0600448 if (!uc_priv->name[offset])
449 return -ENXIO;
Simon Glassb3a47542020-02-04 20:15:17 -0700450 if (gpio_get_ops(dev)->rfree) {
451 ret = gpio_get_ops(dev)->rfree(dev, offset);
Simon Glass0f4517d2014-10-04 11:29:42 -0600452 if (ret)
453 return ret;
454 }
455
456 free(uc_priv->name[offset]);
457 uc_priv->name[offset] = NULL;
458
459 return 0;
460}
461
Simon Glassce555292015-01-05 20:05:27 -0700462/**
463 * gpio_free() - [COMPAT] Relinquish GPIO
464 * gpio: GPIO number
465 *
466 * This function implements the API that's compatible with current
467 * GPIO API used in U-Boot. The request is forwarded to particular
468 * GPIO driver. Returns 0 on success, negative value on error.
469 */
470int gpio_free(unsigned gpio)
471{
472 struct gpio_desc desc;
473 int ret;
474
475 ret = gpio_to_device(gpio, &desc);
476 if (ret)
477 return ret;
478
479 return _dm_gpio_free(desc.dev, desc.offset);
480}
481
Simon Glassfd838972016-03-06 19:27:51 -0700482static int check_reserved(const struct gpio_desc *desc, const char *func)
Simon Glass0f4517d2014-10-04 11:29:42 -0600483{
Simon Glass230c1432015-07-02 18:16:16 -0600484 struct gpio_dev_priv *uc_priv;
485
486 if (!dm_gpio_is_valid(desc))
487 return -ENOENT;
Simon Glass0f4517d2014-10-04 11:29:42 -0600488
Simon Glass230c1432015-07-02 18:16:16 -0600489 uc_priv = dev_get_uclass_priv(desc->dev);
Simon Glassce555292015-01-05 20:05:27 -0700490 if (!uc_priv->name[desc->offset]) {
Simon Glass0f4517d2014-10-04 11:29:42 -0600491 printf("%s: %s: error: gpio %s%d not reserved\n",
Simon Glassce555292015-01-05 20:05:27 -0700492 desc->dev->name, func,
493 uc_priv->bank_name ? uc_priv->bank_name : "",
494 desc->offset);
Simon Glass0f4517d2014-10-04 11:29:42 -0600495 return -EBUSY;
496 }
497
498 return 0;
Simon Glasse821d182014-02-26 15:59:24 -0700499}
500
501/**
502 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
503 * gpio: GPIO number
504 *
505 * This function implements the API that's compatible with current
506 * GPIO API used in U-Boot. The request is forwarded to particular
507 * GPIO driver. Returns 0 on success, negative value on error.
508 */
509int gpio_direction_input(unsigned gpio)
510{
Simon Glassce555292015-01-05 20:05:27 -0700511 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700512 int ret;
513
Simon Glassce555292015-01-05 20:05:27 -0700514 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700515 if (ret)
516 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700517 ret = check_reserved(&desc, "dir_input");
518 if (ret)
519 return ret;
Simon Glasse821d182014-02-26 15:59:24 -0700520
Simon Glassce555292015-01-05 20:05:27 -0700521 return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
Simon Glasse821d182014-02-26 15:59:24 -0700522}
523
524/**
525 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
526 * gpio: GPIO number
527 * value: Logical value to be set on the GPIO pin
528 *
529 * This function implements the API that's compatible with current
530 * GPIO API used in U-Boot. The request is forwarded to particular
531 * GPIO driver. Returns 0 on success, negative value on error.
532 */
533int gpio_direction_output(unsigned gpio, int value)
534{
Simon Glassce555292015-01-05 20:05:27 -0700535 struct gpio_desc desc;
536 int ret;
537
538 ret = gpio_to_device(gpio, &desc);
539 if (ret)
540 return ret;
541 ret = check_reserved(&desc, "dir_output");
542 if (ret)
543 return ret;
544
545 return gpio_get_ops(desc.dev)->direction_output(desc.dev,
546 desc.offset, value);
547}
548
Patrick Delaunay4c2c96f2020-01-13 11:35:02 +0100549static int _gpio_get_value(const struct gpio_desc *desc)
Simon Glassce555292015-01-05 20:05:27 -0700550{
551 int value;
Patrick Delaunay4c2c96f2020-01-13 11:35:02 +0100552
553 value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
554
555 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
556}
557
558int dm_gpio_get_value(const struct gpio_desc *desc)
559{
Simon Glassce555292015-01-05 20:05:27 -0700560 int ret;
561
562 ret = check_reserved(desc, "get_value");
563 if (ret)
564 return ret;
565
Patrick Delaunay4c2c96f2020-01-13 11:35:02 +0100566 return _gpio_get_value(desc);
Simon Glassce555292015-01-05 20:05:27 -0700567}
568
Simon Glassfd838972016-03-06 19:27:51 -0700569int dm_gpio_set_value(const struct gpio_desc *desc, int value)
Simon Glassce555292015-01-05 20:05:27 -0700570{
571 int ret;
572
573 ret = check_reserved(desc, "set_value");
574 if (ret)
575 return ret;
576
577 if (desc->flags & GPIOD_ACTIVE_LOW)
578 value = !value;
Neil Armstrongf51b8da2020-05-05 10:43:17 +0200579
580 /*
581 * Emulate open drain by not actively driving the line high or
582 * Emulate open source by not actively driving the line low
583 */
584 if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
585 (desc->flags & GPIOD_OPEN_SOURCE && !value))
586 return gpio_get_ops(desc->dev)->direction_input(desc->dev,
587 desc->offset);
588 else if (desc->flags & GPIOD_OPEN_DRAIN ||
589 desc->flags & GPIOD_OPEN_SOURCE)
590 return gpio_get_ops(desc->dev)->direction_output(desc->dev,
591 desc->offset,
592 value);
593
Simon Glassce555292015-01-05 20:05:27 -0700594 gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
595 return 0;
596}
597
Patrick Delaunay187c45f2020-01-13 11:35:04 +0100598/* check dir flags invalid configuration */
599static int check_dir_flags(ulong flags)
600{
601 if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
602 log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
603 __func__, flags);
604 return -EINVAL;
605 }
606
Patrick Delaunay5c1c06e2020-01-13 11:35:07 +0100607 if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
608 log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
609 __func__, flags);
610 return -EINVAL;
611 }
612
613 if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
614 log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
615 __func__, flags);
616 return -EINVAL;
617 }
618
Patrick Delaunay187c45f2020-01-13 11:35:04 +0100619 return 0;
620}
621
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100622static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
Simon Glassce555292015-01-05 20:05:27 -0700623{
624 struct udevice *dev = desc->dev;
625 struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunay187c45f2020-01-13 11:35:04 +0100626 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100627 int ret = 0;
Simon Glasse821d182014-02-26 15:59:24 -0700628
Patrick Delaunay187c45f2020-01-13 11:35:04 +0100629 ret = check_dir_flags(flags);
630 if (ret) {
631 dev_dbg(dev,
632 "%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
633 desc->dev->name,
634 uc_priv->bank_name ? uc_priv->bank_name : "",
635 desc->offset, flags);
636
637 return ret;
638 }
639
Patrick Delaunay684326f2020-01-13 11:35:09 +0100640 /* GPIOD_ are directly managed by driver in set_dir_flags*/
641 if (ops->set_dir_flags) {
642 ret = ops->set_dir_flags(dev, desc->offset, flags);
643 } else {
644 if (flags & GPIOD_IS_OUT) {
645 ret = ops->direction_output(dev, desc->offset,
646 GPIOD_FLAGS_OUTPUT(flags));
647 } else if (flags & GPIOD_IS_IN) {
648 ret = ops->direction_input(dev, desc->offset);
649 }
Simon Glassce555292015-01-05 20:05:27 -0700650 }
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100651
Heiko Schocheraa914cd2020-05-22 11:08:56 +0200652 /* save the flags also in descriptor */
653 if (!ret)
654 desc->flags = flags;
655
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100656 return ret;
657}
658
659int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
660{
661 int ret;
662
663 ret = check_reserved(desc, "set_dir_flags");
Simon Glassce555292015-01-05 20:05:27 -0700664 if (ret)
665 return ret;
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100666
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100667 /* combine the requested flags (for IN/OUT) and the descriptor flags */
668 flags |= desc->flags;
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100669 ret = _dm_gpio_set_dir_flags(desc, flags);
Simon Glassce555292015-01-05 20:05:27 -0700670
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100671 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700672}
673
674int dm_gpio_set_dir(struct gpio_desc *desc)
675{
Patrick Delaunay3b2a1172020-01-13 11:35:03 +0100676 int ret;
677
678 ret = check_reserved(desc, "set_dir");
679 if (ret)
680 return ret;
681
682 return _dm_gpio_set_dir_flags(desc, desc->flags);
Simon Glasse821d182014-02-26 15:59:24 -0700683}
684
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100685int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
686{
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100687 struct udevice *dev = desc->dev;
688 int ret, value;
689 struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100690 ulong dir_flags;
691
692 ret = check_reserved(desc, "get_dir_flags");
693 if (ret)
694 return ret;
695
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100696 /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
697 if (ops->get_dir_flags) {
698 ret = ops->get_dir_flags(dev, desc->offset, &dir_flags);
699 if (ret)
700 return ret;
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100701
Patrick Delaunayfbacd622020-01-13 11:35:08 +0100702 /* GPIOD_ACTIVE_LOW is saved in desc->flags */
703 value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
704 if (desc->flags & GPIOD_ACTIVE_LOW)
705 value = !value;
706 dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
707 dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW);
708 if (value)
709 dir_flags |= GPIOD_IS_OUT_ACTIVE;
710 } else {
711 dir_flags = desc->flags;
712 /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
713 dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
714 if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
715 dir_flags |= GPIOD_IS_OUT_ACTIVE;
716 }
Patrick Delaunayaecf9d72020-01-13 11:35:06 +0100717 *flags = dir_flags;
718
719 return 0;
720}
721
Simon Glasse821d182014-02-26 15:59:24 -0700722/**
723 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
724 * gpio: GPIO number
725 *
726 * This function implements the API that's compatible with current
727 * GPIO API used in U-Boot. The request is forwarded to particular
728 * GPIO driver. Returns the value of the GPIO pin, or negative value
729 * on error.
730 */
731int gpio_get_value(unsigned gpio)
732{
Simon Glasse821d182014-02-26 15:59:24 -0700733 int ret;
734
Simon Glassce555292015-01-05 20:05:27 -0700735 struct gpio_desc desc;
736
737 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700738 if (ret)
739 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700740 return dm_gpio_get_value(&desc);
Simon Glasse821d182014-02-26 15:59:24 -0700741}
742
743/**
744 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
745 * gpio: GPIO number
746 * value: Logical value to be set on the GPIO pin.
747 *
748 * This function implements the API that's compatible with current
749 * GPIO API used in U-Boot. The request is forwarded to particular
750 * GPIO driver. Returns 0 on success, negative value on error.
751 */
752int gpio_set_value(unsigned gpio, int value)
753{
Simon Glassce555292015-01-05 20:05:27 -0700754 struct gpio_desc desc;
Simon Glasse821d182014-02-26 15:59:24 -0700755 int ret;
756
Simon Glassce555292015-01-05 20:05:27 -0700757 ret = gpio_to_device(gpio, &desc);
Simon Glasse821d182014-02-26 15:59:24 -0700758 if (ret)
759 return ret;
Simon Glassce555292015-01-05 20:05:27 -0700760 return dm_gpio_set_value(&desc, value);
Simon Glasse821d182014-02-26 15:59:24 -0700761}
762
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200763const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
Simon Glasse821d182014-02-26 15:59:24 -0700764{
765 struct gpio_dev_priv *priv;
766
767 /* Must be called on an active device */
Simon Glassde0977b2015-03-05 12:25:20 -0700768 priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -0700769 assert(priv);
770
771 *bit_count = priv->gpio_count;
772 return priv->bank_name;
773}
774
Simon Glass6e5e6dd2014-10-04 11:29:43 -0600775static const char * const gpio_function[GPIOF_COUNT] = {
776 "input",
777 "output",
778 "unused",
779 "unknown",
780 "func",
781};
782
Masahiro Yamada286c2522017-06-22 16:50:25 +0900783static int get_function(struct udevice *dev, int offset, bool skip_unused,
784 const char **namep)
Simon Glass6e5e6dd2014-10-04 11:29:43 -0600785{
Simon Glassde0977b2015-03-05 12:25:20 -0700786 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass6e5e6dd2014-10-04 11:29:43 -0600787 struct dm_gpio_ops *ops = gpio_get_ops(dev);
788
789 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
790 if (!device_active(dev))
791 return -ENODEV;
792 if (offset < 0 || offset >= uc_priv->gpio_count)
793 return -EINVAL;
794 if (namep)
795 *namep = uc_priv->name[offset];
796 if (skip_unused && !uc_priv->name[offset])
797 return GPIOF_UNUSED;
798 if (ops->get_function) {
799 int ret;
800
801 ret = ops->get_function(dev, offset);
802 if (ret < 0)
803 return ret;
804 if (ret >= ARRAY_SIZE(gpio_function))
805 return -ENODATA;
806 return ret;
807 }
808
809 return GPIOF_UNKNOWN;
810}
811
812int gpio_get_function(struct udevice *dev, int offset, const char **namep)
813{
814 return get_function(dev, offset, true, namep);
815}
816
817int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
818{
819 return get_function(dev, offset, false, namep);
820}
821
Simon Glass6b1ef592014-10-04 11:29:44 -0600822int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
823{
824 struct dm_gpio_ops *ops = gpio_get_ops(dev);
825 struct gpio_dev_priv *priv;
826 char *str = buf;
827 int func;
828 int ret;
829 int len;
830
831 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
832
833 *buf = 0;
Simon Glassde0977b2015-03-05 12:25:20 -0700834 priv = dev_get_uclass_priv(dev);
Simon Glass6b1ef592014-10-04 11:29:44 -0600835 ret = gpio_get_raw_function(dev, offset, NULL);
836 if (ret < 0)
837 return ret;
838 func = ret;
839 len = snprintf(str, buffsize, "%s%d: %s",
840 priv->bank_name ? priv->bank_name : "",
841 offset, gpio_function[func]);
842 if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
843 func == GPIOF_UNUSED) {
844 const char *label;
845 bool used;
846
847 ret = ops->get_value(dev, offset);
848 if (ret < 0)
849 return ret;
850 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
851 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
852 ret,
853 used ? 'x' : ' ',
854 used ? " " : "",
855 label ? label : "");
856 }
857
858 return 0;
859}
860
Simon Glass3176b6c2020-07-07 13:11:44 -0600861#if CONFIG_IS_ENABLED(ACPIGEN)
862int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
863{
864 struct dm_gpio_ops *ops;
865
866 memset(gpio, '\0', sizeof(*gpio));
867 if (!dm_gpio_is_valid(desc)) {
868 /* Indicate that the GPIO is not valid */
869 gpio->pin_count = 0;
870 gpio->pins[0] = 0;
871 return -EINVAL;
872 }
873
874 ops = gpio_get_ops(desc->dev);
875 if (!ops->get_acpi)
876 return -ENOSYS;
877
878 return ops->get_acpi(desc, gpio);
879}
880#endif
881
Simon Glassbef54db2015-04-14 21:03:20 -0600882int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
883{
884 int i, ret;
885 int gpio;
886
887 for (i = 0; i < 32; i++) {
888 gpio = gpio_num_array[i];
889 if (gpio == -1)
890 break;
891 ret = gpio_requestf(gpio, fmt, i);
892 if (ret)
893 goto err;
894 ret = gpio_direction_input(gpio);
895 if (ret) {
896 gpio_free(gpio);
897 goto err;
898 }
899 }
900
901 return 0;
902err:
903 for (i--; i >= 0; i--)
904 gpio_free(gpio_num_array[i]);
905
906 return ret;
907}
908
Simon Glass2c97a8f2014-11-10 18:00:21 -0700909/*
910 * get a number comprised of multiple GPIO values. gpio_num_array points to
911 * the array of gpio pin numbers to scan, terminated by -1.
912 */
Simon Glassbef54db2015-04-14 21:03:20 -0600913int gpio_get_values_as_int(const int *gpio_list)
Simon Glass2c97a8f2014-11-10 18:00:21 -0700914{
915 int gpio;
916 unsigned bitmask = 1;
917 unsigned vector = 0;
Simon Glassbef54db2015-04-14 21:03:20 -0600918 int ret;
Simon Glass2c97a8f2014-11-10 18:00:21 -0700919
920 while (bitmask &&
Simon Glassbef54db2015-04-14 21:03:20 -0600921 ((gpio = *gpio_list++) != -1)) {
922 ret = gpio_get_value(gpio);
923 if (ret < 0)
924 return ret;
925 else if (ret)
Simon Glass2c97a8f2014-11-10 18:00:21 -0700926 vector |= bitmask;
927 bitmask <<= 1;
928 }
Simon Glassbef54db2015-04-14 21:03:20 -0600929
Simon Glass2c97a8f2014-11-10 18:00:21 -0700930 return vector;
931}
932
Simon Glassfd838972016-03-06 19:27:51 -0700933int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
Simon Glassdf1687d2016-03-06 19:27:50 -0700934{
935 unsigned bitmask = 1;
936 unsigned vector = 0;
937 int ret, i;
938
939 for (i = 0; i < count; i++) {
940 ret = dm_gpio_get_value(&desc_list[i]);
941 if (ret < 0)
942 return ret;
943 else if (ret)
944 vector |= bitmask;
945 bitmask <<= 1;
946 }
947
948 return vector;
949}
950
Heiko Schocher58e4c382019-07-17 06:59:51 +0200951/**
952 * gpio_request_tail: common work for requesting a gpio.
953 *
954 * ret: return value from previous work in function which calls
955 * this function.
956 * This seems bogus (why calling this function instead not
957 * calling it and end caller function instead?).
958 * Because on error in caller function we want to set some
959 * default values in gpio desc and have a common error
960 * debug message, which provides this function.
961 * nodename: Name of node for which gpio gets requested
962 * used for gpio label name.
963 * args: pointer to output arguments structure
964 * list_name: Name of GPIO list
965 * used for gpio label name.
966 * index: gpio index in gpio list
967 * used for gpio label name.
968 * desc: pointer to gpio descriptor, filled from this
969 * function.
970 * flags: gpio flags to use.
971 * add_index: should index added to gpio label name
972 * gpio_dev: pointer to gpio device from which the gpio
973 * will be requested. If NULL try to get the
974 * gpio device with uclass_get_device_by_ofnode()
975 *
976 * return: In error case this function sets default values in
977 * gpio descriptor, also emmits a debug message.
978 * On success it returns 0 else the error code from
979 * function calls, or the error code passed through
980 * ret to this function.
981 *
982 */
Heiko Schocher39cb3402019-06-12 06:11:46 +0200983static int gpio_request_tail(int ret, const char *nodename,
Simon Glass12faa022017-05-18 20:09:18 -0600984 struct ofnode_phandle_args *args,
985 const char *list_name, int index,
Heiko Schocher39cb3402019-06-12 06:11:46 +0200986 struct gpio_desc *desc, int flags,
Heiko Schocher58e4c382019-07-17 06:59:51 +0200987 bool add_index, struct udevice *gpio_dev)
Simon Glass16e10402015-01-05 20:05:29 -0700988{
Patrick Delaunay758bba92020-01-13 11:35:01 +0100989 gpio_desc_init(desc, gpio_dev, 0);
Simon Glass12faa022017-05-18 20:09:18 -0600990 if (ret)
Simon Glass16e10402015-01-05 20:05:29 -0700991 goto err;
Simon Glass16e10402015-01-05 20:05:29 -0700992
Heiko Schocher39cb3402019-06-12 06:11:46 +0200993 if (!desc->dev) {
994 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
995 &desc->dev);
996 if (ret) {
Heiko Schocher58e4c382019-07-17 06:59:51 +0200997 debug("%s: uclass_get_device_by_ofnode failed\n",
998 __func__);
Heiko Schocher39cb3402019-06-12 06:11:46 +0200999 goto err;
1000 }
Simon Glass16e10402015-01-05 20:05:29 -07001001 }
Simon Glass12faa022017-05-18 20:09:18 -06001002 ret = gpio_find_and_xlate(desc, args);
Simon Glass16e10402015-01-05 20:05:29 -07001003 if (ret) {
1004 debug("%s: gpio_find_and_xlate failed\n", __func__);
1005 goto err;
1006 }
1007 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
Heiko Schocher39cb3402019-06-12 06:11:46 +02001008 nodename, list_name, index);
Simon Glass16e10402015-01-05 20:05:29 -07001009 if (ret) {
1010 debug("%s: dm_gpio_requestf failed\n", __func__);
1011 goto err;
1012 }
Patrick Delaunayaecf9d72020-01-13 11:35:06 +01001013 ret = dm_gpio_set_dir_flags(desc, flags);
Simon Glass16e10402015-01-05 20:05:29 -07001014 if (ret) {
1015 debug("%s: dm_gpio_set_dir failed\n", __func__);
1016 goto err;
1017 }
1018
1019 return 0;
1020err:
1021 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
Heiko Schocher39cb3402019-06-12 06:11:46 +02001022 __func__, nodename, list_name, index, ret);
Simon Glass16e10402015-01-05 20:05:29 -07001023 return ret;
1024}
1025
Simon Glass1d9af1f2017-05-30 21:47:09 -06001026static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
1027 int index, struct gpio_desc *desc,
1028 int flags, bool add_index)
Simon Glass12faa022017-05-18 20:09:18 -06001029{
1030 struct ofnode_phandle_args args;
1031 int ret;
1032
Simon Glass1d9af1f2017-05-30 21:47:09 -06001033 ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
1034 index, &args);
Simon Glass12faa022017-05-18 20:09:18 -06001035
Heiko Schocher39cb3402019-06-12 06:11:46 +02001036 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1037 index, desc, flags, add_index, NULL);
Simon Glass12faa022017-05-18 20:09:18 -06001038}
1039
Simon Glass1d9af1f2017-05-30 21:47:09 -06001040int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
Simon Glass16e10402015-01-05 20:05:29 -07001041 struct gpio_desc *desc, int flags)
1042{
Simon Glass1d9af1f2017-05-30 21:47:09 -06001043 return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
1044 index > 0);
Simon Glass16e10402015-01-05 20:05:29 -07001045}
1046
Simon Glass1d9af1f2017-05-30 21:47:09 -06001047int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
Simon Glass16e10402015-01-05 20:05:29 -07001048 struct gpio_desc *desc, int flags)
1049{
Simon Glass1d9af1f2017-05-30 21:47:09 -06001050 struct ofnode_phandle_args args;
Heiko Schocher39cb3402019-06-12 06:11:46 +02001051 ofnode node;
Simon Glass1d9af1f2017-05-30 21:47:09 -06001052 int ret;
1053
1054 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
1055 index, &args);
Heiko Schocher39cb3402019-06-12 06:11:46 +02001056 node = dev_ofnode(dev);
1057 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1058 index, desc, flags, index > 0, NULL);
Simon Glass16e10402015-01-05 20:05:29 -07001059}
1060
Simon Glass1d9af1f2017-05-30 21:47:09 -06001061int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
Simon Glass16e10402015-01-05 20:05:29 -07001062 struct gpio_desc *desc, int max_count,
1063 int flags)
1064{
1065 int count;
1066 int ret;
1067
Przemyslaw Marczak44fc5362015-03-31 18:57:16 +02001068 for (count = 0; count < max_count; count++) {
Simon Glass1d9af1f2017-05-30 21:47:09 -06001069 ret = _gpio_request_by_name_nodev(node, list_name, count,
Simon Glass16e10402015-01-05 20:05:29 -07001070 &desc[count], flags, true);
1071 if (ret == -ENOENT)
1072 break;
1073 else if (ret)
1074 goto err;
1075 }
1076
1077 /* We ran out of GPIOs in the list */
1078 return count;
1079
1080err:
1081 gpio_free_list_nodev(desc, count - 1);
1082
1083 return ret;
1084}
1085
1086int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
1087 struct gpio_desc *desc, int max_count,
1088 int flags)
1089{
1090 /*
1091 * This isn't ideal since we don't use dev->name in the debug()
1092 * calls in gpio_request_by_name(), but we can do this until
1093 * gpio_request_list_by_name_nodev() can be dropped.
1094 */
Simon Glass1d9af1f2017-05-30 21:47:09 -06001095 return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
1096 max_count, flags);
Simon Glass16e10402015-01-05 20:05:29 -07001097}
1098
1099int gpio_get_list_count(struct udevice *dev, const char *list_name)
1100{
1101 int ret;
1102
Patrick Delaunay75969032020-09-09 18:26:16 +02001103 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0, -1,
1104 NULL);
Simon Glass16e10402015-01-05 20:05:29 -07001105 if (ret) {
1106 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
1107 __func__, dev->name, list_name, ret);
1108 }
1109
1110 return ret;
1111}
1112
1113int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
1114{
1115 /* For now, we don't do any checking of dev */
1116 return _dm_gpio_free(desc->dev, desc->offset);
1117}
1118
1119int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
1120{
1121 int i;
1122
1123 /* For now, we don't do any checking of dev */
1124 for (i = 0; i < count; i++)
1125 dm_gpio_free(dev, &desc[i]);
1126
1127 return 0;
1128}
1129
1130int gpio_free_list_nodev(struct gpio_desc *desc, int count)
1131{
1132 return gpio_free_list(NULL, desc, count);
1133}
1134
Simon Glasse821d182014-02-26 15:59:24 -07001135/* We need to renumber the GPIOs when any driver is probed/removed */
Simon Glass0f4517d2014-10-04 11:29:42 -06001136static int gpio_renumber(struct udevice *removed_dev)
Simon Glasse821d182014-02-26 15:59:24 -07001137{
1138 struct gpio_dev_priv *uc_priv;
Heiko Schocherb74fcb42014-05-22 12:43:05 +02001139 struct udevice *dev;
Simon Glasse821d182014-02-26 15:59:24 -07001140 struct uclass *uc;
1141 unsigned base;
1142 int ret;
1143
1144 ret = uclass_get(UCLASS_GPIO, &uc);
1145 if (ret)
1146 return ret;
1147
1148 /* Ensure that we have a base for each bank */
1149 base = 0;
1150 uclass_foreach_dev(dev, uc) {
Simon Glass0f4517d2014-10-04 11:29:42 -06001151 if (device_active(dev) && dev != removed_dev) {
Simon Glassde0977b2015-03-05 12:25:20 -07001152 uc_priv = dev_get_uclass_priv(dev);
Simon Glasse821d182014-02-26 15:59:24 -07001153 uc_priv->gpio_base = base;
1154 base += uc_priv->gpio_count;
1155 }
1156 }
1157
1158 return 0;
1159}
1160
Simon Glassfd838972016-03-06 19:27:51 -07001161int gpio_get_number(const struct gpio_desc *desc)
Simon Glass94f54d12015-03-25 12:21:58 -06001162{
1163 struct udevice *dev = desc->dev;
1164 struct gpio_dev_priv *uc_priv;
1165
1166 if (!dev)
1167 return -1;
Simon Glass95588622020-12-22 19:30:28 -07001168 uc_priv = dev_get_uclass_priv(dev);
Simon Glass94f54d12015-03-25 12:21:58 -06001169
1170 return uc_priv->gpio_base + desc->offset;
1171}
1172
Heiko Schocherb74fcb42014-05-22 12:43:05 +02001173static int gpio_post_probe(struct udevice *dev)
Simon Glasse821d182014-02-26 15:59:24 -07001174{
Simon Glassde0977b2015-03-05 12:25:20 -07001175 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -06001176
1177 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
1178 if (!uc_priv->name)
1179 return -ENOMEM;
1180
1181 return gpio_renumber(NULL);
Simon Glasse821d182014-02-26 15:59:24 -07001182}
1183
Heiko Schocherb74fcb42014-05-22 12:43:05 +02001184static int gpio_pre_remove(struct udevice *dev)
Simon Glasse821d182014-02-26 15:59:24 -07001185{
Simon Glassde0977b2015-03-05 12:25:20 -07001186 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass0f4517d2014-10-04 11:29:42 -06001187 int i;
1188
1189 for (i = 0; i < uc_priv->gpio_count; i++) {
1190 if (uc_priv->name[i])
1191 free(uc_priv->name[i]);
1192 }
1193 free(uc_priv->name);
1194
1195 return gpio_renumber(dev);
Simon Glasse821d182014-02-26 15:59:24 -07001196}
1197
Heiko Schocher39cb3402019-06-12 06:11:46 +02001198int gpio_dev_request_index(struct udevice *dev, const char *nodename,
1199 char *list_name, int index, int flags,
1200 int dtflags, struct gpio_desc *desc)
1201{
1202 struct ofnode_phandle_args args;
1203
1204 args.node = ofnode_null();
1205 args.args_count = 2;
1206 args.args[0] = index;
1207 args.args[1] = dtflags;
1208
1209 return gpio_request_tail(0, nodename, &args, list_name, index, desc,
1210 flags, 0, dev);
1211}
1212
Jean-Jacques Hiblot775d6a22020-09-11 13:43:34 +05301213static void devm_gpiod_release(struct udevice *dev, void *res)
1214{
1215 dm_gpio_free(dev, res);
1216}
1217
1218static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
1219{
1220 return res == data;
1221}
1222
1223struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
1224 unsigned int index, int flags)
1225{
1226 int rc;
1227 struct gpio_desc *desc;
1228 char *propname;
1229 static const char suffix[] = "-gpios";
1230
1231 propname = malloc(strlen(id) + sizeof(suffix));
1232 if (!propname) {
1233 rc = -ENOMEM;
1234 goto end;
1235 }
1236
1237 strcpy(propname, id);
1238 strcat(propname, suffix);
1239
1240 desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
1241 __GFP_ZERO);
1242 if (unlikely(!desc)) {
1243 rc = -ENOMEM;
1244 goto end;
1245 }
1246
1247 rc = gpio_request_by_name(dev, propname, index, desc, flags);
1248
1249end:
1250 if (propname)
1251 free(propname);
1252
1253 if (rc)
1254 return ERR_PTR(rc);
1255
1256 devres_add(dev, desc);
1257
1258 return desc;
1259}
1260
1261struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
1262 const char *id,
1263 unsigned int index,
1264 int flags)
1265{
1266 struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);
1267
1268 if (IS_ERR(desc))
1269 return NULL;
1270
1271 return desc;
1272}
1273
1274void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
1275{
1276 int rc;
1277
1278 rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
1279 WARN_ON(rc);
1280}
1281
Michal Simek5f7202c2018-07-12 12:42:27 +02001282static int gpio_post_bind(struct udevice *dev)
1283{
Heiko Schocher39cb3402019-06-12 06:11:46 +02001284 struct udevice *child;
1285 ofnode node;
Heiko Schocher39cb3402019-06-12 06:11:46 +02001286
Michal Simek5f7202c2018-07-12 12:42:27 +02001287#if defined(CONFIG_NEEDS_MANUAL_RELOC)
1288 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
1289 static int reloc_done;
1290
1291 if (!reloc_done) {
1292 if (ops->request)
1293 ops->request += gd->reloc_off;
Simon Glassb3a47542020-02-04 20:15:17 -07001294 if (ops->rfree)
1295 ops->rfree += gd->reloc_off;
Michal Simek5f7202c2018-07-12 12:42:27 +02001296 if (ops->direction_input)
1297 ops->direction_input += gd->reloc_off;
1298 if (ops->direction_output)
1299 ops->direction_output += gd->reloc_off;
1300 if (ops->get_value)
1301 ops->get_value += gd->reloc_off;
1302 if (ops->set_value)
1303 ops->set_value += gd->reloc_off;
Michal Simek5f7202c2018-07-12 12:42:27 +02001304 if (ops->get_function)
1305 ops->get_function += gd->reloc_off;
1306 if (ops->xlate)
1307 ops->xlate += gd->reloc_off;
Patrick Delaunay684326f2020-01-13 11:35:09 +01001308 if (ops->set_dir_flags)
1309 ops->set_dir_flags += gd->reloc_off;
Patrick Delaunayfbacd622020-01-13 11:35:08 +01001310 if (ops->get_dir_flags)
1311 ops->get_dir_flags += gd->reloc_off;
Michal Simek5f7202c2018-07-12 12:42:27 +02001312
1313 reloc_done++;
1314 }
1315#endif
Heiko Schocher39cb3402019-06-12 06:11:46 +02001316
Heiko Schocher58e4c382019-07-17 06:59:51 +02001317 if (IS_ENABLED(CONFIG_GPIO_HOG)) {
1318 dev_for_each_subnode(node, dev) {
1319 if (ofnode_read_bool(node, "gpio-hog")) {
1320 const char *name = ofnode_get_name(node);
1321 int ret;
Heiko Schocher39cb3402019-06-12 06:11:46 +02001322
Heiko Schocher58e4c382019-07-17 06:59:51 +02001323 ret = device_bind_driver_to_node(dev,
1324 "gpio_hog",
1325 name, node,
1326 &child);
1327 if (ret)
1328 return ret;
1329 }
Heiko Schocher39cb3402019-06-12 06:11:46 +02001330 }
1331 }
Michal Simek5f7202c2018-07-12 12:42:27 +02001332 return 0;
1333}
1334
Simon Glasse821d182014-02-26 15:59:24 -07001335UCLASS_DRIVER(gpio) = {
1336 .id = UCLASS_GPIO,
1337 .name = "gpio",
Bhuvanchandra DVb1a1fc92015-06-01 18:37:15 +05301338 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glasse821d182014-02-26 15:59:24 -07001339 .post_probe = gpio_post_probe,
Michal Simek5f7202c2018-07-12 12:42:27 +02001340 .post_bind = gpio_post_bind,
Simon Glasse821d182014-02-26 15:59:24 -07001341 .pre_remove = gpio_pre_remove,
Simon Glass8a2b47f2020-12-03 16:55:17 -07001342 .per_device_auto = sizeof(struct gpio_dev_priv),
Simon Glasse821d182014-02-26 15:59:24 -07001343};