1 /*
2  * Copyright (C) 2008-2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "Sensors"
18 
19 #include <dirent.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <linux/input.h>
23 #include <math.h>
24 #include <poll.h>
25 #include <pthread.h>
26 #include <stdlib.h>
27 
28 #include <utils/Atomic.h>
29 #include <utils/Log.h>
30 
31 #include <hardware/sensors.h>
32 
33 #include "sensors.h"
34 #include "CwMcuSensor.h"
35 
36 /*****************************************************************************/
37 
38 #define DELAY_OUT_TIME 0x7FFFFFFF
39 
40 #define LIGHT_SENSOR_POLLTIME    2000000000
41 
42 /*****************************************************************************/
43 static const struct sensor_t sSensorList[] = {
44         {.name =       "Accelerometer Sensor",
45          .vendor =     "HTC Group Ltd.",
46          .version =    1,
47          .handle =     ID_A,
48          .type =       SENSOR_TYPE_ACCELEROMETER,
49          .maxRange =   RANGE_A,
50          .resolution = CONVERT_A,
51          .power =      0.17f,
52          .minDelay =   10000,
53          .fifoReservedEventCount = 0,
54          .fifoMaxEventCount =   1220,
55          .stringType =         0,
56          .requiredPermission = 0,
57          .maxDelay =      200000,
58          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
59          .reserved =          {}
60         },
61         {.name =       "Magnetic field Sensor",
62          .vendor =     "HTC Group Ltd.",
63          .version =    1,
64          .handle =     ID_M,
65          .type =       SENSOR_TYPE_MAGNETIC_FIELD,
66          .maxRange =   200.0f,
67          .resolution = CONVERT_M,
68          .power =      5.0f,
69          .minDelay =   10000,
70          .fifoReservedEventCount = 0,
71          .fifoMaxEventCount =   1220,
72          .stringType =         0,
73          .requiredPermission = 0,
74          .maxDelay =      200000,
75          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
76          .reserved =          {}
77         },
78         {.name =       "Gyroscope Sensor",
79          .vendor =     "HTC Group Ltd.",
80          .version =    1,
81          .handle =     ID_GY,
82          .type =       SENSOR_TYPE_GYROSCOPE,
83          .maxRange =   2000.0f,
84          .resolution = CONVERT_GYRO,
85          .power =      6.1f,
86          .minDelay =   10000,
87          .fifoReservedEventCount = 0,
88          .fifoMaxEventCount =   1220,
89          .stringType =         0,
90          .requiredPermission = 0,
91          .maxDelay =      200000,
92          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
93          .reserved =          {}
94         },
95         {.name =       "CM32181 Light sensor",
96          .vendor =     "Capella Microsystems",
97          .version =    1,
98          .handle =     ID_L,
99          .type =       SENSOR_TYPE_LIGHT,
100          .maxRange =   10240.0f,
101          .resolution = 1.0f,
102          .power =      0.15f,
103          .minDelay =   0,
104          .fifoReservedEventCount = 0,
105          .fifoMaxEventCount =      0,
106          .stringType =         NULL,
107          .requiredPermission = NULL,
108          .maxDelay =           0,
109          .flags = SENSOR_FLAG_ON_CHANGE_MODE,
110          .reserved =          {}
111         },
112         {.name =       "Pressure Sensor",
113          .vendor =     "HTC Group Ltd.",
114          .version =    1,
115          .handle =     ID_PS,
116          .type =       SENSOR_TYPE_PRESSURE,
117          .maxRange =   2000,
118          .resolution = 1.0f,
119          .power =      0.0027f,
120          .minDelay =   10000,
121          .fifoReservedEventCount = 0,
122          .fifoMaxEventCount =   1220,
123          .stringType =         0,
124          .requiredPermission = 0,
125          .maxDelay =      200000,
126          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
127          .reserved =          {}
128         },
129         {.name =       "CWGD Orientation Sensor",
130          .vendor =     "HTC Group Ltd.",
131          .version =    1,
132          .handle =     ID_O,
133          .type =       SENSOR_TYPE_ORIENTATION,
134          .maxRange =   360.0f,
135          .resolution = 0.1f,
136          .power =      11.27f,
137          .minDelay =   10000,
138          .fifoReservedEventCount = 0,
139          .fifoMaxEventCount =   1220,
140          .stringType =         0,
141          .requiredPermission = 0,
142          .maxDelay =      200000,
143          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
144          .reserved =          {}
145         },
146         {.name =       "Rotation Vector",
147          .vendor =     "HTC Group Ltd.",
148          .version =    1,
149          .handle =     ID_RV,
150          .type =       SENSOR_TYPE_ROTATION_VECTOR,
151          .maxRange =   1.0f,
152          .resolution = 0.0001f,
153          .power =      11.27f,
154          .minDelay =   10000,
155          .fifoReservedEventCount = 0,
156          .fifoMaxEventCount =   1220,
157          .stringType =         0,
158          .requiredPermission = 0,
159          .maxDelay =      200000,
160          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
161          .reserved =          {}
162         },
163         {.name =       "Linear Acceleration",
164          .vendor =     "HTC Group Ltd.",
165          .version =    1,
166          .handle =     ID_LA,
167          .type =       SENSOR_TYPE_LINEAR_ACCELERATION,
168          .maxRange =   RANGE_A,
169          .resolution = 0.01,
170          .power =      11.27f,
171          .minDelay =   10000,
172          .fifoReservedEventCount = 0,
173          .fifoMaxEventCount =   1220,
174          .stringType =         0,
175          .requiredPermission = 0,
176          .maxDelay =      200000,
177          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
178          .reserved =          {}
179         },
180         {.name =       "Gravity",
181          .vendor =     "HTC Group Ltd.",
182          .version =    1,
183          .handle =     ID_G,
184          .type =       SENSOR_TYPE_GRAVITY,
185          .maxRange =   GRAVITY_EARTH,
186          .resolution = 0.01,
187          .power =      11.27f,
188          .minDelay =   10000,
189          .fifoReservedEventCount = 0,
190          .fifoMaxEventCount =   1220,
191          .stringType =         0,
192          .requiredPermission = 0,
193          .maxDelay =      200000,
194          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
195          .reserved =          {}
196         },
197         {.name =       "Magnetic Uncalibrated",
198          .vendor =     "hTC Corp.",
199          .version =    1,
200          .handle =     ID_CW_MAGNETIC_UNCALIBRATED,
201          .type =       SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
202          .maxRange =   200.0f,
203          .resolution = CONVERT_M,
204          .power =      5.0f,
205          .minDelay =   10000,
206          .fifoReservedEventCount = 0,
207          .fifoMaxEventCount =    610,
208          .stringType =         0,
209          .requiredPermission = 0,
210          .maxDelay =      200000,
211          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
212          .reserved =          {}
213         },
214         {.name =       "Gyroscope Uncalibrated",
215          .vendor =     "hTC Corp.",
216          .version =    1,
217          .handle =     ID_CW_GYROSCOPE_UNCALIBRATED,
218          .type =       SENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
219          .maxRange =   2000.0f,
220          .resolution = CONVERT_GYRO,
221          .power =      6.1f,
222          .minDelay =   10000,
223          .fifoReservedEventCount = 0,
224          .fifoMaxEventCount =    610,
225          .stringType =         0,
226          .requiredPermission = 0,
227          .maxDelay =      200000,
228          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
229          .reserved =          {}
230         },
231         {.name =       "Game Rotation Vector",
232          .vendor =     "hTC Corp.",
233          .version =    1,
234          .handle =     ID_CW_GAME_ROTATION_VECTOR,
235          .type =       SENSOR_TYPE_GAME_ROTATION_VECTOR,
236          .maxRange =   1.0f,
237          .resolution = 0.0001f,
238          .power =      11.27f,
239          .minDelay =   10000,
240          .fifoReservedEventCount = 0,
241          .fifoMaxEventCount =   1220,
242          .stringType =         0,
243          .requiredPermission = 0,
244          .maxDelay =      200000,
245          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
246          .reserved =          {}
247         },
248         {.name =       "Geomagnetic Rotation Vector",
249          .vendor =     "hTC Corp.",
250          .version =    1,
251          .handle =     ID_CW_GEOMAGNETIC_ROTATION_VECTOR,
252          .type =       SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
253          .maxRange =   1.0f,
254          .resolution = 0.0001f,
255          .power =      11.27f,
256          .minDelay =   10000,
257          .fifoReservedEventCount = 0,
258          .fifoMaxEventCount =   1220,
259          .stringType =         0,
260          .requiredPermission = 0,
261          .maxDelay =      200000,
262          .flags = SENSOR_FLAG_CONTINUOUS_MODE,
263          .reserved =          {}
264         },
265         {.name =       "Significant Motion",
266          .vendor =     "hTC Corp.",
267          .version =    1,
268          .handle =     ID_CW_SIGNIFICANT_MOTION,
269          .type =       SENSOR_TYPE_SIGNIFICANT_MOTION,
270          .maxRange =   200.0f,
271          .resolution = 1.0f,
272          .power =      0.17f,
273          .minDelay =   -1,
274          .fifoReservedEventCount = 0,
275          .fifoMaxEventCount =      0,
276          .stringType =         0,
277          .requiredPermission = 0,
278          .maxDelay =           0,
279          .flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP,
280          .reserved =          {}
281         },
282         {.name =       "Step Detector",
283          .vendor =     "hTC Corp.",
284          .version =    1,
285          .handle =     ID_CW_STEP_DETECTOR,
286          .type =       SENSOR_TYPE_STEP_DETECTOR,
287          .maxRange =   200.0f,
288          .resolution = 1.0f,
289          .power =      0.17f,
290          .minDelay =   0,
291          .fifoReservedEventCount = 0,
292          .fifoMaxEventCount =   1220,
293          .stringType =         0,
294          .requiredPermission = 0,
295          .maxDelay =           0,
296          .flags = SENSOR_FLAG_SPECIAL_REPORTING_MODE,
297          .reserved =          {}
298         },
299         {.name =       "Step Counter",
300          .vendor =     "hTC Corp.",
301          .version =    1,
302          .handle =     ID_CW_STEP_COUNTER,
303          .type =       SENSOR_TYPE_STEP_COUNTER,
304          .maxRange =   200.0f,
305          .resolution = 1.0f,
306          .power =      0.17f,
307          .minDelay =   0,
308          .fifoReservedEventCount = 0,
309          .fifoMaxEventCount =   1220,
310          .stringType =         0,
311          .requiredPermission = 0,
312          .maxDelay =           0,
313          .flags = SENSOR_FLAG_ON_CHANGE_MODE,
314          .reserved =          {}
315         },
316 
317 
318         {.name =       "Accelerometer Sensor (WAKE_UP)",
319          .vendor =     "HTC Group Ltd.",
320          .version =    1,
321          .handle =     ID_A_W,
322          .type =       SENSOR_TYPE_ACCELEROMETER,
323          .maxRange =   RANGE_A,
324          .resolution = CONVERT_A,
325          .power =      0.17f,
326          .minDelay =   10000,
327          .fifoReservedEventCount = 0,
328          .fifoMaxEventCount =   1220,
329          .stringType =         0,
330          .requiredPermission = 0,
331          .maxDelay =      200000,
332          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
333          .reserved =          {}
334         },
335         {.name =       "Magnetic field Sensor (WAKE_UP)",
336          .vendor =     "HTC Group Ltd.",
337          .version =    1,
338          .handle =     ID_M_W,
339          .type =       SENSOR_TYPE_MAGNETIC_FIELD,
340          .maxRange =   200.0f,
341          .resolution = CONVERT_M,
342          .power =      5.0f,
343          .minDelay =   10000,
344          .fifoReservedEventCount = 0,
345          .fifoMaxEventCount =   1220,
346          .stringType =         0,
347          .requiredPermission = 0,
348          .maxDelay =      200000,
349          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
350          .reserved =          {}
351         },
352         {.name =       "Gyroscope Sensor (WAKE_UP)",
353          .vendor =     "HTC Group Ltd.",
354          .version =    1,
355          .handle =     ID_GY_W,
356          .type =       SENSOR_TYPE_GYROSCOPE,
357          .maxRange =   2000.0f,
358          .resolution = CONVERT_GYRO,
359          .power =      6.1f,
360          .minDelay =   10000,
361          .fifoReservedEventCount = 0,
362          .fifoMaxEventCount =   1220,
363          .stringType =         0,
364          .requiredPermission = 0,
365          .maxDelay =      200000,
366          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
367          .reserved =          {}
368         },
369         {.name =       "Pressure Sensor (WAKE_UP)",
370          .vendor =     "HTC Group Ltd.",
371          .version =    1,
372          .handle =     ID_PS_W,
373          .type =       SENSOR_TYPE_PRESSURE,
374          .maxRange =   2000,
375          .resolution = 1.0f,
376          .power =      0.0027f,
377          .minDelay =   10000,
378          .fifoReservedEventCount = 0,
379          .fifoMaxEventCount =   1220,
380          .stringType =         0,
381          .requiredPermission = 0,
382          .maxDelay =      200000,
383          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
384          .reserved =          {}
385         },
386         {.name =       "CWGD Orientation Sensor (WAKE_UP)",
387          .vendor =     "HTC Group Ltd.",
388          .version =    1,
389          .handle =     ID_O_W,
390          .type =       SENSOR_TYPE_ORIENTATION,
391          .maxRange =   360.0f,
392          .resolution = 0.1f,
393          .power =      11.27f,
394          .minDelay =   10000,
395          .fifoReservedEventCount = 0,
396          .fifoMaxEventCount =   1220,
397          .stringType =         0,
398          .requiredPermission = 0,
399          .maxDelay =      200000,
400          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
401          .reserved =          {}
402         },
403         {.name =       "Rotation Vector (WAKE_UP)",
404          .vendor =     "HTC Group Ltd.",
405          .version =    1,
406          .handle =     ID_RV_W,
407          .type =       SENSOR_TYPE_ROTATION_VECTOR,
408          .maxRange =   1.0f,
409          .resolution = 0.0001f,
410          .power =      11.27f,
411          .minDelay =   10000,
412          .fifoReservedEventCount = 0,
413          .fifoMaxEventCount =   1220,
414          .stringType =         0,
415          .requiredPermission = 0,
416          .maxDelay =      200000,
417          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
418          .reserved =          {}
419         },
420         {.name =       "Linear Acceleration (WAKE_UP)",
421          .vendor =     "HTC Group Ltd.",
422          .version =    1,
423          .handle =     ID_LA_W,
424          .type =       SENSOR_TYPE_LINEAR_ACCELERATION,
425          .maxRange =   RANGE_A,
426          .resolution = 0.01,
427          .power =      11.27f,
428          .minDelay =   10000,
429          .fifoReservedEventCount = 0,
430          .fifoMaxEventCount =   1220,
431          .stringType =         0,
432          .requiredPermission = 0,
433          .maxDelay =      200000,
434          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
435          .reserved =          {}
436         },
437         {.name =       "Gravity (WAKE_UP)",
438          .vendor =     "HTC Group Ltd.",
439          .version =    1,
440          .handle =     ID_G_W,
441          .type =       SENSOR_TYPE_GRAVITY,
442          .maxRange =   GRAVITY_EARTH,
443          .resolution = 0.01,
444          .power =      11.27f,
445          .minDelay =   10000,
446          .fifoReservedEventCount = 0,
447          .fifoMaxEventCount =   1220,
448          .stringType =         0,
449          .requiredPermission = 0,
450          .maxDelay =      200000,
451          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
452          .reserved =          {}
453         },
454         {.name =       "Magnetic Uncalibrated (WAKE_UP)",
455          .vendor =     "hTC Corp.",
456          .version =    1,
457          .handle =     ID_CW_MAGNETIC_UNCALIBRATED_W,
458          .type =       SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
459          .maxRange =   200.0f,
460          .resolution = CONVERT_M,
461          .power =      5.0f,
462          .minDelay =   10000,
463          .fifoReservedEventCount = 0,
464          .fifoMaxEventCount =    610,
465          .stringType =         0,
466          .requiredPermission = 0,
467          .maxDelay =      200000,
468          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
469          .reserved =          {}
470         },
471         {.name =       "Gyroscope Uncalibrated (WAKE_UP)",
472          .vendor =     "hTC Corp.",
473          .version =    1,
474          .handle =     ID_CW_GYROSCOPE_UNCALIBRATED_W,
475          .type =       SENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
476          .maxRange =   2000.0f,
477          .resolution = CONVERT_GYRO,
478          .power =      6.1f,
479          .minDelay =   10000,
480          .fifoReservedEventCount = 0,
481          .fifoMaxEventCount =    610,
482          .stringType =         0,
483          .requiredPermission = 0,
484          .maxDelay =      200000,
485          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
486          .reserved =          {}
487         },
488         {.name =       "Game Rotation Vector (WAKE_UP)",
489          .vendor =     "hTC Corp.",
490          .version =    1,
491          .handle =     ID_CW_GAME_ROTATION_VECTOR_W,
492          .type =       SENSOR_TYPE_GAME_ROTATION_VECTOR,
493          .maxRange =   1.0f,
494          .resolution = 0.0001f,
495          .power =      11.27f,
496          .minDelay =   10000,
497          .fifoReservedEventCount = 0,
498          .fifoMaxEventCount =   1220,
499          .stringType =         0,
500          .requiredPermission = 0,
501          .maxDelay =      200000,
502          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
503          .reserved =          {}
504         },
505         {.name =       "Geomagnetic Rotation Vector (WAKE_UP)",
506          .vendor =     "hTC Corp.",
507          .version =    1,
508          .handle =     ID_CW_GEOMAGNETIC_ROTATION_VECTOR_W,
509          .type =       SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
510          .maxRange =   1.0f,
511          .resolution = 0.0001f,
512          .power =      11.27f,
513          .minDelay =   10000,
514          .fifoReservedEventCount = 0,
515          .fifoMaxEventCount =   1220,
516          .stringType =         0,
517          .requiredPermission = 0,
518          .maxDelay =      200000,
519          .flags = SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP,
520          .reserved =          {}
521         },
522         {.name =       "Step Detector (WAKE_UP)",
523          .vendor =     "hTC Corp.",
524          .version =    1,
525          .handle =     ID_CW_STEP_DETECTOR_W,
526          .type =       SENSOR_TYPE_STEP_DETECTOR,
527          .maxRange =   200.0f,
528          .resolution = 1.0f,
529          .power =      0.17f,
530          .minDelay =   0,
531          .fifoReservedEventCount = 0,
532          .fifoMaxEventCount =   1220,
533          .stringType =         0,
534          .requiredPermission = 0,
535          .maxDelay =           0,
536          .flags = SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP,
537          .reserved =          {}
538         },
539         {.name =       "Step Counter (WAKE_UP)",
540          .vendor =     "hTC Corp.",
541          .version =    1,
542          .handle =     ID_CW_STEP_COUNTER_W,
543          .type =       SENSOR_TYPE_STEP_COUNTER,
544          .maxRange =   200.0f,
545          .resolution = 1.0f,
546          .power =      0.17f,
547          .minDelay =   0,
548          .fifoReservedEventCount = 0,
549          .fifoMaxEventCount =   1220,
550          .stringType =         0,
551          .requiredPermission = 0,
552          .maxDelay =           0,
553          .flags = SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP,
554          .reserved =          {}
555         },
556 };
557 
558 static int open_sensors(const struct hw_module_t* module, const char* id,
559                         struct hw_device_t** device);
560 
sensors__get_sensors_list(struct sensors_module_t *,struct sensor_t const ** list)561 static int sensors__get_sensors_list(struct sensors_module_t*,
562                                      struct sensor_t const** list)
563 {
564     *list = sSensorList;
565     return ARRAY_SIZE(sSensorList);
566 }
567 
568 static struct hw_module_methods_t sensors_module_methods = {
569     open: open_sensors
570 };
571 
572 struct sensors_module_t HAL_MODULE_INFO_SYM = {
573     common: {
574             tag: HARDWARE_MODULE_TAG,
575             version_major: 1,
576             version_minor: 0,
577             id: SENSORS_HARDWARE_MODULE_ID,
578             name: "Sensor module",
579             author: "Electronic Company",
580             methods: &sensors_module_methods,
581             dso: NULL,
582             reserved: { },
583     },
584     get_sensors_list: sensors__get_sensors_list,
585 };
586 
587 struct sensors_poll_context_t {
588     sensors_poll_device_1_t device; // must be first
589 
590         sensors_poll_context_t();
591         ~sensors_poll_context_t();
592     int activate(int handle, int enabled);
593     int setDelay(int handle, int64_t ns);
594     int pollEvents(sensors_event_t* data, int count);
595     int batch(int handle, int flags, int64_t period_ns, int64_t timeout);
596     int flush(int handle);
597 
598 private:
599     enum {
600         cwmcu            = 0,
601         numSensorDrivers,
602         numFds,
603     };
604 
605     static const size_t wake = numFds - 1;
606     static const char WAKE_MESSAGE = 'W';
607     struct pollfd mPollFds[numFds];
608     int mWritePipeFd;
609     SensorBase* mSensors[numSensorDrivers];
610 
handleToDriversensors_poll_context_t611 int handleToDriver(int handle) const {
612         switch (handle) {
613                 case ID_A:
614                 case ID_M:
615                 case ID_GY:
616                 case ID_L:
617                 case ID_PS:
618                 case ID_O:
619                 case ID_RV:
620                 case ID_LA:
621                 case ID_G:
622                 case ID_CW_MAGNETIC_UNCALIBRATED:
623                 case ID_CW_GYROSCOPE_UNCALIBRATED:
624                 case ID_CW_GAME_ROTATION_VECTOR:
625                 case ID_CW_GEOMAGNETIC_ROTATION_VECTOR:
626                 case ID_CW_SIGNIFICANT_MOTION:
627                 case ID_CW_STEP_DETECTOR:
628                 case ID_CW_STEP_COUNTER:
629                 case ID_A_W:
630                 case ID_M_W:
631                 case ID_GY_W:
632                 case ID_PS_W:
633                 case ID_O_W:
634                 case ID_RV_W:
635                 case ID_LA_W:
636                 case ID_G_W:
637                 case ID_CW_MAGNETIC_UNCALIBRATED_W:
638                 case ID_CW_GYROSCOPE_UNCALIBRATED_W:
639                 case ID_CW_GAME_ROTATION_VECTOR_W:
640                 case ID_CW_GEOMAGNETIC_ROTATION_VECTOR_W:
641                 case ID_CW_STEP_DETECTOR_W:
642                 case ID_CW_STEP_COUNTER_W:
643                         return cwmcu;
644         }
645         return -EINVAL;
646     }
647 };
648 
649 /*****************************************************************************/
650 
sensors_poll_context_t()651 sensors_poll_context_t::sensors_poll_context_t()
652 {
653     mSensors[cwmcu] = new CwMcuSensor();
654     mPollFds[cwmcu].fd = mSensors[cwmcu]->getFd();
655     mPollFds[cwmcu].events = POLLIN;
656     mPollFds[cwmcu].revents = 0;
657 
658     int wakeFds[2];
659     int result = pipe(wakeFds);
660     ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));
661     fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
662     fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
663     mWritePipeFd = wakeFds[1];
664 
665     mPollFds[wake].fd = wakeFds[0];
666     mPollFds[wake].events = POLLIN;
667     mPollFds[wake].revents = 0;
668 }
669 
~sensors_poll_context_t()670 sensors_poll_context_t::~sensors_poll_context_t() {
671     for (int i=0 ; i<numSensorDrivers ; i++) {
672         delete mSensors[i];
673     }
674     close(mPollFds[wake].fd);
675     close(mWritePipeFd);
676 }
677 
activate(int handle,int enabled)678 int sensors_poll_context_t::activate(int handle, int enabled) {
679     int index = handleToDriver(handle);
680     if (index < 0) return index;
681     int err =  mSensors[index]->setEnable(handle, enabled);
682     if (enabled && !err) {
683         const char wakeMessage(WAKE_MESSAGE);
684         int result = write(mWritePipeFd, &wakeMessage, 1);
685         ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));
686     }
687     return err;
688 }
689 
setDelay(int handle,int64_t ns)690 int sensors_poll_context_t::setDelay(int handle, int64_t ns) {
691 
692     int index = handleToDriver(handle);
693     if (index < 0) return index;
694     return mSensors[index]->setDelay(handle, ns);
695 }
696 
pollEvents(sensors_event_t * data,int count)697 int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
698 {
699     int nbEvents = 0;
700     int n = 0;
701     do {
702         // see if we have some leftover from the last poll()
703         for (int i=0 ; count && i<numSensorDrivers ; i++) {
704             SensorBase* const sensor(mSensors[i]);
705             if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) {
706                 int nb = sensor->readEvents(data, count);
707                 if (nb < count) {
708                     // no more data for this sensor
709                     mPollFds[i].revents = 0;
710                 }
711                 count -= nb;
712                 nbEvents += nb;
713                 data += nb;
714             }
715         }
716 
717         if (count) {
718             // we still have some room, so try to see if we can get
719             // some events immediately or just wait if we don't have
720             // anything to return
721             do {
722                 TEMP_FAILURE_RETRY(n = poll(mPollFds, numFds, nbEvents ? 0 : -1));
723             } while (n < 0 && errno == EINTR);
724             if (n<0) {
725                 ALOGE("poll() failed (%s)", strerror(errno));
726                 return -errno;
727             }
728             if (mPollFds[wake].revents & POLLIN) {
729                 char msg(WAKE_MESSAGE);
730                 int result = read(mPollFds[wake].fd, &msg, 1);
731                 ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
732                 ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
733                 mPollFds[wake].revents = 0;
734             }
735         }
736         // if we have events and space, go read them
737     } while (n && count);
738     return nbEvents;
739 }
740 
batch(int handle,int flags,int64_t period_ns,int64_t timeout)741 int sensors_poll_context_t::batch(int handle, int flags, int64_t period_ns, int64_t timeout)
742 {
743     int index = handleToDriver(handle);
744 
745     if (index < 0)
746         return index;
747 
748     int err = mSensors[index]->batch(handle, flags, period_ns, timeout);
749 
750     return err;
751 }
752 
flush(int handle)753 int sensors_poll_context_t::flush(int handle)
754 {
755     int index = handleToDriver(handle);
756 
757     if (index < 0)
758         return index;
759 
760     int err = mSensors[index]->flush(handle);
761 
762     return err;
763 }
764 
765 
766 /*****************************************************************************/
767 
poll__close(struct hw_device_t * dev)768 static int poll__close(struct hw_device_t *dev)
769 {
770     sensors_poll_context_t *ctx = reinterpret_cast<sensors_poll_context_t *>(dev);
771     if (ctx) {
772         delete ctx;
773     }
774     return 0;
775 }
776 
poll__activate(struct sensors_poll_device_t * dev,int handle,int enabled)777 static int poll__activate(struct sensors_poll_device_t *dev,
778         int handle, int enabled) {
779     sensors_poll_context_t *ctx = reinterpret_cast<sensors_poll_context_t *>(dev);
780     return ctx->activate(handle, enabled);
781 }
782 
poll__setDelay(struct sensors_poll_device_t * dev,int handle,int64_t ns)783 static int poll__setDelay(struct sensors_poll_device_t *dev,
784         int handle, int64_t ns) {
785     sensors_poll_context_t *ctx = reinterpret_cast<sensors_poll_context_t *>(dev);
786     return ctx->setDelay(handle, ns);
787 }
788 
poll__poll(struct sensors_poll_device_t * dev,sensors_event_t * data,int count)789 static int poll__poll(struct sensors_poll_device_t *dev,
790         sensors_event_t* data, int count) {
791     sensors_poll_context_t *ctx = reinterpret_cast<sensors_poll_context_t *>(dev);
792     return ctx->pollEvents(data, count);
793 }
794 
poll__batch(struct sensors_poll_device_1 * dev,int handle,int flags,int64_t period_ns,int64_t timeout)795 static int poll__batch(struct sensors_poll_device_1 *dev,
796                       int handle, int flags, int64_t period_ns, int64_t timeout)
797 {
798     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
799     return ctx->batch(handle, flags, period_ns, timeout);
800 }
801 
poll__flush(struct sensors_poll_device_1 * dev,int handle)802 static int poll__flush(struct sensors_poll_device_1 *dev,
803                       int handle)
804 {
805     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
806     return ctx->flush(handle);
807 }
808 /*****************************************************************************/
809 
810 // Open a new instance of a sensor device using name
open_sensors(const struct hw_module_t * module,const char *,struct hw_device_t ** device)811 static int open_sensors(const struct hw_module_t* module, const char*,
812                         struct hw_device_t** device)
813 {
814     sensors_poll_context_t *dev = new sensors_poll_context_t();
815 
816     memset(&dev->device, 0, sizeof(sensors_poll_device_1_t));
817 
818     dev->device.common.tag = HARDWARE_DEVICE_TAG;
819     dev->device.common.version  = SENSORS_DEVICE_API_VERSION_1_3;
820     dev->device.common.module   = const_cast<hw_module_t*>(module);
821     dev->device.common.close    = poll__close;
822     dev->device.activate        = poll__activate;
823     dev->device.setDelay        = poll__setDelay;
824     dev->device.poll            = poll__poll;
825 
826     // Batch processing
827     dev->device.batch           = poll__batch;
828     dev->device.flush           = poll__flush;
829 
830     *device = &dev->device.common;
831 
832     return 0;
833 }
834 
835