blob: 9eeab22eef5a63c72564083aa912dc944e7e1cab [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass96495d92014-02-26 15:59:24 -07002/*
3 * Copyright (c) 2013 Google, Inc
Simon Glass96495d92014-02-26 15:59:24 -07004 */
5
6#include <common.h>
7#include <dm.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -06008#include <log.h>
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02009#include <dm/device-internal.h>
10#include <dm/lists.h>
11#include <dm/uclass-internal.h>
Eric Nelson6c880b72016-04-24 16:32:40 -070012#include <dt-bindings/gpio/gpio.h>
Simon Glass96495d92014-02-26 15:59:24 -070013#include <errno.h>
Simon Glass0dac4d52015-01-05 20:05:28 -070014#include <fdtdec.h>
Simon Glassb892d122014-10-04 11:29:42 -060015#include <malloc.h>
Simon Glass96495d92014-02-26 15:59:24 -070016#include <asm/gpio.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060017#include <dm/device_compat.h>
Masahiro Yamada84b8bf62016-01-24 23:27:48 +090018#include <linux/bug.h>
Simon Glassfe1ef502014-10-22 21:37:01 -060019#include <linux/ctype.h>
Simon Glass96495d92014-02-26 15:59:24 -070020
Simon Glass3669e0e2015-01-05 20:05:29 -070021DECLARE_GLOBAL_DATA_PTR;
22
Simon Glass96495d92014-02-26 15:59:24 -070023/**
Patrick Delaunay9f2b0662020-01-13 11:35:01 +010024 * gpio_desc_init() - Initialize the GPIO descriptor
25 *
26 * @desc: GPIO descriptor to initialize
27 * @dev: GPIO device
28 * @offset: Offset of device GPIO
29 */
30static void gpio_desc_init(struct gpio_desc *desc,
31 struct udevice *dev,
32 uint offset)
33{
34 desc->dev = dev;
35 desc->offset = offset;
36 desc->flags = 0;
37}
38
39/**
Simon Glass96495d92014-02-26 15:59:24 -070040 * gpio_to_device() - Convert global GPIO number to device, number
Simon Glass96495d92014-02-26 15:59:24 -070041 *
42 * Convert the GPIO number to an entry in the list of GPIOs
43 * or GPIO blocks registered with the GPIO controller. Returns
44 * entry on success, NULL on error.
Simon Glassae7123f2015-01-05 20:05:27 -070045 *
46 * @gpio: The numeric representation of the GPIO
47 * @desc: Returns description (desc->flags will always be 0)
48 * @return 0 if found, -ENOENT if not found
Simon Glass96495d92014-02-26 15:59:24 -070049 */
Simon Glassae7123f2015-01-05 20:05:27 -070050static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
Simon Glass96495d92014-02-26 15:59:24 -070051{
52 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +020053 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -070054 int ret;
55
56 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
57 dev;
58 ret = uclass_next_device(&dev)) {
Simon Glasse564f052015-03-05 12:25:20 -070059 uc_priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -070060 if (gpio >= uc_priv->gpio_base &&
61 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
Patrick Delaunay9f2b0662020-01-13 11:35:01 +010062 gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
Simon Glass96495d92014-02-26 15:59:24 -070063 return 0;
64 }
65 }
66
67 /* No such GPIO */
Simon Glassae7123f2015-01-05 20:05:27 -070068 return ret ? ret : -ENOENT;
Simon Glass96495d92014-02-26 15:59:24 -070069}
70
Simon Glass32ec1592015-06-23 15:38:40 -060071int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
Simon Glass96495d92014-02-26 15:59:24 -070072{
Simon Glassfe1ef502014-10-22 21:37:01 -060073 struct gpio_dev_priv *uc_priv = NULL;
Heiko Schocher54c5d082014-05-22 12:43:05 +020074 struct udevice *dev;
Simon Glassfe1ef502014-10-22 21:37:01 -060075 ulong offset;
76 int numeric;
Simon Glass96495d92014-02-26 15:59:24 -070077 int ret;
78
Simon Glassfe1ef502014-10-22 21:37:01 -060079 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
Simon Glass96495d92014-02-26 15:59:24 -070080 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
81 dev;
82 ret = uclass_next_device(&dev)) {
Simon Glass96495d92014-02-26 15:59:24 -070083 int len;
84
Simon Glasse564f052015-03-05 12:25:20 -070085 uc_priv = dev_get_uclass_priv(dev);
Simon Glassfe1ef502014-10-22 21:37:01 -060086 if (numeric != -1) {
87 offset = numeric - uc_priv->gpio_base;
88 /* Allow GPIOs to be numbered from 0 */
Tom Rini75897912017-05-10 15:20:15 -040089 if (offset < uc_priv->gpio_count)
Simon Glassfe1ef502014-10-22 21:37:01 -060090 break;
91 }
92
Simon Glass96495d92014-02-26 15:59:24 -070093 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
94
Simon Glass939cda52014-06-11 23:29:47 -060095 if (!strncasecmp(name, uc_priv->bank_name, len)) {
Simon Glassfe1ef502014-10-22 21:37:01 -060096 if (!strict_strtoul(name + len, 10, &offset))
97 break;
Simon Glass96495d92014-02-26 15:59:24 -070098 }
99 }
100
Simon Glassfe1ef502014-10-22 21:37:01 -0600101 if (!dev)
102 return ret ? ret : -EINVAL;
103
Patrick Delaunay9f2b0662020-01-13 11:35:01 +0100104 gpio_desc_init(desc, dev, offset);
Simon Glass32ec1592015-06-23 15:38:40 -0600105
106 return 0;
107}
108
109int gpio_lookup_name(const char *name, struct udevice **devp,
110 unsigned int *offsetp, unsigned int *gpiop)
111{
112 struct gpio_desc desc;
113 int ret;
114
Simon Glassfe1ef502014-10-22 21:37:01 -0600115 if (devp)
Simon Glass32ec1592015-06-23 15:38:40 -0600116 *devp = NULL;
117 ret = dm_gpio_lookup_name(name, &desc);
118 if (ret)
119 return ret;
120
121 if (devp)
122 *devp = desc.dev;
Simon Glassfe1ef502014-10-22 21:37:01 -0600123 if (offsetp)
Simon Glass32ec1592015-06-23 15:38:40 -0600124 *offsetp = desc.offset;
125 if (gpiop) {
126 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
127
128 *gpiop = uc_priv->gpio_base + desc.offset;
129 }
Simon Glassfe1ef502014-10-22 21:37:01 -0600130
131 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700132}
133
Simon Glass3a571232017-05-18 20:09:18 -0600134int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
135 struct ofnode_phandle_args *args)
Eric Nelson6c880b72016-04-24 16:32:40 -0700136{
137 if (args->args_count < 1)
138 return -EINVAL;
139
140 desc->offset = args->args[0];
141
142 if (args->args_count < 2)
143 return 0;
144
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100145 desc->flags = 0;
Eric Nelson6c880b72016-04-24 16:32:40 -0700146 if (args->args[1] & GPIO_ACTIVE_LOW)
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100147 desc->flags |= GPIOD_ACTIVE_LOW;
Eric Nelson6c880b72016-04-24 16:32:40 -0700148
Patrick Delaunay477ca572020-01-13 11:35:07 +0100149 /*
150 * need to test 2 bits for gpio output binding:
151 * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
152 * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
153 */
154 if (args->args[1] & GPIO_SINGLE_ENDED) {
155 if (args->args[1] & GPIO_LINE_OPEN_DRAIN)
156 desc->flags |= GPIOD_OPEN_DRAIN;
157 else
158 desc->flags |= GPIOD_OPEN_SOURCE;
159 }
160
161 if (args->args[1] & GPIO_PULL_UP)
162 desc->flags |= GPIOD_PULL_UP;
163
164 if (args->args[1] & GPIO_PULL_DOWN)
165 desc->flags |= GPIOD_PULL_DOWN;
166
Eric Nelson6c880b72016-04-24 16:32:40 -0700167 return 0;
168}
169
Simon Glass3669e0e2015-01-05 20:05:29 -0700170static int gpio_find_and_xlate(struct gpio_desc *desc,
Simon Glass3a571232017-05-18 20:09:18 -0600171 struct ofnode_phandle_args *args)
Simon Glass0dac4d52015-01-05 20:05:28 -0700172{
173 struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
174
Eric Nelson6c880b72016-04-24 16:32:40 -0700175 if (ops->xlate)
176 return ops->xlate(desc->dev, desc, args);
Simon Glass0dac4d52015-01-05 20:05:28 -0700177 else
Eric Nelson6c880b72016-04-24 16:32:40 -0700178 return gpio_xlate_offs_flags(desc->dev, desc, args);
Simon Glass0dac4d52015-01-05 20:05:28 -0700179}
180
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200181#if defined(CONFIG_GPIO_HOG)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200182
183struct gpio_hog_priv {
184 struct gpio_desc gpiod;
185};
186
187struct gpio_hog_data {
188 int gpiod_flags;
189 int value;
190 u32 val[2];
191};
192
193static int gpio_hog_ofdata_to_platdata(struct udevice *dev)
194{
195 struct gpio_hog_data *plat = dev_get_platdata(dev);
196 const char *nodename;
197 int ret;
198
199 plat->value = 0;
200 if (dev_read_bool(dev, "input")) {
201 plat->gpiod_flags = GPIOD_IS_IN;
202 } else if (dev_read_bool(dev, "output-high")) {
203 plat->value = 1;
204 plat->gpiod_flags = GPIOD_IS_OUT;
205 } else if (dev_read_bool(dev, "output-low")) {
206 plat->gpiod_flags = GPIOD_IS_OUT;
207 } else {
208 printf("%s: missing gpio-hog state.\n", __func__);
209 return -EINVAL;
210 }
211 ret = dev_read_u32_array(dev, "gpios", plat->val, 2);
212 if (ret) {
213 printf("%s: wrong gpios property, 2 values needed %d\n",
214 __func__, ret);
215 return ret;
216 }
217 nodename = dev_read_string(dev, "line-name");
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200218 if (nodename)
219 device_set_name(dev, nodename);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200220
221 return 0;
222}
223
224static int gpio_hog_probe(struct udevice *dev)
225{
226 struct gpio_hog_data *plat = dev_get_platdata(dev);
227 struct gpio_hog_priv *priv = dev_get_priv(dev);
228 int ret;
229
230 ret = gpio_dev_request_index(dev->parent, dev->name, "gpio-hog",
231 plat->val[0], plat->gpiod_flags,
232 plat->val[1], &priv->gpiod);
233 if (ret < 0) {
234 debug("%s: node %s could not get gpio.\n", __func__,
235 dev->name);
236 return ret;
237 }
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200238
239 if (plat->gpiod_flags == GPIOD_IS_OUT) {
240 ret = dm_gpio_set_value(&priv->gpiod, plat->value);
241 if (ret < 0) {
242 debug("%s: node %s could not set gpio.\n", __func__,
243 dev->name);
244 return ret;
245 }
246 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200247
248 return 0;
249}
250
251int gpio_hog_probe_all(void)
252{
253 struct udevice *dev;
254 int ret;
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200255 int retval = 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200256
257 for (uclass_first_device(UCLASS_NOP, &dev);
258 dev;
259 uclass_find_next_device(&dev)) {
260 if (dev->driver == DM_GET_DRIVER(gpio_hog)) {
261 ret = device_probe(dev);
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200262 if (ret) {
263 printf("Failed to probe device %s err: %d\n",
264 dev->name, ret);
265 retval = ret;
266 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200267 }
268 }
269
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200270 return retval;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200271}
272
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200273int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200274{
275 struct udevice *dev;
276
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200277 *desc = NULL;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200278 gpio_hog_probe_all();
279 if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
280 struct gpio_hog_priv *priv = dev_get_priv(dev);
281
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200282 *desc = &priv->gpiod;
283 return 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200284 }
285
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200286 return -ENODEV;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200287}
288
289U_BOOT_DRIVER(gpio_hog) = {
290 .name = "gpio_hog",
291 .id = UCLASS_NOP,
292 .ofdata_to_platdata = gpio_hog_ofdata_to_platdata,
293 .probe = gpio_hog_probe,
294 .priv_auto_alloc_size = sizeof(struct gpio_hog_priv),
295 .platdata_auto_alloc_size = sizeof(struct gpio_hog_data),
296};
297#else
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200298int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200299{
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200300 return 0;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200301}
302#endif
303
Simon Glassefa677f2015-06-23 15:38:41 -0600304int dm_gpio_request(struct gpio_desc *desc, const char *label)
Simon Glassae7123f2015-01-05 20:05:27 -0700305{
306 struct udevice *dev = desc->dev;
307 struct gpio_dev_priv *uc_priv;
308 char *str;
309 int ret;
310
Simon Glasse564f052015-03-05 12:25:20 -0700311 uc_priv = dev_get_uclass_priv(dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700312 if (uc_priv->name[desc->offset])
313 return -EBUSY;
314 str = strdup(label);
315 if (!str)
316 return -ENOMEM;
317 if (gpio_get_ops(dev)->request) {
318 ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
319 if (ret) {
320 free(str);
321 return ret;
322 }
323 }
324 uc_priv->name[desc->offset] = str;
325
326 return 0;
327}
328
Simon Glass3669e0e2015-01-05 20:05:29 -0700329static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
330{
Simon Glass27084c02019-09-25 08:56:27 -0600331#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glass3669e0e2015-01-05 20:05:29 -0700332 va_list args;
333 char buf[40];
334
335 va_start(args, fmt);
336 vscnprintf(buf, sizeof(buf), fmt, args);
337 va_end(args);
338 return dm_gpio_request(desc, buf);
Simon Glass4dc52592015-12-29 05:22:48 -0700339#else
340 return dm_gpio_request(desc, fmt);
341#endif
Simon Glass3669e0e2015-01-05 20:05:29 -0700342}
343
Simon Glass96495d92014-02-26 15:59:24 -0700344/**
345 * gpio_request() - [COMPAT] Request GPIO
346 * gpio: GPIO number
347 * label: Name for the requested GPIO
348 *
Simon Glassb892d122014-10-04 11:29:42 -0600349 * The label is copied and allocated so the caller does not need to keep
350 * the pointer around.
351 *
Simon Glass96495d92014-02-26 15:59:24 -0700352 * This function implements the API that's compatible with current
353 * GPIO API used in U-Boot. The request is forwarded to particular
354 * GPIO driver. Returns 0 on success, negative value on error.
355 */
356int gpio_request(unsigned gpio, const char *label)
357{
Simon Glassae7123f2015-01-05 20:05:27 -0700358 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700359 int ret;
360
Simon Glassae7123f2015-01-05 20:05:27 -0700361 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700362 if (ret)
363 return ret;
364
Simon Glassae7123f2015-01-05 20:05:27 -0700365 return dm_gpio_request(&desc, label);
Simon Glass96495d92014-02-26 15:59:24 -0700366}
367
368/**
Simon Glassd44f5972014-10-04 11:29:49 -0600369 * gpio_requestf() - [COMPAT] Request GPIO
370 * @gpio: GPIO number
371 * @fmt: Format string for the requested GPIO
372 * @...: Arguments for the printf() format string
373 *
374 * This function implements the API that's compatible with current
375 * GPIO API used in U-Boot. The request is forwarded to particular
376 * GPIO driver. Returns 0 on success, negative value on error.
377 */
378int gpio_requestf(unsigned gpio, const char *fmt, ...)
379{
Simon Glass27084c02019-09-25 08:56:27 -0600380#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
Simon Glassd44f5972014-10-04 11:29:49 -0600381 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 gpio_request(gpio, buf);
Simon Glass4dc52592015-12-29 05:22:48 -0700388#else
389 return gpio_request(gpio, fmt);
390#endif
Simon Glassd44f5972014-10-04 11:29:49 -0600391}
392
Simon Glassae7123f2015-01-05 20:05:27 -0700393int _dm_gpio_free(struct udevice *dev, uint offset)
Simon Glass96495d92014-02-26 15:59:24 -0700394{
Simon Glassb892d122014-10-04 11:29:42 -0600395 struct gpio_dev_priv *uc_priv;
Simon Glass96495d92014-02-26 15:59:24 -0700396 int ret;
397
Simon Glasse564f052015-03-05 12:25:20 -0700398 uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -0600399 if (!uc_priv->name[offset])
400 return -ENXIO;
Simon Glass093152f2020-02-04 20:15:17 -0700401 if (gpio_get_ops(dev)->rfree) {
402 ret = gpio_get_ops(dev)->rfree(dev, offset);
Simon Glassb892d122014-10-04 11:29:42 -0600403 if (ret)
404 return ret;
405 }
406
407 free(uc_priv->name[offset]);
408 uc_priv->name[offset] = NULL;
409
410 return 0;
411}
412
Simon Glassae7123f2015-01-05 20:05:27 -0700413/**
414 * gpio_free() - [COMPAT] Relinquish GPIO
415 * gpio: GPIO number
416 *
417 * This function implements the API that's compatible with current
418 * GPIO API used in U-Boot. The request is forwarded to particular
419 * GPIO driver. Returns 0 on success, negative value on error.
420 */
421int gpio_free(unsigned gpio)
Simon Glassb892d122014-10-04 11:29:42 -0600422{
Simon Glassae7123f2015-01-05 20:05:27 -0700423 struct gpio_desc desc;
424 int ret;
Simon Glassb892d122014-10-04 11:29:42 -0600425
Simon Glassae7123f2015-01-05 20:05:27 -0700426 ret = gpio_to_device(gpio, &desc);
427 if (ret)
428 return ret;
429
430 return _dm_gpio_free(desc.dev, desc.offset);
431}
432
Simon Glass17c43f12016-03-06 19:27:51 -0700433static int check_reserved(const struct gpio_desc *desc, const char *func)
Simon Glassae7123f2015-01-05 20:05:27 -0700434{
Simon Glasseca48662015-07-02 18:16:16 -0600435 struct gpio_dev_priv *uc_priv;
Simon Glassae7123f2015-01-05 20:05:27 -0700436
Simon Glasseca48662015-07-02 18:16:16 -0600437 if (!dm_gpio_is_valid(desc))
438 return -ENOENT;
439
440 uc_priv = dev_get_uclass_priv(desc->dev);
Simon Glassae7123f2015-01-05 20:05:27 -0700441 if (!uc_priv->name[desc->offset]) {
Simon Glassb892d122014-10-04 11:29:42 -0600442 printf("%s: %s: error: gpio %s%d not reserved\n",
Simon Glassae7123f2015-01-05 20:05:27 -0700443 desc->dev->name, func,
444 uc_priv->bank_name ? uc_priv->bank_name : "",
445 desc->offset);
Simon Glassb892d122014-10-04 11:29:42 -0600446 return -EBUSY;
447 }
448
449 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700450}
451
452/**
453 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
454 * gpio: GPIO number
455 *
456 * This function implements the API that's compatible with current
457 * GPIO API used in U-Boot. The request is forwarded to particular
458 * GPIO driver. Returns 0 on success, negative value on error.
459 */
460int gpio_direction_input(unsigned gpio)
461{
Simon Glassae7123f2015-01-05 20:05:27 -0700462 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700463 int ret;
464
Simon Glassae7123f2015-01-05 20:05:27 -0700465 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700466 if (ret)
467 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700468 ret = check_reserved(&desc, "dir_input");
469 if (ret)
470 return ret;
Simon Glass96495d92014-02-26 15:59:24 -0700471
Simon Glassae7123f2015-01-05 20:05:27 -0700472 return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
Simon Glass96495d92014-02-26 15:59:24 -0700473}
474
475/**
476 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
477 * gpio: GPIO number
478 * value: Logical value to be set on the GPIO pin
479 *
480 * This function implements the API that's compatible with current
481 * GPIO API used in U-Boot. The request is forwarded to particular
482 * GPIO driver. Returns 0 on success, negative value on error.
483 */
484int gpio_direction_output(unsigned gpio, int value)
485{
Simon Glassae7123f2015-01-05 20:05:27 -0700486 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700487 int ret;
488
Simon Glassae7123f2015-01-05 20:05:27 -0700489 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700490 if (ret)
491 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700492 ret = check_reserved(&desc, "dir_output");
493 if (ret)
494 return ret;
Simon Glass96495d92014-02-26 15:59:24 -0700495
Simon Glassae7123f2015-01-05 20:05:27 -0700496 return gpio_get_ops(desc.dev)->direction_output(desc.dev,
497 desc.offset, value);
498}
499
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100500static int _gpio_get_value(const struct gpio_desc *desc)
Simon Glassae7123f2015-01-05 20:05:27 -0700501{
502 int value;
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100503
504 value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
505
506 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
507}
508
509int dm_gpio_get_value(const struct gpio_desc *desc)
510{
Simon Glassae7123f2015-01-05 20:05:27 -0700511 int ret;
512
513 ret = check_reserved(desc, "get_value");
514 if (ret)
515 return ret;
516
Patrick Delaunay8a9140c2020-01-13 11:35:02 +0100517 return _gpio_get_value(desc);
Simon Glassae7123f2015-01-05 20:05:27 -0700518}
519
Simon Glass17c43f12016-03-06 19:27:51 -0700520int dm_gpio_set_value(const struct gpio_desc *desc, int value)
Simon Glassae7123f2015-01-05 20:05:27 -0700521{
522 int ret;
523
524 ret = check_reserved(desc, "set_value");
525 if (ret)
526 return ret;
527
528 if (desc->flags & GPIOD_ACTIVE_LOW)
529 value = !value;
Neil Armstrong47bd5332020-05-05 10:43:17 +0200530
531 /*
532 * Emulate open drain by not actively driving the line high or
533 * Emulate open source by not actively driving the line low
534 */
535 if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
536 (desc->flags & GPIOD_OPEN_SOURCE && !value))
537 return gpio_get_ops(desc->dev)->direction_input(desc->dev,
538 desc->offset);
539 else if (desc->flags & GPIOD_OPEN_DRAIN ||
540 desc->flags & GPIOD_OPEN_SOURCE)
541 return gpio_get_ops(desc->dev)->direction_output(desc->dev,
542 desc->offset,
543 value);
544
Simon Glassae7123f2015-01-05 20:05:27 -0700545 gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
546 return 0;
547}
548
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100549/* check dir flags invalid configuration */
550static int check_dir_flags(ulong flags)
551{
552 if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
553 log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
554 __func__, flags);
555 return -EINVAL;
556 }
557
Patrick Delaunay477ca572020-01-13 11:35:07 +0100558 if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
559 log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
560 __func__, flags);
561 return -EINVAL;
562 }
563
564 if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
565 log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
566 __func__, flags);
567 return -EINVAL;
568 }
569
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100570 return 0;
571}
572
Patrick Delaunay788ea832020-01-13 11:35:03 +0100573static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
Simon Glassae7123f2015-01-05 20:05:27 -0700574{
575 struct udevice *dev = desc->dev;
576 struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100577 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Patrick Delaunay788ea832020-01-13 11:35:03 +0100578 int ret = 0;
Simon Glassae7123f2015-01-05 20:05:27 -0700579
Patrick Delaunay4292fb12020-01-13 11:35:04 +0100580 ret = check_dir_flags(flags);
581 if (ret) {
582 dev_dbg(dev,
583 "%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
584 desc->dev->name,
585 uc_priv->bank_name ? uc_priv->bank_name : "",
586 desc->offset, flags);
587
588 return ret;
589 }
590
Patrick Delaunay8fd9daf2020-01-13 11:35:09 +0100591 /* GPIOD_ are directly managed by driver in set_dir_flags*/
592 if (ops->set_dir_flags) {
593 ret = ops->set_dir_flags(dev, desc->offset, flags);
594 } else {
595 if (flags & GPIOD_IS_OUT) {
596 ret = ops->direction_output(dev, desc->offset,
597 GPIOD_FLAGS_OUTPUT(flags));
598 } else if (flags & GPIOD_IS_IN) {
599 ret = ops->direction_input(dev, desc->offset);
600 }
Simon Glassae7123f2015-01-05 20:05:27 -0700601 }
Patrick Delaunay788ea832020-01-13 11:35:03 +0100602
603 return ret;
604}
605
606int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
607{
608 int ret;
609
610 ret = check_reserved(desc, "set_dir_flags");
Simon Glassae7123f2015-01-05 20:05:27 -0700611 if (ret)
612 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700613
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100614 /* combine the requested flags (for IN/OUT) and the descriptor flags */
615 flags |= desc->flags;
Patrick Delaunay788ea832020-01-13 11:35:03 +0100616 ret = _dm_gpio_set_dir_flags(desc, flags);
617
618 /* update the descriptor flags */
619 if (ret)
620 desc->flags = flags;
621
622 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700623}
624
625int dm_gpio_set_dir(struct gpio_desc *desc)
626{
Patrick Delaunay788ea832020-01-13 11:35:03 +0100627 int ret;
628
629 ret = check_reserved(desc, "set_dir");
630 if (ret)
631 return ret;
632
633 return _dm_gpio_set_dir_flags(desc, desc->flags);
Simon Glass96495d92014-02-26 15:59:24 -0700634}
635
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100636int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
637{
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100638 struct udevice *dev = desc->dev;
639 int ret, value;
640 struct dm_gpio_ops *ops = gpio_get_ops(dev);
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100641 ulong dir_flags;
642
643 ret = check_reserved(desc, "get_dir_flags");
644 if (ret)
645 return ret;
646
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100647 /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
648 if (ops->get_dir_flags) {
649 ret = ops->get_dir_flags(dev, desc->offset, &dir_flags);
650 if (ret)
651 return ret;
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100652
Patrick Delaunayd2c07e52020-01-13 11:35:08 +0100653 /* GPIOD_ACTIVE_LOW is saved in desc->flags */
654 value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
655 if (desc->flags & GPIOD_ACTIVE_LOW)
656 value = !value;
657 dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
658 dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW);
659 if (value)
660 dir_flags |= GPIOD_IS_OUT_ACTIVE;
661 } else {
662 dir_flags = desc->flags;
663 /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
664 dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
665 if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
666 dir_flags |= GPIOD_IS_OUT_ACTIVE;
667 }
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100668 *flags = dir_flags;
669
670 return 0;
671}
672
Simon Glass96495d92014-02-26 15:59:24 -0700673/**
674 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
675 * gpio: GPIO number
676 *
677 * This function implements the API that's compatible with current
678 * GPIO API used in U-Boot. The request is forwarded to particular
679 * GPIO driver. Returns the value of the GPIO pin, or negative value
680 * on error.
681 */
682int gpio_get_value(unsigned gpio)
683{
Simon Glass96495d92014-02-26 15:59:24 -0700684 int ret;
685
Simon Glassae7123f2015-01-05 20:05:27 -0700686 struct gpio_desc desc;
687
688 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700689 if (ret)
690 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700691 return dm_gpio_get_value(&desc);
Simon Glass96495d92014-02-26 15:59:24 -0700692}
693
694/**
695 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
696 * gpio: GPIO number
697 * value: Logical value to be set on the GPIO pin.
698 *
699 * This function implements the API that's compatible with current
700 * GPIO API used in U-Boot. The request is forwarded to particular
701 * GPIO driver. Returns 0 on success, negative value on error.
702 */
703int gpio_set_value(unsigned gpio, int value)
704{
Simon Glassae7123f2015-01-05 20:05:27 -0700705 struct gpio_desc desc;
Simon Glass96495d92014-02-26 15:59:24 -0700706 int ret;
707
Simon Glassae7123f2015-01-05 20:05:27 -0700708 ret = gpio_to_device(gpio, &desc);
Simon Glass96495d92014-02-26 15:59:24 -0700709 if (ret)
710 return ret;
Simon Glassae7123f2015-01-05 20:05:27 -0700711 return dm_gpio_set_value(&desc, value);
Simon Glass96495d92014-02-26 15:59:24 -0700712}
713
Heiko Schocher54c5d082014-05-22 12:43:05 +0200714const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
Simon Glass96495d92014-02-26 15:59:24 -0700715{
716 struct gpio_dev_priv *priv;
717
718 /* Must be called on an active device */
Simon Glasse564f052015-03-05 12:25:20 -0700719 priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -0700720 assert(priv);
721
722 *bit_count = priv->gpio_count;
723 return priv->bank_name;
724}
725
Simon Glass6449a502014-10-04 11:29:43 -0600726static const char * const gpio_function[GPIOF_COUNT] = {
727 "input",
728 "output",
729 "unused",
730 "unknown",
731 "func",
732};
733
Masahiro Yamadafb07f972017-06-22 16:50:25 +0900734static int get_function(struct udevice *dev, int offset, bool skip_unused,
735 const char **namep)
Simon Glass6449a502014-10-04 11:29:43 -0600736{
Simon Glasse564f052015-03-05 12:25:20 -0700737 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glass6449a502014-10-04 11:29:43 -0600738 struct dm_gpio_ops *ops = gpio_get_ops(dev);
739
740 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
741 if (!device_active(dev))
742 return -ENODEV;
743 if (offset < 0 || offset >= uc_priv->gpio_count)
744 return -EINVAL;
745 if (namep)
746 *namep = uc_priv->name[offset];
747 if (skip_unused && !uc_priv->name[offset])
748 return GPIOF_UNUSED;
749 if (ops->get_function) {
750 int ret;
751
752 ret = ops->get_function(dev, offset);
753 if (ret < 0)
754 return ret;
755 if (ret >= ARRAY_SIZE(gpio_function))
756 return -ENODATA;
757 return ret;
758 }
759
760 return GPIOF_UNKNOWN;
761}
762
763int gpio_get_function(struct udevice *dev, int offset, const char **namep)
764{
765 return get_function(dev, offset, true, namep);
766}
767
768int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
769{
770 return get_function(dev, offset, false, namep);
771}
772
Simon Glass07575352014-10-04 11:29:44 -0600773int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
774{
775 struct dm_gpio_ops *ops = gpio_get_ops(dev);
776 struct gpio_dev_priv *priv;
777 char *str = buf;
778 int func;
779 int ret;
780 int len;
781
782 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
783
784 *buf = 0;
Simon Glasse564f052015-03-05 12:25:20 -0700785 priv = dev_get_uclass_priv(dev);
Simon Glass07575352014-10-04 11:29:44 -0600786 ret = gpio_get_raw_function(dev, offset, NULL);
787 if (ret < 0)
788 return ret;
789 func = ret;
790 len = snprintf(str, buffsize, "%s%d: %s",
791 priv->bank_name ? priv->bank_name : "",
792 offset, gpio_function[func]);
793 if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
794 func == GPIOF_UNUSED) {
795 const char *label;
796 bool used;
797
798 ret = ops->get_value(dev, offset);
799 if (ret < 0)
800 return ret;
801 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
802 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
803 ret,
804 used ? 'x' : ' ',
805 used ? " " : "",
806 label ? label : "");
807 }
808
809 return 0;
810}
811
Simon Glass962f5ca2015-04-14 21:03:20 -0600812int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
813{
814 int i, ret;
815 int gpio;
816
817 for (i = 0; i < 32; i++) {
818 gpio = gpio_num_array[i];
819 if (gpio == -1)
820 break;
821 ret = gpio_requestf(gpio, fmt, i);
822 if (ret)
823 goto err;
824 ret = gpio_direction_input(gpio);
825 if (ret) {
826 gpio_free(gpio);
827 goto err;
828 }
829 }
830
831 return 0;
832err:
833 for (i--; i >= 0; i--)
834 gpio_free(gpio_num_array[i]);
835
836 return ret;
837}
838
Simon Glasse5901c92014-11-10 18:00:21 -0700839/*
840 * get a number comprised of multiple GPIO values. gpio_num_array points to
841 * the array of gpio pin numbers to scan, terminated by -1.
842 */
Simon Glass962f5ca2015-04-14 21:03:20 -0600843int gpio_get_values_as_int(const int *gpio_list)
Simon Glasse5901c92014-11-10 18:00:21 -0700844{
845 int gpio;
846 unsigned bitmask = 1;
847 unsigned vector = 0;
Simon Glass962f5ca2015-04-14 21:03:20 -0600848 int ret;
Simon Glasse5901c92014-11-10 18:00:21 -0700849
850 while (bitmask &&
Simon Glass962f5ca2015-04-14 21:03:20 -0600851 ((gpio = *gpio_list++) != -1)) {
852 ret = gpio_get_value(gpio);
853 if (ret < 0)
854 return ret;
855 else if (ret)
Simon Glasse5901c92014-11-10 18:00:21 -0700856 vector |= bitmask;
857 bitmask <<= 1;
858 }
Simon Glass962f5ca2015-04-14 21:03:20 -0600859
Simon Glasse5901c92014-11-10 18:00:21 -0700860 return vector;
861}
862
Simon Glass17c43f12016-03-06 19:27:51 -0700863int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
Simon Glassbbf24782016-03-06 19:27:50 -0700864{
865 unsigned bitmask = 1;
866 unsigned vector = 0;
867 int ret, i;
868
869 for (i = 0; i < count; i++) {
870 ret = dm_gpio_get_value(&desc_list[i]);
871 if (ret < 0)
872 return ret;
873 else if (ret)
874 vector |= bitmask;
875 bitmask <<= 1;
876 }
877
878 return vector;
879}
880
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200881/**
882 * gpio_request_tail: common work for requesting a gpio.
883 *
884 * ret: return value from previous work in function which calls
885 * this function.
886 * This seems bogus (why calling this function instead not
887 * calling it and end caller function instead?).
888 * Because on error in caller function we want to set some
889 * default values in gpio desc and have a common error
890 * debug message, which provides this function.
891 * nodename: Name of node for which gpio gets requested
892 * used for gpio label name.
893 * args: pointer to output arguments structure
894 * list_name: Name of GPIO list
895 * used for gpio label name.
896 * index: gpio index in gpio list
897 * used for gpio label name.
898 * desc: pointer to gpio descriptor, filled from this
899 * function.
900 * flags: gpio flags to use.
901 * add_index: should index added to gpio label name
902 * gpio_dev: pointer to gpio device from which the gpio
903 * will be requested. If NULL try to get the
904 * gpio device with uclass_get_device_by_ofnode()
905 *
906 * return: In error case this function sets default values in
907 * gpio descriptor, also emmits a debug message.
908 * On success it returns 0 else the error code from
909 * function calls, or the error code passed through
910 * ret to this function.
911 *
912 */
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200913static int gpio_request_tail(int ret, const char *nodename,
Simon Glass3a571232017-05-18 20:09:18 -0600914 struct ofnode_phandle_args *args,
915 const char *list_name, int index,
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200916 struct gpio_desc *desc, int flags,
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200917 bool add_index, struct udevice *gpio_dev)
Simon Glass3669e0e2015-01-05 20:05:29 -0700918{
Patrick Delaunay9f2b0662020-01-13 11:35:01 +0100919 gpio_desc_init(desc, gpio_dev, 0);
Simon Glass3a571232017-05-18 20:09:18 -0600920 if (ret)
Simon Glass3669e0e2015-01-05 20:05:29 -0700921 goto err;
Simon Glass3669e0e2015-01-05 20:05:29 -0700922
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200923 if (!desc->dev) {
924 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
925 &desc->dev);
926 if (ret) {
Heiko Schocher49b10cb2019-07-17 06:59:51 +0200927 debug("%s: uclass_get_device_by_ofnode failed\n",
928 __func__);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200929 goto err;
930 }
Simon Glass3669e0e2015-01-05 20:05:29 -0700931 }
Simon Glass3a571232017-05-18 20:09:18 -0600932 ret = gpio_find_and_xlate(desc, args);
Simon Glass3669e0e2015-01-05 20:05:29 -0700933 if (ret) {
934 debug("%s: gpio_find_and_xlate failed\n", __func__);
935 goto err;
936 }
937 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200938 nodename, list_name, index);
Simon Glass3669e0e2015-01-05 20:05:29 -0700939 if (ret) {
940 debug("%s: dm_gpio_requestf failed\n", __func__);
941 goto err;
942 }
Patrick Delaunay695e5fd2020-01-13 11:35:06 +0100943 ret = dm_gpio_set_dir_flags(desc, flags);
Simon Glass3669e0e2015-01-05 20:05:29 -0700944 if (ret) {
945 debug("%s: dm_gpio_set_dir failed\n", __func__);
946 goto err;
947 }
948
949 return 0;
950err:
951 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200952 __func__, nodename, list_name, index, ret);
Simon Glass3669e0e2015-01-05 20:05:29 -0700953 return ret;
954}
955
Simon Glass150c5af2017-05-30 21:47:09 -0600956static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
957 int index, struct gpio_desc *desc,
958 int flags, bool add_index)
Simon Glass3a571232017-05-18 20:09:18 -0600959{
960 struct ofnode_phandle_args args;
961 int ret;
962
Simon Glass150c5af2017-05-30 21:47:09 -0600963 ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
964 index, &args);
Simon Glass3a571232017-05-18 20:09:18 -0600965
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200966 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
967 index, desc, flags, add_index, NULL);
Simon Glass3a571232017-05-18 20:09:18 -0600968}
969
Simon Glass150c5af2017-05-30 21:47:09 -0600970int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
Simon Glass3669e0e2015-01-05 20:05:29 -0700971 struct gpio_desc *desc, int flags)
972{
Simon Glass150c5af2017-05-30 21:47:09 -0600973 return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
974 index > 0);
Simon Glass3669e0e2015-01-05 20:05:29 -0700975}
976
Simon Glass150c5af2017-05-30 21:47:09 -0600977int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
Simon Glass3669e0e2015-01-05 20:05:29 -0700978 struct gpio_desc *desc, int flags)
979{
Simon Glass150c5af2017-05-30 21:47:09 -0600980 struct ofnode_phandle_args args;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200981 ofnode node;
Simon Glass150c5af2017-05-30 21:47:09 -0600982 int ret;
983
984 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
985 index, &args);
Heiko Schocher5fc7cf82019-06-12 06:11:46 +0200986 node = dev_ofnode(dev);
987 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
988 index, desc, flags, index > 0, NULL);
Simon Glass3669e0e2015-01-05 20:05:29 -0700989}
990
Simon Glass150c5af2017-05-30 21:47:09 -0600991int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
Simon Glass3669e0e2015-01-05 20:05:29 -0700992 struct gpio_desc *desc, int max_count,
993 int flags)
994{
995 int count;
996 int ret;
997
Przemyslaw Marczak2984e7a2015-03-31 18:57:16 +0200998 for (count = 0; count < max_count; count++) {
Simon Glass150c5af2017-05-30 21:47:09 -0600999 ret = _gpio_request_by_name_nodev(node, list_name, count,
Simon Glass3669e0e2015-01-05 20:05:29 -07001000 &desc[count], flags, true);
1001 if (ret == -ENOENT)
1002 break;
1003 else if (ret)
1004 goto err;
1005 }
1006
1007 /* We ran out of GPIOs in the list */
1008 return count;
1009
1010err:
1011 gpio_free_list_nodev(desc, count - 1);
1012
1013 return ret;
1014}
1015
1016int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
1017 struct gpio_desc *desc, int max_count,
1018 int flags)
1019{
1020 /*
1021 * This isn't ideal since we don't use dev->name in the debug()
1022 * calls in gpio_request_by_name(), but we can do this until
1023 * gpio_request_list_by_name_nodev() can be dropped.
1024 */
Simon Glass150c5af2017-05-30 21:47:09 -06001025 return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
1026 max_count, flags);
Simon Glass3669e0e2015-01-05 20:05:29 -07001027}
1028
1029int gpio_get_list_count(struct udevice *dev, const char *list_name)
1030{
1031 int ret;
1032
Simon Glasse160f7d2017-01-17 16:52:55 -07001033 ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
Simon Glass3669e0e2015-01-05 20:05:29 -07001034 list_name, "#gpio-cells", 0, -1,
1035 NULL);
1036 if (ret) {
1037 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
1038 __func__, dev->name, list_name, ret);
1039 }
1040
1041 return ret;
1042}
1043
1044int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
1045{
1046 /* For now, we don't do any checking of dev */
1047 return _dm_gpio_free(desc->dev, desc->offset);
1048}
1049
1050int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
1051{
1052 int i;
1053
1054 /* For now, we don't do any checking of dev */
1055 for (i = 0; i < count; i++)
1056 dm_gpio_free(dev, &desc[i]);
1057
1058 return 0;
1059}
1060
1061int gpio_free_list_nodev(struct gpio_desc *desc, int count)
1062{
1063 return gpio_free_list(NULL, desc, count);
1064}
1065
Simon Glass96495d92014-02-26 15:59:24 -07001066/* We need to renumber the GPIOs when any driver is probed/removed */
Simon Glassb892d122014-10-04 11:29:42 -06001067static int gpio_renumber(struct udevice *removed_dev)
Simon Glass96495d92014-02-26 15:59:24 -07001068{
1069 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +02001070 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -07001071 struct uclass *uc;
1072 unsigned base;
1073 int ret;
1074
1075 ret = uclass_get(UCLASS_GPIO, &uc);
1076 if (ret)
1077 return ret;
1078
1079 /* Ensure that we have a base for each bank */
1080 base = 0;
1081 uclass_foreach_dev(dev, uc) {
Simon Glassb892d122014-10-04 11:29:42 -06001082 if (device_active(dev) && dev != removed_dev) {
Simon Glasse564f052015-03-05 12:25:20 -07001083 uc_priv = dev_get_uclass_priv(dev);
Simon Glass96495d92014-02-26 15:59:24 -07001084 uc_priv->gpio_base = base;
1085 base += uc_priv->gpio_count;
1086 }
1087 }
1088
1089 return 0;
1090}
1091
Simon Glass17c43f12016-03-06 19:27:51 -07001092int gpio_get_number(const struct gpio_desc *desc)
Simon Glass56a71f82015-03-25 12:21:58 -06001093{
1094 struct udevice *dev = desc->dev;
1095 struct gpio_dev_priv *uc_priv;
1096
1097 if (!dev)
1098 return -1;
1099 uc_priv = dev->uclass_priv;
1100
1101 return uc_priv->gpio_base + desc->offset;
1102}
1103
Heiko Schocher54c5d082014-05-22 12:43:05 +02001104static int gpio_post_probe(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -07001105{
Simon Glasse564f052015-03-05 12:25:20 -07001106 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -06001107
1108 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
1109 if (!uc_priv->name)
1110 return -ENOMEM;
1111
1112 return gpio_renumber(NULL);
Simon Glass96495d92014-02-26 15:59:24 -07001113}
1114
Heiko Schocher54c5d082014-05-22 12:43:05 +02001115static int gpio_pre_remove(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -07001116{
Simon Glasse564f052015-03-05 12:25:20 -07001117 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
Simon Glassb892d122014-10-04 11:29:42 -06001118 int i;
1119
1120 for (i = 0; i < uc_priv->gpio_count; i++) {
1121 if (uc_priv->name[i])
1122 free(uc_priv->name[i]);
1123 }
1124 free(uc_priv->name);
1125
1126 return gpio_renumber(dev);
Simon Glass96495d92014-02-26 15:59:24 -07001127}
1128
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001129int gpio_dev_request_index(struct udevice *dev, const char *nodename,
1130 char *list_name, int index, int flags,
1131 int dtflags, struct gpio_desc *desc)
1132{
1133 struct ofnode_phandle_args args;
1134
1135 args.node = ofnode_null();
1136 args.args_count = 2;
1137 args.args[0] = index;
1138 args.args[1] = dtflags;
1139
1140 return gpio_request_tail(0, nodename, &args, list_name, index, desc,
1141 flags, 0, dev);
1142}
1143
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001144static int gpio_post_bind(struct udevice *dev)
1145{
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001146 struct udevice *child;
1147 ofnode node;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001148
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001149#if defined(CONFIG_NEEDS_MANUAL_RELOC)
1150 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
1151 static int reloc_done;
1152
1153 if (!reloc_done) {
1154 if (ops->request)
1155 ops->request += gd->reloc_off;
Simon Glass093152f2020-02-04 20:15:17 -07001156 if (ops->rfree)
1157 ops->rfree += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001158 if (ops->direction_input)
1159 ops->direction_input += gd->reloc_off;
1160 if (ops->direction_output)
1161 ops->direction_output += gd->reloc_off;
1162 if (ops->get_value)
1163 ops->get_value += gd->reloc_off;
1164 if (ops->set_value)
1165 ops->set_value += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001166 if (ops->get_function)
1167 ops->get_function += gd->reloc_off;
1168 if (ops->xlate)
1169 ops->xlate += gd->reloc_off;
Patrick Delaunay8fd9daf2020-01-13 11:35:09 +01001170 if (ops->set_dir_flags)
1171 ops->set_dir_flags += gd->reloc_off;
Patrick Delaunayd2c07e52020-01-13 11:35:08 +01001172 if (ops->get_dir_flags)
1173 ops->get_dir_flags += gd->reloc_off;
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001174
1175 reloc_done++;
1176 }
1177#endif
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001178
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001179 if (IS_ENABLED(CONFIG_GPIO_HOG)) {
1180 dev_for_each_subnode(node, dev) {
1181 if (ofnode_read_bool(node, "gpio-hog")) {
1182 const char *name = ofnode_get_name(node);
1183 int ret;
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001184
Heiko Schocher49b10cb2019-07-17 06:59:51 +02001185 ret = device_bind_driver_to_node(dev,
1186 "gpio_hog",
1187 name, node,
1188 &child);
1189 if (ret)
1190 return ret;
1191 }
Heiko Schocher5fc7cf82019-06-12 06:11:46 +02001192 }
1193 }
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001194 return 0;
1195}
1196
Simon Glass96495d92014-02-26 15:59:24 -07001197UCLASS_DRIVER(gpio) = {
1198 .id = UCLASS_GPIO,
1199 .name = "gpio",
Bhuvanchandra DVae89bb02015-06-01 18:37:15 +05301200 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass96495d92014-02-26 15:59:24 -07001201 .post_probe = gpio_post_probe,
Michal Simek1b4c2aa2018-07-12 12:42:27 +02001202 .post_bind = gpio_post_bind,
Simon Glass96495d92014-02-26 15:59:24 -07001203 .pre_remove = gpio_pre_remove,
1204 .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
1205};