blob: 45e9a5ad2278378814b7351c5d70dd5c53fbf287 [file] [log] [blame]
Simon Glass96495d92014-02-26 15:59:24 -07001/*
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>
Simon Glassb892d122014-10-04 11:29:42 -060010#include <malloc.h>
Simon Glass96495d92014-02-26 15:59:24 -070011#include <asm/gpio.h>
Simon Glassfe1ef502014-10-22 21:37:01 -060012#include <linux/ctype.h>
Simon Glass96495d92014-02-26 15:59:24 -070013
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 */
Heiko Schocher54c5d082014-05-22 12:43:05 +020022static int gpio_to_device(unsigned int gpio, struct udevice **devp,
Simon Glass96495d92014-02-26 15:59:24 -070023 unsigned int *offset)
24{
25 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +020026 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -070027 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
Heiko Schocher54c5d082014-05-22 12:43:05 +020045int gpio_lookup_name(const char *name, struct udevice **devp,
Simon Glass96495d92014-02-26 15:59:24 -070046 unsigned int *offsetp, unsigned int *gpiop)
47{
Simon Glassfe1ef502014-10-22 21:37:01 -060048 struct gpio_dev_priv *uc_priv = NULL;
Heiko Schocher54c5d082014-05-22 12:43:05 +020049 struct udevice *dev;
Simon Glassfe1ef502014-10-22 21:37:01 -060050 ulong offset;
51 int numeric;
Simon Glass96495d92014-02-26 15:59:24 -070052 int ret;
53
54 if (devp)
55 *devp = NULL;
Simon Glassfe1ef502014-10-22 21:37:01 -060056 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
Simon Glass96495d92014-02-26 15:59:24 -070057 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
58 dev;
59 ret = uclass_next_device(&dev)) {
Simon Glass96495d92014-02-26 15:59:24 -070060 int len;
61
62 uc_priv = dev->uclass_priv;
Simon Glassfe1ef502014-10-22 21:37:01 -060063 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
Simon Glass96495d92014-02-26 15:59:24 -070070 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
71
Simon Glass939cda52014-06-11 23:29:47 -060072 if (!strncasecmp(name, uc_priv->bank_name, len)) {
Simon Glassfe1ef502014-10-22 21:37:01 -060073 if (!strict_strtoul(name + len, 10, &offset))
74 break;
Simon Glass96495d92014-02-26 15:59:24 -070075 }
76 }
77
Simon Glassfe1ef502014-10-22 21:37:01 -060078 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;
Simon Glass96495d92014-02-26 15:59:24 -070089}
90
91/**
92 * gpio_request() - [COMPAT] Request GPIO
93 * gpio: GPIO number
94 * label: Name for the requested GPIO
95 *
Simon Glassb892d122014-10-04 11:29:42 -060096 * The label is copied and allocated so the caller does not need to keep
97 * the pointer around.
98 *
Simon Glass96495d92014-02-26 15:59:24 -070099 * 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{
Simon Glassb892d122014-10-04 11:29:42 -0600105 struct gpio_dev_priv *uc_priv;
Simon Glass96495d92014-02-26 15:59:24 -0700106 unsigned int offset;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200107 struct udevice *dev;
Simon Glassb892d122014-10-04 11:29:42 -0600108 char *str;
Simon Glass96495d92014-02-26 15:59:24 -0700109 int ret;
110
111 ret = gpio_to_device(gpio, &dev, &offset);
112 if (ret)
113 return ret;
114
Simon Glassb892d122014-10-04 11:29:42 -0600115 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;
Simon Glass96495d92014-02-26 15:59:24 -0700129
Simon Glassb892d122014-10-04 11:29:42 -0600130 return 0;
Simon Glass96495d92014-02-26 15:59:24 -0700131}
132
133/**
Simon Glassd44f5972014-10-04 11:29:49 -0600134 * 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
154/**
Simon Glass96495d92014-02-26 15:59:24 -0700155 * 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{
Simon Glassb892d122014-10-04 11:29:42 -0600164 struct gpio_dev_priv *uc_priv;
Simon Glass96495d92014-02-26 15:59:24 -0700165 unsigned int offset;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200166 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -0700167 int ret;
168
169 ret = gpio_to_device(gpio, &dev, &offset);
170 if (ret)
171 return ret;
172
Simon Glassb892d122014-10-04 11:29:42 -0600173 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;
Simon Glass96495d92014-02-26 15:59:24 -0700201}
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;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200214 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -0700215 int ret;
216
217 ret = gpio_to_device(gpio, &dev, &offset);
218 if (ret)
219 return ret;
Simon Glassb892d122014-10-04 11:29:42 -0600220 ret = check_reserved(dev, offset, "dir_input");
Simon Glass96495d92014-02-26 15:59:24 -0700221
Simon Glassb892d122014-10-04 11:29:42 -0600222 return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
Simon Glass96495d92014-02-26 15:59:24 -0700223}
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;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200237 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -0700238 int ret;
239
240 ret = gpio_to_device(gpio, &dev, &offset);
241 if (ret)
242 return ret;
Simon Glassb892d122014-10-04 11:29:42 -0600243 ret = check_reserved(dev, offset, "dir_output");
Simon Glass96495d92014-02-26 15:59:24 -0700244
Simon Glassb892d122014-10-04 11:29:42 -0600245 return ret ? ret :
246 gpio_get_ops(dev)->direction_output(dev, offset, value);
Simon Glass96495d92014-02-26 15:59:24 -0700247}
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;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200261 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -0700262 int ret;
263
264 ret = gpio_to_device(gpio, &dev, &offset);
265 if (ret)
266 return ret;
Simon Glassb892d122014-10-04 11:29:42 -0600267 ret = check_reserved(dev, offset, "get_value");
Simon Glass96495d92014-02-26 15:59:24 -0700268
Simon Glassb892d122014-10-04 11:29:42 -0600269 return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
Simon Glass96495d92014-02-26 15:59:24 -0700270}
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;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200284 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -0700285 int ret;
286
287 ret = gpio_to_device(gpio, &dev, &offset);
288 if (ret)
289 return ret;
Simon Glassb892d122014-10-04 11:29:42 -0600290 ret = check_reserved(dev, offset, "set_value");
Simon Glass96495d92014-02-26 15:59:24 -0700291
Simon Glassb892d122014-10-04 11:29:42 -0600292 return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
Simon Glass96495d92014-02-26 15:59:24 -0700293}
294
Heiko Schocher54c5d082014-05-22 12:43:05 +0200295const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
Simon Glass96495d92014-02-26 15:59:24 -0700296{
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
Simon Glass6449a502014-10-04 11:29:43 -0600307static 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
Simon Glass07575352014-10-04 11:29:44 -0600354int 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
Simon Glass96495d92014-02-26 15:59:24 -0700393/* We need to renumber the GPIOs when any driver is probed/removed */
Simon Glassb892d122014-10-04 11:29:42 -0600394static int gpio_renumber(struct udevice *removed_dev)
Simon Glass96495d92014-02-26 15:59:24 -0700395{
396 struct gpio_dev_priv *uc_priv;
Heiko Schocher54c5d082014-05-22 12:43:05 +0200397 struct udevice *dev;
Simon Glass96495d92014-02-26 15:59:24 -0700398 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) {
Simon Glassb892d122014-10-04 11:29:42 -0600409 if (device_active(dev) && dev != removed_dev) {
Simon Glass96495d92014-02-26 15:59:24 -0700410 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
Heiko Schocher54c5d082014-05-22 12:43:05 +0200419static int gpio_post_probe(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -0700420{
Simon Glassb892d122014-10-04 11:29:42 -0600421 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);
Simon Glass96495d92014-02-26 15:59:24 -0700428}
429
Heiko Schocher54c5d082014-05-22 12:43:05 +0200430static int gpio_pre_remove(struct udevice *dev)
Simon Glass96495d92014-02-26 15:59:24 -0700431{
Simon Glassb892d122014-10-04 11:29:42 -0600432 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);
Simon Glass96495d92014-02-26 15:59:24 -0700442}
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};