diff options
Diffstat (limited to 'tools/gpio/lsgpio.c')
-rw-r--r-- | tools/gpio/lsgpio.c | 91 |
1 files changed, 79 insertions, 12 deletions
diff --git a/tools/gpio/lsgpio.c b/tools/gpio/lsgpio.c index 692233f561fb..5535ce81f8f7 100644 --- a/tools/gpio/lsgpio.c +++ b/tools/gpio/lsgpio.c | |||
@@ -26,12 +26,56 @@ | |||
26 | 26 | ||
27 | #include "gpio-utils.h" | 27 | #include "gpio-utils.h" |
28 | 28 | ||
29 | struct gpio_flag { | ||
30 | char *name; | ||
31 | unsigned long mask; | ||
32 | }; | ||
33 | |||
34 | struct gpio_flag flagnames[] = { | ||
35 | { | ||
36 | .name = "kernel", | ||
37 | .mask = GPIOLINE_FLAG_KERNEL, | ||
38 | }, | ||
39 | { | ||
40 | .name = "output", | ||
41 | .mask = GPIOLINE_FLAG_IS_OUT, | ||
42 | }, | ||
43 | { | ||
44 | .name = "active-low", | ||
45 | .mask = GPIOLINE_FLAG_ACTIVE_LOW, | ||
46 | }, | ||
47 | { | ||
48 | .name = "open-drain", | ||
49 | .mask = GPIOLINE_FLAG_OPEN_DRAIN, | ||
50 | }, | ||
51 | { | ||
52 | .name = "open-source", | ||
53 | .mask = GPIOLINE_FLAG_OPEN_SOURCE, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | void print_flags(unsigned long flags) | ||
58 | { | ||
59 | int i; | ||
60 | int printed = 0; | ||
61 | |||
62 | for (i = 0; i < ARRAY_SIZE(flagnames); i++) { | ||
63 | if (flags & flagnames[i].mask) { | ||
64 | if (printed) | ||
65 | fprintf(stdout, " "); | ||
66 | fprintf(stdout, "%s", flagnames[i].name); | ||
67 | printed++; | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
29 | int list_device(const char *device_name) | 72 | int list_device(const char *device_name) |
30 | { | 73 | { |
31 | struct gpiochip_info cinfo; | 74 | struct gpiochip_info cinfo; |
32 | char *chrdev_name; | 75 | char *chrdev_name; |
33 | int fd; | 76 | int fd; |
34 | int ret; | 77 | int ret; |
78 | int i; | ||
35 | 79 | ||
36 | ret = asprintf(&chrdev_name, "/dev/%s", device_name); | 80 | ret = asprintf(&chrdev_name, "/dev/%s", device_name); |
37 | if (ret < 0) | 81 | if (ret < 0) |
@@ -41,32 +85,55 @@ int list_device(const char *device_name) | |||
41 | if (fd == -1) { | 85 | if (fd == -1) { |
42 | ret = -errno; | 86 | ret = -errno; |
43 | fprintf(stderr, "Failed to open %s\n", chrdev_name); | 87 | fprintf(stderr, "Failed to open %s\n", chrdev_name); |
44 | goto free_chrdev_name; | 88 | goto exit_close_error; |
45 | } | 89 | } |
46 | 90 | ||
47 | /* Inspect this GPIO chip */ | 91 | /* Inspect this GPIO chip */ |
48 | ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &cinfo); | 92 | ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &cinfo); |
49 | if (ret == -1) { | 93 | if (ret == -1) { |
50 | ret = -errno; | 94 | ret = -errno; |
51 | fprintf(stderr, "Failed to retrieve GPIO fd\n"); | 95 | perror("Failed to issue CHIPINFO IOCTL\n"); |
52 | if (close(fd) == -1) | 96 | goto exit_close_error; |
53 | perror("Failed to close GPIO character device file"); | ||
54 | |||
55 | goto free_chrdev_name; | ||
56 | } | 97 | } |
57 | fprintf(stdout, "GPIO chip: %s, \"%s\", %u GPIO lines\n", | 98 | fprintf(stdout, "GPIO chip: %s, \"%s\", %u GPIO lines\n", |
58 | cinfo.name, cinfo.label, cinfo.lines); | 99 | cinfo.name, cinfo.label, cinfo.lines); |
59 | 100 | ||
60 | if (close(fd) == -1) { | 101 | /* Loop over the lines and print info */ |
61 | ret = -errno; | 102 | for (i = 0; i < cinfo.lines; i++) { |
62 | goto free_chrdev_name; | 103 | struct gpioline_info linfo; |
104 | |||
105 | memset(&linfo, 0, sizeof(linfo)); | ||
106 | linfo.line_offset = i; | ||
107 | |||
108 | ret = ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &linfo); | ||
109 | if (ret == -1) { | ||
110 | ret = -errno; | ||
111 | perror("Failed to issue LINEINFO IOCTL\n"); | ||
112 | goto exit_close_error; | ||
113 | } | ||
114 | fprintf(stdout, "\tline %d:", linfo.line_offset); | ||
115 | if (linfo.name[0]) | ||
116 | fprintf(stdout, " %s", linfo.name); | ||
117 | else | ||
118 | fprintf(stdout, " unnamed"); | ||
119 | if (linfo.label[0]) | ||
120 | fprintf(stdout, " \"%s\"", linfo.label); | ||
121 | else | ||
122 | fprintf(stdout, " unlabeled"); | ||
123 | if (linfo.flags) { | ||
124 | fprintf(stdout, " ["); | ||
125 | print_flags(linfo.flags); | ||
126 | fprintf(stdout, "]"); | ||
127 | } | ||
128 | fprintf(stdout, "\n"); | ||
129 | |||
63 | } | 130 | } |
64 | 131 | ||
65 | free_chrdev_name: | 132 | exit_close_error: |
133 | if (close(fd) == -1) | ||
134 | perror("Failed to close GPIO character device file"); | ||
66 | free(chrdev_name); | 135 | free(chrdev_name); |
67 | |||
68 | return ret; | 136 | return ret; |
69 | |||
70 | } | 137 | } |
71 | 138 | ||
72 | void print_usage(void) | 139 | void print_usage(void) |