hardware/libsensors
Revision | 76cd154fcd4ccde8d211183120668d9480b0bfb2 (tree) |
---|---|
Time | 2014-07-02 17:14:56 |
Author | Tanguy Pruvot <tanguy.pruvot@gmai...> |
Commiter | Chih-Wei Huang |
hdaps: add support for ST LIS302DL (Acer 1425P/1825PTZ)
Allow also to tune axis signs and to swap axis like X<>Y
setprop hal.sensors.axis.revert "1,-1,1" # to revert Y axis
setprop hal.sensors.axis.order "1,0,2" # for Y,X,Z
This could be required for tablet pc with Accelerometers in Base
and not in Screen part (Acer 1425P has a rotative screen)
Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
@@ -4,11 +4,13 @@ | ||
4 | 4 | * Copyright (C) 2011 The Android-x86 Open Source Project |
5 | 5 | * |
6 | 6 | * by Stefan Seidel <stefans@android-x86.org> |
7 | + * Adaptation by Tanguy Pruvot <tpruvot@github> | |
7 | 8 | * |
8 | 9 | * Licensed under GPLv2 or later |
9 | 10 | * |
10 | 11 | **/ |
11 | 12 | |
13 | +/* #define LOG_NDEBUG 0 */ | |
12 | 14 | #define LOG_TAG "HdapsSensors" |
13 | 15 | |
14 | 16 | #include <stdint.h> |
@@ -26,12 +28,9 @@ | ||
26 | 28 | |
27 | 29 | #include <cutils/atomic.h> |
28 | 30 | #include <cutils/log.h> |
31 | +#include <cutils/properties.h> | |
29 | 32 | #include <hardware/sensors.h> |
30 | 33 | |
31 | -//#define DEBUG_SENSOR 1 | |
32 | - | |
33 | -#define CONVERT (GRAVITY_EARTH / 156.0f) | |
34 | -#define CONVERT_PEGA (GRAVITY_EARTH / 256.0f) | |
35 | 34 | #define INPUT_DIR "/dev/input" |
36 | 35 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) |
37 | 36 | #define ID_ACCELERATION (SENSORS_HANDLE_BASE + 0) |
@@ -44,12 +43,25 @@ | ||
44 | 43 | typedef struct { |
45 | 44 | const char *name; |
46 | 45 | float conv[3]; |
46 | + int swap[3]; | |
47 | 47 | int avg_cnt; |
48 | 48 | } accel_params; |
49 | 49 | |
50 | +/* precision, result data should give GRAVITY_EARTH ~9.8 */ | |
51 | +#define CONVERT (GRAVITY_EARTH / 156.0f) | |
52 | +#define CONVERT_PEGA (GRAVITY_EARTH / 256.0f) | |
53 | +#define CONVERT_LIS (GRAVITY_EARTH / 1024.0f) | |
54 | + | |
55 | +/* axis swap for tablet pcs, X=0, Y=1, Z=2 */ | |
56 | +#define NO_SWAP { 0, 1, 2 } | |
57 | +#define SWAP_YXZ { 1, 0, 2 } | |
58 | +#define SWAP_ZXY { 2, 0, 1 } | |
59 | + | |
50 | 60 | static accel_params accel_list[] = { |
51 | - { "hdaps", { CONVERT, -CONVERT, 0 }, 1 }, | |
52 | - { "Pegatron Lucid Tablet Accelerometer", { CONVERT_PEGA, CONVERT_PEGA, CONVERT_PEGA }, 4 }, | |
61 | + { "hdaps", { CONVERT, -CONVERT, 0 }, NO_SWAP, 1 }, | |
62 | + { "Pegatron Lucid Tablet Accelerometer", { CONVERT_PEGA, CONVERT_PEGA, CONVERT_PEGA }, NO_SWAP, 4 }, | |
63 | +// { "ST LIS3LV02DL Accelerometer", { -CONVERT_LIS, CONVERT_LIS, CONVERT_LIS }, SWAP_YXZ, 2 }, /* tablet mode */ | |
64 | + { "ST LIS3LV02DL Accelerometer", { CONVERT_LIS, -CONVERT_LIS, CONVERT_LIS }, SWAP_ZXY, 2 }, /* pc mode */ | |
53 | 65 | }; |
54 | 66 | |
55 | 67 | static accel_params accelerometer; |
@@ -88,20 +100,46 @@ static int device__poll(struct sensors_poll_device_t *device, | ||
88 | 100 | sensors_event_t *data, int count) { |
89 | 101 | |
90 | 102 | struct input_event event; |
91 | - int ret; | |
92 | 103 | struct sensors_poll_context_t *dev = |
93 | 104 | (struct sensors_poll_context_t *) device; |
94 | 105 | |
106 | + accel_params signs; | |
107 | + char prop[PROPERTY_VALUE_MAX] = ""; | |
108 | + float val; | |
109 | + int x, y, z; | |
110 | + | |
95 | 111 | if (dev->fd < 0) |
96 | 112 | return 0; |
97 | 113 | |
98 | - while (1) { | |
114 | + // dynamic axis tuning, expect "1,-1,-1" format | |
115 | + if (property_get("hal.sensors.axis.revert", prop, 0)) { | |
116 | + sscanf(prop, "%d,%d,%d", &x, &y, &z); | |
117 | + ALOGD("axis signs set to %d %d %d", x, y, z); | |
118 | + } else { | |
119 | + x = y = z = 1; | |
120 | + } | |
121 | + signs.conv[ABS_X] = accelerometer.conv[ABS_X] * x; | |
122 | + signs.conv[ABS_Y] = accelerometer.conv[ABS_Y] * y; | |
123 | + signs.conv[ABS_Z] = accelerometer.conv[ABS_Z] * z; | |
124 | + | |
125 | + ALOGV("axis convert set to %.6f %.6f %.6f", | |
126 | + signs.conv[ABS_X], signs.conv[ABS_Y] ,signs.conv[ABS_Z]); | |
127 | + | |
128 | + // dynamic axis swap, expect "0,1,2" format | |
129 | + if (property_get("hal.sensors.axis.order", prop, 0)) { | |
130 | + sscanf(prop, "%d,%d,%d", &x, &y, &z); | |
131 | + ALOGD("axis order set to %c %c %c", 'x'+x, 'x'+y, 'x'+z); | |
132 | + } else { | |
133 | + // use default values (accel_params) | |
134 | + x = accelerometer.swap[0]; | |
135 | + y = accelerometer.swap[1]; | |
136 | + z = accelerometer.swap[2]; | |
137 | + } | |
138 | + | |
139 | + while (read(dev->fd, &event, sizeof(event)) > 0) { | |
99 | 140 | |
100 | - ret = read(dev->fd, &event, sizeof(event)); | |
141 | + ALOGV("gsensor event %d - %d - %d", event.type, event.code, event.value); | |
101 | 142 | |
102 | -#ifdef DEBUG_SENSOR | |
103 | - ALOGD("hdaps event %d - %d - %d\n", event.type, event.code, event.value); | |
104 | -#endif | |
105 | 143 | if (event.type == EV_ABS) { |
106 | 144 | switch (event.code) { |
107 | 145 | // Even though this mapping results in wrong results with some apps, |
@@ -113,7 +151,13 @@ static int device__poll(struct sensors_poll_device_t *device, | ||
113 | 151 | case ABS_X: // 0x00 |
114 | 152 | case ABS_Y: // 0x01 |
115 | 153 | case ABS_Z: // 0x02 |
116 | - events_q[event_cnt].v[event.code] = accelerometer.conv[event.code] * event.value; | |
154 | + val = signs.conv[event.code] * event.value; | |
155 | + if (event.code == ABS_X) | |
156 | + events_q[event_cnt].v[x] = val; | |
157 | + else if (event.code == ABS_Y) | |
158 | + events_q[event_cnt].v[y] = val; | |
159 | + else if (event.code == ABS_Z) | |
160 | + events_q[event_cnt].v[z] = val; | |
117 | 161 | break; |
118 | 162 | } |
119 | 163 | } else if (event.type == EV_SYN) { |
@@ -121,7 +165,7 @@ static int device__poll(struct sensors_poll_device_t *device, | ||
121 | 165 | data->timestamp = (int64_t) ((int64_t) event.time.tv_sec |
122 | 166 | * 1000000000 + (int64_t) event.time.tv_usec * 1000); |
123 | 167 | // hdaps doesn't have z-axis, so simulate it by rotation matrix solution |
124 | - if (accelerometer.conv[2] == 0) | |
168 | + if (signs.conv[2] == 0) | |
125 | 169 | events_q[event_cnt].z = COS_ASIN_2D(GRAVITY_EARTH, events_q[event_cnt].x, events_q[event_cnt].y); |
126 | 170 | memset(&data->acceleration, 0, sizeof(sensors_vec_t)); |
127 | 171 | for (i = 0; i < accelerometer.avg_cnt; ++i) { |
@@ -134,6 +178,7 @@ static int device__poll(struct sensors_poll_device_t *device, | ||
134 | 178 | data->acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; |
135 | 179 | if (++event_cnt >= accelerometer.avg_cnt) |
136 | 180 | event_cnt = 0; |
181 | + | |
137 | 182 | // spare the CPU if desired |
138 | 183 | if (forced_delay) |
139 | 184 | usleep(forced_delay); |
@@ -174,13 +219,12 @@ static int open_input_device(void) { | ||
174 | 219 | name[0] = '\0'; |
175 | 220 | } |
176 | 221 | |
177 | -#ifdef DEBUG_SENSOR | |
178 | - ALOGD("%s name is %s", devname, name); | |
179 | -#endif | |
222 | + ALOGV("%s name is %s", devname, name); | |
223 | + | |
180 | 224 | for (i = 0; i < ARRAY_SIZE(accel_list); ++i) { |
181 | 225 | if (!strcmp(name, accel_list[i].name)) { |
182 | 226 | int c = accel_list[i].avg_cnt; |
183 | - accelerometer.avg_cnt = c; | |
227 | + memcpy(&accelerometer, &accel_list[i], sizeof(accel_params)); | |
184 | 228 | accelerometer.conv[0] = accel_list[i].conv[0] / c; |
185 | 229 | accelerometer.conv[1] = accel_list[i].conv[1] / c; |
186 | 230 | accelerometer.conv[2] = accel_list[i].conv[2] / c; |
@@ -258,7 +302,7 @@ static int open_sensors(const struct hw_module_t* module, const char* name, | ||
258 | 302 | dev->device.poll = device__poll; |
259 | 303 | |
260 | 304 | if ((dev->fd = open_input_device()) < 0) { |
261 | - ALOGE("g sensor get class path error \n"); | |
305 | + ALOGE("GSensor get class path error"); | |
262 | 306 | } else { |
263 | 307 | *device = &dev->device.common; |
264 | 308 | status = 0; |