Home | History | Annotate | Download | only in sensors
      1 /*
      2  * Copyright (C) 2010 Motorola, Inc.
      3  * Copyright (C) 2008 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #include <fcntl.h>
     19 #include <errno.h>
     20 #include <math.h>
     21 #include <poll.h>
     22 #include <unistd.h>
     23 #include <dirent.h>
     24 #include <sys/select.h>
     25 
     26 #include <linux/bmp085.h>
     27 
     28 #include <cutils/log.h>
     29 
     30 #include "PressureSensor.h"
     31 
     32 /*****************************************************************************/
     33 
     34 PressureSensor::PressureSensor()
     35     : SensorBase(BAROMETER_DEVICE_NAME, "barometer"),
     36       mEnabled(0),
     37       mInputReader(32)
     38 {
     39     mPendingEvent.version = sizeof(sensors_event_t);
     40     mPendingEvent.sensor = ID_B;
     41     mPendingEvent.type = SENSOR_TYPE_PRESSURE;
     42     memset(mPendingEvent.data, 0x00, sizeof(mPendingEvent.data));
     43 
     44     open_device();
     45 
     46     // read the actual value of all sensors if they're enabled already
     47     struct input_absinfo absinfo;
     48     int flags = 0;
     49     if (!ioctl(dev_fd, BMP085_IOCTL_GET_ENABLE, &flags)) {
     50         if (flags)  {
     51             mEnabled = 1;
     52             if (!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_PRESSURE), &absinfo)) {
     53                 mPendingEvent.pressure = absinfo.value * CONVERT_B;
     54             }
     55         }
     56     }
     57     if (!mEnabled) {
     58         close_device();
     59     }
     60 }
     61 
     62 PressureSensor::~PressureSensor() {
     63 }
     64 
     65 int PressureSensor::enable(int32_t, int en)
     66 {
     67     int flags = en ? 1 : 0;
     68     int err = 0;
     69     if (flags != mEnabled) {
     70         if (flags) {
     71             open_device();
     72         }
     73         err = ioctl(dev_fd, BMP085_IOCTL_SET_ENABLE, &flags);
     74         err = err<0 ? -errno : 0;
     75         ALOGE_IF(err, "BMP085_IOCTL_SET_ENABLE failed (%s)", strerror(-err));
     76         if (!err) {
     77             mEnabled = flags;
     78         }
     79         if (!flags) {
     80             close_device();
     81         }
     82     }
     83     return err;
     84 }
     85 
     86 int PressureSensor::setDelay(int32_t handle, int64_t ns)
     87 {
     88     if (ns < 0)
     89         return -EINVAL;
     90 
     91     int delay = ns / 1000000;
     92     if (ioctl(dev_fd, BMP085_IOCTL_SET_DELAY, &delay)) {
     93         return -errno;
     94     }
     95     return 0;
     96 }
     97 
     98 int PressureSensor::readEvents(sensors_event_t* data, int count)
     99 {
    100     if (count < 1)
    101         return -EINVAL;
    102 
    103     ssize_t n = mInputReader.fill(data_fd);
    104     if (n < 0)
    105         return n;
    106     int numEventReceived = 0;
    107     input_event const* event;
    108 
    109     while (count && mInputReader.readEvent(&event)) {
    110         int type = event->type;
    111         if (type == EV_ABS) {
    112             processEvent(event->code, event->value);
    113         } else if (type == EV_SYN) {
    114             int64_t time = timevalToNano(event->time);
    115             mPendingEvent.timestamp = time;
    116             if (mEnabled) {
    117                 *data++ = mPendingEvent;
    118                 count--;
    119                 numEventReceived++;
    120             }
    121         } else {
    122             ALOGE("PressureSensor: unknown event (type=%d, code=%d)",
    123                     type, event->code);
    124         }
    125         mInputReader.next();
    126     }
    127 
    128     return numEventReceived;
    129 }
    130 
    131 void PressureSensor::processEvent(int code, int value)
    132 {
    133     if (code == EVENT_TYPE_PRESSURE) {
    134             mPendingEvent.pressure = value * CONVERT_B;
    135     }
    136 }
    137