tools:iio:iio_utils: add missing documentation
[deliverable/linux.git] / tools / iio / iio_utils.c
CommitLineData
c57f1ba7
JC
1/* IIO - useful set of util functionality
2 *
3 * Copyright (c) 2008 Jonathan Cameron
4 *
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.
8 */
37e3be9d
CO
9#ifndef _IIO_UTILS_H
10#define _IIO_UTILS_H
c57f1ba7 11
9d8ae6c8
JC
12#include <string.h>
13#include <stdlib.h>
e58537cc
JC
14#include <stdio.h>
15#include <stdint.h>
bc9f35db 16#include <dirent.h>
bb23378c 17#include <errno.h>
bdcb31d0
RD
18#include <ctype.h>
19#include "iio_utils.h"
c57f1ba7 20
9d8ae6c8
JC
21const char *iio_dir = "/sys/bus/iio/devices/";
22
d9d7b990
IT
23static char * const iio_direction[] = {
24 "in",
25 "out",
26};
27
e58537cc
JC
28/**
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
5dc65d79
HK
32 *
33 * Returns 0 on success, or a negative error code if string extraction failed.
e58537cc 34 **/
bdcb31d0 35int iioutils_break_up_name(const char *full_name,
e58537cc
JC
36 char **generic_name)
37{
38 char *current;
39 char *w, *r;
d9d7b990 40 char *working, *prefix = "";
e9e45b43 41 int i, ret;
d9d7b990
IT
42
43 for (i = 0; i < sizeof(iio_direction) / sizeof(iio_direction[0]); i++)
44 if (!strncmp(full_name, iio_direction[i],
45 strlen(iio_direction[i]))) {
46 prefix = iio_direction[i];
47 break;
48 }
79bdd48a 49
d9d7b990 50 current = strdup(full_name + strlen(prefix) + 1);
e9e45b43
HK
51 if (!current)
52 return -ENOMEM;
53
e58537cc 54 working = strtok(current, "_\0");
53118557
HK
55 if (!working) {
56 free(current);
57 return -EINVAL;
58 }
d9d7b990 59
e58537cc
JC
60 w = working;
61 r = working;
62
8b68bb20 63 while (*r != '\0') {
e58537cc
JC
64 if (!isdigit(*r)) {
65 *w = *r;
66 w++;
67 }
68 r++;
69 }
70 *w = '\0';
e9e45b43 71 ret = asprintf(generic_name, "%s_%s", prefix, working);
e58537cc
JC
72 free(current);
73
e9e45b43 74 return (ret == -1) ? -ENOMEM : 0;
e58537cc
JC
75}
76
e58537cc
JC
77/**
78 * iioutils_get_type() - find and process _type attribute data
79 * @is_signed: output whether channel is signed
80 * @bytes: output how many bytes the channel storage occupies
5dc65d79
HK
81 * @bits_used: output number of valid bits of data
82 * @shift: output amount of bits to shift right data before applying bit mask
e58537cc 83 * @mask: output a bit mask for the raw data
5dc65d79
HK
84 * @be: output if data in big endian
85 * @device_dir: the IIO device directory
e58537cc
JC
86 * @name: the channel name
87 * @generic_name: the channel type name
5dc65d79
HK
88 *
89 * Returns a value >= 0 on success, otherwise a negative error code.
e58537cc 90 **/
bdcb31d0 91int iioutils_get_type(unsigned *is_signed,
e58537cc
JC
92 unsigned *bytes,
93 unsigned *bits_used,
52615d47 94 unsigned *shift,
e58537cc 95 uint64_t *mask,
117cf8b7 96 unsigned *be,
e58537cc
JC
97 const char *device_dir,
98 const char *name,
99 const char *generic_name)
100{
101 FILE *sysfsfp;
102 int ret;
103 DIR *dp;
104 char *scan_el_dir, *builtname, *builtname_generic, *filename = 0;
117cf8b7 105 char signchar, endianchar;
fc7f95a9 106 unsigned padint;
e58537cc
JC
107 const struct dirent *ent;
108
109 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
110 if (ret < 0) {
111 ret = -ENOMEM;
112 goto error_ret;
113 }
114 ret = asprintf(&builtname, FORMAT_TYPE_FILE, name);
115 if (ret < 0) {
116 ret = -ENOMEM;
117 goto error_free_scan_el_dir;
118 }
119 ret = asprintf(&builtname_generic, FORMAT_TYPE_FILE, generic_name);
120 if (ret < 0) {
121 ret = -ENOMEM;
122 goto error_free_builtname;
123 }
124
125 dp = opendir(scan_el_dir);
126 if (dp == NULL) {
127 ret = -errno;
128 goto error_free_builtname_generic;
129 }
53118557 130 ret = -ENOENT;
e58537cc
JC
131 while (ent = readdir(dp), ent != NULL)
132 /*
133 * Do we allow devices to override a generic name with
134 * a specific one?
135 */
136 if ((strcmp(builtname, ent->d_name) == 0) ||
137 (strcmp(builtname_generic, ent->d_name) == 0)) {
138 ret = asprintf(&filename,
139 "%s/%s", scan_el_dir, ent->d_name);
140 if (ret < 0) {
141 ret = -ENOMEM;
142 goto error_closedir;
143 }
144 sysfsfp = fopen(filename, "r");
145 if (sysfsfp == NULL) {
e58537cc 146 ret = -errno;
2b6a6e67 147 printf("failed to open %s\n", filename);
e58537cc
JC
148 goto error_free_filename;
149 }
a7f7c364
JC
150
151 ret = fscanf(sysfsfp,
152 "%ce:%c%u/%u>>%u",
153 &endianchar,
154 &signchar,
155 bits_used,
156 &padint, shift);
157 if (ret < 0) {
578f737d 158 ret = -errno;
2b6a6e67 159 printf("failed to pass scan type description\n");
578f737d 160 goto error_close_sysfsfp;
dc8b5d6e
HK
161 } else if (ret != 5) {
162 ret = -EIO;
163 printf("scan type description didn't match\n");
164 goto error_close_sysfsfp;
a7f7c364 165 }
117cf8b7 166 *be = (endianchar == 'b');
e58537cc 167 *bytes = padint / 8;
fc7f95a9 168 if (*bits_used == 64)
e58537cc
JC
169 *mask = ~0;
170 else
171 *mask = (1 << *bits_used) - 1;
172 if (signchar == 's')
173 *is_signed = 1;
174 else
175 *is_signed = 0;
53118557
HK
176 if (fclose(sysfsfp)) {
177 ret = -errno;
178 printf("Failed to close %s\n", filename);
179 goto error_free_filename;
180 }
181
a7f7c364
JC
182 free(filename);
183
184 filename = 0;
578f737d 185 sysfsfp = 0;
e58537cc 186 }
578f737d
PM
187error_close_sysfsfp:
188 if (sysfsfp)
53118557
HK
189 if (fclose(sysfsfp))
190 perror("iioutils_get_type(): Failed to close file");
191
e58537cc
JC
192error_free_filename:
193 if (filename)
194 free(filename);
195error_closedir:
53118557
HK
196 if (closedir(dp) == -1)
197 perror("iioutils_get_type(): Failed to close directory");
198
e58537cc
JC
199error_free_builtname_generic:
200 free(builtname_generic);
201error_free_builtname:
202 free(builtname);
203error_free_scan_el_dir:
204 free(scan_el_dir);
205error_ret:
206 return ret;
207}
208
5dc65d79
HK
209/**
210 * iioutils_get_param_float() - read a float value from a channel parameter
211 * @output: output the float value
212 * @param_name: the parameter name to read
213 * @device_dir: the IIO device directory in sysfs
214 * @name: the channel name
215 * @generic_name: the channel type name
216 *
217 * Returns a value >= 0 on success, otherwise a negative error code.
218 **/
bdcb31d0 219int iioutils_get_param_float(float *output,
e58537cc
JC
220 const char *param_name,
221 const char *device_dir,
222 const char *name,
223 const char *generic_name)
224{
225 FILE *sysfsfp;
226 int ret;
227 DIR *dp;
228 char *builtname, *builtname_generic;
229 char *filename = NULL;
230 const struct dirent *ent;
231
232 ret = asprintf(&builtname, "%s_%s", name, param_name);
233 if (ret < 0) {
234 ret = -ENOMEM;
235 goto error_ret;
236 }
237 ret = asprintf(&builtname_generic,
238 "%s_%s", generic_name, param_name);
239 if (ret < 0) {
240 ret = -ENOMEM;
241 goto error_free_builtname;
242 }
243 dp = opendir(device_dir);
244 if (dp == NULL) {
245 ret = -errno;
246 goto error_free_builtname_generic;
247 }
53118557 248 ret = -ENOENT;
e58537cc
JC
249 while (ent = readdir(dp), ent != NULL)
250 if ((strcmp(builtname, ent->d_name) == 0) ||
251 (strcmp(builtname_generic, ent->d_name) == 0)) {
252 ret = asprintf(&filename,
253 "%s/%s", device_dir, ent->d_name);
254 if (ret < 0) {
255 ret = -ENOMEM;
256 goto error_closedir;
257 }
258 sysfsfp = fopen(filename, "r");
259 if (!sysfsfp) {
260 ret = -errno;
261 goto error_free_filename;
262 }
53118557
HK
263 errno = 0;
264 if (fscanf(sysfsfp, "%f", output) != 1)
265 ret = errno ? -errno : -ENODATA;
266
e58537cc
JC
267 break;
268 }
269error_free_filename:
270 if (filename)
271 free(filename);
272error_closedir:
53118557
HK
273 if (closedir(dp) == -1)
274 perror("iioutils_get_param_float(): Failed to close directory");
275
e58537cc
JC
276error_free_builtname_generic:
277 free(builtname_generic);
278error_free_builtname:
279 free(builtname);
280error_ret:
281 return ret;
282}
283
8b68bb20 284/**
5dc65d79
HK
285 * bsort_channel_array_by_index() - sort the array in index order
286 * @ci_array: the iio_channel_info array to be sorted
287 * @cnt: the amount of array elements
8b68bb20
MH
288 **/
289
bdcb31d0 290void bsort_channel_array_by_index(struct iio_channel_info **ci_array,
8b68bb20
MH
291 int cnt)
292{
293
294 struct iio_channel_info temp;
295 int x, y;
296
297 for (x = 0; x < cnt; x++)
298 for (y = 0; y < (cnt - 1); y++)
299 if ((*ci_array)[y].index > (*ci_array)[y+1].index) {
300 temp = (*ci_array)[y + 1];
301 (*ci_array)[y + 1] = (*ci_array)[y];
302 (*ci_array)[y] = temp;
303 }
304}
e58537cc
JC
305
306/**
307 * build_channel_array() - function to figure out what channels are present
308 * @device_dir: the IIO device directory in sysfs
5dc65d79
HK
309 * @ci_array: output the resulting array of iio_channel_info
310 * @counter: output the amount of array elements
311 *
312 * Returns 0 on success, otherwise a negative error code.
e58537cc 313 **/
bdcb31d0 314int build_channel_array(const char *device_dir,
e58537cc
JC
315 struct iio_channel_info **ci_array,
316 int *counter)
317{
318 DIR *dp;
319 FILE *sysfsfp;
10937921 320 int count, i;
e58537cc
JC
321 struct iio_channel_info *current;
322 int ret;
323 const struct dirent *ent;
324 char *scan_el_dir;
325 char *filename;
326
327 *counter = 0;
328 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
329 if (ret < 0) {
330 ret = -ENOMEM;
331 goto error_ret;
332 }
333 dp = opendir(scan_el_dir);
334 if (dp == NULL) {
335 ret = -errno;
336 goto error_free_name;
337 }
338 while (ent = readdir(dp), ent != NULL)
339 if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
340 "_en") == 0) {
341 ret = asprintf(&filename,
342 "%s/%s", scan_el_dir, ent->d_name);
343 if (ret < 0) {
344 ret = -ENOMEM;
345 goto error_close_dir;
346 }
347 sysfsfp = fopen(filename, "r");
348 if (sysfsfp == NULL) {
349 ret = -errno;
350 free(filename);
351 goto error_close_dir;
352 }
53118557
HK
353 errno = 0;
354 if (fscanf(sysfsfp, "%i", &ret) != 1) {
355 ret = errno ? -errno : -ENODATA;
356 if (fclose(sysfsfp))
357 perror("build_channel_array(): Failed to close file");
358
359 free(filename);
360 goto error_close_dir;
361 }
362
e58537cc
JC
363 if (ret == 1)
364 (*counter)++;
53118557
HK
365 if (fclose(sysfsfp)) {
366 ret = -errno;
367 free(filename);
368 goto error_close_dir;
369 }
370
e58537cc
JC
371 free(filename);
372 }
8b68bb20 373 *ci_array = malloc(sizeof(**ci_array) * (*counter));
e58537cc
JC
374 if (*ci_array == NULL) {
375 ret = -ENOMEM;
376 goto error_close_dir;
377 }
378 seekdir(dp, 0);
7ccd4506 379 count = 0;
e58537cc
JC
380 while (ent = readdir(dp), ent != NULL) {
381 if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
382 "_en") == 0) {
66c65d90 383 int current_enabled = 0;
79bdd48a 384
e58537cc
JC
385 current = &(*ci_array)[count++];
386 ret = asprintf(&filename,
387 "%s/%s", scan_el_dir, ent->d_name);
388 if (ret < 0) {
389 ret = -ENOMEM;
390 /* decrement count to avoid freeing name */
391 count--;
392 goto error_cleanup_array;
393 }
394 sysfsfp = fopen(filename, "r");
395 if (sysfsfp == NULL) {
e58537cc 396 ret = -errno;
2b6a6e67 397 free(filename);
121b5e50 398 count--;
e58537cc
JC
399 goto error_cleanup_array;
400 }
53118557
HK
401 errno = 0;
402 if (fscanf(sysfsfp, "%i", &current_enabled) != 1) {
403 ret = errno ? -errno : -ENODATA;
404 free(filename);
405 count--;
406 goto error_cleanup_array;
407 }
408
409 if (fclose(sysfsfp)) {
410 ret = -errno;
411 free(filename);
412 count--;
413 goto error_cleanup_array;
414 }
8b68bb20 415
66c65d90 416 if (!current_enabled) {
8b68bb20
MH
417 free(filename);
418 count--;
419 continue;
420 }
421
e58537cc
JC
422 current->scale = 1.0;
423 current->offset = 0;
424 current->name = strndup(ent->d_name,
425 strlen(ent->d_name) -
426 strlen("_en"));
427 if (current->name == NULL) {
428 free(filename);
429 ret = -ENOMEM;
121b5e50 430 count--;
e58537cc
JC
431 goto error_cleanup_array;
432 }
433 /* Get the generic and specific name elements */
434 ret = iioutils_break_up_name(current->name,
435 &current->generic_name);
436 if (ret) {
437 free(filename);
121b5e50
HK
438 free(current->name);
439 count--;
e58537cc
JC
440 goto error_cleanup_array;
441 }
442 ret = asprintf(&filename,
443 "%s/%s_index",
444 scan_el_dir,
445 current->name);
446 if (ret < 0) {
447 free(filename);
448 ret = -ENOMEM;
449 goto error_cleanup_array;
450 }
451 sysfsfp = fopen(filename, "r");
53118557
HK
452 if (sysfsfp == NULL) {
453 ret = -errno;
454 printf("failed to open %s\n", filename);
455 free(filename);
456 goto error_cleanup_array;
457 }
458
459 errno = 0;
460 if (fscanf(sysfsfp, "%u", &current->index) != 1) {
461 ret = errno ? -errno : -ENODATA;
462 if (fclose(sysfsfp))
463 perror("build_channel_array(): Failed to close file");
464
465 free(filename);
466 goto error_cleanup_array;
467 }
468
469 if (fclose(sysfsfp)) {
470 ret = -errno;
471 free(filename);
472 goto error_cleanup_array;
473 }
474
e58537cc
JC
475 free(filename);
476 /* Find the scale */
477 ret = iioutils_get_param_float(&current->scale,
478 "scale",
479 device_dir,
480 current->name,
481 current->generic_name);
482 if (ret < 0)
483 goto error_cleanup_array;
484 ret = iioutils_get_param_float(&current->offset,
485 "offset",
486 device_dir,
487 current->name,
488 current->generic_name);
489 if (ret < 0)
490 goto error_cleanup_array;
491 ret = iioutils_get_type(&current->is_signed,
492 &current->bytes,
493 &current->bits_used,
52615d47 494 &current->shift,
e58537cc 495 &current->mask,
117cf8b7 496 &current->be,
e58537cc
JC
497 device_dir,
498 current->name,
499 current->generic_name);
53118557
HK
500 if (ret < 0)
501 goto error_cleanup_array;
e58537cc
JC
502 }
503 }
8b68bb20 504
53118557
HK
505 if (closedir(dp) == -1) {
506 ret = -errno;
507 goto error_cleanup_array;
508 }
509
66dd08fd 510 free(scan_el_dir);
8b68bb20
MH
511 /* reorder so that the array is in index order */
512 bsort_channel_array_by_index(ci_array, *counter);
e58537cc
JC
513
514 return 0;
515
516error_cleanup_array:
63f05c85 517 for (i = count - 1; i >= 0; i--) {
e58537cc 518 free((*ci_array)[i].name);
63f05c85
HK
519 free((*ci_array)[i].generic_name);
520 }
e58537cc
JC
521 free(*ci_array);
522error_close_dir:
53118557
HK
523 if (dp)
524 if (closedir(dp) == -1)
525 perror("build_channel_array(): Failed to close dir");
526
e58537cc
JC
527error_free_name:
528 free(scan_el_dir);
529error_ret:
530 return ret;
531}
532
096f9b86
HK
533int calc_digits(int num)
534{
535 int count = 0;
536
537 while (num != 0) {
538 num /= 10;
539 count++;
540 }
541
542 return count;
543}
544
9d8ae6c8
JC
545/**
546 * find_type_by_name() - function to match top level types by name
547 * @name: top level type instance name
5dc65d79 548 * @type: the type of top level instance being searched
9d8ae6c8 549 *
5dc65d79
HK
550 * Returns the device number of a matched IIO device on success, otherwise a
551 * negative error code.
9d8ae6c8
JC
552 * Typical types this is used for are device and trigger.
553 **/
bdcb31d0 554int find_type_by_name(const char *name, const char *type)
c57f1ba7 555{
c57f1ba7 556 const struct dirent *ent;
096f9b86 557 int number, numstrlen, ret;
c57f1ba7
JC
558
559 FILE *nameFile;
560 DIR *dp;
9d8ae6c8
JC
561 char thisname[IIO_MAX_NAME_LENGTH];
562 char *filename;
9d8ae6c8 563
c57f1ba7
JC
564 dp = opendir(iio_dir);
565 if (dp == NULL) {
c866ffc7 566 printf("No industrialio devices available\n");
9d8ae6c8 567 return -ENODEV;
c57f1ba7 568 }
9d8ae6c8 569
c57f1ba7 570 while (ent = readdir(dp), ent != NULL) {
c57f1ba7 571 if (strcmp(ent->d_name, ".") != 0 &&
9d8ae6c8
JC
572 strcmp(ent->d_name, "..") != 0 &&
573 strlen(ent->d_name) > strlen(type) &&
574 strncmp(ent->d_name, type, strlen(type)) == 0) {
096f9b86
HK
575 errno = 0;
576 ret = sscanf(ent->d_name + strlen(type), "%d", &number);
577 if (ret < 0) {
578 ret = -errno;
579 printf("failed to read element number\n");
580 goto error_close_dir;
581 } else if (ret != 1) {
582 ret = -EIO;
583 printf("failed to match element number\n");
584 goto error_close_dir;
585 }
586
587 numstrlen = calc_digits(number);
9d8ae6c8
JC
588 /* verify the next character is not a colon */
589 if (strncmp(ent->d_name + strlen(type) + numstrlen,
590 ":",
591 1) != 0) {
592 filename = malloc(strlen(iio_dir)
593 + strlen(type)
9d8ae6c8 594 + numstrlen
b6ee30a2 595 + 6);
a4d429e3 596 if (filename == NULL) {
53118557
HK
597 ret = -ENOMEM;
598 goto error_close_dir;
599 }
600
601 ret = sprintf(filename, "%s%s%d/name", iio_dir,
602 type, number);
603 if (ret < 0) {
604 free(filename);
605 goto error_close_dir;
a4d429e3 606 }
53118557 607
9d8ae6c8 608 nameFile = fopen(filename, "r");
a4d429e3
PM
609 if (!nameFile) {
610 free(filename);
9d8ae6c8 611 continue;
a4d429e3 612 }
9d8ae6c8 613 free(filename);
53118557
HK
614 errno = 0;
615 if (fscanf(nameFile, "%s", thisname) != 1) {
616 ret = errno ? -errno : -ENODATA;
617 goto error_close_dir;
618 }
619
620 if (fclose(nameFile)) {
621 ret = -errno;
622 goto error_close_dir;
623 }
624
a4d429e3 625 if (strcmp(name, thisname) == 0) {
53118557
HK
626 if (closedir(dp) == -1)
627 return -errno;
a4d429e3
PM
628 return number;
629 }
c57f1ba7
JC
630 }
631 }
632 }
53118557
HK
633 if (closedir(dp) == -1)
634 return -errno;
635
9d8ae6c8 636 return -ENODEV;
096f9b86
HK
637
638error_close_dir:
639 if (closedir(dp) == -1)
640 perror("find_type_by_name(): Failed to close directory");
641 return ret;
c57f1ba7
JC
642}
643
2156b179 644static int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
c57f1ba7 645{
11cb454f 646 int ret = 0;
9d8ae6c8
JC
647 FILE *sysfsfp;
648 int test;
649 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
79bdd48a 650
9d8ae6c8
JC
651 if (temp == NULL)
652 return -ENOMEM;
53118557
HK
653 ret = sprintf(temp, "%s/%s", basedir, filename);
654 if (ret < 0)
655 goto error_free;
656
c57f1ba7 657 sysfsfp = fopen(temp, "w");
9d8ae6c8 658 if (sysfsfp == NULL) {
9d8ae6c8 659 ret = -errno;
2b6a6e67 660 printf("failed to open %s\n", temp);
9d8ae6c8
JC
661 goto error_free;
662 }
53118557
HK
663 ret = fprintf(sysfsfp, "%d", val);
664 if (ret < 0) {
665 if (fclose(sysfsfp))
666 perror("_write_sysfs_int(): Failed to close dir");
667
668 goto error_free;
669 }
670
671 if (fclose(sysfsfp)) {
672 ret = -errno;
673 goto error_free;
674 }
675
9d8ae6c8
JC
676 if (verify) {
677 sysfsfp = fopen(temp, "r");
678 if (sysfsfp == NULL) {
9d8ae6c8 679 ret = -errno;
2b6a6e67 680 printf("failed to open %s\n", temp);
9d8ae6c8
JC
681 goto error_free;
682 }
53118557
HK
683 if (fscanf(sysfsfp, "%d", &test) != 1) {
684 ret = errno ? -errno : -ENODATA;
685 if (fclose(sysfsfp))
686 perror("_write_sysfs_int(): Failed to close dir");
687
688 goto error_free;
689 }
690
691 if (fclose(sysfsfp)) {
692 ret = -errno;
693 goto error_free;
694 }
695
9d8ae6c8
JC
696 if (test != val) {
697 printf("Possible failure in int write %d to %s%s\n",
698 val,
699 basedir,
700 filename);
701 ret = -1;
702 }
703 }
704error_free:
705 free(temp);
706 return ret;
707}
708
5dc65d79
HK
709/**
710 * write_sysfs_int() - write an integer value to a sysfs file
711 * @filename: name of the file to write to
712 * @basedir: the sysfs directory in which the file is to be found
713 * @val: integer value to write to file
714 *
715 * Returns a value >= 0 on success, otherwise a negative error code.
716 **/
9d8ae6c8
JC
717int write_sysfs_int(char *filename, char *basedir, int val)
718{
719 return _write_sysfs_int(filename, basedir, val, 0);
c57f1ba7
JC
720}
721
5dc65d79
HK
722/**
723 * write_sysfs_int_and_verify() - write an integer value to a sysfs file
724 * and verify
725 * @filename: name of the file to write to
726 * @basedir: the sysfs directory in which the file is to be found
727 * @val: integer value to write to file
728 *
729 * Returns a value >= 0 on success, otherwise a negative error code.
730 **/
eaf86ff9 731int write_sysfs_int_and_verify(char *filename, char *basedir, int val)
9d8ae6c8
JC
732{
733 return _write_sysfs_int(filename, basedir, val, 1);
734}
735
2156b179
HK
736static int _write_sysfs_string(char *filename, char *basedir, char *val,
737 int verify)
eaf86ff9 738{
e58537cc 739 int ret = 0;
eaf86ff9 740 FILE *sysfsfp;
9d8ae6c8 741 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
79bdd48a 742
9d8ae6c8
JC
743 if (temp == NULL) {
744 printf("Memory allocation failed\n");
745 return -ENOMEM;
746 }
53118557
HK
747 ret = sprintf(temp, "%s/%s", basedir, filename);
748 if (ret < 0)
749 goto error_free;
750
eaf86ff9 751 sysfsfp = fopen(temp, "w");
9d8ae6c8 752 if (sysfsfp == NULL) {
9d8ae6c8 753 ret = -errno;
2b6a6e67 754 printf("Could not open %s\n", temp);
9d8ae6c8
JC
755 goto error_free;
756 }
53118557
HK
757 ret = fprintf(sysfsfp, "%s", val);
758 if (ret < 0) {
759 if (fclose(sysfsfp))
760 perror("_write_sysfs_string(): Failed to close dir");
761
762 goto error_free;
763 }
764
765 if (fclose(sysfsfp)) {
766 ret = -errno;
767 goto error_free;
768 }
769
9d8ae6c8
JC
770 if (verify) {
771 sysfsfp = fopen(temp, "r");
772 if (sysfsfp == NULL) {
773 ret = -errno;
2b6a6e67 774 printf("could not open file to verify\n");
9d8ae6c8
JC
775 goto error_free;
776 }
53118557
HK
777 if (fscanf(sysfsfp, "%s", temp) != 1) {
778 ret = errno ? -errno : -ENODATA;
779 if (fclose(sysfsfp))
780 perror("_write_sysfs_string(): Failed to close dir");
781
782 goto error_free;
783 }
784
785 if (fclose(sysfsfp)) {
786 ret = -errno;
787 goto error_free;
788 }
789
9d8ae6c8
JC
790 if (strcmp(temp, val) != 0) {
791 printf("Possible failure in string write of %s "
792 "Should be %s "
25985edc 793 "written to %s\%s\n",
9d8ae6c8
JC
794 temp,
795 val,
796 basedir,
797 filename);
798 ret = -1;
799 }
eaf86ff9 800 }
9d8ae6c8
JC
801error_free:
802 free(temp);
eaf86ff9 803
9d8ae6c8 804 return ret;
eaf86ff9 805}
e58537cc 806
c57f1ba7
JC
807/**
808 * write_sysfs_string_and_verify() - string write, readback and verify
809 * @filename: name of file to write to
810 * @basedir: the sysfs directory in which the file is to be found
811 * @val: the string to write
5dc65d79
HK
812 *
813 * Returns a value >= 0 on success, otherwise a negative error code.
c57f1ba7
JC
814 **/
815int write_sysfs_string_and_verify(char *filename, char *basedir, char *val)
816{
9d8ae6c8
JC
817 return _write_sysfs_string(filename, basedir, val, 1);
818}
c57f1ba7 819
5dc65d79
HK
820/**
821 * write_sysfs_string() - write string to a sysfs file
822 * @filename: name of file to write to
823 * @basedir: the sysfs directory in which the file is to be found
824 * @val: the string to write
825 *
826 * Returns a value >= 0 on success, otherwise a negative error code.
827 **/
9d8ae6c8
JC
828int write_sysfs_string(char *filename, char *basedir, char *val)
829{
830 return _write_sysfs_string(filename, basedir, val, 0);
c57f1ba7
JC
831}
832
5dc65d79
HK
833/**
834 * read_sysfs_posint() - read an integer value from file
835 * @filename: name of file to read from
836 * @basedir: the sysfs directory in which the file is to be found
837 *
838 * Returns the read integer value >= 0 on success, otherwise a negative error
839 * code.
840 **/
c57f1ba7
JC
841int read_sysfs_posint(char *filename, char *basedir)
842{
843 int ret;
844 FILE *sysfsfp;
9d8ae6c8 845 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
79bdd48a 846
9d8ae6c8
JC
847 if (temp == NULL) {
848 printf("Memory allocation failed");
849 return -ENOMEM;
850 }
53118557
HK
851 ret = sprintf(temp, "%s/%s", basedir, filename);
852 if (ret < 0)
853 goto error_free;
854
c57f1ba7 855 sysfsfp = fopen(temp, "r");
9d8ae6c8
JC
856 if (sysfsfp == NULL) {
857 ret = -errno;
858 goto error_free;
859 }
53118557
HK
860 errno = 0;
861 if (fscanf(sysfsfp, "%d\n", &ret) != 1) {
862 ret = errno ? -errno : -ENODATA;
863 if (fclose(sysfsfp))
864 perror("read_sysfs_posint(): Failed to close dir");
865
866 goto error_free;
867 }
868
869 if (fclose(sysfsfp))
870 ret = -errno;
871
9d8ae6c8
JC
872error_free:
873 free(temp);
874 return ret;
875}
876
5dc65d79
HK
877/**
878 * read_sysfs_float() - read a float value from file
879 * @filename: name of file to read from
880 * @basedir: the sysfs directory in which the file is to be found
881 * @val: output the read float value
882 *
883 * Returns a value >= 0 on success, otherwise a negative error code.
884 **/
9d8ae6c8
JC
885int read_sysfs_float(char *filename, char *basedir, float *val)
886{
f5709d5f 887 int ret = 0;
9d8ae6c8
JC
888 FILE *sysfsfp;
889 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
79bdd48a 890
9d8ae6c8
JC
891 if (temp == NULL) {
892 printf("Memory allocation failed");
893 return -ENOMEM;
894 }
53118557
HK
895 ret = sprintf(temp, "%s/%s", basedir, filename);
896 if (ret < 0)
897 goto error_free;
898
9d8ae6c8
JC
899 sysfsfp = fopen(temp, "r");
900 if (sysfsfp == NULL) {
901 ret = -errno;
902 goto error_free;
903 }
53118557
HK
904 errno = 0;
905 if (fscanf(sysfsfp, "%f\n", val) != 1) {
906 ret = errno ? -errno : -ENODATA;
907 if (fclose(sysfsfp))
908 perror("read_sysfs_float(): Failed to close dir");
909
910 goto error_free;
911 }
912
913 if (fclose(sysfsfp))
914 ret = -errno;
915
9d8ae6c8
JC
916error_free:
917 free(temp);
c57f1ba7
JC
918 return ret;
919}
49d916ec 920
5dc65d79
HK
921/**
922 * read_sysfs_string() - read a string from file
923 * @filename: name of file to read from
924 * @basedir: the sysfs directory in which the file is to be found
925 * @str: output the read string
926 *
927 * Returns a value >= 0 on success, otherwise a negative error code.
928 **/
f5709d5f 929int read_sysfs_string(const char *filename, const char *basedir, char *str)
49d916ec 930{
f5709d5f 931 int ret = 0;
49d916ec
MS
932 FILE *sysfsfp;
933 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
79bdd48a 934
49d916ec
MS
935 if (temp == NULL) {
936 printf("Memory allocation failed");
937 return -ENOMEM;
938 }
53118557
HK
939 ret = sprintf(temp, "%s/%s", basedir, filename);
940 if (ret < 0)
941 goto error_free;
942
49d916ec
MS
943 sysfsfp = fopen(temp, "r");
944 if (sysfsfp == NULL) {
945 ret = -errno;
946 goto error_free;
947 }
53118557
HK
948 errno = 0;
949 if (fscanf(sysfsfp, "%s\n", str) != 1) {
950 ret = errno ? -errno : -ENODATA;
951 if (fclose(sysfsfp))
952 perror("read_sysfs_string(): Failed to close dir");
953
954 goto error_free;
955 }
956
957 if (fclose(sysfsfp))
958 ret = -errno;
959
49d916ec
MS
960error_free:
961 free(temp);
962 return ret;
963}
37e3be9d
CO
964
965#endif /* _IIO_UTILS_H */
This page took 0.608719 seconds and 5 git commands to generate.