OSDN Git Service

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