Home | History | Annotate | Download | only in libsensors_iio
      1 /*
      2 * Copyright (C) 2012 Invensense, Inc.
      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 FUNC_LOG LOGV("%s", __PRETTY_FUNCTION__)
     18 
     19 #include <hardware/sensors.h>
     20 #include <fcntl.h>
     21 #include <errno.h>
     22 #include <dirent.h>
     23 #include <math.h>
     24 #include <poll.h>
     25 #include <pthread.h>
     26 #include <stdlib.h>
     27 
     28 #include <linux/input.h>
     29 
     30 #include <utils/Atomic.h>
     31 #include <utils/Log.h>
     32 
     33 #include "sensors.h"
     34 #include "MPLSensor.h"
     35 
     36 /*****************************************************************************/
     37 /* The SENSORS Module */
     38 
     39 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
     40 #define LOCAL_SENSORS (MPLSensor::numSensors + 1)
     41 #else
     42 #define LOCAL_SENSORS MPLSensor::numSensors
     43 #endif
     44 
     45 /* Vendor-defined Accel Load Calibration File Method
     46 * @param[out] Accel bias, length 3.  In HW units scaled by 2^16 in body frame
     47 * @return '0' for a successful load, '1' otherwise
     48 * example: int AccelLoadConfig(long* offset);
     49 * End of Vendor-defined Accel Load Cal Method
     50 */
     51 
     52 static struct sensor_t sSensorList[LOCAL_SENSORS];
     53 static int sensors = (sizeof(sSensorList) / sizeof(sensor_t));
     54 
     55 static int open_sensors(const struct hw_module_t* module, const char* id,
     56                         struct hw_device_t** device);
     57 
     58 static int sensors__get_sensors_list(struct sensors_module_t* module,
     59                                      struct sensor_t const** list)
     60 {
     61     *list = sSensorList;
     62     return sensors;
     63 }
     64 
     65 static struct hw_module_methods_t sensors_module_methods = {
     66         open: open_sensors
     67 };
     68 
     69 struct sensors_module_t HAL_MODULE_INFO_SYM = {
     70         common: {
     71                 tag: HARDWARE_MODULE_TAG,
     72                 version_major: 1,
     73                 version_minor: 0,
     74                 id: SENSORS_HARDWARE_MODULE_ID,
     75                 name: "Invensense module",
     76                 author: "Invensense Inc.",
     77                 methods: &sensors_module_methods,
     78         },
     79         get_sensors_list: sensors__get_sensors_list,
     80 };
     81 
     82 struct sensors_poll_context_t {
     83     struct sensors_poll_device_t device; // must be first
     84 
     85     sensors_poll_context_t();
     86     ~sensors_poll_context_t();
     87     int activate(int handle, int enabled);
     88     int setDelay(int handle, int64_t ns);
     89     int pollEvents(sensors_event_t* data, int count);
     90 
     91 private:
     92     enum {
     93         mpl = 0,
     94         compass,
     95         dmpOrient,
     96         numSensorDrivers,   // wake pipe goes here
     97         numFds,
     98     };
     99 
    100     struct pollfd mPollFds[numSensorDrivers];
    101     SensorBase *mSensor;
    102 };
    103 
    104 /******************************************************************************/
    105 
    106 sensors_poll_context_t::sensors_poll_context_t() {
    107     VFUNC_LOG;
    108 
    109     mCompassSensor = new CompassSensor();
    110     MPLSensor *mplSensor = new MPLSensor(mCompassSensor);
    111 
    112    /* For Vendor-defined Accel Calibration File Load
    113     * Use the Following Constructor and Pass Your Load Cal File Function
    114     *
    115     * MPLSensor *mplSensor = new MPLSensor(mCompassSensor, AccelLoadConfig);
    116     */
    117 
    118     // setup the callback object for handing mpl callbacks
    119     setCallbackObject(mplSensor);
    120 
    121     // populate the sensor list
    122     sensors =
    123             mplSensor->populateSensorList(sSensorList, sizeof(sSensorList));
    124 
    125     mSensor = mplSensor;
    126     mPollFds[mpl].fd = mSensor->getFd();
    127     mPollFds[mpl].events = POLLIN;
    128     mPollFds[mpl].revents = 0;
    129 
    130     mPollFds[compass].fd = mCompassSensor->getFd();
    131     mPollFds[compass].events = POLLIN;
    132     mPollFds[compass].revents = 0;
    133 
    134     mPollFds[dmpOrient].fd = ((MPLSensor*) mSensor)->getDmpOrientFd();
    135     mPollFds[dmpOrient].events = POLLPRI;
    136     mPollFds[dmpOrient].revents = 0;
    137 }
    138 
    139 sensors_poll_context_t::~sensors_poll_context_t() {
    140     FUNC_LOG;
    141     delete mSensor;
    142 }
    143 
    144 int sensors_poll_context_t::activate(int handle, int enabled) {
    145     FUNC_LOG;
    146     return mSensor->enable(handle, enabled);
    147 }
    148 
    149 int sensors_poll_context_t::setDelay(int handle, int64_t ns)
    150 {
    151     FUNC_LOG;
    152     return mSensor->setDelay(handle, ns);
    153 }
    154 
    155 int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count)
    156 {
    157     VHANDLER_LOG;
    158 
    159     int nbEvents = 0;
    160     int nb, polltime = -1;
    161 
    162     // look for new events
    163     nb = poll(mPollFds, numSensorDrivers, polltime);
    164 
    165     if (nb > 0) {
    166         for (int i = 0; count && i < numSensorDrivers; i++) {
    167             if (mPollFds[i].revents & (POLLIN | POLLPRI)) {
    168                 nb = 0;
    169                 if (i == mpl) {
    170                     /* Ignore res */
    171                     mSensor->readEvents(NULL, 0);
    172                     mPollFds[i].revents = 0;
    173                 }
    174                 else if (i == compass) {
    175                     /* Ignore res */
    176                     ((MPLSensor*) mSensor)->readCompassEvents(NULL, count);
    177                     mPollFds[i].revents = 0;
    178                 }
    179             }
    180         }
    181         nb = ((MPLSensor*) mSensor)->executeOnData(data, count);
    182         if (nb > 0) {
    183             count -= nb;
    184             nbEvents += nb;
    185             data += nb;
    186         }
    187 
    188         if (mPollFds[dmpOrient].revents & (POLLIN | POLLPRI)) {
    189             nb = ((MPLSensor*) mSensor)->readDmpOrientEvents(data, count);
    190             mPollFds[dmpOrient].revents= 0;
    191             if (isDmpScreenAutoRotationEnabled() && nb > 0) {
    192                 count -= nb;
    193                 nbEvents += nb;
    194                 data += nb;
    195             }
    196         }
    197     }
    198 
    199     return nbEvents;
    200 }
    201 
    202 /******************************************************************************/
    203 
    204 static int poll__close(struct hw_device_t *dev)
    205 {
    206     FUNC_LOG;
    207     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    208     if (ctx) {
    209         delete ctx;
    210     }
    211     return 0;
    212 }
    213 
    214 static int poll__activate(struct sensors_poll_device_t *dev,
    215                           int handle, int enabled)
    216 {
    217     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    218     return ctx->activate(handle, enabled);
    219 }
    220 
    221 static int poll__setDelay(struct sensors_poll_device_t *dev,
    222                           int handle, int64_t ns)
    223 {
    224     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    225     int s= ctx->setDelay(handle, ns);
    226     return s;
    227 }
    228 
    229 static int poll__poll(struct sensors_poll_device_t *dev,
    230                       sensors_event_t* data, int count)
    231 {
    232     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    233     return ctx->pollEvents(data, count);
    234 }
    235 
    236 /******************************************************************************/
    237 
    238 /** Open a new instance of a sensor device using name */
    239 static int open_sensors(const struct hw_module_t* module, const char* id,
    240                         struct hw_device_t** device)
    241 {
    242     FUNC_LOG;
    243     int status = -EINVAL;
    244     sensors_poll_context_t *dev = new sensors_poll_context_t();
    245 
    246     memset(&dev->device, 0, sizeof(sensors_poll_device_t));
    247 
    248     dev->device.common.tag = HARDWARE_DEVICE_TAG;
    249     dev->device.common.version  = 0;
    250     dev->device.common.module   = const_cast<hw_module_t*>(module);
    251     dev->device.common.close    = poll__close;
    252     dev->device.activate        = poll__activate;
    253     dev->device.setDelay        = poll__setDelay;
    254     dev->device.poll            = poll__poll;
    255 
    256     *device = &dev->device.common;
    257     status = 0;
    258 
    259     return status;
    260 }
    261