diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:05:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:05:51 +0000 |
commit | 5d1646d90e1f2cceb9f0828f4b28318cd0ec7744 (patch) | |
tree | a94efe259b9009378be6d90eb30d2b019d95c194 /tools/iio/lsiio.c | |
parent | Initial commit. (diff) | |
download | linux-430c2fc249ea5c0536abd21c23382884005c9093.tar.xz linux-430c2fc249ea5c0536abd21c23382884005c9093.zip |
Adding upstream version 5.10.209.upstream/5.10.209upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tools/iio/lsiio.c')
-rw-r--r-- | tools/iio/lsiio.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/tools/iio/lsiio.c b/tools/iio/lsiio.c new file mode 100644 index 000000000..2cf56fb24 --- /dev/null +++ b/tools/iio/lsiio.c @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Industrial I/O utilities - lsiio.c + * + * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de> + */ + +#include <string.h> +#include <dirent.h> +#include <stdio.h> +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/dir.h> +#include "iio_utils.h" + +static enum verbosity { + VERBLEVEL_DEFAULT, /* 0 gives lspci behaviour */ + VERBLEVEL_SENSORS, /* 1 lists sensors */ +} verblevel = VERBLEVEL_DEFAULT; + +const char *type_device = "iio:device"; +const char *type_trigger = "trigger"; + +static inline int check_prefix(const char *str, const char *prefix) +{ + return strlen(str) > strlen(prefix) && + strncmp(str, prefix, strlen(prefix)) == 0; +} + +static inline int check_postfix(const char *str, const char *postfix) +{ + return strlen(str) > strlen(postfix) && + strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; +} + +static int dump_channels(const char *dev_dir_name) +{ + DIR *dp; + const struct dirent *ent; + + dp = opendir(dev_dir_name); + if (!dp) + return -errno; + + while (ent = readdir(dp), ent) + if (check_prefix(ent->d_name, "in_") && + (check_postfix(ent->d_name, "_raw") || + check_postfix(ent->d_name, "_input"))) + printf(" %-10s\n", ent->d_name); + + return (closedir(dp) == -1) ? -errno : 0; +} + +static int dump_one_device(const char *dev_dir_name) +{ + char name[IIO_MAX_NAME_LENGTH]; + int dev_idx; + int ret; + + ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i", + &dev_idx); + if (ret != 1) + return -EINVAL; + + ret = read_sysfs_string("name", dev_dir_name, name); + if (ret < 0) + return ret; + + printf("Device %03d: %s\n", dev_idx, name); + + if (verblevel >= VERBLEVEL_SENSORS) + return dump_channels(dev_dir_name); + + return 0; +} + +static int dump_one_trigger(const char *dev_dir_name) +{ + char name[IIO_MAX_NAME_LENGTH]; + int dev_idx; + int ret; + + ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger), + "%i", &dev_idx); + if (ret != 1) + return -EINVAL; + + ret = read_sysfs_string("name", dev_dir_name, name); + if (ret < 0) + return ret; + + printf("Trigger %03d: %s\n", dev_idx, name); + + return 0; +} + +static int dump_devices(void) +{ + const struct dirent *ent; + int ret; + DIR *dp; + + dp = opendir(iio_dir); + if (!dp) { + fprintf(stderr, "No industrial I/O devices available\n"); + return -ENODEV; + } + + while (ent = readdir(dp), ent) { + if (check_prefix(ent->d_name, type_device)) { + char *dev_dir_name; + + if (asprintf(&dev_dir_name, "%s%s", iio_dir, + ent->d_name) < 0) { + ret = -ENOMEM; + goto error_close_dir; + } + + ret = dump_one_device(dev_dir_name); + if (ret) { + free(dev_dir_name); + goto error_close_dir; + } + + free(dev_dir_name); + if (verblevel >= VERBLEVEL_SENSORS) + printf("\n"); + } + } + rewinddir(dp); + while (ent = readdir(dp), ent) { + if (check_prefix(ent->d_name, type_trigger)) { + char *dev_dir_name; + + if (asprintf(&dev_dir_name, "%s%s", iio_dir, + ent->d_name) < 0) { + ret = -ENOMEM; + goto error_close_dir; + } + + ret = dump_one_trigger(dev_dir_name); + if (ret) { + free(dev_dir_name); + goto error_close_dir; + } + + free(dev_dir_name); + } + } + + return (closedir(dp) == -1) ? -errno : 0; + +error_close_dir: + if (closedir(dp) == -1) + perror("dump_devices(): Failed to close directory"); + + return ret; +} + +int main(int argc, char **argv) +{ + int c, err = 0; + + while ((c = getopt(argc, argv, "v")) != EOF) { + switch (c) { + case 'v': + verblevel++; + break; + + case '?': + default: + err++; + break; + } + } + if (err || argc > optind) { + fprintf(stderr, "Usage: lsiio [options]...\n" + "List industrial I/O devices\n" + " -v Increase verbosity (may be given multiple times)\n"); + exit(1); + } + + return dump_devices(); +} |