OSDN Git Service

Move module path to vendor
[android-x86/hardware-intel-libsensors.git] / utils.c
diff --git a/utils.c b/utils.c
index a0c9a7b..488b70a 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -1,11 +1,15 @@
 /*
- * Copyright (C) 2014 Intel Corporation.
+ * Copyright (C) 2014-2015 Intel Corporation.
  */
 
 #include <stdlib.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
 #include <utils/Log.h>
 #include <hardware/sensors.h>
+#include <utils/Atomic.h>
+#include <linux/android_alarm.h>
+
 #include "common.h"
 #include "utils.h"
 
  * possible sysfs attributes. As an optimization we may want to cache which
  * ones are valid and immediately return in error for inexistent entries.
  */
-
-int sysfs_write_int(const char path[PATH_MAX], int value)
+int sysfs_read(const char path[PATH_MAX], void *buf, int buf_len)
 {
-       int ret;
-       int fd;
-       int len;
-       char buf[20];
+       int fd, len;
 
-       len = sprintf(buf, "%d", value);
-
-       if (!path[0] || len <= 0) {
-               ALOGE("Unexpected condition in sysfs_write_int\n");
+       if (!path[0] || !buf || buf_len < 1)
                return -1;
-       }
 
-       fd = open(path, O_WRONLY);
+       fd = open(path, O_RDONLY);
 
        if (fd == -1) {
                ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
                return -1;
        }
 
-       ret = write(fd, buf, len);
-
-       if (ret != len) {
-               ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
-                     strerror(errno));
-       }
+       len = read(fd, buf, buf_len);
 
        close(fd);
 
-       return ret;
+       if (len == -1)
+               ALOGW("Cannot read from %s (%s)\n", path, strerror(errno));
+       else
+               ALOGV("Read %d bytes from %s\n", len, path);
+
+       return len;
 }
 
 
-int sysfs_read_int(const char path[PATH_MAX], int *value)
+int sysfs_write(const char path[PATH_MAX], const void *buf, const int buf_len)
 {
-       int fd;
-       int len;
-       char buf[20] = {0};
+       int fd, len;
 
-       if (!path[0] || !value) {
+       if (!path[0] || !buf || buf_len < 1)
                return -1;
-       }
 
-       fd = open(path, O_RDONLY);
+       fd = open(path, O_WRONLY);
 
        if (fd == -1) {
                ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
                return -1;
        }
 
-       len = read(fd, buf, sizeof(buf));
+       len = write(fd, buf, buf_len);
 
        close(fd);
 
-       if (len <= 0) {
-               ALOGW("Cannot read integer from %s (%s)\n", path,
-                     strerror(errno));
-               return -1;
-       }
+       if (len == -1)
+               ALOGW("Cannot write to %s (%s)\n", path, strerror(errno));
+       else if (len != buf_len)
+               ALOGW("Cannot write %d bytes to %s (%d)\n", buf_len, path, len);
+       else
+               ALOGV("Wrote %d bytes to %s\n", buf_len, path);
 
-       *value = atoi(buf);
+       return len;
+}
 
-       ALOGV("Read %d from %s\n", *value, path);
 
-       return 0;
+static void str2int(const char* buf, void *v)
+{
+       *(int*)v = atoi(buf);
 }
 
 
-int sysfs_write_str(const char path[PATH_MAX], const char *str)
+static void str2float(const char* buf, void *v)
 {
-       int ret;
-       int fd;
-       int len;
-
-       if (!path[0] || !str || !str[0]) {
-               return -1;
-       }
+       *(float*)v = strtof(buf, NULL);
+}
 
-       fd = open(path, O_WRONLY);
 
-       if (fd == -1) {
-               ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
-               return -1;
-       }
+static void str2uint64(const char* buf, void *v)
+{
+       *(uint64_t*)v = atoll(buf);
+}
 
-       len = strlen(str);
 
-       ret = write(fd, str, len);
+int sysfs_read_num(const char path[PATH_MAX], void *v,
+               void (*str2num)(const char* buf, void *v))
+{
+       char buf[20];
+       int len = sysfs_read_str(path, buf, sizeof(buf));
 
-       if (ret != len) {
-               ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", str, len, path,
+       if (len <= 0) {
+               ALOGW("Cannot read number from %s (%s)\n", path,
                      strerror(errno));
+               return -1;
        }
-       else
-               ALOGV("Wrote %s to %s\n", str, path);
-
-       close(fd);
 
-       return ret;
+       str2num(buf, v);
+       return 0;
 }
 
 
-int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len)
+int sysfs_read_int(const char path[PATH_MAX], int *value)
 {
-       int fd;
-       int len;
+       return sysfs_read_num(path, value, str2int);
+}
 
-       if (!path[0] || !buf || buf_len < 1)
-               return -1;
 
-       fd = open(path, O_RDONLY);
+int sysfs_read_float(const char path[PATH_MAX], float *value)
+{
+       return sysfs_read_num(path, value, str2float);
+}
 
-       if (fd == -1) {
-               ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
-               return -1;
-       }
 
-       len = read(fd, buf, buf_len);
+int sysfs_read_uint64(const char path[PATH_MAX], uint64_t *value)
+{
+       return sysfs_read_num(path, value, str2uint64);
+}
 
-       close(fd);
 
