Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: event_monitor: Enable events before monitoring

After some painful sessions with a driver that register an
enable/disable sysfs knob (gp2ap002) and manually going
in and enabling the event before monitoring it:

cd /sys/bus/iio/devices/iio\:device2/events
# ls
in_proximity_thresh_either_en
# echo 1 > in_proximity_thresh_either_en

I realized that it's better if the iio_event_monitor is
smart enough to enable all events by itself and disable them
after use, if passed the -a flag familiar from the
iio_generic_buffer tool.

Auto-enabling events depend on the hardware being able
to handle all events at the same time which isn't
necessarily the case, so a command line option is required
for this.

Cc: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20210319135301.542911-1-linus.walleij@linaro.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Linus Walleij and committed by
Jonathan Cameron
e1d392dc 346e19ec

+64 -4
+63 -4
tools/iio/iio_event_monitor.c
··· 14 14 15 15 #include <unistd.h> 16 16 #include <stdlib.h> 17 + #include <dirent.h> 17 18 #include <stdbool.h> 18 19 #include <stdio.h> 19 20 #include <errno.h> ··· 281 280 printf("\n"); 282 281 } 283 282 283 + /* Enable or disable events in sysfs if the knob is available */ 284 + static void enable_events(char *dev_dir, int enable) 285 + { 286 + const struct dirent *ent; 287 + char evdir[256]; 288 + int ret; 289 + DIR *dp; 290 + 291 + snprintf(evdir, sizeof(evdir), FORMAT_EVENTS_DIR, dev_dir); 292 + evdir[sizeof(evdir)-1] = '\0'; 293 + 294 + dp = opendir(evdir); 295 + if (!dp) { 296 + fprintf(stderr, "Enabling/disabling events: can't open %s\n", 297 + evdir); 298 + return; 299 + } 300 + 301 + while (ent = readdir(dp), ent) { 302 + if (iioutils_check_suffix(ent->d_name, "_en")) { 303 + printf("%sabling: %s\n", 304 + enable ? "En" : "Dis", 305 + ent->d_name); 306 + ret = write_sysfs_int(ent->d_name, evdir, 307 + enable); 308 + if (ret < 0) 309 + fprintf(stderr, "Failed to enable/disable %s\n", 310 + ent->d_name); 311 + } 312 + } 313 + 314 + if (closedir(dp) == -1) { 315 + perror("Enabling/disabling channels: " 316 + "Failed to close directory"); 317 + return; 318 + } 319 + } 320 + 284 321 int main(int argc, char **argv) 285 322 { 286 323 struct iio_event_data event; 287 324 const char *device_name; 325 + char *dev_dir_name = NULL; 288 326 char *chrdev_name; 289 327 int ret; 290 328 int dev_num; 291 329 int fd, event_fd; 330 + bool all_events = false; 292 331 293 - if (argc <= 1) { 294 - fprintf(stderr, "Usage: %s <device_name>\n", argv[0]); 332 + if (argc == 2) { 333 + device_name = argv[1]; 334 + } else if (argc == 3) { 335 + device_name = argv[2]; 336 + if (!strcmp(argv[1], "-a")) 337 + all_events = true; 338 + } else { 339 + fprintf(stderr, 340 + "Usage: iio_event_monitor [options] <device_name>\n" 341 + "Listen and display events from IIO devices\n" 342 + " -a Auto-activate all available events\n"); 295 343 return -1; 296 344 } 297 - 298 - device_name = argv[1]; 299 345 300 346 dev_num = find_type_by_name(device_name, "iio:device"); 301 347 if (dev_num >= 0) { 302 348 printf("Found IIO device with name %s with device number %d\n", 303 349 device_name, dev_num); 304 350 ret = asprintf(&chrdev_name, "/dev/iio:device%d", dev_num); 351 + if (ret < 0) 352 + return -ENOMEM; 353 + /* Look up sysfs dir as well if we can */ 354 + ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num); 305 355 if (ret < 0) 306 356 return -ENOMEM; 307 357 } else { ··· 364 312 if (!chrdev_name) 365 313 return -ENOMEM; 366 314 } 315 + 316 + if (all_events && dev_dir_name) 317 + enable_events(dev_dir_name, 1); 367 318 368 319 fd = open(chrdev_name, 0); 369 320 if (fd == -1) { ··· 420 365 perror("Failed to close event file"); 421 366 422 367 error_free_chrdev_name: 368 + /* Disable events after use */ 369 + if (all_events && dev_dir_name) 370 + enable_events(dev_dir_name, 0); 371 + 423 372 free(chrdev_name); 424 373 425 374 return ret;
+1
tools/iio/iio_utils.h
··· 13 13 #define IIO_MAX_NAME_LENGTH 64 14 14 15 15 #define FORMAT_SCAN_ELEMENTS_DIR "%s/buffer%d" 16 + #define FORMAT_EVENTS_DIR "%s/events" 16 17 #define FORMAT_TYPE_FILE "%s_type" 17 18 18 19 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))