blob: 35154d60faf6120813bb26bf2477994e66fd259f [file] [log] [blame]
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +01001/* 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 */
9
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010010#include <string.h>
11#include <stdlib.h>
Jonathan Camerone58537c2010-10-08 12:14:14 +010012#include <ctype.h>
13#include <stdio.h>
14#include <stdint.h>
Lars-Peter Clausenbc9f35d2011-10-26 17:27:44 +010015#include <dirent.h>
Peter Meerwaldbb233782012-06-25 23:12:17 +020016#include <errno.h>
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010017
Peter Meerwaldb42f2a02012-06-25 23:12:13 +020018/* Made up value to limit allocation sizes */
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010019#define IIO_MAX_NAME_LENGTH 30
20
Jonathan Cameron1aa04272011-08-30 12:32:47 +010021#define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements"
Jonathan Camerone58537c2010-10-08 12:14:14 +010022#define FORMAT_TYPE_FILE "%s_type"
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010023
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010024const char *iio_dir = "/sys/bus/iio/devices/";
25
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010026/**
Jonathan Camerone58537c2010-10-08 12:14:14 +010027 * iioutils_break_up_name() - extract generic name from full channel name
28 * @full_name: the full channel name
29 * @generic_name: the output generic channel name
30 **/
Peter Meerwald42196d32012-06-25 23:12:15 +020031inline int iioutils_break_up_name(const char *full_name,
Jonathan Camerone58537c2010-10-08 12:14:14 +010032 char **generic_name)
33{
34 char *current;
35 char *w, *r;
36 char *working;
37 current = strdup(full_name);
38 working = strtok(current, "_\0");
39 w = working;
40 r = working;
41
Michael Hennerich8b68bb22011-03-08 08:55:48 +010042 while (*r != '\0') {
Jonathan Camerone58537c2010-10-08 12:14:14 +010043 if (!isdigit(*r)) {
44 *w = *r;
45 w++;
46 }
47 r++;
48 }
49 *w = '\0';
50 *generic_name = strdup(working);
51 free(current);
52
53 return 0;
54}
55
56/**
57 * struct iio_channel_info - information about a given channel
58 * @name: channel name
59 * @generic_name: general name for channel type
60 * @scale: scale factor to be applied for conversion to si units
61 * @offset: offset to be applied for conversion to si units
62 * @index: the channel index in the buffer output
63 * @bytes: number of bytes occupied in buffer output
64 * @mask: a bit mask for the raw output
65 * @is_signed: is the raw value stored signed
66 * @enabled: is this channel enabled
67 **/
68struct iio_channel_info {
69 char *name;
70 char *generic_name;
71 float scale;
72 float offset;
73 unsigned index;
74 unsigned bytes;
75 unsigned bits_used;
Jonathan Cameron52615d42011-05-18 14:41:19 +010076 unsigned shift;
Jonathan Camerone58537c2010-10-08 12:14:14 +010077 uint64_t mask;
Jonathan Cameron117cf8b2011-12-04 19:10:59 +000078 unsigned be;
Jonathan Camerone58537c2010-10-08 12:14:14 +010079 unsigned is_signed;
80 unsigned enabled;
81 unsigned location;
82};
83
84/**
85 * iioutils_get_type() - find and process _type attribute data
86 * @is_signed: output whether channel is signed
87 * @bytes: output how many bytes the channel storage occupies
88 * @mask: output a bit mask for the raw data
Jonathan Cameron117cf8b2011-12-04 19:10:59 +000089 * @be: big endian
Jonathan Camerone58537c2010-10-08 12:14:14 +010090 * @device_dir: the iio device directory
91 * @name: the channel name
92 * @generic_name: the channel type name
93 **/
94inline int iioutils_get_type(unsigned *is_signed,
95 unsigned *bytes,
96 unsigned *bits_used,
Jonathan Cameron52615d42011-05-18 14:41:19 +010097 unsigned *shift,
Jonathan Camerone58537c2010-10-08 12:14:14 +010098 uint64_t *mask,
Jonathan Cameron117cf8b2011-12-04 19:10:59 +000099 unsigned *be,
Jonathan Camerone58537c2010-10-08 12:14:14 +0100100 const char *device_dir,
101 const char *name,
102 const char *generic_name)
103{
104 FILE *sysfsfp;
105 int ret;
106 DIR *dp;
107 char *scan_el_dir, *builtname, *builtname_generic, *filename = 0;
Jonathan Cameron117cf8b2011-12-04 19:10:59 +0000108 char signchar, endianchar;
Michael Hennerichfc7f95a2011-02-24 16:34:54 +0100109 unsigned padint;
Jonathan Camerone58537c2010-10-08 12:14:14 +0100110 const struct dirent *ent;
111
112 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
113 if (ret < 0) {
114 ret = -ENOMEM;
115 goto error_ret;
116 }
117 ret = asprintf(&builtname, FORMAT_TYPE_FILE, name);
118 if (ret < 0) {
119 ret = -ENOMEM;
120 goto error_free_scan_el_dir;
121 }
122 ret = asprintf(&builtname_generic, FORMAT_TYPE_FILE, generic_name);
123 if (ret < 0) {
124 ret = -ENOMEM;
125 goto error_free_builtname;
126 }
127
128 dp = opendir(scan_el_dir);
129 if (dp == NULL) {
130 ret = -errno;
131 goto error_free_builtname_generic;
132 }
133 while (ent = readdir(dp), ent != NULL)
134 /*
135 * Do we allow devices to override a generic name with
136 * a specific one?
137 */
138 if ((strcmp(builtname, ent->d_name) == 0) ||
139 (strcmp(builtname_generic, ent->d_name) == 0)) {
140 ret = asprintf(&filename,
141 "%s/%s", scan_el_dir, ent->d_name);
142 if (ret < 0) {
143 ret = -ENOMEM;
144 goto error_closedir;
145 }
146 sysfsfp = fopen(filename, "r");
147 if (sysfsfp == NULL) {
148 printf("failed to open %s\n", filename);
149 ret = -errno;
150 goto error_free_filename;
151 }
Jonathan Camerona7f7c362011-12-04 19:10:58 +0000152
153 ret = fscanf(sysfsfp,
154 "%ce:%c%u/%u>>%u",
155 &endianchar,
156 &signchar,
157 bits_used,
158 &padint, shift);
159 if (ret < 0) {
160 printf("failed to pass scan type description\n");
Peter Meerwald578f7372012-06-25 23:13:24 +0200161 ret = -errno;
162 goto error_close_sysfsfp;
Jonathan Camerona7f7c362011-12-04 19:10:58 +0000163 }
Jonathan Cameron117cf8b2011-12-04 19:10:59 +0000164 *be = (endianchar == 'b');
Jonathan Camerone58537c2010-10-08 12:14:14 +0100165 *bytes = padint / 8;
Michael Hennerichfc7f95a2011-02-24 16:34:54 +0100166 if (*bits_used == 64)
Jonathan Camerone58537c2010-10-08 12:14:14 +0100167 *mask = ~0;
168 else
169 *mask = (1 << *bits_used) - 1;
170 if (signchar == 's')
171 *is_signed = 1;
172 else
173 *is_signed = 0;
Jonathan Camerona7f7c362011-12-04 19:10:58 +0000174 fclose(sysfsfp);
175 free(filename);
176
177 filename = 0;
Peter Meerwald578f7372012-06-25 23:13:24 +0200178 sysfsfp = 0;
Jonathan Camerone58537c2010-10-08 12:14:14 +0100179 }
Peter Meerwald578f7372012-06-25 23:13:24 +0200180error_close_sysfsfp:
181 if (sysfsfp)
182 fclose(sysfsfp);
Jonathan Camerone58537c2010-10-08 12:14:14 +0100183error_free_filename:
184 if (filename)
185 free(filename);
186error_closedir:
187 closedir(dp);
188error_free_builtname_generic:
189 free(builtname_generic);
190error_free_builtname:
191 free(builtname);
192error_free_scan_el_dir:
193 free(scan_el_dir);
194error_ret:
195 return ret;
196}
197
198inline int iioutils_get_param_float(float *output,
199 const char *param_name,
200 const char *device_dir,
201 const char *name,
202 const char *generic_name)
203{
204 FILE *sysfsfp;
205 int ret;
206 DIR *dp;
207 char *builtname, *builtname_generic;
208 char *filename = NULL;
209 const struct dirent *ent;
210
211 ret = asprintf(&builtname, "%s_%s", name, param_name);
212 if (ret < 0) {
213 ret = -ENOMEM;
214 goto error_ret;
215 }
216 ret = asprintf(&builtname_generic,
217 "%s_%s", generic_name, param_name);
218 if (ret < 0) {
219 ret = -ENOMEM;
220 goto error_free_builtname;
221 }
222 dp = opendir(device_dir);
223 if (dp == NULL) {
224 ret = -errno;
225 goto error_free_builtname_generic;
226 }
227 while (ent = readdir(dp), ent != NULL)
228 if ((strcmp(builtname, ent->d_name) == 0) ||
229 (strcmp(builtname_generic, ent->d_name) == 0)) {
230 ret = asprintf(&filename,
231 "%s/%s", device_dir, ent->d_name);
232 if (ret < 0) {
233 ret = -ENOMEM;
234 goto error_closedir;
235 }
236 sysfsfp = fopen(filename, "r");
237 if (!sysfsfp) {
238 ret = -errno;
239 goto error_free_filename;
240 }
241 fscanf(sysfsfp, "%f", output);
242 break;
243 }
244error_free_filename:
245 if (filename)
246 free(filename);
247error_closedir:
248 closedir(dp);
249error_free_builtname_generic:
250 free(builtname_generic);
251error_free_builtname:
252 free(builtname);
253error_ret:
254 return ret;
255}
256
Michael Hennerich8b68bb22011-03-08 08:55:48 +0100257/**
258 * bsort_channel_array_by_index() - reorder so that the array is in index order
259 *
260 **/
261
262inline void bsort_channel_array_by_index(struct iio_channel_info **ci_array,
263 int cnt)
264{
265
266 struct iio_channel_info temp;
267 int x, y;
268
269 for (x = 0; x < cnt; x++)
270 for (y = 0; y < (cnt - 1); y++)
271 if ((*ci_array)[y].index > (*ci_array)[y+1].index) {
272 temp = (*ci_array)[y + 1];
273 (*ci_array)[y + 1] = (*ci_array)[y];
274 (*ci_array)[y] = temp;
275 }
276}
Jonathan Camerone58537c2010-10-08 12:14:14 +0100277
278/**
279 * build_channel_array() - function to figure out what channels are present
280 * @device_dir: the IIO device directory in sysfs
281 * @
282 **/
283inline int build_channel_array(const char *device_dir,
284 struct iio_channel_info **ci_array,
285 int *counter)
286{
287 DIR *dp;
288 FILE *sysfsfp;
Peter Meerwald10937922012-06-25 23:12:12 +0200289 int count, i;
Jonathan Camerone58537c2010-10-08 12:14:14 +0100290 struct iio_channel_info *current;
291 int ret;
292 const struct dirent *ent;
293 char *scan_el_dir;
294 char *filename;
295
296 *counter = 0;
297 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir);
298 if (ret < 0) {
299 ret = -ENOMEM;
300 goto error_ret;
301 }
302 dp = opendir(scan_el_dir);
303 if (dp == NULL) {
304 ret = -errno;
305 goto error_free_name;
306 }
307 while (ent = readdir(dp), ent != NULL)
308 if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
309 "_en") == 0) {
310 ret = asprintf(&filename,
311 "%s/%s", scan_el_dir, ent->d_name);
312 if (ret < 0) {
313 ret = -ENOMEM;
314 goto error_close_dir;
315 }
316 sysfsfp = fopen(filename, "r");
317 if (sysfsfp == NULL) {
318 ret = -errno;
319 free(filename);
320 goto error_close_dir;
321 }
322 fscanf(sysfsfp, "%u", &ret);
323 if (ret == 1)
324 (*counter)++;
325 fclose(sysfsfp);
326 free(filename);
327 }
Michael Hennerich8b68bb22011-03-08 08:55:48 +0100328 *ci_array = malloc(sizeof(**ci_array) * (*counter));
Jonathan Camerone58537c2010-10-08 12:14:14 +0100329 if (*ci_array == NULL) {
330 ret = -ENOMEM;
331 goto error_close_dir;
332 }
333 seekdir(dp, 0);
Michael Hennerich7ccd4502011-02-24 16:34:53 +0100334 count = 0;
Jonathan Camerone58537c2010-10-08 12:14:14 +0100335 while (ent = readdir(dp), ent != NULL) {
336 if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
337 "_en") == 0) {
338 current = &(*ci_array)[count++];
339 ret = asprintf(&filename,
340 "%s/%s", scan_el_dir, ent->d_name);
341 if (ret < 0) {
342 ret = -ENOMEM;
343 /* decrement count to avoid freeing name */
344 count--;
345 goto error_cleanup_array;
346 }
347 sysfsfp = fopen(filename, "r");
348 if (sysfsfp == NULL) {
349 free(filename);
350 ret = -errno;
351 goto error_cleanup_array;
352 }
353 fscanf(sysfsfp, "%u", &current->enabled);
354 fclose(sysfsfp);
Michael Hennerich8b68bb22011-03-08 08:55:48 +0100355
356 if (!current->enabled) {
357 free(filename);
358 count--;
359 continue;
360 }
361
Jonathan Camerone58537c2010-10-08 12:14:14 +0100362 current->scale = 1.0;
363 current->offset = 0;
364 current->name = strndup(ent->d_name,
365 strlen(ent->d_name) -
366 strlen("_en"));
367 if (current->name == NULL) {
368 free(filename);
369 ret = -ENOMEM;
370 goto error_cleanup_array;
371 }
372 /* Get the generic and specific name elements */
373 ret = iioutils_break_up_name(current->name,
374 &current->generic_name);
375 if (ret) {
376 free(filename);
377 goto error_cleanup_array;
378 }
379 ret = asprintf(&filename,
380 "%s/%s_index",
381 scan_el_dir,
382 current->name);
383 if (ret < 0) {
384 free(filename);
385 ret = -ENOMEM;
386 goto error_cleanup_array;
387 }
388 sysfsfp = fopen(filename, "r");
389 fscanf(sysfsfp, "%u", &current->index);
390 fclose(sysfsfp);
391 free(filename);
392 /* Find the scale */
393 ret = iioutils_get_param_float(&current->scale,
394 "scale",
395 device_dir,
396 current->name,
397 current->generic_name);
398 if (ret < 0)
399 goto error_cleanup_array;
400 ret = iioutils_get_param_float(&current->offset,
401 "offset",
402 device_dir,
403 current->name,
404 current->generic_name);
405 if (ret < 0)
406 goto error_cleanup_array;
407 ret = iioutils_get_type(&current->is_signed,
408 &current->bytes,
409 &current->bits_used,
Jonathan Cameron52615d42011-05-18 14:41:19 +0100410 &current->shift,
Jonathan Camerone58537c2010-10-08 12:14:14 +0100411 &current->mask,
Jonathan Cameron117cf8b2011-12-04 19:10:59 +0000412 &current->be,
Jonathan Camerone58537c2010-10-08 12:14:14 +0100413 device_dir,
414 current->name,
415 current->generic_name);
416 }
417 }
Michael Hennerich8b68bb22011-03-08 08:55:48 +0100418
Jonathan Camerone58537c2010-10-08 12:14:14 +0100419 closedir(dp);
Michael Hennerich8b68bb22011-03-08 08:55:48 +0100420 /* reorder so that the array is in index order */
421 bsort_channel_array_by_index(ci_array, *counter);
Jonathan Camerone58537c2010-10-08 12:14:14 +0100422
423 return 0;
424
425error_cleanup_array:
roel kluin267024a2011-01-01 18:01:51 +0000426 for (i = count - 1; i >= 0; i--)
Jonathan Camerone58537c2010-10-08 12:14:14 +0100427 free((*ci_array)[i].name);
428 free(*ci_array);
429error_close_dir:
430 closedir(dp);
431error_free_name:
432 free(scan_el_dir);
433error_ret:
434 return ret;
435}
436
437/**
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100438 * find_type_by_name() - function to match top level types by name
439 * @name: top level type instance name
440 * @type: the type of top level instance being sort
441 *
442 * Typical types this is used for are device and trigger.
443 **/
444inline int find_type_by_name(const char *name, const char *type)
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100445{
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100446 const struct dirent *ent;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100447 int number, numstrlen;
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100448
449 FILE *nameFile;
450 DIR *dp;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100451 char thisname[IIO_MAX_NAME_LENGTH];
452 char *filename;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100453
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100454 dp = opendir(iio_dir);
455 if (dp == NULL) {
Peter Meerwaldc866ffc2012-07-01 00:47:41 +0200456 printf("No industrialio devices available\n");
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100457 return -ENODEV;
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100458 }
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100459
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100460 while (ent = readdir(dp), ent != NULL) {
461 if (strcmp(ent->d_name, ".") != 0 &&
462 strcmp(ent->d_name, "..") != 0 &&
463 strlen(ent->d_name) > strlen(type) &&
464 strncmp(ent->d_name, type, strlen(type)) == 0) {
465 numstrlen = sscanf(ent->d_name + strlen(type),
466 "%d",
467 &number);
468 /* verify the next character is not a colon */
469 if (strncmp(ent->d_name + strlen(type) + numstrlen,
470 ":",
471 1) != 0) {
472 filename = malloc(strlen(iio_dir)
473 + strlen(type)
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100474 + numstrlen
Barry Songb6ee30a2010-05-25 17:40:04 +0800475 + 6);
Peter Meerwalda4d429e2012-06-25 23:13:25 +0200476 if (filename == NULL) {
477 closedir(dp);
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100478 return -ENOMEM;
Peter Meerwalda4d429e2012-06-25 23:13:25 +0200479 }
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100480 sprintf(filename, "%s%s%d/name",
481 iio_dir,
482 type,
483 number);
484 nameFile = fopen(filename, "r");
Peter Meerwalda4d429e2012-06-25 23:13:25 +0200485 if (!nameFile) {
486 free(filename);
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100487 continue;
Peter Meerwalda4d429e2012-06-25 23:13:25 +0200488 }
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100489 free(filename);
490 fscanf(nameFile, "%s", thisname);
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100491 fclose(nameFile);
Peter Meerwalda4d429e2012-06-25 23:13:25 +0200492 if (strcmp(name, thisname) == 0) {
493 closedir(dp);
494 return number;
495 }
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100496 }
497 }
498 }
Peter Meerwalda4d429e2012-06-25 23:13:25 +0200499 closedir(dp);
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100500 return -ENODEV;
501}
502
503inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
504{
Sebastian Andrzej Siewior11cb4542013-10-07 13:42:00 +0100505 int ret = 0;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100506 FILE *sysfsfp;
507 int test;
508 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
509 if (temp == NULL)
510 return -ENOMEM;
511 sprintf(temp, "%s/%s", basedir, filename);
512 sysfsfp = fopen(temp, "w");
513 if (sysfsfp == NULL) {
514 printf("failed to open %s\n", temp);
515 ret = -errno;
516 goto error_free;
517 }
518 fprintf(sysfsfp, "%d", val);
519 fclose(sysfsfp);
520 if (verify) {
521 sysfsfp = fopen(temp, "r");
522 if (sysfsfp == NULL) {
523 printf("failed to open %s\n", temp);
524 ret = -errno;
525 goto error_free;
526 }
527 fscanf(sysfsfp, "%d", &test);
Peter Meerwaldce7b04c2012-06-25 23:13:26 +0200528 fclose(sysfsfp);
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100529 if (test != val) {
530 printf("Possible failure in int write %d to %s%s\n",
531 val,
532 basedir,
533 filename);
534 ret = -1;
535 }
536 }
537error_free:
538 free(temp);
539 return ret;
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100540}
541
542int write_sysfs_int(char *filename, char *basedir, int val)
543{
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100544 return _write_sysfs_int(filename, basedir, val, 0);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100545}
546
Jonathan Cameroneaf86ff2010-05-04 14:43:04 +0100547int write_sysfs_int_and_verify(char *filename, char *basedir, int val)
548{
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100549 return _write_sysfs_int(filename, basedir, val, 1);
Jonathan Cameroneaf86ff2010-05-04 14:43:04 +0100550}
551
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100552int _write_sysfs_string(char *filename, char *basedir, char *val, int verify)
553{
Jonathan Camerone58537c2010-10-08 12:14:14 +0100554 int ret = 0;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100555 FILE *sysfsfp;
556 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
557 if (temp == NULL) {
558 printf("Memory allocation failed\n");
559 return -ENOMEM;
560 }
561 sprintf(temp, "%s/%s", basedir, filename);
562 sysfsfp = fopen(temp, "w");
563 if (sysfsfp == NULL) {
564 printf("Could not open %s\n", temp);
565 ret = -errno;
566 goto error_free;
567 }
568 fprintf(sysfsfp, "%s", val);
569 fclose(sysfsfp);
570 if (verify) {
571 sysfsfp = fopen(temp, "r");
572 if (sysfsfp == NULL) {
Jonathan Camerone58537c2010-10-08 12:14:14 +0100573 printf("could not open file to verify\n");
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100574 ret = -errno;
575 goto error_free;
576 }
577 fscanf(sysfsfp, "%s", temp);
Peter Meerwaldce7b04c2012-06-25 23:13:26 +0200578 fclose(sysfsfp);
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100579 if (strcmp(temp, val) != 0) {
580 printf("Possible failure in string write of %s "
581 "Should be %s "
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300582 "written to %s\%s\n",
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100583 temp,
584 val,
585 basedir,
586 filename);
587 ret = -1;
588 }
589 }
590error_free:
591 free(temp);
592
593 return ret;
594}
Jonathan Camerone58537c2010-10-08 12:14:14 +0100595
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100596/**
597 * write_sysfs_string_and_verify() - string write, readback and verify
598 * @filename: name of file to write to
599 * @basedir: the sysfs directory in which the file is to be found
600 * @val: the string to write
601 **/
602int write_sysfs_string_and_verify(char *filename, char *basedir, char *val)
603{
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100604 return _write_sysfs_string(filename, basedir, val, 1);
605}
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100606
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100607int write_sysfs_string(char *filename, char *basedir, char *val)
608{
609 return _write_sysfs_string(filename, basedir, val, 0);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100610}
611
612int read_sysfs_posint(char *filename, char *basedir)
613{
614 int ret;
615 FILE *sysfsfp;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100616 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
617 if (temp == NULL) {
618 printf("Memory allocation failed");
619 return -ENOMEM;
620 }
621 sprintf(temp, "%s/%s", basedir, filename);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100622 sysfsfp = fopen(temp, "r");
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100623 if (sysfsfp == NULL) {
624 ret = -errno;
625 goto error_free;
626 }
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100627 fscanf(sysfsfp, "%d\n", &ret);
628 fclose(sysfsfp);
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100629error_free:
630 free(temp);
631 return ret;
632}
633
634int read_sysfs_float(char *filename, char *basedir, float *val)
635{
636 float ret = 0;
637 FILE *sysfsfp;
638 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
639 if (temp == NULL) {
640 printf("Memory allocation failed");
641 return -ENOMEM;
642 }
643 sprintf(temp, "%s/%s", basedir, filename);
644 sysfsfp = fopen(temp, "r");
645 if (sysfsfp == NULL) {
646 ret = -errno;
647 goto error_free;
648 }
649 fscanf(sysfsfp, "%f\n", val);
650 fclose(sysfsfp);
651error_free:
652 free(temp);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100653 return ret;
654}