blob: a4555e6f133f0f4cca98924a6085aa8b7f0b6ad0 [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/* Made up value to limit allocation sizes */
11#include <string.h>
12#include <stdlib.h>
13
14#define IIO_MAX_NAME_LENGTH 30
15
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010016#define IIO_EVENT_CODE_RING_50_FULL 200
17#define IIO_EVENT_CODE_RING_75_FULL 201
18#define IIO_EVENT_CODE_RING_100_FULL 202
19
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010020const char *iio_dir = "/sys/bus/iio/devices/";
21
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010022struct iio_event_data {
23 int id;
24 __s64 timestamp;
25};
26
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010027/**
28 * find_type_by_name() - function to match top level types by name
29 * @name: top level type instance name
30 * @type: the type of top level instance being sort
31 *
32 * Typical types this is used for are device and trigger.
33 **/
34inline int find_type_by_name(const char *name, const char *type)
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010035{
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010036 const struct dirent *ent;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010037 int number, numstrlen;
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010038
39 FILE *nameFile;
40 DIR *dp;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010041 char thisname[IIO_MAX_NAME_LENGTH];
42 char *filename;
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010043 struct stat Stat;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010044
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010045 dp = opendir(iio_dir);
46 if (dp == NULL) {
47 printf("No industrialio devices available");
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010048 return -ENODEV;
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010049 }
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010050
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010051 while (ent = readdir(dp), ent != NULL) {
52 if (strcmp(ent->d_name, ".") != 0 &&
53 strcmp(ent->d_name, "..") != 0 &&
54 strlen(ent->d_name) > strlen(type) &&
55 strncmp(ent->d_name, type, strlen(type)) == 0) {
56 numstrlen = sscanf(ent->d_name + strlen(type),
57 "%d",
58 &number);
59 /* verify the next character is not a colon */
60 if (strncmp(ent->d_name + strlen(type) + numstrlen,
61 ":",
62 1) != 0) {
63 filename = malloc(strlen(iio_dir)
64 + strlen(type)
65 + 1
66 + numstrlen
67 + 1);
68 if (filename == NULL)
69 return -ENOMEM;
70 sprintf(filename, "%s%s%d/name",
71 iio_dir,
72 type,
73 number);
74 nameFile = fopen(filename, "r");
75 if (!nameFile)
76 continue;
77 free(filename);
78 fscanf(nameFile, "%s", thisname);
79 if (strcmp(name, thisname) == 0)
80 return number;
81 fclose(nameFile);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +010082 }
83 }
84 }
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +010085 return -ENODEV;
86}
87
88inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
89{
90 int ret;
91 FILE *sysfsfp;
92 int test;
93 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
94 if (temp == NULL)
95 return -ENOMEM;
96 sprintf(temp, "%s/%s", basedir, filename);
97 sysfsfp = fopen(temp, "w");
98 if (sysfsfp == NULL) {
99 printf("failed to open %s\n", temp);
100 ret = -errno;
101 goto error_free;
102 }
103 fprintf(sysfsfp, "%d", val);
104 fclose(sysfsfp);
105 if (verify) {
106 sysfsfp = fopen(temp, "r");
107 if (sysfsfp == NULL) {
108 printf("failed to open %s\n", temp);
109 ret = -errno;
110 goto error_free;
111 }
112 fscanf(sysfsfp, "%d", &test);
113 if (test != val) {
114 printf("Possible failure in int write %d to %s%s\n",
115 val,
116 basedir,
117 filename);
118 ret = -1;
119 }
120 }
121error_free:
122 free(temp);
123 return ret;
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100124}
125
126int write_sysfs_int(char *filename, char *basedir, int val)
127{
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100128 return _write_sysfs_int(filename, basedir, val, 0);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100129}
130
Jonathan Cameroneaf86ff2010-05-04 14:43:04 +0100131int write_sysfs_int_and_verify(char *filename, char *basedir, int val)
132{
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100133 return _write_sysfs_int(filename, basedir, val, 1);
Jonathan Cameroneaf86ff2010-05-04 14:43:04 +0100134}
135
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100136int _write_sysfs_string(char *filename, char *basedir, char *val, int verify)
137{
138 int ret;
139 FILE *sysfsfp;
140 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
141 if (temp == NULL) {
142 printf("Memory allocation failed\n");
143 return -ENOMEM;
144 }
145 sprintf(temp, "%s/%s", basedir, filename);
146 sysfsfp = fopen(temp, "w");
147 if (sysfsfp == NULL) {
148 printf("Could not open %s\n", temp);
149 ret = -errno;
150 goto error_free;
151 }
152 fprintf(sysfsfp, "%s", val);
153 fclose(sysfsfp);
154 if (verify) {
155 sysfsfp = fopen(temp, "r");
156 if (sysfsfp == NULL) {
157 ret = -errno;
158 goto error_free;
159 }
160 fscanf(sysfsfp, "%s", temp);
161 if (strcmp(temp, val) != 0) {
162 printf("Possible failure in string write of %s "
163 "Should be %s "
164 "writen to %s\%s\n",
165 temp,
166 val,
167 basedir,
168 filename);
169 ret = -1;
170 }
171 }
172error_free:
173 free(temp);
174
175 return ret;
176}
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100177/**
178 * write_sysfs_string_and_verify() - string write, readback and verify
179 * @filename: name of file to write to
180 * @basedir: the sysfs directory in which the file is to be found
181 * @val: the string to write
182 **/
183int write_sysfs_string_and_verify(char *filename, char *basedir, char *val)
184{
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100185 return _write_sysfs_string(filename, basedir, val, 1);
186}
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100187
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100188int write_sysfs_string(char *filename, char *basedir, char *val)
189{
190 return _write_sysfs_string(filename, basedir, val, 0);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100191}
192
193int read_sysfs_posint(char *filename, char *basedir)
194{
195 int ret;
196 FILE *sysfsfp;
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100197 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
198 if (temp == NULL) {
199 printf("Memory allocation failed");
200 return -ENOMEM;
201 }
202 sprintf(temp, "%s/%s", basedir, filename);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100203 sysfsfp = fopen(temp, "r");
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100204 if (sysfsfp == NULL) {
205 ret = -errno;
206 goto error_free;
207 }
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100208 fscanf(sysfsfp, "%d\n", &ret);
209 fclose(sysfsfp);
Jonathan Cameron9d8ae6c2010-05-04 14:43:13 +0100210error_free:
211 free(temp);
212 return ret;
213}
214
215int read_sysfs_float(char *filename, char *basedir, float *val)
216{
217 float ret = 0;
218 FILE *sysfsfp;
219 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
220 if (temp == NULL) {
221 printf("Memory allocation failed");
222 return -ENOMEM;
223 }
224 sprintf(temp, "%s/%s", basedir, filename);
225 sysfsfp = fopen(temp, "r");
226 if (sysfsfp == NULL) {
227 ret = -errno;
228 goto error_free;
229 }
230 fscanf(sysfsfp, "%f\n", val);
231 fclose(sysfsfp);
232error_free:
233 free(temp);
Jonathan Cameronc57f1ba2009-08-18 18:06:32 +0100234 return ret;
235}