gpio: Added port-number mapping.
[utils.git] / gpio.c
CommitLineData
35647167
FT
1#include <unistd.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5#include <fcntl.h>
6#include <errno.h>
7#include <err.h>
8
cc450aa9
FT
9static const int bmap[] = {
10 -1,
11 -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1,
12 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12, 13, -1, 19, 16, 21, 20, -1, 21,
13};
14static const int imap[] = {
15 -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
16 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, 27,
17};
18static const int *umap = bmap;
19static int mapn = sizeof(bmap) / sizeof(*bmap);
20
21static int mappin(int num)
22{
23 if((num < 0) || (num >= mapn))
24 return(-1);
25 return(umap[num]);
26}
27
35647167
FT
28static void setport(int p, int v)
29{
30 char path[256], line[256];
31 FILE *fp;
cc450aa9 32 int rv, rp;
35647167 33
cc450aa9
FT
34 if((rp = mappin(p)) < 0) {
35 fprintf(stderr, "gpio: %i: no such port\n", p);
36 exit(1);
37 }
38 sprintf(path, "/sys/class/gpio/gpio%i/direction", rp);
35647167
FT
39 if((fp = fopen(path, "r")) == NULL)
40 err(1, "%s", path);
41 rv = !!fgets(line, sizeof(line), fp);
42 fclose(fp);
43 if(!rv || strcmp(line, "out\n")) {
44 if((fp = fopen(path, "w")) == NULL)
45 err(1, "%s", path);
46 fprintf(fp, "out\n"); fflush(fp);
47 if(ferror(fp))
cc450aa9 48 errx(1, "gpio%i: could not set to output", rp);
35647167
FT
49 fclose(fp);
50 }
cc450aa9 51 sprintf(path, "/sys/class/gpio/gpio%i/value", rp);
35647167
FT
52 if((fp = fopen(path, "w")) == NULL)
53 err(1, "%s", path);
54 fprintf(fp, "%i\n", v); fflush(fp);
55 if(ferror(fp))
cc450aa9 56 errx(1, "gpio%i: could not set value", rp);
35647167
FT
57 fclose(fp);
58}
59
cc450aa9
FT
60static void usage(FILE *out)
61{
62 fprintf(out, "usage: gpio [-hi] PORT=VAL...\n");
63}
64
35647167
FT
65int main(int argc, char **argv)
66{
cc450aa9 67 int c, i, port, val;
35647167
FT
68 char *p, *e;
69
cc450aa9
FT
70 while((c = getopt(argc, argv, "hi")) >= 0) {
71 switch(c) {
72 case 'h':
73 usage(stdout);
74 return(0);
75 case 'i':
76 umap = imap;
77 mapn = sizeof(imap) / sizeof(*imap);
78 break;
79 default:
80 usage(stderr);
81 return(1);
82 }
83 }
84 if(optind >= argc) {
85 usage(stderr);
86 return(1);
87 }
88 for(i = optind; i < argc; i++) {
35647167
FT
89 if((p = strchr(argv[i], '=')) == NULL) {
90 fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]);
91 exit(1);
92 }
93 port = strtol(argv[i], &e, 10);
94 if(e != p) {
95 fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]);
96 exit(1);
97 }
98 val = strtol(p + 1, &e, 10);
99 if(*e) {
100 fprintf(stderr, "gpio: %s: not of the form PORT=VAL\n", argv[i]);
101 exit(1);
102 }
103 setport(port, val);
104 }
105 return(0);
106}
cc450aa9
FT
107
108/*
109 * Local Variables:
110 * compile-command: "gcc -Wall -g -O2 -march=native -o gpio gpio.c"
111 * End:
112 */