1 /* IIO - useful set of util functionality
3 * Copyright (c) 2008 Jonathan Cameron
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
19 #include "iio_utils.h"
21 const char *iio_dir
= "/sys/bus/iio/devices/";
23 static char * const iio_direction
[] = {
29 * iioutils_break_up_name() - extract generic name from full channel name
30 * @full_name: the full channel name
31 * @generic_name: the output generic channel name
33 int iioutils_break_up_name(const char *full_name
,
38 char *working
, *prefix
= "";
41 for (i
= 0; i
< sizeof(iio_direction
) / sizeof(iio_direction
[0]); i
++)
42 if (!strncmp(full_name
, iio_direction
[i
],
43 strlen(iio_direction
[i
]))) {
44 prefix
= iio_direction
[i
];
48 current
= strdup(full_name
+ strlen(prefix
) + 1);
49 working
= strtok(current
, "_\0");
62 asprintf(generic_name
, "%s_%s", prefix
, working
);
69 * iioutils_get_type() - find and process _type attribute data
70 * @is_signed: output whether channel is signed
71 * @bytes: output how many bytes the channel storage occupies
72 * @mask: output a bit mask for the raw data
74 * @device_dir: the iio device directory
75 * @name: the channel name
76 * @generic_name: the channel type name
78 int iioutils_get_type(unsigned *is_signed
,
84 const char *device_dir
,
86 const char *generic_name
)
91 char *scan_el_dir
, *builtname
, *builtname_generic
, *filename
= 0;
92 char signchar
, endianchar
;
94 const struct dirent
*ent
;
96 ret
= asprintf(&scan_el_dir
, FORMAT_SCAN_ELEMENTS_DIR
, device_dir
);
101 ret
= asprintf(&builtname
, FORMAT_TYPE_FILE
, name
);
104 goto error_free_scan_el_dir
;
106 ret
= asprintf(&builtname_generic
, FORMAT_TYPE_FILE
, generic_name
);
109 goto error_free_builtname
;
112 dp
= opendir(scan_el_dir
);
115 goto error_free_builtname_generic
;
117 while (ent
= readdir(dp
), ent
!= NULL
)
119 * Do we allow devices to override a generic name with
122 if ((strcmp(builtname
, ent
->d_name
) == 0) ||
123 (strcmp(builtname_generic
, ent
->d_name
) == 0)) {
124 ret
= asprintf(&filename
,
125 "%s/%s", scan_el_dir
, ent
->d_name
);
130 sysfsfp
= fopen(filename
, "r");
131 if (sysfsfp
== NULL
) {
132 printf("failed to open %s\n", filename
);
134 goto error_free_filename
;
137 ret
= fscanf(sysfsfp
,
144 printf("failed to pass scan type description\n");
146 goto error_close_sysfsfp
;
148 *be
= (endianchar
== 'b');
150 if (*bits_used
== 64)
153 *mask
= (1 << *bits_used
) - 1;
172 error_free_builtname_generic
:
173 free(builtname_generic
);
174 error_free_builtname
:
176 error_free_scan_el_dir
:
182 int iioutils_get_param_float(float *output
,
183 const char *param_name
,
184 const char *device_dir
,
186 const char *generic_name
)
191 char *builtname
, *builtname_generic
;
192 char *filename
= NULL
;
193 const struct dirent
*ent
;
195 ret
= asprintf(&builtname
, "%s_%s", name
, param_name
);
200 ret
= asprintf(&builtname_generic
,
201 "%s_%s", generic_name
, param_name
);
204 goto error_free_builtname
;
206 dp
= opendir(device_dir
);
209 goto error_free_builtname_generic
;
211 while (ent
= readdir(dp
), ent
!= NULL
)
212 if ((strcmp(builtname
, ent
->d_name
) == 0) ||
213 (strcmp(builtname_generic
, ent
->d_name
) == 0)) {
214 ret
= asprintf(&filename
,
215 "%s/%s", device_dir
, ent
->d_name
);
220 sysfsfp
= fopen(filename
, "r");
223 goto error_free_filename
;
225 fscanf(sysfsfp
, "%f", output
);
233 error_free_builtname_generic
:
234 free(builtname_generic
);
235 error_free_builtname
:
242 * bsort_channel_array_by_index() - reorder so that the array is in index order
246 void bsort_channel_array_by_index(struct iio_channel_info
**ci_array
,
250 struct iio_channel_info temp
;
253 for (x
= 0; x
< cnt
; x
++)
254 for (y
= 0; y
< (cnt
- 1); y
++)
255 if ((*ci_array
)[y
].index
> (*ci_array
)[y
+1].index
) {
256 temp
= (*ci_array
)[y
+ 1];
257 (*ci_array
)[y
+ 1] = (*ci_array
)[y
];
258 (*ci_array
)[y
] = temp
;
263 * build_channel_array() - function to figure out what channels are present
264 * @device_dir: the IIO device directory in sysfs
267 int build_channel_array(const char *device_dir
,
268 struct iio_channel_info
**ci_array
,
274 struct iio_channel_info
*current
;
276 const struct dirent
*ent
;
281 ret
= asprintf(&scan_el_dir
, FORMAT_SCAN_ELEMENTS_DIR
, device_dir
);
286 dp
= opendir(scan_el_dir
);
289 goto error_free_name
;
291 while (ent
= readdir(dp
), ent
!= NULL
)
292 if (strcmp(ent
->d_name
+ strlen(ent
->d_name
) - strlen("_en"),
294 ret
= asprintf(&filename
,
295 "%s/%s", scan_el_dir
, ent
->d_name
);
298 goto error_close_dir
;
300 sysfsfp
= fopen(filename
, "r");
301 if (sysfsfp
== NULL
) {
304 goto error_close_dir
;
306 fscanf(sysfsfp
, "%i", &ret
);
312 *ci_array
= malloc(sizeof(**ci_array
) * (*counter
));
313 if (*ci_array
== NULL
) {
315 goto error_close_dir
;
319 while (ent
= readdir(dp
), ent
!= NULL
) {
320 if (strcmp(ent
->d_name
+ strlen(ent
->d_name
) - strlen("_en"),
322 int current_enabled
= 0;
324 current
= &(*ci_array
)[count
++];
325 ret
= asprintf(&filename
,
326 "%s/%s", scan_el_dir
, ent
->d_name
);
329 /* decrement count to avoid freeing name */
331 goto error_cleanup_array
;
333 sysfsfp
= fopen(filename
, "r");
334 if (sysfsfp
== NULL
) {
337 goto error_cleanup_array
;
339 fscanf(sysfsfp
, "%i", ¤t_enabled
);
342 if (!current_enabled
) {
348 current
->scale
= 1.0;
350 current
->name
= strndup(ent
->d_name
,
351 strlen(ent
->d_name
) -
353 if (current
->name
== NULL
) {
356 goto error_cleanup_array
;
358 /* Get the generic and specific name elements */
359 ret
= iioutils_break_up_name(current
->name
,
360 ¤t
->generic_name
);
363 goto error_cleanup_array
;
365 ret
= asprintf(&filename
,
372 goto error_cleanup_array
;
374 sysfsfp
= fopen(filename
, "r");
375 fscanf(sysfsfp
, "%u", ¤t
->index
);
379 ret
= iioutils_get_param_float(¤t
->scale
,
383 current
->generic_name
);
385 goto error_cleanup_array
;
386 ret
= iioutils_get_param_float(¤t
->offset
,
390 current
->generic_name
);
392 goto error_cleanup_array
;
393 ret
= iioutils_get_type(¤t
->is_signed
,
401 current
->generic_name
);
406 /* reorder so that the array is in index order */
407 bsort_channel_array_by_index(ci_array
, *counter
);
412 for (i
= count
- 1; i
>= 0; i
--)
413 free((*ci_array
)[i
].name
);
424 * find_type_by_name() - function to match top level types by name
425 * @name: top level type instance name
426 * @type: the type of top level instance being sort
428 * Typical types this is used for are device and trigger.
430 int find_type_by_name(const char *name
, const char *type
)
432 const struct dirent
*ent
;
433 int number
, numstrlen
;
437 char thisname
[IIO_MAX_NAME_LENGTH
];
440 dp
= opendir(iio_dir
);
442 printf("No industrialio devices available\n");
446 while (ent
= readdir(dp
), ent
!= NULL
) {
447 if (strcmp(ent
->d_name
, ".") != 0 &&
448 strcmp(ent
->d_name
, "..") != 0 &&
449 strlen(ent
->d_name
) > strlen(type
) &&
450 strncmp(ent
->d_name
, type
, strlen(type
)) == 0) {
451 numstrlen
= sscanf(ent
->d_name
+ strlen(type
),
454 /* verify the next character is not a colon */
455 if (strncmp(ent
->d_name
+ strlen(type
) + numstrlen
,
458 filename
= malloc(strlen(iio_dir
)
462 if (filename
== NULL
) {
466 sprintf(filename
, "%s%s%d/name",
470 nameFile
= fopen(filename
, "r");
476 fscanf(nameFile
, "%s", thisname
);
478 if (strcmp(name
, thisname
) == 0) {
489 int _write_sysfs_int(char *filename
, char *basedir
, int val
, int verify
)
494 char *temp
= malloc(strlen(basedir
) + strlen(filename
) + 2);
498 sprintf(temp
, "%s/%s", basedir
, filename
);
499 sysfsfp
= fopen(temp
, "w");
500 if (sysfsfp
== NULL
) {
501 printf("failed to open %s\n", temp
);
505 fprintf(sysfsfp
, "%d", val
);
508 sysfsfp
= fopen(temp
, "r");
509 if (sysfsfp
== NULL
) {
510 printf("failed to open %s\n", temp
);
514 fscanf(sysfsfp
, "%d", &test
);
517 printf("Possible failure in int write %d to %s%s\n",
529 int write_sysfs_int(char *filename
, char *basedir
, int val
)
531 return _write_sysfs_int(filename
, basedir
, val
, 0);
534 int write_sysfs_int_and_verify(char *filename
, char *basedir
, int val
)
536 return _write_sysfs_int(filename
, basedir
, val
, 1);
539 int _write_sysfs_string(char *filename
, char *basedir
, char *val
, int verify
)
543 char *temp
= malloc(strlen(basedir
) + strlen(filename
) + 2);
546 printf("Memory allocation failed\n");
549 sprintf(temp
, "%s/%s", basedir
, filename
);
550 sysfsfp
= fopen(temp
, "w");
551 if (sysfsfp
== NULL
) {
552 printf("Could not open %s\n", temp
);
556 fprintf(sysfsfp
, "%s", val
);
559 sysfsfp
= fopen(temp
, "r");
560 if (sysfsfp
== NULL
) {
561 printf("could not open file to verify\n");
565 fscanf(sysfsfp
, "%s", temp
);
567 if (strcmp(temp
, val
) != 0) {
568 printf("Possible failure in string write of %s "
570 "written to %s\%s\n",
585 * write_sysfs_string_and_verify() - string write, readback and verify
586 * @filename: name of file to write to
587 * @basedir: the sysfs directory in which the file is to be found
588 * @val: the string to write
590 int write_sysfs_string_and_verify(char *filename
, char *basedir
, char *val
)
592 return _write_sysfs_string(filename
, basedir
, val
, 1);
595 int write_sysfs_string(char *filename
, char *basedir
, char *val
)
597 return _write_sysfs_string(filename
, basedir
, val
, 0);
600 int read_sysfs_posint(char *filename
, char *basedir
)
604 char *temp
= malloc(strlen(basedir
) + strlen(filename
) + 2);
607 printf("Memory allocation failed");
610 sprintf(temp
, "%s/%s", basedir
, filename
);
611 sysfsfp
= fopen(temp
, "r");
612 if (sysfsfp
== NULL
) {
616 fscanf(sysfsfp
, "%d\n", &ret
);
623 int read_sysfs_float(char *filename
, char *basedir
, float *val
)
627 char *temp
= malloc(strlen(basedir
) + strlen(filename
) + 2);
630 printf("Memory allocation failed");
633 sprintf(temp
, "%s/%s", basedir
, filename
);
634 sysfsfp
= fopen(temp
, "r");
635 if (sysfsfp
== NULL
) {
639 fscanf(sysfsfp
, "%f\n", val
);
646 int read_sysfs_string(const char *filename
, const char *basedir
, char *str
)
650 char *temp
= malloc(strlen(basedir
) + strlen(filename
) + 2);
653 printf("Memory allocation failed");
656 sprintf(temp
, "%s/%s", basedir
, filename
);
657 sysfsfp
= fopen(temp
, "r");
658 if (sysfsfp
== NULL
) {
662 fscanf(sysfsfp
, "%s\n", str
);
669 #endif /* _IIO_UTILS_H */