2 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
3 * Copyright (c) 2014, Rui Paulo <rpaulo@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
48 static struct flag_desc gpio_flags[] = {
49 { "IN", GPIO_PIN_INPUT },
50 { "OUT", GPIO_PIN_OUTPUT },
51 { "OD", GPIO_PIN_OPENDRAIN },
52 { "PP", GPIO_PIN_PUSHPULL },
53 { "TS", GPIO_PIN_TRISTATE },
54 { "PU", GPIO_PIN_PULLUP },
55 { "PD", GPIO_PIN_PULLDOWN },
56 { "II", GPIO_PIN_INVIN },
57 { "IO", GPIO_PIN_INVOUT },
58 { "PULSE", GPIO_PIN_PULSATE },
62 int str2cap(const char *str);
67 fprintf(stderr, "Usage:\n");
68 fprintf(stderr, "\tgpioctl [-f ctldev] -l [-v]\n");
69 fprintf(stderr, "\tgpioctl [-f ctldev] -t pin\n");
70 fprintf(stderr, "\tgpioctl [-f ctldev] -c pin flag ...\n");
71 fprintf(stderr, "\tgpioctl [-f ctldev] -n pin pin-name\n");
72 fprintf(stderr, "\tgpioctl [-f ctldev] pin [0|1]\n");
79 struct flag_desc * pdesc = gpio_flags;
81 if (pdesc->flag == cap)
90 str2cap(const char *str)
92 struct flag_desc * pdesc = gpio_flags;
94 if (strcasecmp(str, pdesc->name) == 0)
103 * Our handmade function for converting string to number
106 str2int(const char *s, int *ok)
109 int res = strtod(s, &endptr);
110 if (endptr != s + strlen(s) )
125 for (i = 0; i < 32; i++) {
126 if (caps & (1 << i)) {
129 printf("%s", cap2str(1 << i));
137 dump_pins(gpio_handle_t handle, int verbose)
143 maxpin = gpio_pin_list(handle, &cfgs);
145 perror("gpio_pin_list");
149 for (i = 0; i <= maxpin; i++) {
151 pinv = gpio_pin_get(handle, pin->g_pin);
152 printf("pin %02d:\t%d\t%s", pin->g_pin, pinv,
155 print_caps(pin->g_flags);
159 print_caps(pin->g_caps);
167 fail(const char *fmt, ...)
172 vfprintf(stderr, fmt, ap);
178 main(int argc, char **argv)
182 gpio_handle_t handle;
183 char *ctlfile = NULL;
186 int config, list, name, toggle, verbose;
188 config = toggle = verbose = list = name = pinn = 0;
190 while ((ch = getopt(argc, argv, "c:f:ln:t:v")) != -1) {
194 pinn = str2int(optarg, &ok);
196 fail("Invalid pin number: %s\n", optarg);
206 pinn = str2int(optarg, &ok);
208 fail("Invalid pin number: %s\n", optarg);
212 pinn = str2int(optarg, &ok);
214 fail("Invalid pin number: %s\n", optarg);
227 handle = gpio_open(0);
229 handle = gpio_open_device(ctlfile);
230 if (handle == GPIO_INVALID_HANDLE) {
235 /* Set the pin name. */
241 if (gpio_pin_set_name(handle, pinn, argv[0]) < 0) {
242 perror("gpio_pin_set_name");
249 dump_pins(handle, verbose);
256 * -t pin assumes no additional arguments
262 if (gpio_pin_toggle(handle, pinn) < 0) {
263 perror("gpio_pin_toggle");
272 for (i = 0; i < argc; i++) {
273 flag = str2cap(argv[i]);
275 fail("Invalid flag: %s\n", argv[i]);
280 if (gpio_pin_set_flags(handle, &pin) < 0) {
281 perror("gpio_pin_set_flags");
288 * Last two cases - set value or print value
290 if ((argc == 0) || (argc > 2)) {
295 pinn = str2int(argv[0], &ok);
297 fail("Invalid pin number: %s\n", argv[0]);
303 pinv = gpio_pin_get(handle, pinn);
305 perror("gpio_pin_get");
308 printf("%d\n", pinv);
312 /* Is it valid number (0 or 1) ? */
313 pinv = str2int(argv[1], &ok);
314 if (!ok || ((pinv != 0) && (pinv != 1)))
315 fail("Invalid pin value: %s\n", argv[1]);
320 if (gpio_pin_set(handle, pinn, pinv) < 0) {
321 perror("gpio_pin_set");