OSDN Git Service

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