xref: /OK3568_Linux_fs/kernel/tools/iio/iio_event_monitor.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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