1968ec6a6SOleksandr Tymoshenko /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni *
4968ec6a6SOleksandr Tymoshenko * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
5244c371dSRui Paulo * Copyright (c) 2014, Rui Paulo <rpaulo@FreeBSD.org>
63b2bb133SOleksandr Tymoshenko * Copyright (c) 2015, Emmanuel Vadot <manu@bidouilliste.com>
7968ec6a6SOleksandr Tymoshenko * All rights reserved.
8968ec6a6SOleksandr Tymoshenko *
9968ec6a6SOleksandr Tymoshenko * Redistribution and use in source and binary forms, with or without
10968ec6a6SOleksandr Tymoshenko * modification, are permitted provided that the following conditions
11968ec6a6SOleksandr Tymoshenko * are met:
12968ec6a6SOleksandr Tymoshenko * 1. Redistributions of source code must retain the above copyright
13968ec6a6SOleksandr Tymoshenko * notice unmodified, this list of conditions, and the following
14968ec6a6SOleksandr Tymoshenko * disclaimer.
15968ec6a6SOleksandr Tymoshenko * 2. Redistributions in binary form must reproduce the above copyright
16968ec6a6SOleksandr Tymoshenko * notice, this list of conditions and the following disclaimer in the
17968ec6a6SOleksandr Tymoshenko * documentation and/or other materials provided with the distribution.
18968ec6a6SOleksandr Tymoshenko *
19968ec6a6SOleksandr Tymoshenko * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20968ec6a6SOleksandr Tymoshenko * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21968ec6a6SOleksandr Tymoshenko * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22968ec6a6SOleksandr Tymoshenko * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23968ec6a6SOleksandr Tymoshenko * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24968ec6a6SOleksandr Tymoshenko * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25968ec6a6SOleksandr Tymoshenko * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26968ec6a6SOleksandr Tymoshenko * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27968ec6a6SOleksandr Tymoshenko * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28968ec6a6SOleksandr Tymoshenko * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29968ec6a6SOleksandr Tymoshenko * SUCH DAMAGE.
30968ec6a6SOleksandr Tymoshenko */
31968ec6a6SOleksandr Tymoshenko
32968ec6a6SOleksandr Tymoshenko #include <sys/cdefs.h>
33968ec6a6SOleksandr Tymoshenko #include <fcntl.h>
34968ec6a6SOleksandr Tymoshenko #include <getopt.h>
3522e3858cSSean Bruno #include <paths.h>
36968ec6a6SOleksandr Tymoshenko #include <stdio.h>
37968ec6a6SOleksandr Tymoshenko #include <stdarg.h>
38968ec6a6SOleksandr Tymoshenko #include <stdlib.h>
39968ec6a6SOleksandr Tymoshenko #include <string.h>
40968ec6a6SOleksandr Tymoshenko #include <unistd.h>
41968ec6a6SOleksandr Tymoshenko
42244c371dSRui Paulo #include <libgpio.h>
43968ec6a6SOleksandr Tymoshenko
443b2bb133SOleksandr Tymoshenko #define PIN_TYPE_NUMBER 1
453b2bb133SOleksandr Tymoshenko #define PIN_TYPE_NAME 2
463b2bb133SOleksandr Tymoshenko
47968ec6a6SOleksandr Tymoshenko struct flag_desc {
48968ec6a6SOleksandr Tymoshenko const char *name;
49968ec6a6SOleksandr Tymoshenko uint32_t flag;
50968ec6a6SOleksandr Tymoshenko };
51968ec6a6SOleksandr Tymoshenko
52bf70beceSEd Schouten static struct flag_desc gpio_flags[] = {
53968ec6a6SOleksandr Tymoshenko { "IN", GPIO_PIN_INPUT },
54968ec6a6SOleksandr Tymoshenko { "OUT", GPIO_PIN_OUTPUT },
55968ec6a6SOleksandr Tymoshenko { "OD", GPIO_PIN_OPENDRAIN },
56968ec6a6SOleksandr Tymoshenko { "PP", GPIO_PIN_PUSHPULL },
57968ec6a6SOleksandr Tymoshenko { "TS", GPIO_PIN_TRISTATE },
58968ec6a6SOleksandr Tymoshenko { "PU", GPIO_PIN_PULLUP },
59968ec6a6SOleksandr Tymoshenko { "PD", GPIO_PIN_PULLDOWN },
60968ec6a6SOleksandr Tymoshenko { "II", GPIO_PIN_INVIN },
61968ec6a6SOleksandr Tymoshenko { "IO", GPIO_PIN_INVOUT },
62968ec6a6SOleksandr Tymoshenko { "PULSE", GPIO_PIN_PULSATE },
6319602a38SEmmanuel Vadot { "INTRLL", GPIO_INTR_LEVEL_LOW},
6419602a38SEmmanuel Vadot { "INTRLH", GPIO_INTR_LEVEL_HIGH},
6519602a38SEmmanuel Vadot { "INTRER", GPIO_INTR_EDGE_RISING},
6619602a38SEmmanuel Vadot { "INTREF", GPIO_INTR_EDGE_FALLING},
6719602a38SEmmanuel Vadot { "INTREB", GPIO_INTR_EDGE_BOTH},
68968ec6a6SOleksandr Tymoshenko { NULL, 0 },
69968ec6a6SOleksandr Tymoshenko };
70968ec6a6SOleksandr Tymoshenko
71968ec6a6SOleksandr Tymoshenko int str2cap(const char *str);
72968ec6a6SOleksandr Tymoshenko
73968ec6a6SOleksandr Tymoshenko static void
usage(void)74968ec6a6SOleksandr Tymoshenko usage(void)
75968ec6a6SOleksandr Tymoshenko {
76968ec6a6SOleksandr Tymoshenko fprintf(stderr, "Usage:\n");
7722e3858cSSean Bruno fprintf(stderr, "\tgpioctl [-f ctldev] -l [-v]\n");
783b2bb133SOleksandr Tymoshenko fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -t pin\n");
793b2bb133SOleksandr Tymoshenko fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -c pin flag ...\n");
803b2bb133SOleksandr Tymoshenko fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -n pin pin-name\n");
813b2bb133SOleksandr Tymoshenko fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] pin [0|1]\n");
82968ec6a6SOleksandr Tymoshenko exit(1);
83968ec6a6SOleksandr Tymoshenko }
84968ec6a6SOleksandr Tymoshenko
85968ec6a6SOleksandr Tymoshenko static const char *
cap2str(uint32_t cap)86968ec6a6SOleksandr Tymoshenko cap2str(uint32_t cap)
87968ec6a6SOleksandr Tymoshenko {
88968ec6a6SOleksandr Tymoshenko struct flag_desc * pdesc = gpio_flags;
89968ec6a6SOleksandr Tymoshenko while (pdesc->name) {
90968ec6a6SOleksandr Tymoshenko if (pdesc->flag == cap)
91968ec6a6SOleksandr Tymoshenko return pdesc->name;
92968ec6a6SOleksandr Tymoshenko pdesc++;
93968ec6a6SOleksandr Tymoshenko }
94968ec6a6SOleksandr Tymoshenko
95968ec6a6SOleksandr Tymoshenko return "UNKNOWN";
96968ec6a6SOleksandr Tymoshenko }
97968ec6a6SOleksandr Tymoshenko
98968ec6a6SOleksandr Tymoshenko int
str2cap(const char * str)99968ec6a6SOleksandr Tymoshenko str2cap(const char *str)
100968ec6a6SOleksandr Tymoshenko {
101968ec6a6SOleksandr Tymoshenko struct flag_desc * pdesc = gpio_flags;
102968ec6a6SOleksandr Tymoshenko while (pdesc->name) {
103968ec6a6SOleksandr Tymoshenko if (strcasecmp(str, pdesc->name) == 0)
104968ec6a6SOleksandr Tymoshenko return pdesc->flag;
105968ec6a6SOleksandr Tymoshenko pdesc++;
106968ec6a6SOleksandr Tymoshenko }
107968ec6a6SOleksandr Tymoshenko
108968ec6a6SOleksandr Tymoshenko return (-1);
109968ec6a6SOleksandr Tymoshenko }
110968ec6a6SOleksandr Tymoshenko
111968ec6a6SOleksandr Tymoshenko /*
112968ec6a6SOleksandr Tymoshenko * Our handmade function for converting string to number
113968ec6a6SOleksandr Tymoshenko */
114968ec6a6SOleksandr Tymoshenko static int
str2int(const char * s,int * ok)115968ec6a6SOleksandr Tymoshenko str2int(const char *s, int *ok)
116968ec6a6SOleksandr Tymoshenko {
117968ec6a6SOleksandr Tymoshenko char *endptr;
118968ec6a6SOleksandr Tymoshenko int res = strtod(s, &endptr);
119968ec6a6SOleksandr Tymoshenko if (endptr != s + strlen(s) )
120968ec6a6SOleksandr Tymoshenko *ok = 0;
121968ec6a6SOleksandr Tymoshenko else
122968ec6a6SOleksandr Tymoshenko *ok = 1;
123968ec6a6SOleksandr Tymoshenko
124968ec6a6SOleksandr Tymoshenko return res;
125968ec6a6SOleksandr Tymoshenko }
126968ec6a6SOleksandr Tymoshenko
127968ec6a6SOleksandr Tymoshenko static void
print_caps(int caps)128968ec6a6SOleksandr Tymoshenko print_caps(int caps)
129968ec6a6SOleksandr Tymoshenko {
130968ec6a6SOleksandr Tymoshenko int i, need_coma;
131968ec6a6SOleksandr Tymoshenko
132968ec6a6SOleksandr Tymoshenko need_coma = 0;
133968ec6a6SOleksandr Tymoshenko printf("<");
134968ec6a6SOleksandr Tymoshenko for (i = 0; i < 32; i++) {
135968ec6a6SOleksandr Tymoshenko if (caps & (1 << i)) {
136968ec6a6SOleksandr Tymoshenko if (need_coma)
137968ec6a6SOleksandr Tymoshenko printf(",");
138968ec6a6SOleksandr Tymoshenko printf("%s", cap2str(1 << i));
139968ec6a6SOleksandr Tymoshenko need_coma = 1;
140968ec6a6SOleksandr Tymoshenko }
141968ec6a6SOleksandr Tymoshenko }
142968ec6a6SOleksandr Tymoshenko printf(">");
143968ec6a6SOleksandr Tymoshenko }
144968ec6a6SOleksandr Tymoshenko
145968ec6a6SOleksandr Tymoshenko static void
dump_pins(gpio_handle_t handle,int verbose)146244c371dSRui Paulo dump_pins(gpio_handle_t handle, int verbose)
147968ec6a6SOleksandr Tymoshenko {
148244c371dSRui Paulo int i, maxpin, pinv;
149244c371dSRui Paulo gpio_config_t *cfgs;
150244c371dSRui Paulo gpio_config_t *pin;
151968ec6a6SOleksandr Tymoshenko
152244c371dSRui Paulo maxpin = gpio_pin_list(handle, &cfgs);
153244c371dSRui Paulo if (maxpin < 0) {
154244c371dSRui Paulo perror("gpio_pin_list");
155968ec6a6SOleksandr Tymoshenko exit(1);
156968ec6a6SOleksandr Tymoshenko }
157968ec6a6SOleksandr Tymoshenko
158968ec6a6SOleksandr Tymoshenko for (i = 0; i <= maxpin; i++) {
159244c371dSRui Paulo pin = cfgs + i;
160244c371dSRui Paulo pinv = gpio_pin_get(handle, pin->g_pin);
161244c371dSRui Paulo printf("pin %02d:\t%d\t%s", pin->g_pin, pinv,
162244c371dSRui Paulo pin->g_name);
163968ec6a6SOleksandr Tymoshenko
164244c371dSRui Paulo print_caps(pin->g_flags);
165968ec6a6SOleksandr Tymoshenko
166968ec6a6SOleksandr Tymoshenko if (verbose) {
167968ec6a6SOleksandr Tymoshenko printf(", caps:");
168244c371dSRui Paulo print_caps(pin->g_caps);
169968ec6a6SOleksandr Tymoshenko }
170968ec6a6SOleksandr Tymoshenko printf("\n");
171968ec6a6SOleksandr Tymoshenko }
17221bc384aSLuiz Otavio O Souza free(cfgs);
173968ec6a6SOleksandr Tymoshenko }
174968ec6a6SOleksandr Tymoshenko
1753b2bb133SOleksandr Tymoshenko static int
get_pinnum_by_name(gpio_handle_t handle,const char * name)1763b2bb133SOleksandr Tymoshenko get_pinnum_by_name(gpio_handle_t handle, const char *name) {
1773b2bb133SOleksandr Tymoshenko int i, maxpin, pinn;
1783b2bb133SOleksandr Tymoshenko gpio_config_t *cfgs;
1793b2bb133SOleksandr Tymoshenko gpio_config_t *pin;
1803b2bb133SOleksandr Tymoshenko
1813b2bb133SOleksandr Tymoshenko pinn = -1;
1823b2bb133SOleksandr Tymoshenko maxpin = gpio_pin_list(handle, &cfgs);
1833b2bb133SOleksandr Tymoshenko if (maxpin < 0) {
1843b2bb133SOleksandr Tymoshenko perror("gpio_pin_list");
1853b2bb133SOleksandr Tymoshenko exit(1);
1863b2bb133SOleksandr Tymoshenko }
1873b2bb133SOleksandr Tymoshenko
1883b2bb133SOleksandr Tymoshenko for (i = 0; i <= maxpin; i++) {
1893b2bb133SOleksandr Tymoshenko pin = cfgs + i;
1903b2bb133SOleksandr Tymoshenko gpio_pin_get(handle, pin->g_pin);
1913b2bb133SOleksandr Tymoshenko if (!strcmp(name, pin->g_name)) {
1923b2bb133SOleksandr Tymoshenko pinn = i;
1933b2bb133SOleksandr Tymoshenko break;
1943b2bb133SOleksandr Tymoshenko }
1953b2bb133SOleksandr Tymoshenko }
1963b2bb133SOleksandr Tymoshenko free(cfgs);
1973b2bb133SOleksandr Tymoshenko
1983b2bb133SOleksandr Tymoshenko return pinn;
1993b2bb133SOleksandr Tymoshenko }
2003b2bb133SOleksandr Tymoshenko
201968ec6a6SOleksandr Tymoshenko static void
fail(const char * fmt,...)202968ec6a6SOleksandr Tymoshenko fail(const char *fmt, ...)
203968ec6a6SOleksandr Tymoshenko {
204968ec6a6SOleksandr Tymoshenko va_list ap;
205968ec6a6SOleksandr Tymoshenko
206968ec6a6SOleksandr Tymoshenko va_start(ap, fmt);
207968ec6a6SOleksandr Tymoshenko vfprintf(stderr, fmt, ap);
208968ec6a6SOleksandr Tymoshenko va_end(ap);
209968ec6a6SOleksandr Tymoshenko exit(1);
210968ec6a6SOleksandr Tymoshenko }
211968ec6a6SOleksandr Tymoshenko
212968ec6a6SOleksandr Tymoshenko int
main(int argc,char ** argv)213968ec6a6SOleksandr Tymoshenko main(int argc, char **argv)
214968ec6a6SOleksandr Tymoshenko {
215968ec6a6SOleksandr Tymoshenko int i;
216244c371dSRui Paulo gpio_config_t pin;
217244c371dSRui Paulo gpio_handle_t handle;
218968ec6a6SOleksandr Tymoshenko char *ctlfile = NULL;
2193b2bb133SOleksandr Tymoshenko int pinn, pinv, pin_type, ch;
220968ec6a6SOleksandr Tymoshenko int flags, flag, ok;
221d752f0f6SLuiz Otavio O Souza int config, list, name, toggle, verbose;
222968ec6a6SOleksandr Tymoshenko
2233b2bb133SOleksandr Tymoshenko config = toggle = verbose = list = name = pin_type = 0;
224968ec6a6SOleksandr Tymoshenko
2253b2bb133SOleksandr Tymoshenko while ((ch = getopt(argc, argv, "cf:lntvNp")) != -1) {
226968ec6a6SOleksandr Tymoshenko switch (ch) {
227968ec6a6SOleksandr Tymoshenko case 'c':
228968ec6a6SOleksandr Tymoshenko config = 1;
229968ec6a6SOleksandr Tymoshenko break;
230968ec6a6SOleksandr Tymoshenko case 'f':
231968ec6a6SOleksandr Tymoshenko ctlfile = optarg;
232968ec6a6SOleksandr Tymoshenko break;
233968ec6a6SOleksandr Tymoshenko case 'l':
234968ec6a6SOleksandr Tymoshenko list = 1;
235968ec6a6SOleksandr Tymoshenko break;
236d752f0f6SLuiz Otavio O Souza case 'n':
237d752f0f6SLuiz Otavio O Souza name = 1;
2383b2bb133SOleksandr Tymoshenko break;
2393b2bb133SOleksandr Tymoshenko case 'N':
2403b2bb133SOleksandr Tymoshenko pin_type = PIN_TYPE_NAME;
2413b2bb133SOleksandr Tymoshenko break;
2423b2bb133SOleksandr Tymoshenko case'p':
2433b2bb133SOleksandr Tymoshenko pin_type = PIN_TYPE_NUMBER;
244d752f0f6SLuiz Otavio O Souza break;
245968ec6a6SOleksandr Tymoshenko case 't':
246968ec6a6SOleksandr Tymoshenko toggle = 1;
247968ec6a6SOleksandr Tymoshenko break;
248968ec6a6SOleksandr Tymoshenko case 'v':
249968ec6a6SOleksandr Tymoshenko verbose = 1;
250968ec6a6SOleksandr Tymoshenko break;
251968ec6a6SOleksandr Tymoshenko default:
252968ec6a6SOleksandr Tymoshenko usage();
253968ec6a6SOleksandr Tymoshenko break;
254968ec6a6SOleksandr Tymoshenko }
255968ec6a6SOleksandr Tymoshenko }
256968ec6a6SOleksandr Tymoshenko argv += optind;
257968ec6a6SOleksandr Tymoshenko argc -= optind;
258968ec6a6SOleksandr Tymoshenko if (ctlfile == NULL)
259244c371dSRui Paulo handle = gpio_open(0);
260244c371dSRui Paulo else
261244c371dSRui Paulo handle = gpio_open_device(ctlfile);
262244c371dSRui Paulo if (handle == GPIO_INVALID_HANDLE) {
263244c371dSRui Paulo perror("gpio_open");
264968ec6a6SOleksandr Tymoshenko exit(1);
265968ec6a6SOleksandr Tymoshenko }
266968ec6a6SOleksandr Tymoshenko
267968ec6a6SOleksandr Tymoshenko if (list) {
268244c371dSRui Paulo dump_pins(handle, verbose);
269244c371dSRui Paulo gpio_close(handle);
270968ec6a6SOleksandr Tymoshenko exit(0);
271968ec6a6SOleksandr Tymoshenko }
272968ec6a6SOleksandr Tymoshenko
2733b2bb133SOleksandr Tymoshenko if (argc == 0)
2743b2bb133SOleksandr Tymoshenko usage();
2753b2bb133SOleksandr Tymoshenko
2763b2bb133SOleksandr Tymoshenko /* Find the pin number by the name */
2773b2bb133SOleksandr Tymoshenko switch (pin_type) {
278e74d991dSDimitry Andric default:
2793b2bb133SOleksandr Tymoshenko /* First test if it is a pin number */
2803b2bb133SOleksandr Tymoshenko pinn = str2int(argv[0], &ok);
2813b2bb133SOleksandr Tymoshenko if (ok) {
2823b2bb133SOleksandr Tymoshenko /* Test if we have any pin named by this number and tell the user */
2833b2bb133SOleksandr Tymoshenko if (get_pinnum_by_name(handle, argv[0]) != -1)
2843b2bb133SOleksandr Tymoshenko fail("%s is also a pin name, use -p or -N\n", argv[0]);
2853b2bb133SOleksandr Tymoshenko } else {
2863b2bb133SOleksandr Tymoshenko /* Test if it is a name */
2873b2bb133SOleksandr Tymoshenko if ((pinn = get_pinnum_by_name(handle, argv[0])) == -1)
2883b2bb133SOleksandr Tymoshenko fail("Can't find pin named \"%s\"\n", argv[0]);
2893b2bb133SOleksandr Tymoshenko }
2903b2bb133SOleksandr Tymoshenko break;
2913b2bb133SOleksandr Tymoshenko case PIN_TYPE_NUMBER:
2923b2bb133SOleksandr Tymoshenko pinn = str2int(argv[0], &ok);
2933b2bb133SOleksandr Tymoshenko if (!ok)
2943b2bb133SOleksandr Tymoshenko fail("Invalid pin number: %s\n", argv[0]);
2953b2bb133SOleksandr Tymoshenko break;
2963b2bb133SOleksandr Tymoshenko case PIN_TYPE_NAME:
2973b2bb133SOleksandr Tymoshenko if ((pinn = get_pinnum_by_name(handle, argv[0])) == -1)
2983b2bb133SOleksandr Tymoshenko fail("Can't find pin named \"%s\"\n", argv[0]);
2993b2bb133SOleksandr Tymoshenko break;
3003b2bb133SOleksandr Tymoshenko }
3013b2bb133SOleksandr Tymoshenko
3023b2bb133SOleksandr Tymoshenko /* Set the pin name. */
3033b2bb133SOleksandr Tymoshenko if (name) {
3043b2bb133SOleksandr Tymoshenko if (argc != 2)
3053b2bb133SOleksandr Tymoshenko usage();
3063b2bb133SOleksandr Tymoshenko if (gpio_pin_set_name(handle, pinn, argv[1]) < 0) {
3073b2bb133SOleksandr Tymoshenko perror("gpio_pin_set_name");
3083b2bb133SOleksandr Tymoshenko exit(1);
3093b2bb133SOleksandr Tymoshenko }
3103b2bb133SOleksandr Tymoshenko exit(0);
3113b2bb133SOleksandr Tymoshenko }
3123b2bb133SOleksandr Tymoshenko
313968ec6a6SOleksandr Tymoshenko if (toggle) {
314968ec6a6SOleksandr Tymoshenko /*
315968ec6a6SOleksandr Tymoshenko * -t pin assumes no additional arguments
316968ec6a6SOleksandr Tymoshenko */
3173b2bb133SOleksandr Tymoshenko if (argc > 1)
318968ec6a6SOleksandr Tymoshenko usage();
319244c371dSRui Paulo if (gpio_pin_toggle(handle, pinn) < 0) {
320244c371dSRui Paulo perror("gpio_pin_toggle");
321968ec6a6SOleksandr Tymoshenko exit(1);
322968ec6a6SOleksandr Tymoshenko }
323244c371dSRui Paulo gpio_close(handle);
324968ec6a6SOleksandr Tymoshenko exit(0);
325968ec6a6SOleksandr Tymoshenko }
326968ec6a6SOleksandr Tymoshenko
327968ec6a6SOleksandr Tymoshenko if (config) {
328968ec6a6SOleksandr Tymoshenko flags = 0;
3293b2bb133SOleksandr Tymoshenko for (i = 1; i < argc; i++) {
330968ec6a6SOleksandr Tymoshenko flag = str2cap(argv[i]);
331968ec6a6SOleksandr Tymoshenko if (flag < 0)
332968ec6a6SOleksandr Tymoshenko fail("Invalid flag: %s\n", argv[i]);
333ff3468acSIan Lepore else if ((flag & GPIO_INTR_MASK) != 0)
334ff3468acSIan Lepore fail("Interrupt capability %s cannot be set as configuration flag\n", argv[i]);
335968ec6a6SOleksandr Tymoshenko flags |= flag;
336968ec6a6SOleksandr Tymoshenko }
337244c371dSRui Paulo pin.g_pin = pinn;
338244c371dSRui Paulo pin.g_flags = flags;
339244c371dSRui Paulo if (gpio_pin_set_flags(handle, &pin) < 0) {
340244c371dSRui Paulo perror("gpio_pin_set_flags");
341968ec6a6SOleksandr Tymoshenko exit(1);
342968ec6a6SOleksandr Tymoshenko }
343968ec6a6SOleksandr Tymoshenko exit(0);
344968ec6a6SOleksandr Tymoshenko }
345968ec6a6SOleksandr Tymoshenko
346968ec6a6SOleksandr Tymoshenko /*
347968ec6a6SOleksandr Tymoshenko * Last two cases - set value or print value
348968ec6a6SOleksandr Tymoshenko */
3493b2bb133SOleksandr Tymoshenko if ((argc == 0) || (argc > 2))
350968ec6a6SOleksandr Tymoshenko usage();
351968ec6a6SOleksandr Tymoshenko
352968ec6a6SOleksandr Tymoshenko /*
353968ec6a6SOleksandr Tymoshenko * Read pin value
354968ec6a6SOleksandr Tymoshenko */
355968ec6a6SOleksandr Tymoshenko if (argc == 1) {
356244c371dSRui Paulo pinv = gpio_pin_get(handle, pinn);
357244c371dSRui Paulo if (pinv < 0) {
358244c371dSRui Paulo perror("gpio_pin_get");
359968ec6a6SOleksandr Tymoshenko exit(1);
360968ec6a6SOleksandr Tymoshenko }
361244c371dSRui Paulo printf("%d\n", pinv);
362968ec6a6SOleksandr Tymoshenko exit(0);
363968ec6a6SOleksandr Tymoshenko }
364968ec6a6SOleksandr Tymoshenko
365968ec6a6SOleksandr Tymoshenko /* Is it valid number (0 or 1) ? */
366968ec6a6SOleksandr Tymoshenko pinv = str2int(argv[1], &ok);
3673b2bb133SOleksandr Tymoshenko if (ok == 0 || ((pinv != 0) && (pinv != 1)))
368968ec6a6SOleksandr Tymoshenko fail("Invalid pin value: %s\n", argv[1]);
369968ec6a6SOleksandr Tymoshenko
370968ec6a6SOleksandr Tymoshenko /*
371968ec6a6SOleksandr Tymoshenko * Set pin value
372968ec6a6SOleksandr Tymoshenko */
373244c371dSRui Paulo if (gpio_pin_set(handle, pinn, pinv) < 0) {
374244c371dSRui Paulo perror("gpio_pin_set");
375968ec6a6SOleksandr Tymoshenko exit(1);
376968ec6a6SOleksandr Tymoshenko }
377968ec6a6SOleksandr Tymoshenko
378244c371dSRui Paulo gpio_close(handle);
379968ec6a6SOleksandr Tymoshenko exit(0);
380968ec6a6SOleksandr Tymoshenko }
381