1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /* Industrialio event test code.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (c) 2011-2012 Lars-Peter Clausen <lars@metafoo.de>
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This program is primarily intended as an example application.
7*4882a593Smuzhiyun * Reads the current buffer setup from sysfs and starts a short capture
8*4882a593Smuzhiyun * from the specified device, pretty printing the result after appropriate
9*4882a593Smuzhiyun * conversion.
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * Usage:
12*4882a593Smuzhiyun * iio_event_monitor <device_name>
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include <unistd.h>
16*4882a593Smuzhiyun #include <stdlib.h>
17*4882a593Smuzhiyun #include <stdbool.h>
18*4882a593Smuzhiyun #include <stdio.h>
19*4882a593Smuzhiyun #include <errno.h>
20*4882a593Smuzhiyun #include <string.h>
21*4882a593Smuzhiyun #include <poll.h>
22*4882a593Smuzhiyun #include <fcntl.h>
23*4882a593Smuzhiyun #include <sys/ioctl.h>
24*4882a593Smuzhiyun #include "iio_utils.h"
25*4882a593Smuzhiyun #include <linux/iio/events.h>
26*4882a593Smuzhiyun #include <linux/iio/types.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun static const char * const iio_chan_type_name_spec[] = {
29*4882a593Smuzhiyun [IIO_VOLTAGE] = "voltage",
30*4882a593Smuzhiyun [IIO_CURRENT] = "current",
31*4882a593Smuzhiyun [IIO_POWER] = "power",
32*4882a593Smuzhiyun [IIO_ACCEL] = "accel",
33*4882a593Smuzhiyun [IIO_ANGL_VEL] = "anglvel",
34*4882a593Smuzhiyun [IIO_MAGN] = "magn",
35*4882a593Smuzhiyun [IIO_LIGHT] = "illuminance",
36*4882a593Smuzhiyun [IIO_INTENSITY] = "intensity",
37*4882a593Smuzhiyun [IIO_PROXIMITY] = "proximity",
38*4882a593Smuzhiyun [IIO_TEMP] = "temp",
39*4882a593Smuzhiyun [IIO_INCLI] = "incli",
40*4882a593Smuzhiyun [IIO_ROT] = "rot",
41*4882a593Smuzhiyun [IIO_ANGL] = "angl",
42*4882a593Smuzhiyun [IIO_TIMESTAMP] = "timestamp",
43*4882a593Smuzhiyun [IIO_CAPACITANCE] = "capacitance",
44*4882a593Smuzhiyun [IIO_ALTVOLTAGE] = "altvoltage",
45*4882a593Smuzhiyun [IIO_CCT] = "cct",
46*4882a593Smuzhiyun [IIO_PRESSURE] = "pressure",
47*4882a593Smuzhiyun [IIO_HUMIDITYRELATIVE] = "humidityrelative",
48*4882a593Smuzhiyun [IIO_ACTIVITY] = "activity",
49*4882a593Smuzhiyun [IIO_STEPS] = "steps",
50*4882a593Smuzhiyun [IIO_ENERGY] = "energy",
51*4882a593Smuzhiyun [IIO_DISTANCE] = "distance",
52*4882a593Smuzhiyun [IIO_VELOCITY] = "velocity",
53*4882a593Smuzhiyun [IIO_CONCENTRATION] = "concentration",
54*4882a593Smuzhiyun [IIO_RESISTANCE] = "resistance",
55*4882a593Smuzhiyun [IIO_PH] = "ph",
56*4882a593Smuzhiyun [IIO_UVINDEX] = "uvindex",
57*4882a593Smuzhiyun [IIO_GRAVITY] = "gravity",
58*4882a593Smuzhiyun [IIO_POSITIONRELATIVE] = "positionrelative",
59*4882a593Smuzhiyun [IIO_PHASE] = "phase",
60*4882a593Smuzhiyun [IIO_MASSCONCENTRATION] = "massconcentration",
61*4882a593Smuzhiyun #ifdef CONFIG_NO_GKI
62*4882a593Smuzhiyun [IIO_SIGN_MOTION] = "signmotion",
63*4882a593Smuzhiyun [IIO_STEP_DETECTOR] = "stepdetector",
64*4882a593Smuzhiyun [IIO_STEP_COUNTER] = "stepcounter",
65*4882a593Smuzhiyun [IIO_TILT] = "tilt",
66*4882a593Smuzhiyun [IIO_TAP] = "tap",
67*4882a593Smuzhiyun [IIO_TAP_TAP] = "taptap",
68*4882a593Smuzhiyun [IIO_WRIST_TILT_GESTURE] = "wristtiltgesture",
69*4882a593Smuzhiyun [IIO_GESTURE] = "gesture",
70*4882a593Smuzhiyun #endif
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun static const char * const iio_ev_type_text[] = {
74*4882a593Smuzhiyun [IIO_EV_TYPE_THRESH] = "thresh",
75*4882a593Smuzhiyun [IIO_EV_TYPE_MAG] = "mag",
76*4882a593Smuzhiyun [IIO_EV_TYPE_ROC] = "roc",
77*4882a593Smuzhiyun [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
78*4882a593Smuzhiyun [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
79*4882a593Smuzhiyun [IIO_EV_TYPE_CHANGE] = "change",
80*4882a593Smuzhiyun #ifdef CONFIG_NO_GKI
81*4882a593Smuzhiyun [IIO_EV_TYPE_FIFO_FLUSH] = "fifo_flush",
82*4882a593Smuzhiyun #endif
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun static const char * const iio_ev_dir_text[] = {
86*4882a593Smuzhiyun [IIO_EV_DIR_EITHER] = "either",
87*4882a593Smuzhiyun [IIO_EV_DIR_RISING] = "rising",
88*4882a593Smuzhiyun [IIO_EV_DIR_FALLING] = "falling",
89*4882a593Smuzhiyun #ifdef CONFIG_NO_GKI
90*4882a593Smuzhiyun [IIO_EV_DIR_FIFO_EMPTY] = "empty",
91*4882a593Smuzhiyun [IIO_EV_DIR_FIFO_DATA] = "data",
92*4882a593Smuzhiyun #endif
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun static const char * const iio_modifier_names[] = {
96*4882a593Smuzhiyun [IIO_MOD_X] = "x",
97*4882a593Smuzhiyun [IIO_MOD_Y] = "y",
98*4882a593Smuzhiyun [IIO_MOD_Z] = "z",
99*4882a593Smuzhiyun [IIO_MOD_X_AND_Y] = "x&y",
100*4882a593Smuzhiyun [IIO_MOD_X_AND_Z] = "x&z",
101*4882a593Smuzhiyun [IIO_MOD_Y_AND_Z] = "y&z",
102*4882a593Smuzhiyun [IIO_MOD_X_AND_Y_AND_Z] = "x&y&z",
103*4882a593Smuzhiyun [IIO_MOD_X_OR_Y] = "x|y",
104*4882a593Smuzhiyun [IIO_MOD_X_OR_Z] = "x|z",
105*4882a593Smuzhiyun [IIO_MOD_Y_OR_Z] = "y|z",
106*4882a593Smuzhiyun [IIO_MOD_X_OR_Y_OR_Z] = "x|y|z",
107*4882a593Smuzhiyun [IIO_MOD_LIGHT_BOTH] = "both",
108*4882a593Smuzhiyun [IIO_MOD_LIGHT_IR] = "ir",
109*4882a593Smuzhiyun [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
110*4882a593Smuzhiyun [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
111*4882a593Smuzhiyun [IIO_MOD_LIGHT_CLEAR] = "clear",
112*4882a593Smuzhiyun [IIO_MOD_LIGHT_RED] = "red",
113*4882a593Smuzhiyun [IIO_MOD_LIGHT_GREEN] = "green",
114*4882a593Smuzhiyun [IIO_MOD_LIGHT_BLUE] = "blue",
115*4882a593Smuzhiyun [IIO_MOD_LIGHT_UV] = "uv",
116*4882a593Smuzhiyun [IIO_MOD_LIGHT_DUV] = "duv",
117*4882a593Smuzhiyun [IIO_MOD_QUATERNION] = "quaternion",
118*4882a593Smuzhiyun [IIO_MOD_TEMP_AMBIENT] = "ambient",
119*4882a593Smuzhiyun [IIO_MOD_TEMP_OBJECT] = "object",
120*4882a593Smuzhiyun [IIO_MOD_NORTH_MAGN] = "from_north_magnetic",
121*4882a593Smuzhiyun [IIO_MOD_NORTH_TRUE] = "from_north_true",
122*4882a593Smuzhiyun [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
123*4882a593Smuzhiyun [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
124*4882a593Smuzhiyun [IIO_MOD_RUNNING] = "running",
125*4882a593Smuzhiyun [IIO_MOD_JOGGING] = "jogging",
126*4882a593Smuzhiyun [IIO_MOD_WALKING] = "walking",
127*4882a593Smuzhiyun [IIO_MOD_STILL] = "still",
128*4882a593Smuzhiyun [IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z] = "sqrt(x^2+y^2+z^2)",
129*4882a593Smuzhiyun [IIO_MOD_I] = "i",
130*4882a593Smuzhiyun [IIO_MOD_Q] = "q",
131*4882a593Smuzhiyun [IIO_MOD_CO2] = "co2",
132*4882a593Smuzhiyun [IIO_MOD_ETHANOL] = "ethanol",
133*4882a593Smuzhiyun [IIO_MOD_H2] = "h2",
134*4882a593Smuzhiyun [IIO_MOD_VOC] = "voc",
135*4882a593Smuzhiyun [IIO_MOD_PM1] = "pm1",
136*4882a593Smuzhiyun [IIO_MOD_PM2P5] = "pm2p5",
137*4882a593Smuzhiyun [IIO_MOD_PM4] = "pm4",
138*4882a593Smuzhiyun [IIO_MOD_PM10] = "pm10",
139*4882a593Smuzhiyun [IIO_MOD_O2] = "o2",
140*4882a593Smuzhiyun };
141*4882a593Smuzhiyun
event_is_known(struct iio_event_data * event)142*4882a593Smuzhiyun static bool event_is_known(struct iio_event_data *event)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun enum iio_chan_type type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
145*4882a593Smuzhiyun enum iio_modifier mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
146*4882a593Smuzhiyun enum iio_event_type ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
147*4882a593Smuzhiyun enum iio_event_direction dir = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun switch (type) {
150*4882a593Smuzhiyun case IIO_VOLTAGE:
151*4882a593Smuzhiyun case IIO_CURRENT:
152*4882a593Smuzhiyun case IIO_POWER:
153*4882a593Smuzhiyun case IIO_ACCEL:
154*4882a593Smuzhiyun case IIO_ANGL_VEL:
155*4882a593Smuzhiyun case IIO_MAGN:
156*4882a593Smuzhiyun case IIO_LIGHT:
157*4882a593Smuzhiyun case IIO_INTENSITY:
158*4882a593Smuzhiyun case IIO_PROXIMITY:
159*4882a593Smuzhiyun case IIO_TEMP:
160*4882a593Smuzhiyun case IIO_INCLI:
161*4882a593Smuzhiyun case IIO_ROT:
162*4882a593Smuzhiyun case IIO_ANGL:
163*4882a593Smuzhiyun case IIO_TIMESTAMP:
164*4882a593Smuzhiyun case IIO_CAPACITANCE:
165*4882a593Smuzhiyun case IIO_ALTVOLTAGE:
166*4882a593Smuzhiyun case IIO_CCT:
167*4882a593Smuzhiyun case IIO_PRESSURE:
168*4882a593Smuzhiyun case IIO_HUMIDITYRELATIVE:
169*4882a593Smuzhiyun case IIO_ACTIVITY:
170*4882a593Smuzhiyun case IIO_STEPS:
171*4882a593Smuzhiyun case IIO_ENERGY:
172*4882a593Smuzhiyun case IIO_DISTANCE:
173*4882a593Smuzhiyun case IIO_VELOCITY:
174*4882a593Smuzhiyun case IIO_CONCENTRATION:
175*4882a593Smuzhiyun case IIO_RESISTANCE:
176*4882a593Smuzhiyun case IIO_PH:
177*4882a593Smuzhiyun case IIO_UVINDEX:
178*4882a593Smuzhiyun case IIO_GRAVITY:
179*4882a593Smuzhiyun case IIO_POSITIONRELATIVE:
180*4882a593Smuzhiyun case IIO_PHASE:
181*4882a593Smuzhiyun case IIO_MASSCONCENTRATION:
182*4882a593Smuzhiyun break;
183*4882a593Smuzhiyun default:
184*4882a593Smuzhiyun return false;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun switch (mod) {
188*4882a593Smuzhiyun case IIO_NO_MOD:
189*4882a593Smuzhiyun case IIO_MOD_X:
190*4882a593Smuzhiyun case IIO_MOD_Y:
191*4882a593Smuzhiyun case IIO_MOD_Z:
192*4882a593Smuzhiyun case IIO_MOD_X_AND_Y:
193*4882a593Smuzhiyun case IIO_MOD_X_AND_Z:
194*4882a593Smuzhiyun case IIO_MOD_Y_AND_Z:
195*4882a593Smuzhiyun case IIO_MOD_X_AND_Y_AND_Z:
196*4882a593Smuzhiyun case IIO_MOD_X_OR_Y:
197*4882a593Smuzhiyun case IIO_MOD_X_OR_Z:
198*4882a593Smuzhiyun case IIO_MOD_Y_OR_Z:
199*4882a593Smuzhiyun case IIO_MOD_X_OR_Y_OR_Z:
200*4882a593Smuzhiyun case IIO_MOD_LIGHT_BOTH:
201*4882a593Smuzhiyun case IIO_MOD_LIGHT_IR:
202*4882a593Smuzhiyun case IIO_MOD_ROOT_SUM_SQUARED_X_Y:
203*4882a593Smuzhiyun case IIO_MOD_SUM_SQUARED_X_Y_Z:
204*4882a593Smuzhiyun case IIO_MOD_LIGHT_CLEAR:
205*4882a593Smuzhiyun case IIO_MOD_LIGHT_RED:
206*4882a593Smuzhiyun case IIO_MOD_LIGHT_GREEN:
207*4882a593Smuzhiyun case IIO_MOD_LIGHT_BLUE:
208*4882a593Smuzhiyun case IIO_MOD_LIGHT_UV:
209*4882a593Smuzhiyun case IIO_MOD_LIGHT_DUV:
210*4882a593Smuzhiyun case IIO_MOD_QUATERNION:
211*4882a593Smuzhiyun case IIO_MOD_TEMP_AMBIENT:
212*4882a593Smuzhiyun case IIO_MOD_TEMP_OBJECT:
213*4882a593Smuzhiyun case IIO_MOD_NORTH_MAGN:
214*4882a593Smuzhiyun case IIO_MOD_NORTH_TRUE:
215*4882a593Smuzhiyun case IIO_MOD_NORTH_MAGN_TILT_COMP:
216*4882a593Smuzhiyun case IIO_MOD_NORTH_TRUE_TILT_COMP:
217*4882a593Smuzhiyun case IIO_MOD_RUNNING:
218*4882a593Smuzhiyun case IIO_MOD_JOGGING:
219*4882a593Smuzhiyun case IIO_MOD_WALKING:
220*4882a593Smuzhiyun case IIO_MOD_STILL:
221*4882a593Smuzhiyun case IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z:
222*4882a593Smuzhiyun case IIO_MOD_I:
223*4882a593Smuzhiyun case IIO_MOD_Q:
224*4882a593Smuzhiyun case IIO_MOD_CO2:
225*4882a593Smuzhiyun case IIO_MOD_ETHANOL:
226*4882a593Smuzhiyun case IIO_MOD_H2:
227*4882a593Smuzhiyun case IIO_MOD_VOC:
228*4882a593Smuzhiyun case IIO_MOD_PM1:
229*4882a593Smuzhiyun case IIO_MOD_PM2P5:
230*4882a593Smuzhiyun case IIO_MOD_PM4:
231*4882a593Smuzhiyun case IIO_MOD_PM10:
232*4882a593Smuzhiyun case IIO_MOD_O2:
233*4882a593Smuzhiyun break;
234*4882a593Smuzhiyun default:
235*4882a593Smuzhiyun return false;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun switch (ev_type) {
239*4882a593Smuzhiyun case IIO_EV_TYPE_THRESH:
240*4882a593Smuzhiyun case IIO_EV_TYPE_MAG:
241*4882a593Smuzhiyun case IIO_EV_TYPE_ROC:
242*4882a593Smuzhiyun case IIO_EV_TYPE_THRESH_ADAPTIVE:
243*4882a593Smuzhiyun case IIO_EV_TYPE_MAG_ADAPTIVE:
244*4882a593Smuzhiyun case IIO_EV_TYPE_CHANGE:
245*4882a593Smuzhiyun break;
246*4882a593Smuzhiyun default:
247*4882a593Smuzhiyun return false;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun switch (dir) {
251*4882a593Smuzhiyun case IIO_EV_DIR_EITHER:
252*4882a593Smuzhiyun case IIO_EV_DIR_RISING:
253*4882a593Smuzhiyun case IIO_EV_DIR_FALLING:
254*4882a593Smuzhiyun case IIO_EV_DIR_NONE:
255*4882a593Smuzhiyun break;
256*4882a593Smuzhiyun default:
257*4882a593Smuzhiyun return false;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun return true;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
print_event(struct iio_event_data * event)263*4882a593Smuzhiyun static void print_event(struct iio_event_data *event)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun enum iio_chan_type type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
266*4882a593Smuzhiyun enum iio_modifier mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
267*4882a593Smuzhiyun enum iio_event_type ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
268*4882a593Smuzhiyun enum iio_event_direction dir = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
269*4882a593Smuzhiyun int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event->id);
270*4882a593Smuzhiyun int chan2 = IIO_EVENT_CODE_EXTRACT_CHAN2(event->id);
271*4882a593Smuzhiyun bool diff = IIO_EVENT_CODE_EXTRACT_DIFF(event->id);
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun if (!event_is_known(event)) {
274*4882a593Smuzhiyun fprintf(stderr, "Unknown event: time: %lld, id: %llx\n",
275*4882a593Smuzhiyun event->timestamp, event->id);
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun return;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun printf("Event: time: %lld, type: %s", event->timestamp,
281*4882a593Smuzhiyun iio_chan_type_name_spec[type]);
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun if (mod != IIO_NO_MOD)
284*4882a593Smuzhiyun printf("(%s)", iio_modifier_names[mod]);
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun if (chan >= 0) {
287*4882a593Smuzhiyun printf(", channel: %d", chan);
288*4882a593Smuzhiyun if (diff && chan2 >= 0)
289*4882a593Smuzhiyun printf("-%d", chan2);
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun printf(", evtype: %s", iio_ev_type_text[ev_type]);
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun if (dir != IIO_EV_DIR_NONE)
295*4882a593Smuzhiyun printf(", direction: %s", iio_ev_dir_text[dir]);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun printf("\n");
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
main(int argc,char ** argv)300*4882a593Smuzhiyun int main(int argc, char **argv)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun struct iio_event_data event;
303*4882a593Smuzhiyun const char *device_name;
304*4882a593Smuzhiyun char *chrdev_name;
305*4882a593Smuzhiyun int ret;
306*4882a593Smuzhiyun int dev_num;
307*4882a593Smuzhiyun int fd, event_fd;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun if (argc <= 1) {
310*4882a593Smuzhiyun fprintf(stderr, "Usage: %s <device_name>\n", argv[0]);
311*4882a593Smuzhiyun return -1;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun device_name = argv[1];
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun dev_num = find_type_by_name(device_name, "iio:device");
317*4882a593Smuzhiyun if (dev_num >= 0) {
318*4882a593Smuzhiyun printf("Found IIO device with name %s with device number %d\n",
319*4882a593Smuzhiyun device_name, dev_num);
320*4882a593Smuzhiyun ret = asprintf(&chrdev_name, "/dev/iio:device%d", dev_num);
321*4882a593Smuzhiyun if (ret < 0)
322*4882a593Smuzhiyun return -ENOMEM;
323*4882a593Smuzhiyun } else {
324*4882a593Smuzhiyun /*
325*4882a593Smuzhiyun * If we can't find an IIO device by name assume device_name is
326*4882a593Smuzhiyun * an IIO chrdev
327*4882a593Smuzhiyun */
328*4882a593Smuzhiyun chrdev_name = strdup(device_name);
329*4882a593Smuzhiyun if (!chrdev_name)
330*4882a593Smuzhiyun return -ENOMEM;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun fd = open(chrdev_name, 0);
334*4882a593Smuzhiyun if (fd == -1) {
335*4882a593Smuzhiyun ret = -errno;
336*4882a593Smuzhiyun fprintf(stderr, "Failed to open %s\n", chrdev_name);
337*4882a593Smuzhiyun goto error_free_chrdev_name;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun ret = ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd);
341*4882a593Smuzhiyun if (ret == -1 || event_fd == -1) {
342*4882a593Smuzhiyun ret = -errno;
343*4882a593Smuzhiyun if (ret == -ENODEV)
344*4882a593Smuzhiyun fprintf(stderr,
345*4882a593Smuzhiyun "This device does not support events\n");
346*4882a593Smuzhiyun else
347*4882a593Smuzhiyun fprintf(stderr, "Failed to retrieve event fd\n");
348*4882a593Smuzhiyun if (close(fd) == -1)
349*4882a593Smuzhiyun perror("Failed to close character device file");
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun goto error_free_chrdev_name;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun if (close(fd) == -1) {
355*4882a593Smuzhiyun ret = -errno;
356*4882a593Smuzhiyun goto error_free_chrdev_name;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun while (true) {
360*4882a593Smuzhiyun ret = read(event_fd, &event, sizeof(event));
361*4882a593Smuzhiyun if (ret == -1) {
362*4882a593Smuzhiyun if (errno == EAGAIN) {
363*4882a593Smuzhiyun fprintf(stderr, "nothing available\n");
364*4882a593Smuzhiyun continue;
365*4882a593Smuzhiyun } else {
366*4882a593Smuzhiyun ret = -errno;
367*4882a593Smuzhiyun perror("Failed to read event from device");
368*4882a593Smuzhiyun break;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun if (ret != sizeof(event)) {
373*4882a593Smuzhiyun fprintf(stderr, "Reading event failed!\n");
374*4882a593Smuzhiyun ret = -EIO;
375*4882a593Smuzhiyun break;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun print_event(&event);
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun if (close(event_fd) == -1)
382*4882a593Smuzhiyun perror("Failed to close event file");
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun error_free_chrdev_name:
385*4882a593Smuzhiyun free(chrdev_name);
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun return ret;
388*4882a593Smuzhiyun }
389