aboutsummaryrefslogtreecommitdiffstats
path: root/libsensors/orientationd
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2015-06-15 16:22:16 +0200
committerAndreas Blaesius <skate4life@gmx.de>2015-08-15 14:21:25 -0700
commitaf6a75109ed68e89998f221ba27fe15980f01714 (patch)
treeae474f87650bcdc8be89f53c26bfcd0a05b77175 /libsensors/orientationd
parentc9541c3d21b7f1ada9c37fb65d9abace51cdcdc5 (diff)
downloaddevice_samsung_espressowifi-af6a75109ed68e89998f221ba27fe15980f01714.zip
device_samsung_espressowifi-af6a75109ed68e89998f221ba27fe15980f01714.tar.gz
device_samsung_espressowifi-af6a75109ed68e89998f221ba27fe15980f01714.tar.bz2
espresso-common: libsensors: sync with replicant
Change-Id: Idcb9a57af699833c504f236692a6bdb1ef33c98e
Diffstat (limited to 'libsensors/orientationd')
-rw-r--r--libsensors/orientationd/bma250.c85
-rw-r--r--libsensors/orientationd/input.c230
-rw-r--r--libsensors/orientationd/orientationd.c477
-rw-r--r--libsensors/orientationd/orientationd.h72
-rw-r--r--libsensors/orientationd/vector.c61
-rw-r--r--libsensors/orientationd/yas530.c85
6 files changed, 660 insertions, 350 deletions
diff --git a/libsensors/orientationd/bma250.c b/libsensors/orientationd/bma250.c
new file mode 100644
index 0000000..88819ea
--- /dev/null
+++ b/libsensors/orientationd/bma250.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <linux/ioctl.h>
+#include <linux/input.h>
+
+#include <hardware/sensors.h>
+#include <hardware/hardware.h>
+
+#define LOG_TAG "orientationd"
+#include <utils/Log.h>
+
+#include "orientationd.h"
+
+float bma250_convert(int value)
+{
+ return value * (GRAVITY_EARTH / 256.0f);
+}
+
+int bma250_get_data(struct orientationd_handlers *handlers,
+ struct orientationd_data *data)
+{
+ struct input_event input_event;
+ int input_fd;
+ int rc;
+
+ if (handlers == NULL || data == NULL)
+ return -EINVAL;
+
+ input_fd = handlers->poll_fd;
+ if (input_fd < 0)
+ return -1;
+
+ do {
+ rc = read(input_fd, &input_event, sizeof(input_event));
+ if (rc < (int) sizeof(input_event))
+ break;
+
+ if (input_event.type == EV_ABS) {
+ switch (input_event.code) {
+ case ABS_X:
+ data->acceleration.x = bma250_convert(input_event.value);
+ break;
+ case ABS_Y:
+ data->acceleration.y = bma250_convert(input_event.value);
+ break;
+ case ABS_Z:
+ data->acceleration.z = bma250_convert(input_event.value);
+ break;
+ default:
+ continue;
+ }
+ }
+ } while (input_event.type != EV_SYN);
+
+ return 0;
+}
+
+struct orientationd_handlers bma250 = {
+ .input_name = "accelerometer",
+ .handle = SENSOR_TYPE_ACCELEROMETER,
+ .poll_fd = -1,
+ .get_data = bma250_get_data,
+};
diff --git a/libsensors/orientationd/input.c b/libsensors/orientationd/input.c
index eea1494..1afa2b8 100644
--- a/libsensors/orientationd/input.c
+++ b/libsensors/orientationd/input.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Paul Kocialkowski
+ * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,28 +16,117 @@
*/
#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
#include <unistd.h>
-#include <dirent.h>
-#include <stdio.h>
+#include <stdint.h>
#include <fcntl.h>
#include <errno.h>
-
+#include <dirent.h>
#include <linux/ioctl.h>
#include <linux/input.h>
+#include <linux/uinput.h>
+
+#define LOG_TAG "orientationd"
+#include <utils/Log.h>
#include "orientationd.h"
-int64_t input_timestamp(struct input_event *event)
+void input_event_set(struct input_event *event, int type, int code, int value)
{
if (event == NULL)
+ return;
+
+ memset(event, 0, sizeof(struct input_event));
+
+ event->type = type,
+ event->code = code;
+ event->value = value;
+
+ gettimeofday(&event->time, NULL);
+}
+
+long int timestamp(struct timeval *time)
+{
+ if (time == NULL)
return -1;
- return event->time.tv_sec*1000000000LL + event->time.tv_usec*1000;
+ return time->tv_sec * 1000000000LL + time->tv_usec * 1000;
}
-int input_open(char *name, int write)
+long int input_timestamp(struct input_event *event)
+{
+ if (event == NULL)
+ return -1;
+
+ return timestamp(&event->time);
+}
+
+int uinput_rel_create(const char *name)
+{
+ struct uinput_user_dev uinput_dev;
+ int uinput_fd;
+ int rc;
+
+ if (name == NULL)
+ return -1;
+
+ uinput_fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
+ if (uinput_fd < 0) {
+ ALOGE("%s: Unable to open uinput device", __func__);
+ goto error;
+ }
+
+ memset(&uinput_dev, 0, sizeof(uinput_dev));
+
+ strncpy(uinput_dev.name, name, sizeof(uinput_dev.name));
+ uinput_dev.id.bustype = BUS_I2C;
+ uinput_dev.id.vendor = 0;
+ uinput_dev.id.product = 0;
+ uinput_dev.id.version = 0;
+
+ rc = 0;
+ rc |= ioctl(uinput_fd, UI_SET_EVBIT, EV_REL);
+ rc |= ioctl(uinput_fd, UI_SET_RELBIT, REL_X);
+ rc |= ioctl(uinput_fd, UI_SET_RELBIT, REL_Y);
+ rc |= ioctl(uinput_fd, UI_SET_RELBIT, REL_Z);
+ rc |= ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN);
+
+ if (rc < 0) {
+ ALOGE("%s: Unable to set uinput bits", __func__);
+ goto error;
+ }
+
+ rc = write(uinput_fd, &uinput_dev, sizeof(uinput_dev));
+ if (rc < 0) {
+ ALOGE("%s: Unable to write uinput device", __func__);
+ goto error;
+ }
+
+ rc = ioctl(uinput_fd, UI_DEV_CREATE);
+ if (rc < 0) {
+ ALOGE("%s: Unable to create uinput device", __func__);
+ goto error;
+ }
+
+ usleep(3000);
+
+ return uinput_fd;
+
+error:
+ if (uinput_fd >= 0)
+ close(uinput_fd);
+
+ return -1;
+}
+
+void uinput_destroy(int uinput_fd)
+{
+ if (uinput_fd < 0)
+ return;
+
+ ioctl(uinput_fd, UI_DEV_DESTROY);
+}
+
+int input_open(char *name)
{
DIR *d;
struct dirent *di;
@@ -60,7 +149,7 @@ int input_open(char *name, int write)
continue;
snprintf(path, PATH_MAX, "/dev/input/%s", di->d_name);
- fd = open(path, write ? O_RDWR : O_RDONLY | O_NONBLOCK);
+ fd = open(path, O_RDWR | O_NONBLOCK);
if (fd < 0)
continue;
@@ -123,3 +212,124 @@ int sysfs_path_prefix(char *name, char *path_prefix)
return -1;
}
+
+int sysfs_value_read(char *path)
+{
+ char buffer[100];
+ int value;
+ int fd = -1;
+ int rc;
+
+ if (path == NULL)
+ return -1;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ goto error;
+
+ rc = read(fd, &buffer, sizeof(buffer));
+ if (rc <= 0)
+ goto error;
+
+ value = atoi(buffer);
+ goto complete;
+
+error:
+ value = -1;
+
+complete:
+ if (fd >= 0)
+ close(fd);
+
+ return value;
+}
+
+int sysfs_value_write(char *path, int value)
+{
+ char buffer[100];
+ int fd = -1;
+ int rc;
+
+ if (path == NULL)
+ return -1;
+
+ fd = open(path, O_WRONLY);
+ if (fd < 0)
+ goto error;
+
+ snprintf((char *) &buffer, sizeof(buffer), "%d\n", value);
+
+ rc = write(fd, buffer, strlen(buffer));
+ if (rc < (int) strlen(buffer))
+ goto error;
+
+ rc = 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (fd >= 0)
+ close(fd);
+
+ return rc;
+}
+
+int sysfs_string_read(char *path, char *buffer, size_t length)
+{
+ int fd = -1;
+ int rc;
+
+ if (path == NULL || buffer == NULL || length == 0)
+ return -1;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ goto error;
+
+ rc = read(fd, buffer, length);
+ if (rc <= 0)
+ goto error;
+
+ rc = 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (fd >= 0)
+ close(fd);
+
+ return rc;
+}
+
+int sysfs_string_write(char *path, char *buffer, size_t length)
+{
+ int fd = -1;
+ int rc;
+
+ if (path == NULL || buffer == NULL || length == 0)
+ return -1;
+
+ fd = open(path, O_WRONLY);
+ if (fd < 0)
+ goto error;
+
+ rc = write(fd, buffer, length);
+ if (rc <= 0)
+ goto error;
+
+ rc = 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (fd >= 0)
+ close(fd);
+
+ return rc;
+}
diff --git a/libsensors/orientationd/orientationd.c b/libsensors/orientationd/orientationd.c
index 7cc9f0a..8ad84c5 100644
--- a/libsensors/orientationd/orientationd.c
+++ b/libsensors/orientationd/orientationd.c
@@ -1,8 +1,5 @@
/*
- * Copyright (C) 2013 Paul Kocialkowski
- *
- * Orientation calculation based on AK8975_FS:
- * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
+ * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,56 +15,57 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
#include <errno.h>
#include <poll.h>
#include <math.h>
-#include <linux/ioctl.h>
#include <linux/input.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "orientationd.h"
-
#include <hardware/sensors.h>
+#include <hardware/hardware.h>
-#define ABS_CONTROL_REPORT (ABS_THROTTLE)
-
-#define FLAG_X (1 << 0)
-#define FLAG_Y (1 << 1)
-#define FLAG_Z (1 << 2)
-#define FLAG_ALL (FLAG_X | FLAG_Y | FLAG_Z)
+#define LOG_TAG "orientationd"
+#include <utils/Log.h>
-struct sensor_device {
- char *name;
- int handle;
- float (*get_data)(int value);
- int (*set_data)(float value);
+#include "orientationd.h"
- int fd;
+struct orientationd_handlers *orientationd_handlers[] = {
+ &bma250,
+ &yas530,
};
-struct sensor_data {
- vector v;
- int flags;
-};
+int orientationd_handlers_count = sizeof(orientationd_handlers) /
+ sizeof(struct orientationd_handlers *);
-float rad2deg(float v)
+static float rad2deg(float v)
{
return (v * 180.0f / 3.1415926535f);
}
-void orientation_calculate(vector *a, vector *m, vector *o)
+static float vector_scalar(sensors_vec_t *v, sensors_vec_t *d)
+{
+ return v->x * d->x + v->y * d->y + v->z * d->z;
+}
+
+static float vector_length(sensors_vec_t *v)
+{
+ return sqrtf(vector_scalar(v, v));
+}
+
+int orientation_calculate(struct orientationd_data *data)
{
+ sensors_vec_t *a, *m, *o;
float azimuth, pitch, roll;
float la, sinp, cosp, sinr, cosr, x, y;
- if (a == NULL || m == NULL || o == NULL)
- return;
+ if (data == NULL)
+ return -EINVAL;
+
+ a = &data->acceleration;
+ m = &data->magnetic;
+ o = &data->orientation;
la = vector_length(a);
pitch = asinf(-(a->y) / la);
@@ -82,291 +80,248 @@ void orientation_calculate(vector *a, vector *m, vector *o)
x = m->x * sinp * sinr + m->y * cosp + m->z * sinp * cosr;
azimuth = atan2f(y, x);
- o->x = rad2deg(azimuth);
- o->y = rad2deg(pitch);
- o->z = rad2deg(roll);
+ o->azimuth = rad2deg(azimuth);
+ o->pitch = rad2deg(pitch);
+ o->roll = rad2deg(roll);
- if (o->x < 0)
- o->x += 360.0f;
-}
+ if (o->azimuth < 0)
+ o->azimuth += 360.0f;
-float bma250_acceleration(int value)
-{
- return (float) (value * GRAVITY_EARTH) / 256.0f;
-}
-
-float yas530c_magnetic(int value)
-{
- return (float) value / 1000.0f;
+ return 0;
}
-int yas_orientation(float value)
+void *orientationd_thread(void *thread_data)
{
- return (int) (value * 1000);
-}
+ struct orientationd_data *data;
+ struct input_event event;
+ struct timeval time;
+ long int before, after;
+ int diff;
+ int input_fd;
+ int rc;
+
+ if (thread_data == NULL)
+ return NULL;
+
+ data = (struct orientationd_data *) thread_data;
+
+ input_fd = data->input_fd;
+ if (input_fd < 0)
+ return NULL;
+
+ while (data->thread_continue) {
+ pthread_mutex_lock(&data->mutex);
+ if (!data->thread_continue)
+ break;
+
+ while (data->activated) {
+ gettimeofday(&time, NULL);
+ before = timestamp(&time);
+
+ rc = orientation_calculate(data);
+ if (rc < 0) {
+ ALOGE("%s: Unable to calculate orientation", __func__);
+ goto next;
+ }
-struct sensor_device bma250_device = {
- .name = "accelerometer",
- .handle = SENSOR_TYPE_ACCELEROMETER,
- .get_data = bma250_acceleration,
- .set_data = NULL,
- .fd = -1,
-};
+ input_event_set(&event, EV_ABS, ABS_X, (int) (data->orientation.azimuth * 1000));
+ write(input_fd, &event, sizeof(event));
+ input_event_set(&event, EV_ABS, ABS_Y, (int) (data->orientation.pitch * 1000));
+ write(input_fd, &event, sizeof(event));
+ input_event_set(&event, EV_ABS, ABS_Z, (int) (data->orientation.roll * 1000));
+ write(input_fd, &event, sizeof(event));
+ input_event_set(&event, EV_SYN, 0, 0);
+ write(input_fd, &event, sizeof(event));
-struct sensor_device yas530c_device = {
- .name = "geomagnetic",
- .handle = SENSOR_TYPE_MAGNETIC_FIELD,
- .get_data = yas530c_magnetic,
- .set_data = NULL,
- .fd = -1,
-};
+next:
+ gettimeofday(&time, NULL);
+ after = timestamp(&time);
-struct sensor_device yas_orientation_device = {
- .name = "orientation",
- .handle = SENSOR_TYPE_ORIENTATION,
- .get_data = NULL,
- .set_data = yas_orientation,
- .fd = -1,
-};
-
-struct sensor_device *sensor_devices[] = {
- &bma250_device,
- &yas530c_device,
- &yas_orientation_device,
-};
+ diff = (int) (data->delay * 1000000 - (after - before)) / 1000;
+ if (diff <= 0)
+ continue;
-int sensors_devices_count = sizeof(sensor_devices) / sizeof(struct sensor_device *);
+ usleep(diff);
+ }
+ }
+ return NULL;
+}
-int sensor_device_open(struct sensor_device *dev)
+int orientation_get_data(struct orientationd_data *data)
{
- int fd;
+ struct input_event input_event;
+ int input_fd;
+ int activated;
+ unsigned int delay;
+ int rc;
- if (dev == NULL || dev->name == NULL)
+ if (data == NULL)
return -EINVAL;
- printf("Opening %s\n", dev->name);
-
- fd = input_open(dev->name, dev->handle == SENSOR_TYPE_ORIENTATION ? 1 : 0);
- if (fd < 0)
+ input_fd = data->input_fd;
+ if (input_fd < 0)
return -1;
- dev->fd = fd;
+ do {
+ rc = read(input_fd, &input_event, sizeof(input_event));
+ if (rc < (int) sizeof(input_event))
+ break;
- return 0;
-}
+ if (input_event.type == EV_ABS) {
+ switch (input_event.code) {
+ case ABS_THROTTLE:
+ data->activated = input_event.value & (1 << 16) ? 1 : 0;
+ data->delay = input_event.value & ~(1 << 16);
-void sensor_device_close(struct sensor_device *dev)
-{
- if (dev == NULL || dev->fd < 0)
- return;
+ pthread_mutex_unlock(&data->mutex);
+ break;
+ default:
+ continue;
+ }
+ }
+ } while (input_event.type != EV_SYN);
- close(dev->fd);
- dev->fd = -1;
+ return 0;
}
-struct sensor_device *sensor_device_find_handle(int handle)
+int orientationd_poll(struct orientationd_data *data)
{
- int i;
+ int count;
+ int i, j;
+ int rc;
- for (i=0 ; i < sensors_devices_count ; i++) {
- if (sensor_devices[i]->handle == handle)
- return sensor_devices[i];
- }
+ if (data == NULL)
+ return -EINVAL;
- return NULL;
-}
+ ALOGD("Starting orientationd poll");
-struct sensor_device *sensor_device_find_fd(int fd)
-{
- int i;
+ while (1) {
+ if (data->activated)
+ count = data->poll_fds_count;
+ else
+ count = 1;
- for (i=0 ; i < sensors_devices_count ; i++) {
- if (sensor_devices[i]->fd == fd)
- return sensor_devices[i];
- }
+ rc = poll(data->poll_fds, count, -1);
+ if (rc < 0) {
+ ALOGE("%s: poll failure", __func__);
+ goto error;
+ }
- return NULL;
-}
+ for (i = 0; i < count; i++) {
+ if (data->poll_fds[i].revents & POLLIN) {
+ data->poll_fds[i].revents = 0;
-int sensor_device_get_data(struct sensor_device *dev, struct sensor_data *d,
- struct input_event *e)
-{
- if (dev == NULL || d == NULL || e == NULL || dev->get_data == NULL)
- return -EINVAL;
+ if (data->poll_fds[i].fd == data->input_fd) {
+ orientation_get_data(data);
+ continue;
+ }
- if (e->type == EV_ABS) {
- switch (e->code) {
- case ABS_X:
- d->v.x = dev->get_data(e->value);
- d->flags |= FLAG_X;
- return 0;
- case ABS_Y:
- d->v.y = dev->get_data(e->value);
- d->flags |= FLAG_Y;
- return 0;
- case ABS_Z:
- d->v.z = dev->get_data(e->value);
- d->flags |= FLAG_Z;
- return 0;
+ for (j = 0; j < data->handlers_count; j++)
+ if (data->handlers[j] != NULL && data->handlers[j]->poll_fd == data->poll_fds[i].fd && data->handlers[j]->get_data != NULL)
+ data->handlers[j]->get_data(data->handlers[j], data);
+ }
}
}
- return -1;
-}
+ rc = 0;
+ goto complete;
-int sensor_device_set_data(struct sensor_device *dev, struct sensor_data *d)
-{
- struct input_event event;
-
- if (dev == NULL || d == NULL || dev->set_data == NULL)
- return -EINVAL;
-
- event.type = EV_ABS;
- event.code = ABS_X;
- event.value = dev->set_data(d->v.x);
- gettimeofday(&event.time, NULL);
- write(dev->fd, &event, sizeof(event));
-
- event.type = EV_ABS;
- event.code = ABS_Y;
- event.value = dev->set_data(d->v.y);
- gettimeofday(&event.time, NULL);
- write(dev->fd, &event, sizeof(event));
-
- event.type = EV_ABS;
- event.code = ABS_Z;
- event.value = dev->set_data(d->v.z);
- gettimeofday(&event.time, NULL);
- write(dev->fd, &event, sizeof(event));
-
- event.type = EV_SYN;
- event.code = SYN_REPORT;
- event.value = 0;
- gettimeofday(&event.time, NULL);
- write(dev->fd, &event, sizeof(event));
-
- return 0;
-}
-
-int sensor_device_control(struct sensor_device *dev, struct input_event *e)
-{
- int enabled;
-
- if (dev == NULL || e == NULL)
- return -EINVAL;
-
- if (e->type == EV_ABS && e->code == ABS_CONTROL_REPORT) {
- enabled = e->value & (1 << 16);
- if (enabled)
- return 1;
- else
- return 0;
- }
+error:
+ rc = -1;
- return -1;
+complete:
+ return rc;
}
int main(int argc, char *argv[])
{
- struct input_event event;
- struct sensor_data a, m, o;
-
- struct sensor_device *dev;
- struct pollfd *poll_fds;
-
- int enabled, data;
- int index;
-
- int rc, c, i;
-
- memset(&a, 0, sizeof(a));
- memset(&m, 0, sizeof(m));
- memset(&o, 0, sizeof(o));
+ struct orientationd_data *orientationd_data = NULL;
+ pthread_attr_t thread_attr;
+ int input_fd = -1;
+ int poll_fd;
+ int p, i;
+ int rc;
+
+ orientationd_data = (struct orientationd_data *)
+ calloc(1, sizeof(struct orientationd_data));
+ orientationd_data->handlers = orientationd_handlers;
+ orientationd_data->handlers_count = orientationd_handlers_count;
+ orientationd_data->activated = 0;
+ orientationd_data->poll_fds = (struct pollfd *)
+ calloc(1, (orientationd_handlers_count + 1) * sizeof(struct pollfd));
+
+ p = 0;
+
+ input_fd = input_open("orientation");
+ if (input_fd < 0) {
+ ALOGE("%s: Unable to open input", __func__);
+ goto error;
+ }
- poll_fds = (struct pollfd *) calloc(1, sizeof(struct pollfd) * sensors_devices_count);
+ orientationd_data->input_fd = input_fd;
- index = -1;
- c = 0;
+ orientationd_data->poll_fds[p].fd = input_fd;
+ orientationd_data->poll_fds[p].events = POLLIN;
+ p++;
- for (i=0 ; i < sensors_devices_count ; i++) {
- rc = sensor_device_open(sensor_devices[i]);
- if (rc < 0)
+ for (i = 0; i < orientationd_handlers_count; i++) {
+ if (orientationd_handlers[i] == NULL || orientationd_handlers[i]->input_name == NULL)
continue;
- poll_fds[c].fd = sensor_devices[i]->fd;
- poll_fds[c].events = POLLIN;
-
- if (sensor_devices[i]->handle == SENSOR_TYPE_ORIENTATION && index < 0)
- index = c;
+ poll_fd = input_open(orientationd_handlers[i]->input_name);
+ if (poll_fd < 0) {
+ ALOGE("%s: Unable to open input %s", __func__, orientationd_handlers[i]->input_name);
+ continue;
+ }
- c++;
+ orientationd_handlers[i]->poll_fd = poll_fd;
+ orientationd_data->poll_fds[p].fd = poll_fd;
+ orientationd_data->poll_fds[p].events = POLLIN;
+ p++;
}
- if (c <= 0 || index <= 0)
- goto exit;
+ orientationd_data->poll_fds_count = p;
- printf("Starting main loop\n");
+ orientationd_data->thread_continue = 1;
- enabled = 0;
- while (1) {
- data = 0;
+ pthread_mutex_init(&orientationd_data->mutex, NULL);
+ pthread_mutex_lock(&orientationd_data->mutex);
- if (enabled)
- rc = poll(poll_fds, c, -1);
- else
- rc = poll(&poll_fds[index], 1, -1);
+ pthread_attr_init(&thread_attr);
+ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
- if (rc < 0)
- goto exit;
+ rc = pthread_create(&orientationd_data->thread, &thread_attr, orientationd_thread, (void *) orientationd_data);
+ if (rc < 0) {
+ ALOGE("%s: Unable to create orientationd thread", __func__);
+ goto error;
+ }
- for (i=0 ; i < c ; i++) {
- if (poll_fds[i].revents & POLLIN) {
- dev = sensor_device_find_fd(poll_fds[i].fd);
- if (dev == NULL)
- continue;
+ rc = orientationd_poll(orientationd_data);
+ if (rc < 0)
+ goto error;
- read(dev->fd, &event, sizeof(event));
-
- switch (dev->handle) {
- case SENSOR_TYPE_ACCELEROMETER:
- rc = sensor_device_get_data(dev, &a, &event);
- if (rc >= 0)
- data = 1;
- break;
- case SENSOR_TYPE_MAGNETIC_FIELD:
- rc = sensor_device_get_data(dev, &m, &event);
- if (rc >= 0)
- data = 1;
- break;
- case SENSOR_TYPE_ORIENTATION:
- rc = sensor_device_control(dev, &event);
- if (rc == 1)
- enabled = 1;
- else if (rc == 0)
- enabled = 0;
- break;
- }
- }
+ rc = 0;
+ goto complete;
- if (data && a.flags & FLAG_ALL && m.flags & FLAG_ALL) {
- dev = sensor_device_find_handle(SENSOR_TYPE_ORIENTATION);
- if (dev == NULL)
- continue;
+error:
+ while (1)
+ sleep(3600);
- orientation_calculate(&a.v, &m.v, &o.v);
- sensor_device_set_data(dev, &o);
- }
- }
- }
+ rc = 1;
+complete:
+ if (input_fd >= 0)
+ close(input_fd);
-exit:
- for (i=0 ; i < sensors_devices_count ; i++)
- sensor_device_close(sensor_devices[i]);
+ if (orientationd_data != NULL) {
+ orientationd_data->thread_continue = 0;
+ pthread_mutex_destroy(&orientationd_data->mutex);
- while (1) {
- sleep(3600);
+ if (orientationd_data->poll_fds != NULL)
+ free(orientationd_data->poll_fds);
+
+ free(orientationd_data);
}
- return 0;
+ return rc;
}
diff --git a/libsensors/orientationd/orientationd.h b/libsensors/orientationd/orientationd.h
index 41aad5e..7e169e4 100644
--- a/libsensors/orientationd/orientationd.h
+++ b/libsensors/orientationd/orientationd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Paul Kocialkowski
+ * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,36 +15,72 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdint.h>
+#include <poll.h>
#include <linux/input.h>
-#ifndef _ORIENTATION_H_
-#define _ORIENTATION_H_
+#include <hardware/sensors.h>
+#include <hardware/hardware.h>
-/*
- * Vector
- */
+#ifndef _ORIENTATIOND_H_
+#define _ORIENTATIOND_H_
-struct vector {
- float x;
- float y;
- float z;
+struct orientationd_data;
+struct orientationd_handlers {
+ char *input_name;
+ int handle;
+ int poll_fd;
+
+ int (*get_data)(struct orientationd_handlers *handlers,
+ struct orientationd_data *data);
};
-typedef struct vector vector;
+struct orientationd_data {
+ struct orientationd_handlers **handlers;
+ int handlers_count;
+
+ struct pollfd *poll_fds;
+ int poll_fds_count;
-void vector_add(vector *v, vector *a);
-void vector_multiply(vector *v, float k);
-void vector_cross(vector *v, vector *c, vector *out);
-float vector_scalar(vector *v, vector *d);
-float vector_length(vector *v);
+ sensors_vec_t orientation;
+ sensors_vec_t acceleration;
+ sensors_vec_t magnetic;
+
+ unsigned int delay;
+ int input_fd;
+
+ int activated;
+
+ pthread_t thread;
+ pthread_mutex_t mutex;
+ int thread_continue;
+};
+
+extern struct orientationd_handlers *orientationd_handlers[];
+extern int orientationd_handlers_count;
/*
* Input
*/
-int64_t input_timestamp(struct input_event *event);
-int input_open(char *name, int write);
+void input_event_set(struct input_event *event, int type, int code, int value);
+long int timestamp(struct timeval *time);
+long int input_timestamp(struct input_event *event);
+int uinput_rel_create(const char *name);
+void uinput_destroy(int uinput_fd);
+int input_open(char *name);
int sysfs_path_prefix(char *name, char *path_prefix);
+int sysfs_value_read(char *path);
+int sysfs_value_write(char *path, int value);
+int sysfs_string_read(char *path, char *buffer, size_t length);
+int sysfs_string_write(char *path, char *buffer, size_t length);
+
+/*
+ * Sensors
+ */
+
+extern struct orientationd_handlers bma250;
+extern struct orientationd_handlers yas530;
#endif
diff --git a/libsensors/orientationd/vector.c b/libsensors/orientationd/vector.c
deleted file mode 100644
index ee8ba49..0000000
--- a/libsensors/orientationd/vector.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2013 Paul Kocialkowski
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-
-#include "orientationd.h"
-
-void vector_copy(vector *in, vector *out)
-{
- out->x = in->x;
- out->y = in->y;
- out->z = in ->z;
-}
-
-void vector_add(vector *v, vector *a)
-{
- v->x += a->x;
- v->y += a->y;
- v->z += a->z;
-}
-
-void vector_multiply(vector *v, float k)
-{
- v->x *= k;
- v->y *= k;
- v->z *= k;
-}
-
-void vector_cross(vector *v, vector *c, vector *out)
-{
- struct vector t;
-
- t.x = v->x * c->z - v->z * c->y;
- t.y = v->z * c->x - v->x * c->z;
- t.y = v->y * c->y - v->y * c->x;
- vector_copy(&t, out);
-}
-
-float vector_scalar(vector *v, vector *d)
-{
- return v->x * d->x + v->y * d->y + v->z * d->z;
-}
-
-float vector_length(vector *v)
-{
- return sqrtf(vector_scalar(v, v));
-}
diff --git a/libsensors/orientationd/yas530.c b/libsensors/orientationd/yas530.c
new file mode 100644
index 0000000..7942c50
--- /dev/null
+++ b/libsensors/orientationd/yas530.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <linux/ioctl.h>
+#include <linux/input.h>
+
+#include <hardware/sensors.h>
+#include <hardware/hardware.h>
+
+#define LOG_TAG "orientationd"
+#include <utils/Log.h>
+
+#include "orientationd.h"
+
+float yas530_convert(int value)
+{
+ return value / 1000.0f;
+}
+
+int yas530_get_data(struct orientationd_handlers *handlers,
+ struct orientationd_data *data)
+{
+ struct input_event input_event;
+ int input_fd;
+ int rc;
+
+ if (handlers == NULL || data == NULL)
+ return -EINVAL;
+
+ input_fd = handlers->poll_fd;
+ if (input_fd < 0)
+ return -1;
+
+ do {
+ rc = read(input_fd, &input_event, sizeof(input_event));
+ if (rc < (int) sizeof(input_event))
+ break;
+
+ if (input_event.type == EV_ABS) {
+ switch (input_event.code) {
+ case ABS_X:
+ data->magnetic.x = yas530_convert(input_event.value);
+ break;
+ case ABS_Y:
+ data->magnetic.y = yas530_convert(input_event.value);
+ break;
+ case ABS_Z:
+ data->magnetic.z = yas530_convert(input_event.value);
+ break;
+ default:
+ continue;
+ }
+ }
+ } while (input_event.type != EV_SYN);
+
+ return 0;
+}
+
+struct orientationd_handlers yas530 = {
+ .input_name = "geomagnetic",
+ .handle = SENSOR_TYPE_MAGNETIC_FIELD,
+ .poll_fd = -1,
+ .get_data = yas530_get_data,
+};