~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/gpio/lsgpio.c

Version: ~ [ linux-5.4-rc7 ] ~ [ linux-5.3.11 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.84 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.154 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.201 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.201 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.77 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * lsgpio - example on how to list the GPIO lines on a system
  3  *
  4  * Copyright (C) 2015 Linus Walleij
  5  *
  6  * This program is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 as published by
  8  * the Free Software Foundation.
  9  *
 10  * Usage:
 11  *      lsgpio <-n device-name>
 12  */
 13 
 14 #include <unistd.h>
 15 #include <stdlib.h>
 16 #include <stdbool.h>
 17 #include <stdio.h>
 18 #include <dirent.h>
 19 #include <errno.h>
 20 #include <string.h>
 21 #include <poll.h>
 22 #include <fcntl.h>
 23 #include <getopt.h>
 24 #include <sys/ioctl.h>
 25 #include <linux/gpio.h>
 26 
 27 #include "gpio-utils.h"
 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 
 72 int list_device(const char *device_name)
 73 {
 74         struct gpiochip_info cinfo;
 75         char *chrdev_name;
 76         int fd;
 77         int ret;
 78         int i;
 79 
 80         ret = asprintf(&chrdev_name, "/dev/%s", device_name);
 81         if (ret < 0)
 82                 return -ENOMEM;
 83 
 84         fd = open(chrdev_name, 0);
 85         if (fd == -1) {
 86                 ret = -errno;
 87                 fprintf(stderr, "Failed to open %s\n", chrdev_name);
 88                 goto exit_close_error;
 89         }
 90 
 91         /* Inspect this GPIO chip */
 92         ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &cinfo);
 93         if (ret == -1) {
 94                 ret = -errno;
 95                 perror("Failed to issue CHIPINFO IOCTL\n");
 96                 goto exit_close_error;
 97         }
 98         fprintf(stdout, "GPIO chip: %s, \"%s\", %u GPIO lines\n",
 99                 cinfo.name, cinfo.label, cinfo.lines);
100 
101         /* Loop over the lines and print info */
102         for (i = 0; i < cinfo.lines; i++) {
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 %2d:", linfo.line_offset);
115                 if (linfo.name[0])
116                         fprintf(stdout, " \"%s\"", linfo.name);
117                 else
118                         fprintf(stdout, " unnamed");
119                 if (linfo.consumer[0])
120                         fprintf(stdout, " \"%s\"", linfo.consumer);
121                 else
122                         fprintf(stdout, " unused");
123                 if (linfo.flags) {
124                         fprintf(stdout, " [");
125                         print_flags(linfo.flags);
126                         fprintf(stdout, "]");
127                 }
128                 fprintf(stdout, "\n");
129 
130         }
131 
132 exit_close_error:
133         if (close(fd) == -1)
134                 perror("Failed to close GPIO character device file");
135         free(chrdev_name);
136         return ret;
137 }
138 
139 void print_usage(void)
140 {
141         fprintf(stderr, "Usage: lsgpio [options]...\n"
142                 "List GPIO chips, lines and states\n"
143                 "  -n <name>  List GPIOs on a named device\n"
144                 "  -?         This helptext\n"
145         );
146 }
147 
148 int main(int argc, char **argv)
149 {
150         const char *device_name = NULL;
151         int ret;
152         int c;
153 
154         while ((c = getopt(argc, argv, "n:")) != -1) {
155                 switch (c) {
156                 case 'n':
157                         device_name = optarg;
158                         break;
159                 case '?':
160                         print_usage();
161                         return -1;
162                 }
163         }
164 
165         if (device_name)
166                 ret = list_device(device_name);
167         else {
168                 const struct dirent *ent;
169                 DIR *dp;
170 
171                 /* List all GPIO devices one at a time */
172                 dp = opendir("/dev");
173                 if (!dp) {
174                         ret = -errno;
175                         goto error_out;
176                 }
177 
178                 ret = -ENOENT;
179                 while (ent = readdir(dp), ent) {
180                         if (check_prefix(ent->d_name, "gpiochip")) {
181                                 ret = list_device(ent->d_name);
182                                 if (ret)
183                                         break;
184                         }
185                 }
186 
187                 ret = 0;
188                 if (closedir(dp) == -1) {
189                         perror("scanning devices: Failed to close directory");
190                         ret = -errno;
191                 }
192         }
193 error_out:
194         return ret;
195 }
196 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp