162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/* Industrialio event test code.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (c) 2011-2012 Lars-Peter Clausen <lars@metafoo.de>
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This program is primarily intended as an example application.
762306a36Sopenharmony_ci * Reads the current buffer setup from sysfs and starts a short capture
862306a36Sopenharmony_ci * from the specified device, pretty printing the result after appropriate
962306a36Sopenharmony_ci * conversion.
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * Usage:
1262306a36Sopenharmony_ci *	iio_event_monitor <device_name>
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <unistd.h>
1662306a36Sopenharmony_ci#include <stdlib.h>
1762306a36Sopenharmony_ci#include <dirent.h>
1862306a36Sopenharmony_ci#include <stdbool.h>
1962306a36Sopenharmony_ci#include <stdio.h>
2062306a36Sopenharmony_ci#include <errno.h>
2162306a36Sopenharmony_ci#include <string.h>
2262306a36Sopenharmony_ci#include <poll.h>
2362306a36Sopenharmony_ci#include <fcntl.h>
2462306a36Sopenharmony_ci#include <sys/ioctl.h>
2562306a36Sopenharmony_ci#include "iio_utils.h"
2662306a36Sopenharmony_ci#include <linux/iio/events.h>
2762306a36Sopenharmony_ci#include <linux/iio/types.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic const char * const iio_chan_type_name_spec[] = {
3062306a36Sopenharmony_ci	[IIO_VOLTAGE] = "voltage",
3162306a36Sopenharmony_ci	[IIO_CURRENT] = "current",
3262306a36Sopenharmony_ci	[IIO_POWER] = "power",
3362306a36Sopenharmony_ci	[IIO_ACCEL] = "accel",
3462306a36Sopenharmony_ci	[IIO_ANGL_VEL] = "anglvel",
3562306a36Sopenharmony_ci	[IIO_MAGN] = "magn",
3662306a36Sopenharmony_ci	[IIO_LIGHT] = "illuminance",
3762306a36Sopenharmony_ci	[IIO_INTENSITY] = "intensity",
3862306a36Sopenharmony_ci	[IIO_PROXIMITY] = "proximity",
3962306a36Sopenharmony_ci	[IIO_TEMP] = "temp",
4062306a36Sopenharmony_ci	[IIO_INCLI] = "incli",
4162306a36Sopenharmony_ci	[IIO_ROT] = "rot",
4262306a36Sopenharmony_ci	[IIO_ANGL] = "angl",
4362306a36Sopenharmony_ci	[IIO_TIMESTAMP] = "timestamp",
4462306a36Sopenharmony_ci	[IIO_CAPACITANCE] = "capacitance",
4562306a36Sopenharmony_ci	[IIO_ALTVOLTAGE] = "altvoltage",
4662306a36Sopenharmony_ci	[IIO_CCT] = "cct",
4762306a36Sopenharmony_ci	[IIO_PRESSURE] = "pressure",
4862306a36Sopenharmony_ci	[IIO_HUMIDITYRELATIVE] = "humidityrelative",
4962306a36Sopenharmony_ci	[IIO_ACTIVITY] = "activity",
5062306a36Sopenharmony_ci	[IIO_STEPS] = "steps",
5162306a36Sopenharmony_ci	[IIO_ENERGY] = "energy",
5262306a36Sopenharmony_ci	[IIO_DISTANCE] = "distance",
5362306a36Sopenharmony_ci	[IIO_VELOCITY] = "velocity",
5462306a36Sopenharmony_ci	[IIO_CONCENTRATION] = "concentration",
5562306a36Sopenharmony_ci	[IIO_RESISTANCE] = "resistance",
5662306a36Sopenharmony_ci	[IIO_PH] = "ph",
5762306a36Sopenharmony_ci	[IIO_UVINDEX] = "uvindex",
5862306a36Sopenharmony_ci	[IIO_GRAVITY] = "gravity",
5962306a36Sopenharmony_ci	[IIO_POSITIONRELATIVE] = "positionrelative",
6062306a36Sopenharmony_ci	[IIO_PHASE] = "phase",
6162306a36Sopenharmony_ci	[IIO_MASSCONCENTRATION] = "massconcentration",
6262306a36Sopenharmony_ci};
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistatic const char * const iio_ev_type_text[] = {
6562306a36Sopenharmony_ci	[IIO_EV_TYPE_THRESH] = "thresh",
6662306a36Sopenharmony_ci	[IIO_EV_TYPE_MAG] = "mag",
6762306a36Sopenharmony_ci	[IIO_EV_TYPE_ROC] = "roc",
6862306a36Sopenharmony_ci	[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
6962306a36Sopenharmony_ci	[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
7062306a36Sopenharmony_ci	[IIO_EV_TYPE_CHANGE] = "change",
7162306a36Sopenharmony_ci	[IIO_EV_TYPE_MAG_REFERENCED] = "mag_referenced",
7262306a36Sopenharmony_ci	[IIO_EV_TYPE_GESTURE] = "gesture",
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic const char * const iio_ev_dir_text[] = {
7662306a36Sopenharmony_ci	[IIO_EV_DIR_EITHER] = "either",
7762306a36Sopenharmony_ci	[IIO_EV_DIR_RISING] = "rising",
7862306a36Sopenharmony_ci	[IIO_EV_DIR_FALLING] = "falling",
7962306a36Sopenharmony_ci	[IIO_EV_DIR_SINGLETAP] = "singletap",
8062306a36Sopenharmony_ci	[IIO_EV_DIR_DOUBLETAP] = "doubletap",
8162306a36Sopenharmony_ci};
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cistatic const char * const iio_modifier_names[] = {
8462306a36Sopenharmony_ci	[IIO_MOD_X] = "x",
8562306a36Sopenharmony_ci	[IIO_MOD_Y] = "y",
8662306a36Sopenharmony_ci	[IIO_MOD_Z] = "z",
8762306a36Sopenharmony_ci	[IIO_MOD_X_AND_Y] = "x&y",
8862306a36Sopenharmony_ci	[IIO_MOD_X_AND_Z] = "x&z",
8962306a36Sopenharmony_ci	[IIO_MOD_Y_AND_Z] = "y&z",
9062306a36Sopenharmony_ci	[IIO_MOD_X_AND_Y_AND_Z] = "x&y&z",
9162306a36Sopenharmony_ci	[IIO_MOD_X_OR_Y] = "x|y",
9262306a36Sopenharmony_ci	[IIO_MOD_X_OR_Z] = "x|z",
9362306a36Sopenharmony_ci	[IIO_MOD_Y_OR_Z] = "y|z",
9462306a36Sopenharmony_ci	[IIO_MOD_X_OR_Y_OR_Z] = "x|y|z",
9562306a36Sopenharmony_ci	[IIO_MOD_LIGHT_BOTH] = "both",
9662306a36Sopenharmony_ci	[IIO_MOD_LIGHT_IR] = "ir",
9762306a36Sopenharmony_ci	[IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
9862306a36Sopenharmony_ci	[IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
9962306a36Sopenharmony_ci	[IIO_MOD_LIGHT_CLEAR] = "clear",
10062306a36Sopenharmony_ci	[IIO_MOD_LIGHT_RED] = "red",
10162306a36Sopenharmony_ci	[IIO_MOD_LIGHT_GREEN] = "green",
10262306a36Sopenharmony_ci	[IIO_MOD_LIGHT_BLUE] = "blue",
10362306a36Sopenharmony_ci	[IIO_MOD_LIGHT_UV] = "uv",
10462306a36Sopenharmony_ci	[IIO_MOD_LIGHT_DUV] = "duv",
10562306a36Sopenharmony_ci	[IIO_MOD_QUATERNION] = "quaternion",
10662306a36Sopenharmony_ci	[IIO_MOD_TEMP_AMBIENT] = "ambient",
10762306a36Sopenharmony_ci	[IIO_MOD_TEMP_OBJECT] = "object",
10862306a36Sopenharmony_ci	[IIO_MOD_NORTH_MAGN] = "from_north_magnetic",
10962306a36Sopenharmony_ci	[IIO_MOD_NORTH_TRUE] = "from_north_true",
11062306a36Sopenharmony_ci	[IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
11162306a36Sopenharmony_ci	[IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
11262306a36Sopenharmony_ci	[IIO_MOD_RUNNING] = "running",
11362306a36Sopenharmony_ci	[IIO_MOD_JOGGING] = "jogging",
11462306a36Sopenharmony_ci	[IIO_MOD_WALKING] = "walking",
11562306a36Sopenharmony_ci	[IIO_MOD_STILL] = "still",
11662306a36Sopenharmony_ci	[IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z] = "sqrt(x^2+y^2+z^2)",
11762306a36Sopenharmony_ci	[IIO_MOD_I] = "i",
11862306a36Sopenharmony_ci	[IIO_MOD_Q] = "q",
11962306a36Sopenharmony_ci	[IIO_MOD_CO2] = "co2",
12062306a36Sopenharmony_ci	[IIO_MOD_ETHANOL] = "ethanol",
12162306a36Sopenharmony_ci	[IIO_MOD_H2] = "h2",
12262306a36Sopenharmony_ci	[IIO_MOD_VOC] = "voc",
12362306a36Sopenharmony_ci	[IIO_MOD_PM1] = "pm1",
12462306a36Sopenharmony_ci	[IIO_MOD_PM2P5] = "pm2p5",
12562306a36Sopenharmony_ci	[IIO_MOD_PM4] = "pm4",
12662306a36Sopenharmony_ci	[IIO_MOD_PM10] = "pm10",
12762306a36Sopenharmony_ci	[IIO_MOD_O2] = "o2",
12862306a36Sopenharmony_ci	[IIO_MOD_LINEAR_X] = "linear_x",
12962306a36Sopenharmony_ci	[IIO_MOD_LINEAR_Y] = "linear_y",
13062306a36Sopenharmony_ci	[IIO_MOD_LINEAR_Z] = "linear_z",
13162306a36Sopenharmony_ci	[IIO_MOD_PITCH] = "pitch",
13262306a36Sopenharmony_ci	[IIO_MOD_YAW] = "yaw",
13362306a36Sopenharmony_ci	[IIO_MOD_ROLL] = "roll",
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic bool event_is_known(struct iio_event_data *event)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	enum iio_chan_type type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
13962306a36Sopenharmony_ci	enum iio_modifier mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
14062306a36Sopenharmony_ci	enum iio_event_type ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
14162306a36Sopenharmony_ci	enum iio_event_direction dir = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	switch (type) {
14462306a36Sopenharmony_ci	case IIO_VOLTAGE:
14562306a36Sopenharmony_ci	case IIO_CURRENT:
14662306a36Sopenharmony_ci	case IIO_POWER:
14762306a36Sopenharmony_ci	case IIO_ACCEL:
14862306a36Sopenharmony_ci	case IIO_ANGL_VEL:
14962306a36Sopenharmony_ci	case IIO_MAGN:
15062306a36Sopenharmony_ci	case IIO_LIGHT:
15162306a36Sopenharmony_ci	case IIO_INTENSITY:
15262306a36Sopenharmony_ci	case IIO_PROXIMITY:
15362306a36Sopenharmony_ci	case IIO_TEMP:
15462306a36Sopenharmony_ci	case IIO_INCLI:
15562306a36Sopenharmony_ci	case IIO_ROT:
15662306a36Sopenharmony_ci	case IIO_ANGL:
15762306a36Sopenharmony_ci	case IIO_TIMESTAMP:
15862306a36Sopenharmony_ci	case IIO_CAPACITANCE:
15962306a36Sopenharmony_ci	case IIO_ALTVOLTAGE:
16062306a36Sopenharmony_ci	case IIO_CCT:
16162306a36Sopenharmony_ci	case IIO_PRESSURE:
16262306a36Sopenharmony_ci	case IIO_HUMIDITYRELATIVE:
16362306a36Sopenharmony_ci	case IIO_ACTIVITY:
16462306a36Sopenharmony_ci	case IIO_STEPS:
16562306a36Sopenharmony_ci	case IIO_ENERGY:
16662306a36Sopenharmony_ci	case IIO_DISTANCE:
16762306a36Sopenharmony_ci	case IIO_VELOCITY:
16862306a36Sopenharmony_ci	case IIO_CONCENTRATION:
16962306a36Sopenharmony_ci	case IIO_RESISTANCE:
17062306a36Sopenharmony_ci	case IIO_PH:
17162306a36Sopenharmony_ci	case IIO_UVINDEX:
17262306a36Sopenharmony_ci	case IIO_GRAVITY:
17362306a36Sopenharmony_ci	case IIO_POSITIONRELATIVE:
17462306a36Sopenharmony_ci	case IIO_PHASE:
17562306a36Sopenharmony_ci	case IIO_MASSCONCENTRATION:
17662306a36Sopenharmony_ci		break;
17762306a36Sopenharmony_ci	default:
17862306a36Sopenharmony_ci		return false;
17962306a36Sopenharmony_ci	}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	switch (mod) {
18262306a36Sopenharmony_ci	case IIO_NO_MOD:
18362306a36Sopenharmony_ci	case IIO_MOD_X:
18462306a36Sopenharmony_ci	case IIO_MOD_Y:
18562306a36Sopenharmony_ci	case IIO_MOD_Z:
18662306a36Sopenharmony_ci	case IIO_MOD_X_AND_Y:
18762306a36Sopenharmony_ci	case IIO_MOD_X_AND_Z:
18862306a36Sopenharmony_ci	case IIO_MOD_Y_AND_Z:
18962306a36Sopenharmony_ci	case IIO_MOD_X_AND_Y_AND_Z:
19062306a36Sopenharmony_ci	case IIO_MOD_X_OR_Y:
19162306a36Sopenharmony_ci	case IIO_MOD_X_OR_Z:
19262306a36Sopenharmony_ci	case IIO_MOD_Y_OR_Z:
19362306a36Sopenharmony_ci	case IIO_MOD_X_OR_Y_OR_Z:
19462306a36Sopenharmony_ci	case IIO_MOD_LIGHT_BOTH:
19562306a36Sopenharmony_ci	case IIO_MOD_LIGHT_IR:
19662306a36Sopenharmony_ci	case IIO_MOD_ROOT_SUM_SQUARED_X_Y:
19762306a36Sopenharmony_ci	case IIO_MOD_SUM_SQUARED_X_Y_Z:
19862306a36Sopenharmony_ci	case IIO_MOD_LIGHT_CLEAR:
19962306a36Sopenharmony_ci	case IIO_MOD_LIGHT_RED:
20062306a36Sopenharmony_ci	case IIO_MOD_LIGHT_GREEN:
20162306a36Sopenharmony_ci	case IIO_MOD_LIGHT_BLUE:
20262306a36Sopenharmony_ci	case IIO_MOD_LIGHT_UV:
20362306a36Sopenharmony_ci	case IIO_MOD_LIGHT_DUV:
20462306a36Sopenharmony_ci	case IIO_MOD_QUATERNION:
20562306a36Sopenharmony_ci	case IIO_MOD_TEMP_AMBIENT:
20662306a36Sopenharmony_ci	case IIO_MOD_TEMP_OBJECT:
20762306a36Sopenharmony_ci	case IIO_MOD_NORTH_MAGN:
20862306a36Sopenharmony_ci	case IIO_MOD_NORTH_TRUE:
20962306a36Sopenharmony_ci	case IIO_MOD_NORTH_MAGN_TILT_COMP:
21062306a36Sopenharmony_ci	case IIO_MOD_NORTH_TRUE_TILT_COMP:
21162306a36Sopenharmony_ci	case IIO_MOD_RUNNING:
21262306a36Sopenharmony_ci	case IIO_MOD_JOGGING:
21362306a36Sopenharmony_ci	case IIO_MOD_WALKING:
21462306a36Sopenharmony_ci	case IIO_MOD_STILL:
21562306a36Sopenharmony_ci	case IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z:
21662306a36Sopenharmony_ci	case IIO_MOD_I:
21762306a36Sopenharmony_ci	case IIO_MOD_Q:
21862306a36Sopenharmony_ci	case IIO_MOD_CO2:
21962306a36Sopenharmony_ci	case IIO_MOD_ETHANOL:
22062306a36Sopenharmony_ci	case IIO_MOD_H2:
22162306a36Sopenharmony_ci	case IIO_MOD_VOC:
22262306a36Sopenharmony_ci	case IIO_MOD_PM1:
22362306a36Sopenharmony_ci	case IIO_MOD_PM2P5:
22462306a36Sopenharmony_ci	case IIO_MOD_PM4:
22562306a36Sopenharmony_ci	case IIO_MOD_PM10:
22662306a36Sopenharmony_ci	case IIO_MOD_O2:
22762306a36Sopenharmony_ci		break;
22862306a36Sopenharmony_ci	default:
22962306a36Sopenharmony_ci		return false;
23062306a36Sopenharmony_ci	}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	switch (ev_type) {
23362306a36Sopenharmony_ci	case IIO_EV_TYPE_THRESH:
23462306a36Sopenharmony_ci	case IIO_EV_TYPE_MAG:
23562306a36Sopenharmony_ci	case IIO_EV_TYPE_ROC:
23662306a36Sopenharmony_ci	case IIO_EV_TYPE_THRESH_ADAPTIVE:
23762306a36Sopenharmony_ci	case IIO_EV_TYPE_MAG_ADAPTIVE:
23862306a36Sopenharmony_ci	case IIO_EV_TYPE_CHANGE:
23962306a36Sopenharmony_ci	case IIO_EV_TYPE_GESTURE:
24062306a36Sopenharmony_ci		break;
24162306a36Sopenharmony_ci	default:
24262306a36Sopenharmony_ci		return false;
24362306a36Sopenharmony_ci	}
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	switch (dir) {
24662306a36Sopenharmony_ci	case IIO_EV_DIR_EITHER:
24762306a36Sopenharmony_ci	case IIO_EV_DIR_RISING:
24862306a36Sopenharmony_ci	case IIO_EV_DIR_FALLING:
24962306a36Sopenharmony_ci	case IIO_EV_DIR_SINGLETAP:
25062306a36Sopenharmony_ci	case IIO_EV_DIR_DOUBLETAP:
25162306a36Sopenharmony_ci	case IIO_EV_DIR_NONE:
25262306a36Sopenharmony_ci		break;
25362306a36Sopenharmony_ci	default:
25462306a36Sopenharmony_ci		return false;
25562306a36Sopenharmony_ci	}
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	return true;
25862306a36Sopenharmony_ci}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_cistatic void print_event(struct iio_event_data *event)
26162306a36Sopenharmony_ci{
26262306a36Sopenharmony_ci	enum iio_chan_type type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
26362306a36Sopenharmony_ci	enum iio_modifier mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
26462306a36Sopenharmony_ci	enum iio_event_type ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
26562306a36Sopenharmony_ci	enum iio_event_direction dir = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
26662306a36Sopenharmony_ci	int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event->id);
26762306a36Sopenharmony_ci	int chan2 = IIO_EVENT_CODE_EXTRACT_CHAN2(event->id);
26862306a36Sopenharmony_ci	bool diff = IIO_EVENT_CODE_EXTRACT_DIFF(event->id);
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	if (!event_is_known(event)) {
27162306a36Sopenharmony_ci		fprintf(stderr, "Unknown event: time: %lld, id: %llx\n",
27262306a36Sopenharmony_ci			event->timestamp, event->id);
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci		return;
27562306a36Sopenharmony_ci	}
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	printf("Event: time: %lld, type: %s", event->timestamp,
27862306a36Sopenharmony_ci	       iio_chan_type_name_spec[type]);
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	if (mod != IIO_NO_MOD)
28162306a36Sopenharmony_ci		printf("(%s)", iio_modifier_names[mod]);
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	if (chan >= 0) {
28462306a36Sopenharmony_ci		printf(", channel: %d", chan);
28562306a36Sopenharmony_ci		if (diff && chan2 >= 0)
28662306a36Sopenharmony_ci			printf("-%d", chan2);
28762306a36Sopenharmony_ci	}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	printf(", evtype: %s", iio_ev_type_text[ev_type]);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	if (dir != IIO_EV_DIR_NONE)
29262306a36Sopenharmony_ci		printf(", direction: %s", iio_ev_dir_text[dir]);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	printf("\n");
29562306a36Sopenharmony_ci	fflush(stdout);
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci/* Enable or disable events in sysfs if the knob is available */
29962306a36Sopenharmony_cistatic void enable_events(char *dev_dir, int enable)
30062306a36Sopenharmony_ci{
30162306a36Sopenharmony_ci	const struct dirent *ent;
30262306a36Sopenharmony_ci	char evdir[256];
30362306a36Sopenharmony_ci	int ret;
30462306a36Sopenharmony_ci	DIR *dp;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	snprintf(evdir, sizeof(evdir), FORMAT_EVENTS_DIR, dev_dir);
30762306a36Sopenharmony_ci	evdir[sizeof(evdir)-1] = '\0';
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	dp = opendir(evdir);
31062306a36Sopenharmony_ci	if (!dp) {
31162306a36Sopenharmony_ci		fprintf(stderr, "Enabling/disabling events: can't open %s\n",
31262306a36Sopenharmony_ci			evdir);
31362306a36Sopenharmony_ci		return;
31462306a36Sopenharmony_ci	}
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	while (ent = readdir(dp), ent) {
31762306a36Sopenharmony_ci		if (iioutils_check_suffix(ent->d_name, "_en")) {
31862306a36Sopenharmony_ci			printf("%sabling: %s\n",
31962306a36Sopenharmony_ci			       enable ? "En" : "Dis",
32062306a36Sopenharmony_ci			       ent->d_name);
32162306a36Sopenharmony_ci			ret = write_sysfs_int(ent->d_name, evdir,
32262306a36Sopenharmony_ci					      enable);
32362306a36Sopenharmony_ci			if (ret < 0)
32462306a36Sopenharmony_ci				fprintf(stderr, "Failed to enable/disable %s\n",
32562306a36Sopenharmony_ci					ent->d_name);
32662306a36Sopenharmony_ci		}
32762306a36Sopenharmony_ci	}
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	if (closedir(dp) == -1) {
33062306a36Sopenharmony_ci		perror("Enabling/disabling channels: "
33162306a36Sopenharmony_ci		       "Failed to close directory");
33262306a36Sopenharmony_ci		return;
33362306a36Sopenharmony_ci	}
33462306a36Sopenharmony_ci}
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ciint main(int argc, char **argv)
33762306a36Sopenharmony_ci{
33862306a36Sopenharmony_ci	struct iio_event_data event;
33962306a36Sopenharmony_ci	const char *device_name;
34062306a36Sopenharmony_ci	char *dev_dir_name = NULL;
34162306a36Sopenharmony_ci	char *chrdev_name;
34262306a36Sopenharmony_ci	int ret;
34362306a36Sopenharmony_ci	int dev_num;
34462306a36Sopenharmony_ci	int fd, event_fd;
34562306a36Sopenharmony_ci	bool all_events = false;
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	if (argc == 2) {
34862306a36Sopenharmony_ci		device_name = argv[1];
34962306a36Sopenharmony_ci	} else if (argc == 3) {
35062306a36Sopenharmony_ci		device_name = argv[2];
35162306a36Sopenharmony_ci		if (!strcmp(argv[1], "-a"))
35262306a36Sopenharmony_ci			all_events = true;
35362306a36Sopenharmony_ci	} else {
35462306a36Sopenharmony_ci		fprintf(stderr,
35562306a36Sopenharmony_ci			"Usage: iio_event_monitor [options] <device_name>\n"
35662306a36Sopenharmony_ci			"Listen and display events from IIO devices\n"
35762306a36Sopenharmony_ci			"  -a         Auto-activate all available events\n");
35862306a36Sopenharmony_ci		return -1;
35962306a36Sopenharmony_ci	}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	dev_num = find_type_by_name(device_name, "iio:device");
36262306a36Sopenharmony_ci	if (dev_num >= 0) {
36362306a36Sopenharmony_ci		printf("Found IIO device with name %s with device number %d\n",
36462306a36Sopenharmony_ci		       device_name, dev_num);
36562306a36Sopenharmony_ci		ret = asprintf(&chrdev_name, "/dev/iio:device%d", dev_num);
36662306a36Sopenharmony_ci		if (ret < 0)
36762306a36Sopenharmony_ci			return -ENOMEM;
36862306a36Sopenharmony_ci		/* Look up sysfs dir as well if we can */
36962306a36Sopenharmony_ci		ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
37062306a36Sopenharmony_ci		if (ret < 0)
37162306a36Sopenharmony_ci			return -ENOMEM;
37262306a36Sopenharmony_ci	} else {
37362306a36Sopenharmony_ci		/*
37462306a36Sopenharmony_ci		 * If we can't find an IIO device by name assume device_name is
37562306a36Sopenharmony_ci		 * an IIO chrdev
37662306a36Sopenharmony_ci		 */
37762306a36Sopenharmony_ci		chrdev_name = strdup(device_name);
37862306a36Sopenharmony_ci		if (!chrdev_name)
37962306a36Sopenharmony_ci			return -ENOMEM;
38062306a36Sopenharmony_ci	}
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	if (all_events && dev_dir_name)
38362306a36Sopenharmony_ci		enable_events(dev_dir_name, 1);
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	fd = open(chrdev_name, 0);
38662306a36Sopenharmony_ci	if (fd == -1) {
38762306a36Sopenharmony_ci		ret = -errno;
38862306a36Sopenharmony_ci		fprintf(stderr, "Failed to open %s\n", chrdev_name);
38962306a36Sopenharmony_ci		goto error_free_chrdev_name;
39062306a36Sopenharmony_ci	}
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	ret = ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd);
39362306a36Sopenharmony_ci	if (ret == -1 || event_fd == -1) {
39462306a36Sopenharmony_ci		ret = -errno;
39562306a36Sopenharmony_ci		if (ret == -ENODEV)
39662306a36Sopenharmony_ci			fprintf(stderr,
39762306a36Sopenharmony_ci				"This device does not support events\n");
39862306a36Sopenharmony_ci		else
39962306a36Sopenharmony_ci			fprintf(stderr, "Failed to retrieve event fd\n");
40062306a36Sopenharmony_ci		if (close(fd) == -1)
40162306a36Sopenharmony_ci			perror("Failed to close character device file");
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci		goto error_free_chrdev_name;
40462306a36Sopenharmony_ci	}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	if (close(fd) == -1)  {
40762306a36Sopenharmony_ci		ret = -errno;
40862306a36Sopenharmony_ci		goto error_free_chrdev_name;
40962306a36Sopenharmony_ci	}
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	while (true) {
41262306a36Sopenharmony_ci		ret = read(event_fd, &event, sizeof(event));
41362306a36Sopenharmony_ci		if (ret == -1) {
41462306a36Sopenharmony_ci			if (errno == EAGAIN) {
41562306a36Sopenharmony_ci				fprintf(stderr, "nothing available\n");
41662306a36Sopenharmony_ci				continue;
41762306a36Sopenharmony_ci			} else {
41862306a36Sopenharmony_ci				ret = -errno;
41962306a36Sopenharmony_ci				perror("Failed to read event from device");
42062306a36Sopenharmony_ci				break;
42162306a36Sopenharmony_ci			}
42262306a36Sopenharmony_ci		}
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci		if (ret != sizeof(event)) {
42562306a36Sopenharmony_ci			fprintf(stderr, "Reading event failed!\n");
42662306a36Sopenharmony_ci			ret = -EIO;
42762306a36Sopenharmony_ci			break;
42862306a36Sopenharmony_ci		}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci		print_event(&event);
43162306a36Sopenharmony_ci	}
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	if (close(event_fd) == -1)
43462306a36Sopenharmony_ci		perror("Failed to close event file");
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_cierror_free_chrdev_name:
43762306a36Sopenharmony_ci	/* Disable events after use */
43862306a36Sopenharmony_ci	if (all_events && dev_dir_name)
43962306a36Sopenharmony_ci		enable_events(dev_dir_name, 0);
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	free(chrdev_name);
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	return ret;
44462306a36Sopenharmony_ci}
445