Home | History | Annotate | Download | only in sensors
      1 /*
      2  * Copyright (C) 2008 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 #include <hardware/sensors.h>
     18 #include <fcntl.h>
     19 #include <errno.h>
     20 #include <dirent.h>
     21 #include <math.h>
     22 
     23 #include <poll.h>
     24 #include <pthread.h>
     25 
     26 #include <linux/input.h>
     27 
     28 #include <cutils/atomic.h>
     29 #include <cutils/log.h>
     30 
     31 #include "nusensors.h"
     32 #include "AccelerationSensor.h"
     33 #include "LightSensor.h"
     34 #include "AkmSensor.h"
     35 #include "PressureSensor.h"
     36 #include "GyroSensor.h"
     37 
     38 /*****************************************************************************/
     39 
     40 struct sensors_poll_context_t {
     41     struct sensors_poll_device_t device; // must be first
     42 
     43         sensors_poll_context_t();
     44         ~sensors_poll_context_t();
     45     int activate(int handle, int enabled);
     46     int setDelay(int handle, int64_t ns);
     47     int pollEvents(sensors_event_t* data, int count);
     48 
     49 private:
     50     enum {
     51 	acceleration    = 0,
     52 	light           = 1,
     53 	akm		= 2,
     54 	pressure	= 3,
     55 	gyro		= 4,
     56         numSensorDrivers,
     57         numFds,
     58     };
     59 
     60     static const size_t wake = numFds - 1;
     61     static const char WAKE_MESSAGE = 'W';
     62     struct pollfd mPollFds[numFds];
     63     int mWritePipeFd;
     64     SensorBase* mSensors[numSensorDrivers];
     65 
     66     int handleToDriver(int handle) const {
     67         switch (handle) {
     68             case ID_A:
     69                 return acceleration;
     70             case ID_M:
     71             case ID_O:
     72                 return akm;
     73             case ID_G:
     74                 return gyro;
     75             case ID_L:
     76                 return light;
     77 	    case ID_B:
     78                 return pressure;
     79         }
     80         return -EINVAL;
     81     }
     82 };
     83 
     84 /*****************************************************************************/
     85 
     86 sensors_poll_context_t::sensors_poll_context_t()
     87 {
     88     mSensors[acceleration] = new AccelerationSensor();
     89     mPollFds[acceleration].fd = mSensors[acceleration]->getFd();
     90     mPollFds[acceleration].events = POLLIN;
     91     mPollFds[acceleration].revents = 0;
     92 
     93     mSensors[light] = new LightSensor();
     94     mPollFds[light].fd = mSensors[light]->getFd();
     95     mPollFds[light].events = POLLIN;
     96     mPollFds[light].revents = 0;
     97 
     98     mSensors[akm] = new AkmSensor();
     99     mPollFds[akm].fd = mSensors[akm]->getFd();
    100     mPollFds[akm].events = POLLIN;
    101     mPollFds[akm].revents = 0;
    102 
    103     mSensors[pressure] = new PressureSensor();
    104     mPollFds[pressure].fd = mSensors[pressure]->getFd();
    105     mPollFds[pressure].events = POLLIN;
    106     mPollFds[pressure].revents = 0;
    107 
    108     mSensors[gyro] = new GyroSensor();
    109     mPollFds[gyro].fd = mSensors[gyro]->getFd();
    110     mPollFds[gyro].events = POLLIN;
    111     mPollFds[gyro].revents = 0;
    112 
    113     int wakeFds[2];
    114     int result = pipe(wakeFds);
    115     ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));
    116     fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
    117     fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
    118     mWritePipeFd = wakeFds[1];
    119 
    120     mPollFds[wake].fd = wakeFds[0];
    121     mPollFds[wake].events = POLLIN;
    122     mPollFds[wake].revents = 0;
    123 }
    124 
    125 sensors_poll_context_t::~sensors_poll_context_t() {
    126     for (int i=0 ; i<numSensorDrivers ; i++) {
    127         delete mSensors[i];
    128     }
    129     close(mPollFds[wake].fd);
    130     close(mWritePipeFd);
    131 }
    132 
    133 int sensors_poll_context_t::activate(int handle, int enabled) {
    134     int index = handleToDriver(handle);
    135     if (index < 0) return index;
    136     int err =  mSensors[index]->enable(handle, enabled);
    137     if (!err && handle == ID_O) {
    138         err = static_cast<AccelerationSensor*>(
    139                 mSensors[acceleration])->enableOrientation(enabled);
    140     }
    141     if (enabled && !err) {
    142         const char wakeMessage(WAKE_MESSAGE);
    143         int result = write(mWritePipeFd, &wakeMessage, 1);
    144         ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));
    145     }
    146     return err;
    147 }
    148 
    149 int sensors_poll_context_t::setDelay(int handle, int64_t ns) {
    150 
    151     int index = handleToDriver(handle);
    152     if (index < 0) return index;
    153     return mSensors[index]->setDelay(handle, ns);
    154 }
    155 
    156 int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
    157 {
    158     int nbEvents = 0;
    159     int n = 0;
    160 
    161     do {
    162         // see if we have some leftover from the last poll()
    163         for (int i=0 ; count && i<numSensorDrivers ; i++) {
    164             SensorBase* const sensor(mSensors[i]);
    165             if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) {
    166                 int nb = sensor->readEvents(data, count);
    167                 if (nb < count) {
    168                     // no more data for this sensor
    169                     mPollFds[i].revents = 0;
    170                 }
    171                 count -= nb;
    172                 nbEvents += nb;
    173                 data += nb;
    174             }
    175         }
    176 
    177         if (count) {
    178             // we still have some room, so try to see if we can get
    179             // some events immediately or just wait if we don't have
    180             // anything to return
    181             n = poll(mPollFds, numFds, nbEvents ? 0 : -1);
    182             if (n<0) {
    183                 ALOGE("poll() failed (%s)", strerror(errno));
    184                 return -errno;
    185             }
    186             if (mPollFds[wake].revents & POLLIN) {
    187                 char msg;
    188                 int result = read(mPollFds[wake].fd, &msg, 1);
    189                 ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
    190                 ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
    191                 mPollFds[wake].revents = 0;
    192             }
    193         }
    194         // if we have events and space, go read them
    195     } while (n && count);
    196 
    197     return nbEvents;
    198 }
    199 
    200 /*****************************************************************************/
    201 
    202 static int poll__close(struct hw_device_t *dev)
    203 {
    204     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    205     if (ctx) {
    206         delete ctx;
    207     }
    208     return 0;
    209 }
    210 
    211 static int poll__activate(struct sensors_poll_device_t *dev,
    212         int handle, int enabled) {
    213     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    214     return ctx->activate(handle, enabled);
    215 }
    216 
    217 static int poll__setDelay(struct sensors_poll_device_t *dev,
    218         int handle, int64_t ns) {
    219     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    220     return ctx->setDelay(handle, ns);
    221 }
    222 
    223 static int poll__poll(struct sensors_poll_device_t *dev,
    224         sensors_event_t* data, int count) {
    225     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    226     return ctx->pollEvents(data, count);
    227 }
    228 
    229 /*****************************************************************************/
    230 
    231 int init_nusensors(hw_module_t const* module, hw_device_t** device)
    232 {
    233     int status = -EINVAL;
    234 
    235     sensors_poll_context_t *dev = new sensors_poll_context_t();
    236     memset(&dev->device, 0, sizeof(sensors_poll_device_t));
    237 
    238     dev->device.common.tag = HARDWARE_DEVICE_TAG;
    239     dev->device.common.version  = 0;
    240     dev->device.common.module   = const_cast<hw_module_t*>(module);
    241     dev->device.common.close    = poll__close;
    242     dev->device.activate        = poll__activate;
    243     dev->device.setDelay        = poll__setDelay;
    244     dev->device.poll            = poll__poll;
    245 
    246     *device = &dev->device.common;
    247     status = 0;
    248     return status;
    249 }
    250