Home | History | Annotate | Download | only in libsensors_iio
      1 /*
      2 * Copyright (C) 2014 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_legacy/power.h>
     20 #include <hardware/sensors.h>
     21 #include <fcntl.h>
     22 #include <errno.h>
     23 #include <dirent.h>
     24 #include <math.h>
     25 #include <poll.h>
     26 #include <pthread.h>
     27 #include <stdlib.h>
     28 
     29 #include <sys/queue.h>
     30 
     31 #include <linux/input.h>
     32 
     33 #include <utils/Atomic.h>
     34 #include <utils/Log.h>
     35 
     36 #include "sensors.h"
     37 #include "MPLSensor.h"
     38 
     39 /*
     40  * Vendor-defined Accel Load Calibration File Method
     41  * @param[out] Accel bias, length 3.  In HW units scaled by 2^16 in body frame
     42  * @return '0' for a successful load, '1' otherwise
     43  * example: int AccelLoadConfig(long* offset);
     44  * End of Vendor-defined Accel Load Cal Method
     45  */
     46 
     47 /*****************************************************************************/
     48 /* The SENSORS Module */
     49 
     50 #ifdef ENABLE_DMP_SCREEN_AUTO_ROTATION
     51 #define LOCAL_SENSORS (NumSensors + 1)
     52 #else
     53 #define LOCAL_SENSORS (NumSensors)
     54 #endif
     55 
     56 struct handle_entry {
     57     SIMPLEQ_ENTRY(handle_entry) entries;
     58     int handle;
     59 };
     60 
     61 static SIMPLEQ_HEAD(simplehead, handle_entry) pending_flush_items_head;
     62 struct simplehead *headp;
     63 static pthread_mutex_t flush_handles_mutex = PTHREAD_MUTEX_INITIALIZER;
     64 
     65 static const char *smdWakelockStr = "significant motion";
     66 
     67 static struct sensor_t sSensorList[LOCAL_SENSORS];
     68 static int sensors = (sizeof(sSensorList) / sizeof(sensor_t));
     69 
     70 static int open_sensors(const struct hw_module_t* module, const char* id,
     71                         struct hw_device_t** device);
     72 
     73 static int sensors__get_sensors_list(struct sensors_module_t* module,
     74                                      struct sensor_t const** list)
     75 {
     76     *list = sSensorList;
     77     return sensors;
     78 }
     79 
     80 static struct hw_module_methods_t sensors_module_methods = {
     81         open: open_sensors
     82 };
     83 
     84 struct sensors_module_t HAL_MODULE_INFO_SYM = {
     85         common: {
     86                 tag: HARDWARE_MODULE_TAG,
     87                 version_major: 1,
     88                 version_minor: 0,
     89                 id: SENSORS_HARDWARE_MODULE_ID,
     90                 name: "Invensense module",
     91                 author: "Invensense Inc.",
     92                 methods: &sensors_module_methods,
     93                 dso: NULL,
     94                 reserved: {0}
     95         },
     96         get_sensors_list: sensors__get_sensors_list,
     97 };
     98 
     99 struct sensors_poll_context_t {
    100     sensors_poll_device_1_t device; // must be first
    101 
    102     sensors_poll_context_t();
    103     ~sensors_poll_context_t();
    104     int activate(int handle, int enabled);
    105     int setDelay(int handle, int64_t ns);
    106     int pollEvents(sensors_event_t* data, int count);
    107     int query(int what, int *value);
    108     int batch(int handle, int flags, int64_t period_ns, int64_t timeout);
    109 #if defined ANDROID_KITKAT || defined ANDROID_LOLLIPOP
    110     int flush(int handle);
    111 #endif
    112 
    113 private:
    114     enum {
    115         mpl = 0,
    116         compass,
    117         dmpOrient,
    118         dmpSign,
    119         dmpPed,
    120         numSensorDrivers,
    121         numFds,
    122     };
    123 
    124     struct pollfd mPollFds[numFds];
    125     SensorBase *mSensor;
    126     CompassSensor *mCompassSensor;
    127 
    128     /* Significant Motion wakelock support */
    129     bool mSMDWakelockHeld;
    130 
    131 };
    132 
    133 /******************************************************************************/
    134 
    135 sensors_poll_context_t::sensors_poll_context_t() {
    136     VFUNC_LOG;
    137 
    138     /* TODO: Handle external pressure sensor */
    139     mCompassSensor = new CompassSensor();
    140     MPLSensor *mplSensor = new MPLSensor(mCompassSensor);
    141 
    142     /* No significant motion events pending yet */
    143     mSMDWakelockHeld = false;
    144 
    145    /* For Vendor-defined Accel Calibration File Load
    146     * Use the Following Constructor and Pass Your Load Cal File Function
    147     *
    148     * MPLSensor *mplSensor = new MPLSensor(mCompassSensor, AccelLoadConfig);
    149     */
    150 
    151     // Initialize pending flush queue
    152     SIMPLEQ_INIT(&pending_flush_items_head);
    153 
    154     // populate the sensor list
    155     sensors =
    156             mplSensor->populateSensorList(sSensorList, sizeof(sSensorList));
    157 
    158     mSensor = mplSensor;
    159     mPollFds[mpl].fd = mSensor->getFd();
    160     mPollFds[mpl].events = POLLIN;
    161     mPollFds[mpl].revents = 0;
    162 
    163     mPollFds[compass].fd = mCompassSensor->getFd();
    164     mPollFds[compass].events = POLLIN;
    165     mPollFds[compass].revents = 0;
    166 
    167     mPollFds[dmpOrient].fd = ((MPLSensor*) mSensor)->getDmpOrientFd();
    168     mPollFds[dmpOrient].events = POLLPRI;
    169     mPollFds[dmpOrient].revents = 0;
    170 
    171     mPollFds[dmpSign].fd = ((MPLSensor*) mSensor)->getDmpSignificantMotionFd();
    172     mPollFds[dmpSign].events = POLLPRI;
    173     mPollFds[dmpSign].revents = 0;
    174 
    175     mPollFds[dmpPed].fd = ((MPLSensor*) mSensor)->getDmpPedometerFd();
    176     mPollFds[dmpPed].events = POLLPRI;
    177     mPollFds[dmpPed].revents = 0;
    178 }
    179 
    180 sensors_poll_context_t::~sensors_poll_context_t() {
    181     FUNC_LOG;
    182     delete mSensor;
    183     delete mCompassSensor;
    184     for (int i = 0; i < numSensorDrivers; i++) {
    185         close(mPollFds[i].fd);
    186     }
    187 }
    188 
    189 int sensors_poll_context_t::activate(int handle, int enabled) {
    190     FUNC_LOG;
    191 
    192     int err;
    193     err = mSensor->enable(handle, enabled);
    194     return err;
    195 }
    196 
    197 int sensors_poll_context_t::setDelay(int handle, int64_t ns)
    198 {
    199     FUNC_LOG;
    200     return mSensor->setDelay(handle, ns);
    201 }
    202 
    203 int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count)
    204 {
    205     VHANDLER_LOG;
    206 
    207     int nbEvents = 0;
    208     int nb, polltime = -1;
    209 
    210     if (mSMDWakelockHeld) {
    211         mSMDWakelockHeld = false;
    212         release_wake_lock(smdWakelockStr);
    213     }
    214 
    215     struct handle_entry *handle_element;
    216     pthread_mutex_lock(&flush_handles_mutex);
    217     if (!SIMPLEQ_EMPTY(&pending_flush_items_head)) {
    218         sensors_event_t flushCompleteEvent;
    219         flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
    220         flushCompleteEvent.sensor = 0;
    221         handle_element = SIMPLEQ_FIRST(&pending_flush_items_head);
    222         flushCompleteEvent.meta_data.sensor = handle_element->handle;
    223         SIMPLEQ_REMOVE_HEAD(&pending_flush_items_head, entries);
    224         free(handle_element);
    225         memcpy(data, (void *) &flushCompleteEvent, sizeof(flushCompleteEvent));
    226         LOGI_IF(1, "pollEvents() Returning fake flush event completion for handle %d",
    227                 flushCompleteEvent.meta_data.sensor);
    228         pthread_mutex_unlock(&flush_handles_mutex);
    229         return 1;
    230     }
    231     pthread_mutex_unlock(&flush_handles_mutex);
    232 
    233     polltime = ((MPLSensor*) mSensor)->getStepCountPollTime();
    234 
    235     // look for new events
    236     nb = poll(mPollFds, numSensorDrivers, polltime);
    237     LOGI_IF(0, "poll nb=%d, count=%d, pt=%d", nb, count, polltime);
    238     if (nb > 0) {
    239         for (int i = 0; count && i < numSensorDrivers; i++) {
    240             if (mPollFds[i].revents & (POLLIN | POLLPRI)) {
    241                 nb = 0;
    242                 if (i == mpl) {
    243                     ((MPLSensor*) mSensor)->buildMpuEvent();
    244                     mPollFds[i].revents = 0;
    245                 } else if (i == compass) {
    246                     ((MPLSensor*) mSensor)->buildCompassEvent();
    247                     mPollFds[i].revents = 0;
    248                 } else if (i == dmpOrient) {
    249                     nb = ((MPLSensor*)mSensor)->
    250                                         readDmpOrientEvents(data, count);
    251                     mPollFds[dmpOrient].revents= 0;
    252                     if (isDmpScreenAutoRotationEnabled() && nb > 0) {
    253                         count -= nb;
    254                         nbEvents += nb;
    255                         data += nb;
    256                     }
    257                 } else if (i == dmpSign) {
    258                     nb = ((MPLSensor*) mSensor)->
    259                                     readDmpSignificantMotionEvents(data, count);
    260                     mPollFds[i].revents = 0;
    261                     if (nb) {
    262                         if (!mSMDWakelockHeld) {
    263                             /* Hold wakelock until Sensor Services reads event */
    264                             acquire_wake_lock(PARTIAL_WAKE_LOCK, smdWakelockStr);
    265                             LOGI_IF(1, "HAL: grabbed %s wakelock", smdWakelockStr);
    266                             mSMDWakelockHeld = true;
    267                         }
    268 
    269                         count -= nb;
    270                         nbEvents += nb;
    271                         data += nb;
    272                     }
    273                 } else if (i == dmpPed) {
    274                     nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(
    275                             data, count, ID_P, 0);
    276                     mPollFds[i].revents = 0;
    277                     count -= nb;
    278                     nbEvents += nb;
    279                     data += nb;
    280                 }
    281                 if(nb == 0) {
    282                     nb = ((MPLSensor*) mSensor)->readEvents(data, count);
    283                     LOGI_IF(0, "sensors_mpl:readEvents() - "
    284                             "i=%d, nb=%d, count=%d, nbEvents=%d, "
    285                             "data->timestamp=%lld, data->data[0]=%f,",
    286                             i, nb, count, nbEvents, data->timestamp,
    287                             data->data[0]);
    288                     if (nb > 0) {
    289                         count -= nb;
    290                         nbEvents += nb;
    291                         data += nb;
    292                     }
    293                 }
    294             }
    295         }
    296 
    297         /* to see if any step counter events */
    298         if(((MPLSensor*) mSensor)->hasStepCountPendingEvents() == true) {
    299             nb = 0;
    300             nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(
    301                             data, count, ID_SC, 0);
    302             LOGI_IF(SensorBase::HANDLER_DATA, "sensors_mpl:readStepCount() - "
    303                     "nb=%d, count=%d, nbEvents=%d, data->timestamp=%lld, ",
    304                     nb, count, nbEvents, data->timestamp);
    305             if (nb > 0) {
    306                 count -= nb;
    307                 nbEvents += nb;
    308                 data += nb;
    309             }
    310         }
    311     } else if(nb == 0) {
    312         /* to see if any step counter events */
    313         if(((MPLSensor*) mSensor)->hasStepCountPendingEvents() == true) {
    314             nb = 0;
    315             nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(
    316                             data, count, ID_SC, 0);
    317             LOGI_IF(SensorBase::HANDLER_DATA, "sensors_mpl:readStepCount() - "
    318                     "nb=%d, count=%d, nbEvents=%d, data->timestamp=%lld, ",
    319                     nb, count, nbEvents, data->timestamp);
    320             if (nb > 0) {
    321                 count -= nb;
    322                 nbEvents += nb;
    323                 data += nb;
    324             }
    325         }
    326     }
    327     return nbEvents;
    328 }
    329 
    330 int sensors_poll_context_t::query(int what, int* value)
    331 {
    332     FUNC_LOG;
    333     return mSensor->query(what, value);
    334 }
    335 
    336 int sensors_poll_context_t::batch(int handle, int flags, int64_t period_ns,
    337                                   int64_t timeout)
    338 {
    339     FUNC_LOG;
    340     return mSensor->batch(handle, flags, period_ns, timeout);
    341 }
    342 
    343 #if defined ANDROID_KITKAT || defined ANDROID_LOLLIPOP
    344 
    345 void inv_pending_flush(int handle) {
    346     struct handle_entry *the_entry;
    347     pthread_mutex_lock(&flush_handles_mutex);
    348     the_entry = (struct handle_entry*) malloc(sizeof(struct handle_entry));
    349     if (the_entry != NULL) {
    350         LOGI_IF(0, "Inserting %d into pending list", handle);
    351         the_entry->handle = handle;
    352         SIMPLEQ_INSERT_TAIL(&pending_flush_items_head, the_entry, entries);
    353     } else {
    354         LOGE("ERROR malloc'ing space for pending handler flush entry");
    355     }
    356     pthread_mutex_unlock(&flush_handles_mutex);
    357 }
    358 
    359 int sensors_poll_context_t::flush(int handle)
    360 {
    361     FUNC_LOG;
    362     return mSensor->flush(handle);
    363 }
    364 #endif
    365 
    366 /******************************************************************************/
    367 
    368 static int poll__close(struct hw_device_t *dev)
    369 {
    370     FUNC_LOG;
    371     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    372     if (ctx) {
    373         delete ctx;
    374     }
    375     return 0;
    376 }
    377 
    378 static int poll__activate(struct sensors_poll_device_t *dev,
    379                           int handle, int enabled)
    380 {
    381     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    382     return ctx->activate(handle, enabled);
    383 }
    384 
    385 static int poll__setDelay(struct sensors_poll_device_t *dev,
    386                           int handle, int64_t ns)
    387 {
    388     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    389     int s= ctx->setDelay(handle, ns);
    390     return s;
    391 }
    392 
    393 static int poll__poll(struct sensors_poll_device_t *dev,
    394                       sensors_event_t* data, int count)
    395 {
    396     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    397     return ctx->pollEvents(data, count);
    398 }
    399 
    400 static int poll__query(struct sensors_poll_device_1 *dev,
    401                       int what, int *value)
    402 {
    403     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    404     return ctx->query(what, value);
    405 }
    406 
    407 static int poll__batch(struct sensors_poll_device_1 *dev,
    408                       int handle, int flags, int64_t period_ns, int64_t timeout)
    409 {
    410     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    411     return ctx->batch(handle, flags, period_ns, timeout);
    412 }
    413 
    414 #if defined ANDROID_KITKAT || defined ANDROID_LOLLIPOP
    415 static int poll__flush(struct sensors_poll_device_1 *dev,
    416                       int handle)
    417 {
    418     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    419     int status = ctx->flush(handle);
    420     if (handle == SENSORS_STEP_COUNTER_HANDLE) {
    421         LOGI_IF(0, "creating flush completion event for handle %d", handle);
    422         inv_pending_flush(handle);
    423         return 0;
    424     }
    425     return status;
    426 }
    427 #endif
    428 /******************************************************************************/
    429 
    430 /** Open a new instance of a sensor device using name */
    431 static int open_sensors(const struct hw_module_t* module, const char* id,
    432                         struct hw_device_t** device)
    433 {
    434     FUNC_LOG;
    435     int status = -EINVAL;
    436     sensors_poll_context_t *dev = new sensors_poll_context_t();
    437 
    438     memset(&dev->device, 0, sizeof(sensors_poll_device_1));
    439 
    440     dev->device.common.tag = HARDWARE_DEVICE_TAG;
    441     dev->device.common.version  = SENSORS_DEVICE_API_VERSION_1_3;
    442     dev->device.flush           = poll__flush;
    443     dev->device.common.module   = const_cast<hw_module_t*>(module);
    444     dev->device.common.close    = poll__close;
    445     dev->device.activate        = poll__activate;
    446     dev->device.setDelay        = poll__setDelay;
    447     dev->device.poll            = poll__poll;
    448     dev->device.batch           = poll__batch;
    449 
    450     *device = &dev->device.common;
    451     status = 0;
    452 
    453     return status;
    454 }
    455