1
2
3
4
5
6#include <common.h>
7#include <dm.h>
8#include <dt-bindings/gpio/gpio.h>
9#include <errno.h>
10#include <fdtdec.h>
11#include <malloc.h>
12#include <asm/gpio.h>
13#include <linux/bug.h>
14#include <linux/ctype.h>
15
16DECLARE_GLOBAL_DATA_PTR;
17
18
19
20
21
22
23
24
25
26
27
28
29static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
30{
31 struct gpio_dev_priv *uc_priv;
32 struct udevice *dev;
33 int ret;
34
35 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
36 dev;
37 ret = uclass_next_device(&dev)) {
38 uc_priv = dev_get_uclass_priv(dev);
39 if (gpio >= uc_priv->gpio_base &&
40 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
41 desc->dev = dev;
42 desc->offset = gpio - uc_priv->gpio_base;
43 desc->flags = 0;
44 return 0;
45 }
46 }
47
48
49 return ret ? ret : -ENOENT;
50}
51
52int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
53{
54 struct gpio_dev_priv *uc_priv = NULL;
55 struct udevice *dev;
56 ulong offset;
57 int numeric;
58 int ret;
59
60 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
61 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
62 dev;
63 ret = uclass_next_device(&dev)) {
64 int len;
65
66 uc_priv = dev_get_uclass_priv(dev);
67 if (numeric != -1) {
68 offset = numeric - uc_priv->gpio_base;
69
70 if (offset < uc_priv->gpio_count)
71 break;
72 }
73
74 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
75
76 if (!strncasecmp(name, uc_priv->bank_name, len)) {
77 if (!strict_strtoul(name + len, 10, &offset))
78 break;
79 }
80 }
81
82 if (!dev)
83 return ret ? ret : -EINVAL;
84
85 desc->dev = dev;
86 desc->offset = offset;
87
88 return 0;
89}
90
91int gpio_lookup_name(const char *name, struct udevice **devp,
92 unsigned int *offsetp, unsigned int *gpiop)
93{
94 struct gpio_desc desc;
95 int ret;
96
97 if (devp)
98 *devp = NULL;
99 ret = dm_gpio_lookup_name(name, &desc);
100 if (ret)
101 return ret;
102
103 if (devp)
104 *devp = desc.dev;
105 if (offsetp)
106 *offsetp = desc.offset;
107 if (gpiop) {
108 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
109
110 *gpiop = uc_priv->gpio_base + desc.offset;
111 }
112
113 return 0;
114}
115
116int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
117 struct ofnode_phandle_args *args)
118{
119 if (args->args_count < 1)
120 return -EINVAL;
121
122 desc->offset = args->args[0];
123
124 if (args->args_count < 2)
125 return 0;
126
127 if (args->args[1] & GPIO_ACTIVE_LOW)
128 desc->flags = GPIOD_ACTIVE_LOW;
129
130 return 0;
131}
132
133static int gpio_find_and_xlate(struct gpio_desc *desc,
134 struct ofnode_phandle_args *args)
135{
136 struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
137
138 if (ops->xlate)
139 return ops->xlate(desc->dev, desc, args);
140 else
141 return gpio_xlate_offs_flags(desc->dev, desc, args);
142}
143
144int dm_gpio_request(struct gpio_desc *desc, const char *label)
145{
146 struct udevice *dev = desc->dev;
147 struct gpio_dev_priv *uc_priv;
148 char *str;
149 int ret;
150
151 uc_priv = dev_get_uclass_priv(dev);
152 if (uc_priv->name[desc->offset])
153 return -EBUSY;
154 str = strdup(label);
155 if (!str)
156 return -ENOMEM;
157 if (gpio_get_ops(dev)->request) {
158 ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
159 if (ret) {
160 free(str);
161 return ret;
162 }
163 }
164 uc_priv->name[desc->offset] = str;
165
166 return 0;
167}
168
169static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
170{
171#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_USE_TINY_PRINTF)
172 va_list args;
173 char buf[40];
174
175 va_start(args, fmt);
176 vscnprintf(buf, sizeof(buf), fmt, args);
177 va_end(args);
178 return dm_gpio_request(desc, buf);
179#else
180 return dm_gpio_request(desc, fmt);
181#endif
182}
183
184
185
186
187
188
189
190
191
192
193
194
195
196int gpio_request(unsigned gpio, const char *label)
197{
198 struct gpio_desc desc;
199 int ret;
200
201 ret = gpio_to_device(gpio, &desc);
202 if (ret)
203 return ret;
204
205 return dm_gpio_request(&desc, label);
206}
207
208
209
210
211
212
213
214
215
216
217
218int gpio_requestf(unsigned gpio, const char *fmt, ...)
219{
220#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_USE_TINY_PRINTF)
221 va_list args;
222 char buf[40];
223
224 va_start(args, fmt);
225 vscnprintf(buf, sizeof(buf), fmt, args);
226 va_end(args);
227 return gpio_request(gpio, buf);
228#else
229 return gpio_request(gpio, fmt);
230#endif
231}
232
233int _dm_gpio_free(struct udevice *dev, uint offset)
234{
235 struct gpio_dev_priv *uc_priv;
236 int ret;
237
238 uc_priv = dev_get_uclass_priv(dev);
239 if (!uc_priv->name[offset])
240 return -ENXIO;
241 if (gpio_get_ops(dev)->free) {
242 ret = gpio_get_ops(dev)->free(dev, offset);
243 if (ret)
244 return ret;
245 }
246
247 free(uc_priv->name[offset]);
248 uc_priv->name[offset] = NULL;
249
250 return 0;
251}
252
253
254
255
256
257
258
259
260
261int gpio_free(unsigned gpio)
262{
263 struct gpio_desc desc;
264 int ret;
265
266 ret = gpio_to_device(gpio, &desc);
267 if (ret)
268 return ret;
269
270 return _dm_gpio_free(desc.dev, desc.offset);
271}
272
273static int check_reserved(const struct gpio_desc *desc, const char *func)
274{
275 struct gpio_dev_priv *uc_priv;
276
277 if (!dm_gpio_is_valid(desc))
278 return -ENOENT;
279
280 uc_priv = dev_get_uclass_priv(desc->dev);
281 if (!uc_priv->name[desc->offset]) {
282 printf("%s: %s: error: gpio %s%d not reserved\n",
283 desc->dev->name, func,
284 uc_priv->bank_name ? uc_priv->bank_name : "",
285 desc->offset);
286 return -EBUSY;
287 }
288
289 return 0;
290}
291
292
293
294
295
296
297
298
299
300int gpio_direction_input(unsigned gpio)
301{
302 struct gpio_desc desc;
303 int ret;
304
305 ret = gpio_to_device(gpio, &desc);
306 if (ret)
307 return ret;
308 ret = check_reserved(&desc, "dir_input");
309 if (ret)
310 return ret;
311
312 return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
313}
314
315
316
317
318
319
320
321
322
323
324int gpio_direction_output(unsigned gpio, int value)
325{
326 struct gpio_desc desc;
327 int ret;
328
329 ret = gpio_to_device(gpio, &desc);
330 if (ret)
331 return ret;
332 ret = check_reserved(&desc, "dir_output");
333 if (ret)
334 return ret;
335
336 return gpio_get_ops(desc.dev)->direction_output(desc.dev,
337 desc.offset, value);
338}
339
340int dm_gpio_get_value(const struct gpio_desc *desc)
341{
342 int value;
343 int ret;
344
345 ret = check_reserved(desc, "get_value");
346 if (ret)
347 return ret;
348
349 value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
350
351 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
352}
353
354int dm_gpio_set_value(const struct gpio_desc *desc, int value)
355{
356 int ret;
357
358 ret = check_reserved(desc, "set_value");
359 if (ret)
360 return ret;
361
362 if (desc->flags & GPIOD_ACTIVE_LOW)
363 value = !value;
364 gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
365 return 0;
366}
367
368int dm_gpio_get_open_drain(struct gpio_desc *desc)
369{
370 struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
371 int ret;
372
373 ret = check_reserved(desc, "get_open_drain");
374 if (ret)
375 return ret;
376
377 if (ops->set_open_drain)
378 return ops->get_open_drain(desc->dev, desc->offset);
379 else
380 return -ENOSYS;
381}
382
383int dm_gpio_set_open_drain(struct gpio_desc *desc, int value)
384{
385 struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
386 int ret;
387
388 ret = check_reserved(desc, "set_open_drain");
389 if (ret)
390 return ret;
391
392 if (ops->set_open_drain)
393 ret = ops->set_open_drain(desc->dev, desc->offset, value);
394 else
395 return 0;
396
397 return ret;
398}
399
400int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
401{
402 struct udevice *dev = desc->dev;
403 struct dm_gpio_ops *ops = gpio_get_ops(dev);
404 int ret;
405
406 ret = check_reserved(desc, "set_dir");
407 if (ret)
408 return ret;
409
410 if (flags & GPIOD_IS_OUT) {
411 int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
412
413 if (flags & GPIOD_ACTIVE_LOW)
414 value = !value;
415 ret = ops->direction_output(dev, desc->offset, value);
416 } else if (flags & GPIOD_IS_IN) {
417 ret = ops->direction_input(dev, desc->offset);
418 }
419 if (ret)
420 return ret;
421
422
423
424
425 desc->flags = flags;
426
427 return 0;
428}
429
430int dm_gpio_set_dir(struct gpio_desc *desc)
431{
432 return dm_gpio_set_dir_flags(desc, desc->flags);
433}
434
435
436
437
438
439
440
441
442
443
444int gpio_get_value(unsigned gpio)
445{
446 int ret;
447
448 struct gpio_desc desc;
449
450 ret = gpio_to_device(gpio, &desc);
451 if (ret)
452 return ret;
453 return dm_gpio_get_value(&desc);
454}
455
456
457
458
459
460
461
462
463
464
465int gpio_set_value(unsigned gpio, int value)
466{
467 struct gpio_desc desc;
468 int ret;
469
470 ret = gpio_to_device(gpio, &desc);
471 if (ret)
472 return ret;
473 return dm_gpio_set_value(&desc, value);
474}
475
476const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
477{
478 struct gpio_dev_priv *priv;
479
480
481 priv = dev_get_uclass_priv(dev);
482 assert(priv);
483
484 *bit_count = priv->gpio_count;
485 return priv->bank_name;
486}
487
488static const char * const gpio_function[GPIOF_COUNT] = {
489 "input",
490 "output",
491 "unused",
492 "unknown",
493 "func",
494};
495
496static int get_function(struct udevice *dev, int offset, bool skip_unused,
497 const char **namep)
498{
499 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
500 struct dm_gpio_ops *ops = gpio_get_ops(dev);
501
502 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
503 if (!device_active(dev))
504 return -ENODEV;
505 if (offset < 0 || offset >= uc_priv->gpio_count)
506 return -EINVAL;
507 if (namep)
508 *namep = uc_priv->name[offset];
509 if (skip_unused && !uc_priv->name[offset])
510 return GPIOF_UNUSED;
511 if (ops->get_function) {
512 int ret;
513
514 ret = ops->get_function(dev, offset);
515 if (ret < 0)
516 return ret;
517 if (ret >= ARRAY_SIZE(gpio_function))
518 return -ENODATA;
519 return ret;
520 }
521
522 return GPIOF_UNKNOWN;
523}
524
525int gpio_get_function(struct udevice *dev, int offset, const char **namep)
526{
527 return get_function(dev, offset, true, namep);
528}
529
530int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
531{
532 return get_function(dev, offset, false, namep);
533}
534
535int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
536{
537 struct dm_gpio_ops *ops = gpio_get_ops(dev);
538 struct gpio_dev_priv *priv;
539 char *str = buf;
540 int func;
541 int ret;
542 int len;
543
544 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
545
546 *buf = 0;
547 priv = dev_get_uclass_priv(dev);
548 ret = gpio_get_raw_function(dev, offset, NULL);
549 if (ret < 0)
550 return ret;
551 func = ret;
552 len = snprintf(str, buffsize, "%s%d: %s",
553 priv->bank_name ? priv->bank_name : "",
554 offset, gpio_function[func]);
555 if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
556 func == GPIOF_UNUSED) {
557 const char *label;
558 bool used;
559
560 ret = ops->get_value(dev, offset);
561 if (ret < 0)
562 return ret;
563 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
564 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
565 ret,
566 used ? 'x' : ' ',
567 used ? " " : "",
568 label ? label : "");
569 }
570
571 return 0;
572}
573
574int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
575{
576 int i, ret;
577 int gpio;
578
579 for (i = 0; i < 32; i++) {
580 gpio = gpio_num_array[i];
581 if (gpio == -1)
582 break;
583 ret = gpio_requestf(gpio, fmt, i);
584 if (ret)
585 goto err;
586 ret = gpio_direction_input(gpio);
587 if (ret) {
588 gpio_free(gpio);
589 goto err;
590 }
591 }
592
593 return 0;
594err:
595 for (i--; i >= 0; i--)
596 gpio_free(gpio_num_array[i]);
597
598 return ret;
599}
600
601
602
603
604
605int gpio_get_values_as_int(const int *gpio_list)
606{
607 int gpio;
608 unsigned bitmask = 1;
609 unsigned vector = 0;
610 int ret;
611
612 while (bitmask &&
613 ((gpio = *gpio_list++) != -1)) {
614 ret = gpio_get_value(gpio);
615 if (ret < 0)
616 return ret;
617 else if (ret)
618 vector |= bitmask;
619 bitmask <<= 1;
620 }
621
622 return vector;
623}
624
625int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
626{
627 unsigned bitmask = 1;
628 unsigned vector = 0;
629 int ret, i;
630
631 for (i = 0; i < count; i++) {
632 ret = dm_gpio_get_value(&desc_list[i]);
633 if (ret < 0)
634 return ret;
635 else if (ret)
636 vector |= bitmask;
637 bitmask <<= 1;
638 }
639
640 return vector;
641}
642
643static int gpio_request_tail(int ret, ofnode node,
644 struct ofnode_phandle_args *args,
645 const char *list_name, int index,
646 struct gpio_desc *desc, int flags, bool add_index)
647{
648 desc->dev = NULL;
649 desc->offset = 0;
650 desc->flags = 0;
651 if (ret)
652 goto err;
653
654 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
655 &desc->dev);
656 if (ret) {
657 debug("%s: uclass_get_device_by_ofnode failed\n", __func__);
658 goto err;
659 }
660 ret = gpio_find_and_xlate(desc, args);
661 if (ret) {
662 debug("%s: gpio_find_and_xlate failed\n", __func__);
663 goto err;
664 }
665 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
666 ofnode_get_name(node),
667 list_name, index);
668 if (ret) {
669 debug("%s: dm_gpio_requestf failed\n", __func__);
670 goto err;
671 }
672 ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
673 if (ret) {
674 debug("%s: dm_gpio_set_dir failed\n", __func__);
675 goto err;
676 }
677
678 return 0;
679err:
680 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
681 __func__, ofnode_get_name(node), list_name, index, ret);
682 return ret;
683}
684
685static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
686 int index, struct gpio_desc *desc,
687 int flags, bool add_index)
688{
689 struct ofnode_phandle_args args;
690 int ret;
691
692 ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
693 index, &args);
694
695 return gpio_request_tail(ret, node, &args, list_name, index, desc,
696 flags, add_index);
697}
698
699int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
700 struct gpio_desc *desc, int flags)
701{
702 return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
703 index > 0);
704}
705
706int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
707 struct gpio_desc *desc, int flags)
708{
709 struct ofnode_phandle_args args;
710 int ret;
711
712 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
713 index, &args);
714
715 return gpio_request_tail(ret, dev_ofnode(dev), &args, list_name,
716 index, desc, flags, index > 0);
717}
718
719int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
720 struct gpio_desc *desc, int max_count,
721 int flags)
722{
723 int count;
724 int ret;
725
726 for (count = 0; count < max_count; count++) {
727 ret = _gpio_request_by_name_nodev(node, list_name, count,
728 &desc[count], flags, true);
729 if (ret == -ENOENT)
730 break;
731 else if (ret)
732 goto err;
733 }
734
735
736 return count;
737
738err:
739 gpio_free_list_nodev(desc, count - 1);
740
741 return ret;
742}
743
744int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
745 struct gpio_desc *desc, int max_count,
746 int flags)
747{
748
749
750
751
752
753 return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
754 max_count, flags);
755}
756
757int gpio_get_list_count(struct udevice *dev, const char *list_name)
758{
759 int ret;
760
761 ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
762 list_name, "#gpio-cells", 0, -1,
763 NULL);
764 if (ret) {
765 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
766 __func__, dev->name, list_name, ret);
767 }
768
769 return ret;
770}
771
772int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
773{
774
775 return _dm_gpio_free(desc->dev, desc->offset);
776}
777
778int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
779{
780 int i;
781
782
783 for (i = 0; i < count; i++)
784 dm_gpio_free(dev, &desc[i]);
785
786 return 0;
787}
788
789int gpio_free_list_nodev(struct gpio_desc *desc, int count)
790{
791 return gpio_free_list(NULL, desc, count);
792}
793
794
795static int gpio_renumber(struct udevice *removed_dev)
796{
797 struct gpio_dev_priv *uc_priv;
798 struct udevice *dev;
799 struct uclass *uc;
800 unsigned base;
801 int ret;
802
803 ret = uclass_get(UCLASS_GPIO, &uc);
804 if (ret)
805 return ret;
806
807
808 base = 0;
809 uclass_foreach_dev(dev, uc) {
810 if (device_active(dev) && dev != removed_dev) {
811 uc_priv = dev_get_uclass_priv(dev);
812 uc_priv->gpio_base = base;
813 base += uc_priv->gpio_count;
814 }
815 }
816
817 return 0;
818}
819
820int gpio_get_number(const struct gpio_desc *desc)
821{
822 struct udevice *dev = desc->dev;
823 struct gpio_dev_priv *uc_priv;
824
825 if (!dev)
826 return -1;
827 uc_priv = dev->uclass_priv;
828
829 return uc_priv->gpio_base + desc->offset;
830}
831
832static int gpio_post_probe(struct udevice *dev)
833{
834 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
835
836 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
837 if (!uc_priv->name)
838 return -ENOMEM;
839
840 return gpio_renumber(NULL);
841}
842
843static int gpio_pre_remove(struct udevice *dev)
844{
845 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
846 int i;
847
848 for (i = 0; i < uc_priv->gpio_count; i++) {
849 if (uc_priv->name[i])
850 free(uc_priv->name[i]);
851 }
852 free(uc_priv->name);
853
854 return gpio_renumber(dev);
855}
856
857static int gpio_post_bind(struct udevice *dev)
858{
859#if defined(CONFIG_NEEDS_MANUAL_RELOC)
860 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
861 static int reloc_done;
862
863 if (!reloc_done) {
864 if (ops->request)
865 ops->request += gd->reloc_off;
866 if (ops->free)
867 ops->free += gd->reloc_off;
868 if (ops->direction_input)
869 ops->direction_input += gd->reloc_off;
870 if (ops->direction_output)
871 ops->direction_output += gd->reloc_off;
872 if (ops->get_value)
873 ops->get_value += gd->reloc_off;
874 if (ops->set_value)
875 ops->set_value += gd->reloc_off;
876 if (ops->get_open_drain)
877 ops->get_open_drain += gd->reloc_off;
878 if (ops->set_open_drain)
879 ops->set_open_drain += gd->reloc_off;
880 if (ops->get_function)
881 ops->get_function += gd->reloc_off;
882 if (ops->xlate)
883 ops->xlate += gd->reloc_off;
884
885 reloc_done++;
886 }
887#endif
888 return 0;
889}
890
891UCLASS_DRIVER(gpio) = {
892 .id = UCLASS_GPIO,
893 .name = "gpio",
894 .flags = DM_UC_FLAG_SEQ_ALIAS,
895 .post_probe = gpio_post_probe,
896 .post_bind = gpio_post_bind,
897 .pre_remove = gpio_pre_remove,
898 .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
899};
900