2 * Copyright (C) 2014 Intel Corporation.
8 #include <hardware/sensors.h>
14 * Some of these calls are going to fail, because not all sensors expose all
15 * possible sysfs attributes. As an optimization we may want to cache which
16 * ones are valid and immediately return in error for inexistent entries.
19 int sysfs_write_int(const char path[PATH_MAX], int value)
30 fd = open(path, O_WRONLY);
33 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
37 len = sprintf(buf, "%d", value) + 1;
39 ret = write(fd, buf, len);
42 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path,
52 int sysfs_read_int(const char path[PATH_MAX], int *value)
58 if (!path[0] || !value) {
62 fd = open(path, O_RDONLY);
65 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
69 len = read(fd, buf, sizeof(buf));
74 ALOGW("Cannot read integer from %s (%s)\n", path,
81 ALOGV("Read %d from %s\n", *value, path);
87 int sysfs_write_str(const char path[PATH_MAX], const char *str)
93 if (!path[0] || !str || !str[0]) {
97 fd = open(path, O_WRONLY);
100 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
106 ret = write(fd, str, len);
109 ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", str, len, path,
113 ALOGV("Wrote %s to %s\n", str, path);
121 int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len)
126 if (!path[0] || !buf || buf_len < 1)
129 fd = open(path, O_RDONLY);
132 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
136 len = read(fd, buf, buf_len);
141 ALOGW("Cannot read string from %s (%s)\n", path,
146 buf[len == 0 ? 0 : len-1] = '\0';
148 ALOGV("Read %s from %s\n", buf, path);
154 int sysfs_read_float(const char path[PATH_MAX], float *value)
160 if (!path[0] || !value) {
164 fd = open(path, O_RDONLY);
167 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
171 len = read(fd, buf, sizeof(buf));
176 ALOGW("Cannot read float from %s (%s)\n", path,
181 *value = (float) strtod(buf, NULL);
183 ALOGV("Read %f from %s\n", *value, path);
189 int decode_type_spec( const char type_buf[MAX_TYPE_SPEC_LEN],
190 struct datum_info_t *type_info)
192 /* Return size in bytes for this type specification, or -1 in error */
195 unsigned int realbits, storagebits, shift;
198 /* Valid specs: "le:u10/16>>0", "le:s16/32>>0" or "le:s32/32>>0" */
200 tokens = sscanf(type_buf, "%ce:%c%u/%u>>%u",
201 &endianness, &sign, &realbits, &storagebits, &shift);
204 (endianness != 'b' && endianness != 'l') ||
205 (sign != 'u' && sign != 's') ||
206 realbits > storagebits ||
207 (storagebits != 16 && storagebits != 32 && storagebits != 64)) {
208 ALOGE("Invalid iio channel type spec: %s\n", type_buf);
212 type_info->endianness = endianness;
213 type_info->sign = sign;
214 type_info->realbits = (short) realbits;
215 type_info->storagebits = (short) storagebits;
216 type_info->shift = (short) shift;
218 return storagebits / 8;
222 int64_t sample_as_int64(unsigned char* sample, struct datum_info_t* type)
229 switch (type->storagebits) {
233 if (type->endianness == 'b')
235 u64 = (u64 << 8) | sample[i];
238 u64 = (u64 << 8) | sample[i];
240 if (type->sign == 'u')
241 return (int64_t) (u64 >> type->shift);
243 return ((int64_t) u64) >> type->shift;
246 if (type->endianness == 'b')
247 u32 = (sample[0] << 24) | (sample[1] << 16) |
248 (sample[2] << 8) | sample[3];
250 u32 = (sample[3] << 24) | (sample[2] << 16) |
251 (sample[1] << 8) | sample[0];
253 if (type->sign == 'u')
254 return u32 >> type->shift;
256 return ((int32_t) u32) >> type->shift;
259 if (type->endianness == 'b')
260 u16 = (sample[0] << 8) | sample[1];
262 u16 = (sample[1] << 8) | sample[0];
264 if (type->sign == 'u')
265 return u16 >> type->shift;
267 return ((int16_t) u16) >> type->shift;
270 ALOGE("Unhandled sample storage size\n");
275 float transform_sample (int sensor_type, int channel, float val)
277 /* Last opportunity to alter sample data before it goes to Android */
278 switch (sensor_type) {
279 case SENSOR_TYPE_ACCELEROMETER:
281 * Invert x axis orientation from SI units - see
282 * /hardware/libhardware/include/hardware/sensors.h
283 * for a discussion of what Android expects
289 case SENSOR_TYPE_GYROSCOPE:
291 if (val > -0.05 && val < 0.05)
300 int64_t get_timestamp(void)
302 struct timespec ts = {0};
304 clock_gettime(CLOCK_MONOTONIC, &ts);
306 return 1000000000LL * ts.tv_sec + ts.tv_nsec;