1
2
3
4
5
6
7
8
9
10
11
12#include <unistd.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <errno.h>
16#include <string.h>
17#include <fcntl.h>
18#include <getopt.h>
19#include <sys/ioctl.h>
20#include <linux/gpio.h>
21#include "gpio-utils.h"
22
23#define COMSUMER "gpio-utils"
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61int gpiotools_request_linehandle(const char *device_name, unsigned int *lines,
62 unsigned int nlines, unsigned int flag,
63 struct gpiohandle_data *data,
64 const char *consumer_label)
65{
66 struct gpiohandle_request req;
67 char *chrdev_name;
68 int fd;
69 int i;
70 int ret;
71
72 ret = asprintf(&chrdev_name, "/dev/%s", device_name);
73 if (ret < 0)
74 return -ENOMEM;
75
76 fd = open(chrdev_name, 0);
77 if (fd == -1) {
78 ret = -errno;
79 fprintf(stderr, "Failed to open %s, %s\n",
80 chrdev_name, strerror(errno));
81 goto exit_close_error;
82 }
83
84 for (i = 0; i < nlines; i++)
85 req.lineoffsets[i] = lines[i];
86
87 req.flags = flag;
88 strcpy(req.consumer_label, consumer_label);
89 req.lines = nlines;
90 if (flag & GPIOHANDLE_REQUEST_OUTPUT)
91 memcpy(req.default_values, data, sizeof(req.default_values));
92
93 ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
94 if (ret == -1) {
95 ret = -errno;
96 fprintf(stderr, "Failed to issue %s (%d), %s\n",
97 "GPIO_GET_LINEHANDLE_IOCTL", ret, strerror(errno));
98 }
99
100exit_close_error:
101 if (close(fd) == -1)
102 perror("Failed to close GPIO character device file");
103 free(chrdev_name);
104 return ret < 0 ? ret : req.fd;
105}
106
107
108
109
110
111
112
113
114
115int gpiotools_set_values(const int fd, struct gpiohandle_data *data)
116{
117 int ret;
118
119 ret = ioctl(fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, data);
120 if (ret == -1) {
121 ret = -errno;
122 fprintf(stderr, "Failed to issue %s (%d), %s\n",
123 "GPIOHANDLE_SET_LINE_VALUES_IOCTL", ret,
124 strerror(errno));
125 }
126
127 return ret;
128}
129
130
131
132
133
134
135
136
137
138
139int gpiotools_get_values(const int fd, struct gpiohandle_data *data)
140{
141 int ret;
142
143 ret = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, data);
144 if (ret == -1) {
145 ret = -errno;
146 fprintf(stderr, "Failed to issue %s (%d), %s\n",
147 "GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret,
148 strerror(errno));
149 }
150
151 return ret;
152}
153
154
155
156
157
158
159
160
161
162int gpiotools_release_linehandle(const int fd)
163{
164 int ret;
165
166 ret = close(fd);
167 if (ret == -1) {
168 perror("Failed to close GPIO LINEHANDLE device file");
169 ret = -errno;
170 }
171
172 return ret;
173}
174
175
176
177
178
179
180
181
182
183
184int gpiotools_get(const char *device_name, unsigned int line)
185{
186 struct gpiohandle_data data;
187 unsigned int lines[] = {line};
188
189 gpiotools_gets(device_name, lines, 1, &data);
190 return data.values[0];
191}
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206int gpiotools_gets(const char *device_name, unsigned int *lines,
207 unsigned int nlines, struct gpiohandle_data *data)
208{
209 int fd;
210 int ret;
211 int ret_close;
212
213 ret = gpiotools_request_linehandle(device_name, lines, nlines,
214 GPIOHANDLE_REQUEST_INPUT, data,
215 COMSUMER);
216 if (ret < 0)
217 return ret;
218
219 fd = ret;
220 ret = gpiotools_get_values(fd, data);
221 ret_close = gpiotools_release_linehandle(fd);
222 return ret < 0 ? ret : ret_close;
223}
224
225
226
227
228
229
230
231
232
233
234
235int gpiotools_set(const char *device_name, unsigned int line,
236 unsigned int value)
237{
238 struct gpiohandle_data data;
239 unsigned int lines[] = {line};
240
241 data.values[0] = value;
242 return gpiotools_sets(device_name, lines, 1, &data);
243}
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258int gpiotools_sets(const char *device_name, unsigned int *lines,
259 unsigned int nlines, struct gpiohandle_data *data)
260{
261 int ret;
262
263 ret = gpiotools_request_linehandle(device_name, lines, nlines,
264 GPIOHANDLE_REQUEST_OUTPUT, data,
265 COMSUMER);
266 if (ret < 0)
267 return ret;
268
269 return gpiotools_release_linehandle(ret);
270}
271