-       if (len == -1) {
-               ALOGW("Cannot read string from %s (%s)\n", path,
-                     strerror(errno));
+int sysfs_write_int(const char path[PATH_MAX], int value)
+{
+       char buf[20];
+       int len = snprintf(buf, sizeof(buf), "%d", value);
+
+       if (len <= 0) {
+               ALOGE("Unexpected condition in sysfs_write_int\n");
                return -1;
        }
 
-       buf[len == 0 ? 0 : len-1] = '\0';
-
-       ALOGV("Read %s from %s\n", buf, path);
-
-       return len;
+       return sysfs_write(path, buf, len);
 }
 
-
 int sysfs_write_float(const char path[PATH_MAX], float value)
 {
-       int ret;
-       int fd;
-       int len;
        char buf[20];
+       int len = snprintf(buf, sizeof(buf), "%g", value);
 
-       len = snprintf(buf, sizeof(buf), "%g", value);
-
-       if (!path[0] || len <= 0) {
+       if (len <= 0) {
                ALOGE("Unexpected condition in sysfs_write_float\n");
                return -1;
        }
 
-       fd = open(path, O_WRONLY);
-
-       if (fd == -1) {
-               ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
-               return -1;
-       }
-
-       ret = write(fd, buf, len);
+       return sysfs_write(path, buf, len);
+}
 
-       if (ret != len) {
-               ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
-                     strerror(errno));
-       }
 
-       close(fd);
+int sysfs_write_str(const char path[PATH_MAX], const char *str)
+{
+       if (!str || !str[0])
+               return -1;
 
-       return ret;
+       return sysfs_write(path, str, strlen(str));
 }
 
 
-int sysfs_read_float(const char path[PATH_MAX], float *value)
+int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len)
 {
-       int fd;
        int len;
-       char buf[20] = {0};
 
-       if (!path[0] || !value) {
+       if (!buf || buf_len < 1)
                return -1;
-       }
-
-       fd = open(path, O_RDONLY);
-
-       if (fd == -1) {
-               ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
-               return -1;
-       }
 
-       len = read(fd, buf, sizeof(buf));
+       len = sysfs_read(path, buf, buf_len);
 
-       close(fd);
-
-       if (len <= 0) {
-               ALOGW("Cannot read float from %s (%s)\n", path,
+       if (len == -1) {
+               ALOGW("Cannot read string from %s (%s)\n", path,
                      strerror(errno));
                return -1;
        }
 
-       *value = (float) strtod(buf, NULL);
+       buf[len == 0 ? 0 : len - 1] = '\0';
 
-       ALOGV("Read %g from %s\n", *value, path);
+       ALOGV("Read %s from %s\n", buf, path);
 
-       return 0;
+       return len;
 }
 
 
-int decode_type_spec(  const char type_buf[MAX_TYPE_SPEC_LEN],
-                       struct datum_info_t *type_info)
+int64_t get_timestamp (clockid_t clock_id)
 {
-       /* Return size in bytes for this type specification, or -1 in error */
-       char sign;
-       char endianness;
-       unsigned int realbits, storagebits, shift;
-       int tokens;
-
-       /* Valid specs: "le:u10/16>>0", "le:s16/32>>0" or "le:s32/32>>0" */
-
-       tokens = sscanf(type_buf, "%ce:%c%u/%u>>%u",
-                       &endianness, &sign, &realbits, &storagebits, &shift);
-
-       if     (tokens != 5 ||
-               (endianness != 'b' && endianness != 'l') ||
-               (sign != 'u' && sign != 's') ||
-               realbits > storagebits ||
-               (storagebits != 16 && storagebits != 32 && storagebits != 64)) {
-                       ALOGE("Invalid iio channel type spec: %s\n", type_buf);
-                       return -1;
-               }
-
-       type_info->endianness   =               endianness;
-       type_info->sign         =               sign;
-       type_info->realbits     =       (short) realbits;
-       type_info->storagebits  =       (short) storagebits;
-       type_info->shift        =       (short) shift;
-
-       return storagebits / 8;
+       struct timespec ts = {0};
+
+       if (!clock_gettime(clock_id, &ts))
+               return 1000000000LL * ts.tv_sec + ts.tv_nsec;
+       else    /* in this case errno is set appropriately */
+               return -1;
 }
 
-int64_t load_timestamp(struct timespec *ts)
+int64_t get_timestamp_realtime (void)
 {
-       clock_gettime(POLLING_CLOCK, ts);
+       return get_timestamp(CLOCK_REALTIME);
+}
 
-       return 1000000000LL * ts->tv_sec + ts->tv_nsec;
+int64_t get_timestamp_boot (void)
+{
+       return get_timestamp(CLOCK_BOOTTIME);
 }
 
-int64_t get_timestamp(void)
+int64_t get_timestamp_thread (void)
 {
-       struct timespec ts = {0};
+       return get_timestamp(CLOCK_THREAD_CPUTIME_ID);
+}
 
-       return load_timestamp(&ts);
+int64_t get_timestamp_monotonic (void)
+{
+       return get_timestamp(CLOCK_MONOTONIC);
 }
 
-void set_timestamp(struct timespec *out, int64_t target_ns)
+void set_timestamp (struct timespec *out, int64_t target_ns)
 {
        out->tv_sec  = target_ns / 1000000000LL;
        out->tv_nsec = target_ns % 1000000000LL;