2 * Copyright (C) 2014 Intel Corporation.
8 #include <hardware/sensors.h>
9 #include <utils/Atomic.h>
10 #include <linux/android_alarm.h>
18 * Some of these calls are going to fail, because not all sensors expose all
19 * possible sysfs attributes. As an optimization we may want to cache which
20 * ones are valid and immediately return in error for inexistent entries.
23 int sysfs_write_int(const char path[PATH_MAX], int value)
30 len = sprintf(buf, "%d", value);
32 if (!path[0] || len <= 0) {
33 ALOGE("Unexpected condition in sysfs_write_int\n");
37 fd = open(path, O_WRONLY);
40 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
44 ret = write(fd, buf, len);
47 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
57 int sysfs_read_int(const char path[PATH_MAX], int *value)
63 if (!path[0] || !value) {
67 fd = open(path, O_RDONLY);
70 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
74 len = read(fd, buf, sizeof(buf));
79 ALOGW("Cannot read integer from %s (%s)\n", path,
86 ALOGV("Read %d from %s\n", *value, path);
92 int sysfs_write_str(const char path[PATH_MAX], const char *str)
98 if (!path[0] || !str || !str[0]) {
102 fd = open(path, O_WRONLY);
105 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
111 ret = write(fd, str, len);
114 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", str, len, path,
118 ALOGV("Wrote %s to %s\n", str, path);
126 int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len)
131 if (!path[0] || !buf || buf_len < 1)
134 fd = open(path, O_RDONLY);
137 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
141 len = read(fd, buf, buf_len);
146 ALOGW("Cannot read string from %s (%s)\n", path,
151 buf[len == 0 ? 0 : len-1] = '\0';
153 ALOGV("Read %s from %s\n", buf, path);
159 int sysfs_write_float(const char path[PATH_MAX], float value)
166 len = snprintf(buf, sizeof(buf), "%g", value);
168 if (!path[0] || len <= 0) {
169 ALOGE("Unexpected condition in sysfs_write_float\n");
173 fd = open(path, O_WRONLY);
176 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
180 ret = write(fd, buf, len);
183 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
193 int sysfs_read_float(const char path[PATH_MAX], float *value)
199 if (!path[0] || !value) {
203 fd = open(path, O_RDONLY);
206 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
210 len = read(fd, buf, sizeof(buf));
215 ALOGW("Cannot read float from %s (%s)\n", path,
220 *value = (float) strtod(buf, NULL);
222 ALOGV("Read %g from %s\n", *value, path);
228 int decode_type_spec( const char type_buf[MAX_TYPE_SPEC_LEN],
229 struct datum_info_t *type_info)
231 /* Return size in bytes for this type specification, or -1 in error */
234 unsigned int realbits, storagebits, shift;
237 /* Valid specs: "le:u10/16>>0", "le:s16/32>>0" or "le:s32/32>>0" */
239 tokens = sscanf(type_buf, "%ce:%c%u/%u>>%u",
240 &endianness, &sign, &realbits, &storagebits, &shift);
243 (endianness != 'b' && endianness != 'l') ||
244 (sign != 'u' && sign != 's') ||
245 realbits > storagebits ||
246 (storagebits != 16 && storagebits != 32 && storagebits != 64)) {
247 ALOGE("Invalid iio channel type spec: %s\n", type_buf);
251 type_info->endianness = endianness;
252 type_info->sign = sign;
253 type_info->realbits = (short) realbits;
254 type_info->storagebits = (short) storagebits;
255 type_info->shift = (short) shift;
257 return storagebits / 8;
261 int64_t load_timestamp_monotonic(struct timespec *ts)
263 clock_gettime(CLOCK_MONOTONIC, ts);
265 return (1000000000LL * ts->tv_sec + ts->tv_nsec);
269 int64_t load_timestamp_sys_clock(void)
271 static int s_fd = -1;
276 fd = open("/dev/alarm", O_RDONLY);
277 if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
283 ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
286 /** /dev/alarm doesn't exist, fallback to CLOCK_BOOTTIME */
287 result = clock_gettime(CLOCK_BOOTTIME, &ts);
290 return 1000000000LL * ts.tv_sec + ts.tv_nsec;
294 int64_t get_timestamp_realtime (void)
296 struct timespec ts = {0};
298 clock_gettime(CLOCK_REALTIME, &ts);
300 return 1000000000LL * ts.tv_sec + ts.tv_nsec;
304 int64_t get_timestamp_monotonic(void)
306 struct timespec ts = {0};
308 return load_timestamp_monotonic(&ts);
312 int64_t get_timestamp(void)
314 return (get_timestamp_monotonic() + ts_delta);
318 void set_timestamp(struct timespec *out, int64_t target_ns)
320 out->tv_sec = target_ns / 1000000000LL;
321 out->tv_nsec = target_ns % 1000000000LL;