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