]> git.ipfire.org Git - people/ms/u-boot.git/blame - drivers/gpio/gpio-uclass.c
dm: serial: Move current serial port pointer to global_data
[people/ms/u-boot.git] / drivers / gpio / gpio-uclass.c
CommitLineData
96495d90
SG
1/*
2 * Copyright (c) 2013 Google, Inc
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <errno.h>
b892d127 10#include <malloc.h>
96495d90 11#include <asm/gpio.h>
fe1ef503 12#include <linux/ctype.h>
96495d90
SG
13
14/**
15 * gpio_to_device() - Convert global GPIO number to device, number
16 * gpio: The numeric representation of the GPIO
17 *
18 * Convert the GPIO number to an entry in the list of GPIOs
19 * or GPIO blocks registered with the GPIO controller. Returns
20 * entry on success, NULL on error.
21 */
54c5d08a 22static int gpio_to_device(unsigned int gpio, struct udevice **devp,
96495d90
SG
23 unsigned int *offset)
24{
25 struct gpio_dev_priv *uc_priv;
54c5d08a 26 struct udevice *dev;
96495d90
SG
27 int ret;
28
29 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
30 dev;
31 ret = uclass_next_device(&dev)) {
32 uc_priv = dev->uclass_priv;
33 if (gpio >= uc_priv->gpio_base &&
34 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
35 *devp = dev;
36 *offset = gpio - uc_priv->gpio_base;
37 return 0;
38 }
39 }
40
41 /* No such GPIO */
42 return ret ? ret : -EINVAL;
43}
44
54c5d08a 45int gpio_lookup_name(const char *name, struct udevice **devp,
96495d90
SG
46 unsigned int *offsetp, unsigned int *gpiop)
47{
fe1ef503 48 struct gpio_dev_priv *uc_priv = NULL;
54c5d08a 49 struct udevice *dev;
fe1ef503
SG
50 ulong offset;
51 int numeric;
96495d90
SG
52 int ret;
53
54 if (devp)
55 *devp = NULL;
fe1ef503 56 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
96495d90
SG
57 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
58 dev;
59 ret = uclass_next_device(&dev)) {
96495d90
SG
60 int len;
61
62 uc_priv = dev->uclass_priv;
fe1ef503
SG
63 if (numeric != -1) {
64 offset = numeric - uc_priv->gpio_base;
65 /* Allow GPIOs to be numbered from 0 */
66 if (offset >= 0 && offset < uc_priv->gpio_count)
67 break;
68 }
69
96495d90
SG
70 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
71
939cda5b 72 if (!strncasecmp(name, uc_priv->bank_name, len)) {
fe1ef503
SG
73 if (!strict_strtoul(name + len, 10, &offset))
74 break;
96495d90
SG
75 }
76 }
77
fe1ef503
SG
78 if (!dev)
79 return ret ? ret : -EINVAL;
80
81 if (devp)
82 *devp = dev;
83 if (offsetp)
84 *offsetp = offset;
85 if (gpiop)
86 *gpiop = uc_priv->gpio_base + offset;
87
88 return 0;
96495d90
SG
89}
90
91/**
92 * gpio_request() - [COMPAT] Request GPIO
93 * gpio: GPIO number
94 * label: Name for the requested GPIO
95 *
b892d127
SG
96 * The label is copied and allocated so the caller does not need to keep
97 * the pointer around.
98 *
96495d90
SG
99 * This function implements the API that's compatible with current
100 * GPIO API used in U-Boot. The request is forwarded to particular
101 * GPIO driver. Returns 0 on success, negative value on error.
102 */
103int gpio_request(unsigned gpio, const char *label)
104{
b892d127 105 struct gpio_dev_priv *uc_priv;
96495d90 106 unsigned int offset;
54c5d08a 107 struct udevice *dev;
b892d127 108 char *str;
96495d90
SG
109 int ret;
110
111 ret = gpio_to_device(gpio, &dev, &offset);
112 if (ret)
113 return ret;
114
b892d127
SG
115 uc_priv = dev->uclass_priv;
116 if (uc_priv->name[offset])
117 return -EBUSY;
118 str = strdup(label);
119 if (!str)
120 return -ENOMEM;
121 if (gpio_get_ops(dev)->request) {
122 ret = gpio_get_ops(dev)->request(dev, offset, label);
123 if (ret) {
124 free(str);
125 return ret;
126 }
127 }
128 uc_priv->name[offset] = str;
96495d90 129
b892d127 130 return 0;
96495d90
SG
131}
132
d44f597b
SG
133/**
134 * gpio_requestf() - [COMPAT] Request GPIO
135 * @gpio: GPIO number
136 * @fmt: Format string for the requested GPIO
137 * @...: Arguments for the printf() format string
138 *
139 * This function implements the API that's compatible with current
140 * GPIO API used in U-Boot. The request is forwarded to particular
141 * GPIO driver. Returns 0 on success, negative value on error.
142 */
143int gpio_requestf(unsigned gpio, const char *fmt, ...)
144{
145 va_list args;
146 char buf[40];
147
148 va_start(args, fmt);
149 vscnprintf(buf, sizeof(buf), fmt, args);
150 va_end(args);
151 return gpio_request(gpio, buf);
152}
153
96495d90
SG
154/**
155 * gpio_free() - [COMPAT] Relinquish GPIO
156 * gpio: GPIO number
157 *
158 * This function implements the API that's compatible with current
159 * GPIO API used in U-Boot. The request is forwarded to particular
160 * GPIO driver. Returns 0 on success, negative value on error.
161 */
162int gpio_free(unsigned gpio)
163{
b892d127 164 struct gpio_dev_priv *uc_priv;
96495d90 165 unsigned int offset;
54c5d08a 166 struct udevice *dev;
96495d90
SG
167 int ret;
168
169 ret = gpio_to_device(gpio, &dev, &offset);
170 if (ret)
171 return ret;
172
b892d127
SG
173 uc_priv = dev->uclass_priv;
174 if (!uc_priv->name[offset])
175 return -ENXIO;
176 if (gpio_get_ops(dev)->free) {
177 ret = gpio_get_ops(dev)->free(dev, offset);
178 if (ret)
179 return ret;
180 }
181
182 free(uc_priv->name[offset]);
183 uc_priv->name[offset] = NULL;
184
185 return 0;
186}
187
188static int check_reserved(struct udevice *dev, unsigned offset,
189 const char *func)
190{
191 struct gpio_dev_priv *uc_priv = dev->uclass_priv;
192
193 if (!uc_priv->name[offset]) {
194 printf("%s: %s: error: gpio %s%d not reserved\n",
195 dev->name, func,
196 uc_priv->bank_name ? uc_priv->bank_name : "", offset);
197 return -EBUSY;
198 }
199
200 return 0;
96495d90
SG
201}
202
203/**
204 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
205 * gpio: GPIO number
206 *
207 * This function implements the API that's compatible with current
208 * GPIO API used in U-Boot. The request is forwarded to particular
209 * GPIO driver. Returns 0 on success, negative value on error.
210 */
211int gpio_direction_input(unsigned gpio)
212{
213 unsigned int offset;
54c5d08a 214 struct udevice *dev;
96495d90
SG
215 int ret;
216
217 ret = gpio_to_device(gpio, &dev, &offset);
218 if (ret)
219 return ret;
b892d127 220 ret = check_reserved(dev, offset, "dir_input");
96495d90 221
b892d127 222 return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
96495d90
SG
223}
224
225/**
226 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
227 * gpio: GPIO number
228 * value: Logical value to be set on the GPIO pin
229 *
230 * This function implements the API that's compatible with current
231 * GPIO API used in U-Boot. The request is forwarded to particular
232 * GPIO driver. Returns 0 on success, negative value on error.
233 */
234int gpio_direction_output(unsigned gpio, int value)
235{
236 unsigned int offset;
54c5d08a 237 struct udevice *dev;
96495d90
SG
238 int ret;
239
240 ret = gpio_to_device(gpio, &dev, &offset);
241 if (ret)
242 return ret;
b892d127 243 ret = check_reserved(dev, offset, "dir_output");
96495d90 244
b892d127
SG
245 return ret ? ret :
246 gpio_get_ops(dev)->direction_output(dev, offset, value);
96495d90
SG
247}
248
249/**
250 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
251 * gpio: GPIO number
252 *
253 * This function implements the API that's compatible with current
254 * GPIO API used in U-Boot. The request is forwarded to particular
255 * GPIO driver. Returns the value of the GPIO pin, or negative value
256 * on error.
257 */
258int gpio_get_value(unsigned gpio)
259{
260 unsigned int offset;
54c5d08a 261 struct udevice *dev;
96495d90
SG
262 int ret;
263
264 ret = gpio_to_device(gpio, &dev, &offset);
265 if (ret)
266 return ret;
b892d127 267 ret = check_reserved(dev, offset, "get_value");
96495d90 268
b892d127 269 return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
96495d90
SG
270}
271
272/**
273 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
274 * gpio: GPIO number
275 * value: Logical value to be set on the GPIO pin.
276 *
277 * This function implements the API that's compatible with current
278 * GPIO API used in U-Boot. The request is forwarded to particular
279 * GPIO driver. Returns 0 on success, negative value on error.
280 */
281int gpio_set_value(unsigned gpio, int value)
282{
283 unsigned int offset;
54c5d08a 284 struct udevice *dev;
96495d90
SG
285 int ret;
286
287 ret = gpio_to_device(gpio, &dev, &offset);
288 if (ret)
289 return ret;
b892d127 290 ret = check_reserved(dev, offset, "set_value");
96495d90 291
b892d127 292 return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
96495d90
SG
293}
294
54c5d08a 295const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
96495d90
SG
296{
297 struct gpio_dev_priv *priv;
298
299 /* Must be called on an active device */
300 priv = dev->uclass_priv;
301 assert(priv);
302
303 *bit_count = priv->gpio_count;
304 return priv->bank_name;
305}
306
6449a506
SG
307static const char * const gpio_function[GPIOF_COUNT] = {
308 "input",
309 "output",
310 "unused",
311 "unknown",
312 "func",
313};
314
315int get_function(struct udevice *dev, int offset, bool skip_unused,
316 const char **namep)
317{
318 struct gpio_dev_priv *uc_priv = dev->uclass_priv;
319 struct dm_gpio_ops *ops = gpio_get_ops(dev);
320
321 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
322 if (!device_active(dev))
323 return -ENODEV;
324 if (offset < 0 || offset >= uc_priv->gpio_count)
325 return -EINVAL;
326 if (namep)
327 *namep = uc_priv->name[offset];
328 if (skip_unused && !uc_priv->name[offset])
329 return GPIOF_UNUSED;
330 if (ops->get_function) {
331 int ret;
332
333 ret = ops->get_function(dev, offset);
334 if (ret < 0)
335 return ret;
336 if (ret >= ARRAY_SIZE(gpio_function))
337 return -ENODATA;
338 return ret;
339 }
340
341 return GPIOF_UNKNOWN;
342}
343
344int gpio_get_function(struct udevice *dev, int offset, const char **namep)
345{
346 return get_function(dev, offset, true, namep);
347}
348
349int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
350{
351 return get_function(dev, offset, false, namep);
352}
353
0757535a
SG
354int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
355{
356 struct dm_gpio_ops *ops = gpio_get_ops(dev);
357 struct gpio_dev_priv *priv;
358 char *str = buf;
359 int func;
360 int ret;
361 int len;
362
363 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
364
365 *buf = 0;
366 priv = dev->uclass_priv;
367 ret = gpio_get_raw_function(dev, offset, NULL);
368 if (ret < 0)
369 return ret;
370 func = ret;
371 len = snprintf(str, buffsize, "%s%d: %s",
372 priv->bank_name ? priv->bank_name : "",
373 offset, gpio_function[func]);
374 if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
375 func == GPIOF_UNUSED) {
376 const char *label;
377 bool used;
378
379 ret = ops->get_value(dev, offset);
380 if (ret < 0)
381 return ret;
382 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
383 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
384 ret,
385 used ? 'x' : ' ',
386 used ? " " : "",
387 label ? label : "");
388 }
389
390 return 0;
391}
392
96495d90 393/* We need to renumber the GPIOs when any driver is probed/removed */
b892d127 394static int gpio_renumber(struct udevice *removed_dev)
96495d90
SG
395{
396 struct gpio_dev_priv *uc_priv;
54c5d08a 397 struct udevice *dev;
96495d90
SG
398 struct uclass *uc;
399 unsigned base;
400 int ret;
401
402 ret = uclass_get(UCLASS_GPIO, &uc);
403 if (ret)
404 return ret;
405
406 /* Ensure that we have a base for each bank */
407 base = 0;
408 uclass_foreach_dev(dev, uc) {
b892d127 409 if (device_active(dev) && dev != removed_dev) {
96495d90
SG
410 uc_priv = dev->uclass_priv;
411 uc_priv->gpio_base = base;
412 base += uc_priv->gpio_count;
413 }
414 }
415
416 return 0;
417}
418
54c5d08a 419static int gpio_post_probe(struct udevice *dev)
96495d90 420{
b892d127
SG
421 struct gpio_dev_priv *uc_priv = dev->uclass_priv;
422
423 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
424 if (!uc_priv->name)
425 return -ENOMEM;
426
427 return gpio_renumber(NULL);
96495d90
SG
428}
429
54c5d08a 430static int gpio_pre_remove(struct udevice *dev)
96495d90 431{
b892d127
SG
432 struct gpio_dev_priv *uc_priv = dev->uclass_priv;
433 int i;
434
435 for (i = 0; i < uc_priv->gpio_count; i++) {
436 if (uc_priv->name[i])
437 free(uc_priv->name[i]);
438 }
439 free(uc_priv->name);
440
441 return gpio_renumber(dev);
96495d90
SG
442}
443
444UCLASS_DRIVER(gpio) = {
445 .id = UCLASS_GPIO,
446 .name = "gpio",
447 .post_probe = gpio_post_probe,
448 .pre_remove = gpio_pre_remove,
449 .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
450};