aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2015-10-21 09:45:54 -0400
committerLinus Walleij <linus.walleij@linaro.org>2016-02-09 05:09:48 -0500
commit6d591c46bce037696d173bd5c8461b2b4bb680ad (patch)
tree5b7d5e0004de27d1451f38e3e1ddf99837e5d615
parent3c702e9987e261042a07e43460a8148be254412e (diff)
tools/gpio: create GPIO tools
This creates GPIO tools under tools/gpio/* and adds a single example program to list the GPIOs on a system. When proper devices are created it provides this minimal output: Cc: Johan Hovold <johan@kernel.org> Cc: Michael Welling <mwelling@ieee.org> Cc: Markus Pargmann <mpa@pengutronix.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--MAINTAINERS1
-rw-r--r--tools/Makefile8
-rw-r--r--tools/gpio/Makefile12
-rw-r--r--tools/gpio/gpio-utils.c11
-rw-r--r--tools/gpio/gpio-utils.h25
-rw-r--r--tools/gpio/lsgpio.c128
6 files changed, 182 insertions, 3 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 76986c3ab4ff..4d3d1b817873 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4820,6 +4820,7 @@ F: include/linux/gpio/
4820F: include/linux/gpio.h 4820F: include/linux/gpio.h
4821F: include/asm-generic/gpio.h 4821F: include/asm-generic/gpio.h
4822F: include/uapi/linux/gpio.h 4822F: include/uapi/linux/gpio.h
4823F: tools/gpio/
4823 4824
4824GRE DEMULTIPLEXER DRIVER 4825GRE DEMULTIPLEXER DRIVER
4825M: Dmitry Kozlov <xeb@mail.ru> 4826M: Dmitry Kozlov <xeb@mail.ru>
diff --git a/tools/Makefile b/tools/Makefile
index 6339f6ac3ccb..f41e7c6ea23e 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -13,6 +13,7 @@ help:
13 @echo ' cpupower - a tool for all things x86 CPU power' 13 @echo ' cpupower - a tool for all things x86 CPU power'
14 @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' 14 @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer'
15 @echo ' freefall - laptop accelerometer program for disk protection' 15 @echo ' freefall - laptop accelerometer program for disk protection'
16 @echo ' gpio - GPIO tools'
16 @echo ' hv - tools used when in Hyper-V clients' 17 @echo ' hv - tools used when in Hyper-V clients'
17 @echo ' iio - IIO tools' 18 @echo ' iio - IIO tools'
18 @echo ' lguest - a minimal 32-bit x86 hypervisor' 19 @echo ' lguest - a minimal 32-bit x86 hypervisor'
@@ -53,7 +54,7 @@ acpi: FORCE
53cpupower: FORCE 54cpupower: FORCE
54 $(call descend,power/$@) 55 $(call descend,power/$@)
55 56
56cgroup firewire hv guest spi usb virtio vm net iio: FORCE 57cgroup firewire hv guest spi usb virtio vm net iio gpio: FORCE
57 $(call descend,$@) 58 $(call descend,$@)
58 59
59liblockdep: FORCE 60liblockdep: FORCE
@@ -119,7 +120,7 @@ acpi_clean:
119cpupower_clean: 120cpupower_clean:
120 $(call descend,power/cpupower,clean) 121 $(call descend,power/cpupower,clean)
121 122
122cgroup_clean hv_clean firewire_clean lguest_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean: 123cgroup_clean hv_clean firewire_clean lguest_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean gpio_clean:
123 $(call descend,$(@:_clean=),clean) 124 $(call descend,$(@:_clean=),clean)
124 125
125liblockdep_clean: 126liblockdep_clean:
@@ -155,6 +156,7 @@ build_clean:
155clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ 156clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \
156 perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ 157 perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \
157 vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ 158 vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
158 freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean 159 freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \
160 gpio_clean
159 161
160.PHONY: FORCE 162.PHONY: FORCE
diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile
new file mode 100644
index 000000000000..4d198d5c4203
--- /dev/null
+++ b/tools/gpio/Makefile
@@ -0,0 +1,12 @@
1CC = $(CROSS_COMPILE)gcc
2CFLAGS += -Wall -g -D_GNU_SOURCE
3
4all: lsgpio
5
6lsgpio: lsgpio.o gpio-utils.o
7
8%.o: %.c gpio-utils.h
9
10.PHONY: clean
11clean:
12 rm -f *.o lsgpio
diff --git a/tools/gpio/gpio-utils.c b/tools/gpio/gpio-utils.c
new file mode 100644
index 000000000000..8208718f2c99
--- /dev/null
+++ b/tools/gpio/gpio-utils.c
@@ -0,0 +1,11 @@
1/*
2 * GPIO tools - helpers library for the GPIO tools
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
11#include "gpio-utils.h"
diff --git a/tools/gpio/gpio-utils.h b/tools/gpio/gpio-utils.h
new file mode 100644
index 000000000000..b18209a45ad3
--- /dev/null
+++ b/tools/gpio/gpio-utils.h
@@ -0,0 +1,25 @@
1/*
2 * GPIO tools - utility helpers library for the GPIO tools
3 *
4 * Copyright (C) 2015 Linus Walleij
5 *
6 * Portions copied from iio_utils and lssio:
7 * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
8 * Copyright (c) 2008 Jonathan Cameron
9 * *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 */
14#ifndef _GPIO_UTILS_H_
15#define _GPIO_UTILS_H_
16
17#include <string.h>
18
19static inline int check_prefix(const char *str, const char *prefix)
20{
21 return strlen(str) > strlen(prefix) &&
22 strncmp(str, prefix, strlen(prefix)) == 0;
23}
24
25#endif /* _GPIO_UTILS_H_ */
diff --git a/tools/gpio/lsgpio.c b/tools/gpio/lsgpio.c
new file mode 100644
index 000000000000..4cfe29da279b
--- /dev/null
+++ b/tools/gpio/lsgpio.c
@@ -0,0 +1,128 @@
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
29int list_device(const char *device_name)
30{
31 struct gpiochip_info cinfo;
32 char *chrdev_name;
33 int fd;
34 int ret;
35
36 ret = asprintf(&chrdev_name, "/dev/%s", device_name);
37 if (ret < 0)
38 return -ENOMEM;
39
40 fd = open(chrdev_name, 0);
41 if (fd == -1) {
42 ret = -errno;
43 fprintf(stderr, "Failed to open %s\n", chrdev_name);
44 goto free_chrdev_name;
45 }
46
47 /* Inspect this GPIO chip */
48 ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &cinfo);
49 if (ret == -1) {
50 ret = -errno;
51 fprintf(stderr, "Failed to retrieve GPIO fd\n");
52 if (close(fd) == -1)
53 perror("Failed to close GPIO character device file");
54
55 goto free_chrdev_name;
56 }
57 fprintf(stdout, "GPIO chip: %s, %u GPIO lines\n",
58 cinfo.name, cinfo.lines);
59
60 if (close(fd) == -1) {
61 ret = -errno;
62 goto free_chrdev_name;
63 }
64
65free_chrdev_name:
66 free(chrdev_name);
67
68 return ret;
69
70}
71
72void print_usage(void)
73{
74 fprintf(stderr, "Usage: lsgpio [options]...\n"
75 "List GPIO chips, lines and states\n"
76 " -n <name> List GPIOs on a named device\n"
77 " -? This helptext\n"
78 );
79}
80
81int main(int argc, char **argv)
82{
83 const char *device_name;
84 int ret;
85 int c;
86
87 while ((c = getopt(argc, argv, "n:")) != -1) {
88 switch (c) {
89 case 'n':
90 device_name = optarg;
91 break;
92 case '?':
93 print_usage();
94 return -1;
95 }
96 }
97
98 if (device_name)
99 ret = list_device(device_name);
100 else {
101 const struct dirent *ent;
102 DIR *dp;
103
104 /* List all GPIO devices one at a time */
105 dp = opendir("/dev");
106 if (!dp) {
107 ret = -errno;
108 goto error_out;
109 }
110
111 ret = -ENOENT;
112 while (ent = readdir(dp), ent) {
113 if (check_prefix(ent->d_name, "gpiochip")) {
114 ret = list_device(ent->d_name);
115 if (ret)
116 break;
117 }
118 }
119
120 ret = 0;
121 if (closedir(dp) == -1) {
122 perror("scanning devices: Failed to close directory");
123 ret = -errno;
124 }
125 }
126error_out:
127 return ret;
128}