xref: /linux/tools/iio/lsiio.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 /*
2  * Industrial I/O utilities - lsiio.c
3  *
4  * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by
8  * the Free Software Foundation.
9  */
10 
11 #include <string.h>
12 #include <dirent.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <stdint.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/dir.h>
21 #include "iio_utils.h"
22 
23 static enum verbosity {
24 	VERBLEVEL_DEFAULT,	/* 0 gives lspci behaviour */
25 	VERBLEVEL_SENSORS,	/* 1 lists sensors */
26 } verblevel = VERBLEVEL_DEFAULT;
27 
28 const char *type_device = "iio:device";
29 const char *type_trigger = "trigger";
30 
31 static inline int check_prefix(const char *str, const char *prefix)
32 {
33 	return strlen(str) > strlen(prefix) &&
34 	       strncmp(str, prefix, strlen(prefix)) == 0;
35 }
36 
37 static inline int check_postfix(const char *str, const char *postfix)
38 {
39 	return strlen(str) > strlen(postfix) &&
40 	       strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
41 }
42 
43 static int dump_channels(const char *dev_dir_name)
44 {
45 	DIR *dp;
46 	const struct dirent *ent;
47 
48 	dp = opendir(dev_dir_name);
49 	if (!dp)
50 		return -errno;
51 
52 	while (ent = readdir(dp), ent)
53 		if (check_prefix(ent->d_name, "in_") &&
54 		    check_postfix(ent->d_name, "_raw"))
55 			printf("   %-10s\n", ent->d_name);
56 
57 	return (closedir(dp) == -1) ? -errno : 0;
58 }
59 
60 static int dump_one_device(const char *dev_dir_name)
61 {
62 	char name[IIO_MAX_NAME_LENGTH];
63 	int dev_idx;
64 	int ret;
65 
66 	ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i",
67 		     &dev_idx);
68 	if (ret != 1)
69 		return -EINVAL;
70 
71 	ret = read_sysfs_string("name", dev_dir_name, name);
72 	if (ret < 0)
73 		return ret;
74 
75 	printf("Device %03d: %s\n", dev_idx, name);
76 
77 	if (verblevel >= VERBLEVEL_SENSORS)
78 		return dump_channels(dev_dir_name);
79 
80 	return 0;
81 }
82 
83 static int dump_one_trigger(const char *dev_dir_name)
84 {
85 	char name[IIO_MAX_NAME_LENGTH];
86 	int dev_idx;
87 	int ret;
88 
89 	ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
90 		     "%i", &dev_idx);
91 	if (ret != 1)
92 		return -EINVAL;
93 
94 	ret = read_sysfs_string("name", dev_dir_name, name);
95 	if (ret < 0)
96 		return ret;
97 
98 	printf("Trigger %03d: %s\n", dev_idx, name);
99 
100 	return 0;
101 }
102 
103 static int dump_devices(void)
104 {
105 	const struct dirent *ent;
106 	int ret;
107 	DIR *dp;
108 
109 	dp = opendir(iio_dir);
110 	if (!dp) {
111 		fprintf(stderr, "No industrial I/O devices available\n");
112 		return -ENODEV;
113 	}
114 
115 	while (ent = readdir(dp), ent) {
116 		if (check_prefix(ent->d_name, type_device)) {
117 			char *dev_dir_name;
118 
119 			if (asprintf(&dev_dir_name, "%s%s", iio_dir,
120 				     ent->d_name) < 0) {
121 				ret = -ENOMEM;
122 				goto error_close_dir;
123 			}
124 
125 			ret = dump_one_device(dev_dir_name);
126 			if (ret) {
127 				free(dev_dir_name);
128 				goto error_close_dir;
129 			}
130 
131 			free(dev_dir_name);
132 			if (verblevel >= VERBLEVEL_SENSORS)
133 				printf("\n");
134 		}
135 	}
136 	rewinddir(dp);
137 	while (ent = readdir(dp), ent) {
138 		if (check_prefix(ent->d_name, type_trigger)) {
139 			char *dev_dir_name;
140 
141 			if (asprintf(&dev_dir_name, "%s%s", iio_dir,
142 				     ent->d_name) < 0) {
143 				ret = -ENOMEM;
144 				goto error_close_dir;
145 			}
146 
147 			ret = dump_one_trigger(dev_dir_name);
148 			if (ret) {
149 				free(dev_dir_name);
150 				goto error_close_dir;
151 			}
152 
153 			free(dev_dir_name);
154 		}
155 	}
156 
157 	return (closedir(dp) == -1) ? -errno : 0;
158 
159 error_close_dir:
160 	if (closedir(dp) == -1)
161 		perror("dump_devices(): Failed to close directory");
162 
163 	return ret;
164 }
165 
166 int main(int argc, char **argv)
167 {
168 	int c, err = 0;
169 
170 	while ((c = getopt(argc, argv, "v")) != EOF) {
171 		switch (c) {
172 		case 'v':
173 			verblevel++;
174 			break;
175 
176 		case '?':
177 		default:
178 			err++;
179 			break;
180 		}
181 	}
182 	if (err || argc > optind) {
183 		fprintf(stderr, "Usage: lsiio [options]...\n"
184 			"List industrial I/O devices\n"
185 			"  -v  Increase verbosity (may be given multiple times)\n");
186 		exit(1);
187 	}
188 
189 	return dump_devices();
190 }
191