OSDN Git Service

kbdsensor: fix building issues on Android 5.0
[android-x86/hardware-libsensors.git] / s103t_sensor.c
1 /*
2  * s103t_sensor.c
3  *
4  *      Created on: 19.04.2011
5  *      Author: Oliver Dill (oliver@ratio-informatik.de)
6  *      Licensed under GPLv2 or later
7  */
8
9 #define LOG_TAG "S103TSensors"
10
11 #include <linux/types.h>
12 #include <linux/input.h>
13 #include <fcntl.h>
14 #include <cutils/sockets.h>
15 #include <cutils/log.h>
16 #include <cutils/native_handle.h>
17 #include <dirent.h>
18 #include <math.h>
19 #include <hardware/sensors.h>
20
21 #define DRIVER_DESC             "Lenovo front-screen buttons driver"
22 #define SKEY_ROTATE_MAPPING     KEY_F12
23 #define ID_ACCELERATION         (SENSORS_HANDLE_BASE + 0)
24
25 typedef struct SensorContext {
26     struct sensors_poll_device_t device;
27     int fd;
28     uint32_t active_sensors;
29     sensors_event_t orientation;
30     struct timespec delay;
31 } SensorContext;
32
33 static int context__activate(struct sensors_poll_device_t *dev, int handle, int enabled)
34 {
35     ALOGD("%s: called", __FUNCTION__);
36     return 0;
37 }
38
39 static int context__setDelay(struct sensors_poll_device_t *dev, int handle, int64_t ns)
40 {
41     ALOGD("%s: called", __FUNCTION__);
42     return 0;
43 }
44
45 static int context__close(struct hw_device_t *dev)
46 {
47     ALOGD("%s: called", __FUNCTION__);
48     return 0;
49 }
50
51 static int context__poll(struct sensors_poll_device_t *dev, sensors_event_t* data, int count)
52 {
53     bool bChanged = false;
54     SensorContext* ctx = (SensorContext*) dev;
55     ALOGD("%s: dev=%p data=%p count=%d", __FUNCTION__, dev, data, count);
56     while (1) {
57         struct input_event iev;
58         size_t res = read(ctx->fd, &iev, sizeof(iev));
59         if (res == sizeof(iev)) {
60             const double angle = 20.0;
61             const double cos_angle = GRAVITY_EARTH * cos(angle / M_PI);
62             const double sin_angle = GRAVITY_EARTH * sin(angle / M_PI);
63             if (iev.type == EV_KEY) {
64                 ALOGD("type=%d scancode=%d value=%d from fd=%d", iev.type, iev.code, iev.value, ctx->fd);
65                 if (iev.code == SKEY_ROTATE_MAPPING && iev.value == 1) {
66                     if (ctx->orientation.acceleration.x != 0.0) {
67                         // ROT_0
68                         ctx->orientation.acceleration.x = 0.00;
69                         ctx->orientation.acceleration.y = cos_angle;
70                         ctx->orientation.acceleration.z = sin_angle;
71                     } else {
72                         // ROT_90
73                         ctx->orientation.acceleration.x = cos_angle;
74                         ctx->orientation.acceleration.y = 0.00;
75                         ctx->orientation.acceleration.z = sin_angle;
76                     }
77                     bChanged = true;
78                 }
79             }
80             else if (iev.type == EV_SW) {
81                 ALOGD("%s: switching to/from Table Mode type=%d scancode=%d value=%d", __FUNCTION__,iev.type, iev.code, iev.value);
82                 if (iev.value == 0) {
83                     // ROT_0
84                     ctx->orientation.acceleration.x = 0.00;
85                     ctx->orientation.acceleration.y = cos_angle;
86                     ctx->orientation.acceleration.z = sin_angle;
87                 } else {
88                     // ROT_90
89                     ctx->orientation.acceleration.x = cos_angle;
90                     ctx->orientation.acceleration.y = 0.00;
91                     ctx->orientation.acceleration.z = sin_angle;
92                 }
93                 bChanged = true;
94             }
95             if (bChanged) {
96                 nanosleep(&ctx->delay, 0);
97                 ALOGI("orientation changed");
98                 data[0] = ctx->orientation;
99                 data[0].timestamp = iev.time.tv_sec*1000000000LL + iev.time.tv_usec*1000; 
100                 data[1] = ctx->orientation;
101                 data[1].timestamp = data[0].timestamp + 200000000LL;
102                 data[2] = ctx->orientation;
103                 data[2].timestamp = data[1].timestamp + 200000000LL;
104                 return 3;
105             }
106         }
107     }
108 }
109
110 static const struct sensor_t sSensorListInit[] = {
111     { .name =
112         "S103T Orientation sensor",
113         .vendor = "Oliver Dill",
114         .version = 1,
115         .handle = ID_ACCELERATION,
116         .type = SENSOR_TYPE_ACCELEROMETER,
117         .maxRange = 2.8f,
118         .resolution = 1.0f/4032.0f,
119         .power = 3.0f,
120         .reserved = { }
121     },
122 };
123
124 static int sensors__get_sensors_list(struct sensors_module_t* module, struct sensor_t const** list)
125 {
126     ALOGD("%s: sensors__get_sensors_list called", __FUNCTION__);
127     // there is exactly one sensor available, the accelerometer sensor
128     *list = sSensorListInit;
129     return 1;
130 }
131
132 static int open_sensors(const struct hw_module_t* module, const char* id, struct hw_device_t **device)
133 {
134     ALOGD("%s: id=%s", __FUNCTION__, id);
135
136     SensorContext *ctx = malloc(sizeof(*ctx));
137     if (!ctx)
138         return -EINVAL;
139
140     ALOGD("%s: init sensors device", __FUNCTION__);
141     memset(ctx, 0, sizeof(*ctx));
142
143     ctx->device.common.tag = HARDWARE_DEVICE_TAG;
144     ctx->device.common.version = 0;
145     ctx->device.common.module = (struct hw_module_t*) module;
146     ctx->fd = -1;
147     const char *dirname = "/dev/input";
148     DIR *dir = opendir(dirname);
149     if (dir != NULL) {
150         struct dirent *de;
151         // loop over all "eventXX" in /dev/input and look for our driver
152         ALOGD("%s: looping over all eventXX...", __FUNCTION__);
153         while ((de = readdir(dir))) {
154             if (de->d_name[0] != 'e') // eventX
155                 continue;
156             char name[PATH_MAX];
157             snprintf(name, PATH_MAX, "%s/%s", dirname, de->d_name);
158             ALOGD("%s: open device %s", __FUNCTION__, name);
159             ctx->fd = open(name, O_RDWR);
160             if (ctx->fd < 0) {
161                 ALOGE("could not open %s, %s", name, strerror(errno));
162                 continue;
163             }
164             name[sizeof(name) - 1] = '\0';
165             if (ioctl(ctx->fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
166                 ALOGE("could not get device name for %s, %s\n", name, strerror(errno));
167                 name[0] = '\0';
168             }
169
170             if (!strcmp(name, DRIVER_DESC)) {
171                 // ok, it's our driver, stop the loop ...
172                 ALOGI("found device %s", name);
173                 break;
174             }
175             close(ctx->fd);
176         }
177         ALOGD("%s: stop loop and closing directory", __FUNCTION__);
178         closedir(dir);
179     }
180
181     ctx->device.common.close = context__close;
182     ctx->device.activate = context__activate;
183     ctx->device.setDelay = context__setDelay;
184     ctx->device.poll = context__poll;
185     ctx->orientation.version = sizeof(sensors_event_t);
186     ctx->orientation.sensor = ID_ACCELERATION;
187     ctx->orientation.type = SENSOR_TYPE_ACCELEROMETER;
188     ctx->orientation.acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
189     ctx->delay.tv_sec = 0;
190     ctx->delay.tv_nsec = 300000000L;
191
192     *device = &ctx->device.common;
193
194     return 0;
195 }
196
197 static struct hw_module_methods_t sensors_module_methods = {
198    .open = open_sensors
199 };
200
201 struct sensors_module_t HAL_MODULE_INFO_SYM = {
202     .common = {
203         .tag = HARDWARE_MODULE_TAG,
204         .version_major = 1,
205         .version_minor = 0,
206         .id = SENSORS_HARDWARE_MODULE_ID,
207         .name = "s103t SENSORS Module",
208         .author = "Oliver Dill",
209         .methods = &sensors_module_methods,
210         .dso = 0,
211         .reserved = { }
212     },
213     .get_sensors_list = sensors__get_sensors_list
214 };