OSDN Git Service

Merge remote-tracking branch 'origin/abt/topic/gmin/l-dev/sensors/master' into gmin...
[android-x86/hardware-intel-libsensors.git] / utils.c
1 /*
2  * Copyright (C) 2014 Intel Corporation.
3  */
4
5 #include <stdlib.h>
6 #include <fcntl.h>
7 #include <utils/Log.h>
8 #include <hardware/sensors.h>
9 #include "common.h"
10 #include "utils.h"
11
12
13 /* Note:
14  *
15  * Some of these calls are going to fail, because not all sensors expose all
16  * possible sysfs attributes. As an optimization we may want to cache which
17  * ones are valid and immediately return in error for inexistent entries.
18  */
19
20 int sysfs_write_int(const char path[PATH_MAX], int value)
21 {
22         int ret;
23         int fd;
24         int len;
25         char buf[20];
26
27         len = sprintf(buf, "%d", value);
28
29         if (!path[0] || len <= 0) {
30                 ALOGE("Unexpected condition in sysfs_write_int\n");
31                 return -1;
32         }
33
34         fd = open(path, O_WRONLY);
35
36         if (fd == -1) {
37                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
38                 return -1;
39         }
40
41         ret = write(fd, buf, len);
42
43         if (ret != len) {
44                 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
45                       strerror(errno));
46         }
47
48         close(fd);
49
50         return ret;
51 }
52
53
54 int sysfs_read_int(const char path[PATH_MAX], int *value)
55 {
56         int fd;
57         int len;
58         char buf[20] = {0};
59
60         if (!path[0] || !value) {
61                 return -1;
62         }
63
64         fd = open(path, O_RDONLY);
65
66         if (fd == -1) {
67                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
68                 return -1;
69         }
70
71         len = read(fd, buf, sizeof(buf));
72
73         close(fd);
74
75         if (len <= 0) {
76                 ALOGW("Cannot read integer from %s (%s)\n", path,
77                       strerror(errno));
78                 return -1;
79         }
80
81         *value = atoi(buf);
82
83         ALOGV("Read %d from %s\n", *value, path);
84
85         return 0;
86 }
87
88
89 int sysfs_write_str(const char path[PATH_MAX], const char *str)
90 {
91         int ret;
92         int fd;
93         int len;
94
95         if (!path[0] || !str || !str[0]) {
96                 return -1;
97         }
98
99         fd = open(path, O_WRONLY);
100
101         if (fd == -1) {
102                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
103                 return -1;
104         }
105
106         len = strlen(str);
107
108         ret = write(fd, str, len);
109
110         if (ret != len) {
111                 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", str, len, path,
112                       strerror(errno));
113         }
114         else
115                 ALOGV("Wrote %s to %s\n", str, path);
116
117         close(fd);
118
119         return ret;
120 }
121
122
123 int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len)
124 {
125         int fd;
126         int len;
127
128         if (!path[0] || !buf || buf_len < 1)
129                 return -1;
130
131         fd = open(path, O_RDONLY);
132
133         if (fd == -1) {
134                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
135                 return -1;
136         }
137
138         len = read(fd, buf, buf_len);
139
140         close(fd);
141
142         if (len == -1) {
143                 ALOGW("Cannot read string from %s (%s)\n", path,
144                       strerror(errno));
145                 return -1;
146         }
147
148         buf[len == 0 ? 0 : len-1] = '\0';
149
150         ALOGV("Read %s from %s\n", buf, path);
151
152         return len;
153 }
154
155
156 int sysfs_write_float(const char path[PATH_MAX], float value)
157 {
158         int ret;
159         int fd;
160         int len;
161         char buf[20];
162
163         len = snprintf(buf, sizeof(buf), "%g", value);
164
165         if (!path[0] || len <= 0) {
166                 ALOGE("Unexpected condition in sysfs_write_float\n");
167                 return -1;
168         }
169
170         fd = open(path, O_WRONLY);
171
172         if (fd == -1) {
173                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
174                 return -1;
175         }
176
177         ret = write(fd, buf, len);
178
179         if (ret != len) {
180                 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
181                       strerror(errno));
182         }
183
184         close(fd);
185
186         return ret;
187 }
188
189
190 int sysfs_read_float(const char path[PATH_MAX], float *value)
191 {
192         int fd;
193         int len;
194         char buf[20] = {0};
195
196         if (!path[0] || !value) {
197                 return -1;
198         }
199
200         fd = open(path, O_RDONLY);
201
202         if (fd == -1) {
203                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
204                 return -1;
205         }
206
207         len = read(fd, buf, sizeof(buf));
208
209         close(fd);
210
211         if (len <= 0) {
212                 ALOGW("Cannot read float from %s (%s)\n", path,
213                       strerror(errno));
214                 return -1;
215         }
216
217         *value = (float) strtod(buf, NULL);
218
219         ALOGV("Read %g from %s\n", *value, path);
220
221         return 0;
222 }
223
224
225 int decode_type_spec(   const char type_buf[MAX_TYPE_SPEC_LEN],
226                         struct datum_info_t *type_info)
227 {
228         /* Return size in bytes for this type specification, or -1 in error */
229         char sign;
230         char endianness;
231         unsigned int realbits, storagebits, shift;
232         int tokens;
233
234         /* Valid specs: "le:u10/16>>0", "le:s16/32>>0" or "le:s32/32>>0" */
235
236         tokens = sscanf(type_buf, "%ce:%c%u/%u>>%u",
237                         &endianness, &sign, &realbits, &storagebits, &shift);
238
239         if     (tokens != 5 ||
240                 (endianness != 'b' && endianness != 'l') ||
241                 (sign != 'u' && sign != 's') ||
242                 realbits > storagebits ||
243                 (storagebits != 16 && storagebits != 32 && storagebits != 64)) {
244                         ALOGE("Invalid iio channel type spec: %s\n", type_buf);
245                         return -1;
246                 }
247
248         type_info->endianness   =               endianness;
249         type_info->sign         =               sign;
250         type_info->realbits     =       (short) realbits;
251         type_info->storagebits  =       (short) storagebits;
252         type_info->shift        =       (short) shift;
253
254         return storagebits / 8;
255 }
256
257 int64_t load_timestamp(struct timespec *ts)
258 {
259         clock_gettime(POLLING_CLOCK, ts);
260
261         return 1000000000LL * ts->tv_sec + ts->tv_nsec;
262 }
263
264 int64_t get_timestamp(void)
265 {
266         struct timespec ts = {0};
267
268         return load_timestamp(&ts);
269 }
270
271 void set_timestamp(struct timespec *out, int64_t target_ns)
272 {
273         out->tv_sec  = target_ns / 1000000000LL;
274         out->tv_nsec = target_ns % 1000000000LL;
275 }
276