Home | History | Annotate | Download | only in libsensors
      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 
    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 
    611 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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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
    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