dm: gpio: Add gpio_requestf() helper for printf() strings
[platform/kernel/u-boot.git] / drivers / gpio / gpio-uclass.c
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>
10 #include <malloc.h>
11 #include <asm/gpio.h>
12 #include <linux/ctype.h>
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  */
22 static int gpio_to_device(unsigned int gpio, struct udevice **devp,
23                           unsigned int *offset)
24 {
25         struct gpio_dev_priv *uc_priv;
26         struct udevice *dev;
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
45 int gpio_lookup_name(const char *name, struct udevice **devp,
46                      unsigned int *offsetp, unsigned int *gpiop)
47 {
48         struct gpio_dev_priv *uc_priv = NULL;
49         struct udevice *dev;
50         ulong offset;
51         int numeric;
52         int ret;
53
54         if (devp)
55                 *devp = NULL;
56         numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
57         for (ret = uclass_first_device(UCLASS_GPIO, &dev);
58              dev;
59              ret = uclass_next_device(&dev)) {
60                 int len;
61
62                 uc_priv = dev->uclass_priv;
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
70                 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
71
72                 if (!strncasecmp(name, uc_priv->bank_name, len)) {
73                         if (!strict_strtoul(name + len, 10, &offset))
74                                 break;
75                 }
76         }
77
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;
89 }
90
91 /**
92  * gpio_request() - [COMPAT] Request GPIO
93  * gpio:        GPIO number
94  * label:       Name for the requested GPIO
95  *
96  * The label is copied and allocated so the caller does not need to keep
97  * the pointer around.
98  *
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  */
103 int gpio_request(unsigned gpio, const char *label)
104 {
105         struct gpio_dev_priv *uc_priv;
106         unsigned int offset;
107         struct udevice *dev;
108         char *str;
109         int ret;
110
111         ret = gpio_to_device(gpio, &dev, &offset);
112         if (ret)
113                 return ret;
114
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;
129
130         return 0;
131 }
132
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  */
143 int 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 /**
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  */
162 int gpio_free(unsigned gpio)
163 {
164         struct gpio_dev_priv *uc_priv;
165         unsigned int offset;
166         struct udevice *dev;
167         int ret;
168
169         ret = gpio_to_device(gpio, &dev, &offset);
170         if (ret)
171                 return ret;
172
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
188 static 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;
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  */
211 int gpio_direction_input(unsigned gpio)
212 {
213         unsigned int offset;
214         struct udevice *dev;
215         int ret;
216
217         ret = gpio_to_device(gpio, &dev, &offset);
218         if (ret)
219                 return ret;
220         ret = check_reserved(dev, offset, "dir_input");
221
222         return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
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  */
234 int gpio_direction_output(unsigned gpio, int value)
235 {
236         unsigned int offset;
237         struct udevice *dev;
238         int ret;
239
240         ret = gpio_to_device(gpio, &dev, &offset);
241         if (ret)
242                 return ret;
243         ret = check_reserved(dev, offset, "dir_output");
244
245         return ret ? ret :
246                 gpio_get_ops(dev)->direction_output(dev, offset, value);
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  */
258 int gpio_get_value(unsigned gpio)
259 {
260         unsigned int offset;
261         struct udevice *dev;
262         int ret;
263
264         ret = gpio_to_device(gpio, &dev, &offset);
265         if (ret)
266                 return ret;
267         ret = check_reserved(dev, offset, "get_value");
268
269         return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
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  */
281 int gpio_set_value(unsigned gpio, int value)
282 {
283         unsigned int offset;
284         struct udevice *dev;
285         int ret;
286
287         ret = gpio_to_device(gpio, &dev, &offset);
288         if (ret)
289                 return ret;
290         ret = check_reserved(dev, offset, "set_value");
291
292         return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
293 }
294
295 const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
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
307 static const char * const gpio_function[GPIOF_COUNT] = {
308         "input",
309         "output",
310         "unused",
311         "unknown",
312         "func",
313 };
314
315 int 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
344 int gpio_get_function(struct udevice *dev, int offset, const char **namep)
345 {
346         return get_function(dev, offset, true, namep);
347 }
348
349 int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
350 {
351         return get_function(dev, offset, false, namep);
352 }
353
354 int 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
393 /* We need to renumber the GPIOs when any driver is probed/removed */
394 static int gpio_renumber(struct udevice *removed_dev)
395 {
396         struct gpio_dev_priv *uc_priv;
397         struct udevice *dev;
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) {
409                 if (device_active(dev) && dev != removed_dev) {
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
419 static int gpio_post_probe(struct udevice *dev)
420 {
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);
428 }
429
430 static int gpio_pre_remove(struct udevice *dev)
431 {
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);
442 }
443
444 UCLASS_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 };