summaryrefslogtreecommitdiffstats
path: root/tools/gpio/lsgpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gpio/lsgpio.c')
-rw-r--r--tools/gpio/lsgpio.c91
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
29struct gpio_flag {
30 char *name;
31 unsigned long mask;
32};
33
34struct 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
57void 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
29int list_device(const char *device_name) 72int 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
65free_chrdev_name: 132exit_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
72void print_usage(void) 139void print_usage(void)