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 <fcntl.h>
     18 #include <errno.h>
     19 #include <math.h>
     20 #include <poll.h>
     21 #include <unistd.h>
     22 #include <dirent.h>
     23 #include <sys/select.h>
     24 
     25 #include <linux/kxtf9.h>
     26 
     27 #include <cutils/log.h>
     28 
     29 #include "AccelerationSensor.h"
     30 
     31 /*****************************************************************************/
     32 
     33 AccelerationSensor::AccelerationSensor()
     34     : SensorBase(ACCELEROMETER_DEVICE_NAME, "accelerometer"),
     35       mEnabled(0),
     36       mOrientationEnabled(0),
     37       mInputReader(32)
     38 {
     39     mPendingEvent.version = sizeof(sensors_event_t);
     40     mPendingEvent.sensor = ID_A;
     41     mPendingEvent.type = SENSOR_TYPE_ACCELEROMETER;
     42     mPendingEvent.acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
     43     memset(mPendingEvent.data, 0x00, sizeof(mPendingEvent.data));
     44 
     45     open_device();
     46 
     47     int flags = 0;
     48     if (!ioctl(dev_fd, KXTF9_IOCTL_GET_ENABLE, &flags)) {
     49         if (flags)  {
     50             mEnabled = 1;
     51         }
     52     }
     53     if (!mEnabled) {
     54         close_device();
     55     }
     56 }
     57 
     58 AccelerationSensor::~AccelerationSensor() {
     59 }
     60 
     61 int AccelerationSensor::enable(int32_t, int en)
     62 {
     63     int flags = en ? 1 : 0;
     64     int err = 0;
     65     if (flags != mEnabled) {
     66         // don't turn the accelerometer off, if the orientation
     67         // sensor is enabled
     68         if (mOrientationEnabled && !en) {
     69             mEnabled = flags;
     70             return 0;
     71         }
     72         if (flags) {
     73             open_device();
     74         }
     75         err = ioctl(dev_fd, KXTF9_IOCTL_SET_ENABLE, &flags);
     76         err = err<0 ? -errno : 0;
     77         ALOGE_IF(err, "KXTF9_IOCTL_SET_ENABLE failed (%s)", strerror(-err));
     78         if (!err) {
     79             mEnabled = flags;
     80         }
     81         if (!flags) {
     82             close_device();
     83         }
     84     }
     85     return err;
     86 }
     87 
     88 int AccelerationSensor::enableOrientation(int en)
     89 {
     90     int flags = en ? 1 : 0;
     91     int err = 0;
     92     if (flags != mOrientationEnabled) {
     93         // don't turn the accelerometer off, if the user has requested it
     94         if (mEnabled && !en) {
     95             mOrientationEnabled = flags;
     96             return 0;
     97         }
     98 
     99         if (flags) {
    100             open_device();
    101         }
    102         err = ioctl(dev_fd, KXTF9_IOCTL_SET_ENABLE, &flags);
    103         err = err<0 ? -errno : 0;
    104         ALOGE_IF(err, "KXTF9_IOCTL_SET_ENABLE failed (%s)", strerror(-err));
    105         if (!err) {
    106             mOrientationEnabled = flags;
    107         }
    108         if (!flags) {
    109             close_device();
    110         }
    111     }
    112     return err;
    113 }
    114 
    115 int AccelerationSensor::setDelay(int32_t handle, int64_t ns)
    116 {
    117     if (ns < 0)
    118         return -EINVAL;
    119 
    120     if (mEnabled || mOrientationEnabled) {
    121         int delay = ns / 1000000;
    122         if (ioctl(dev_fd, KXTF9_IOCTL_SET_DELAY, &delay)) {
    123             return -errno;
    124         }
    125     }
    126     return 0;
    127 }
    128 
    129 int AccelerationSensor::readEvents(sensors_event_t* data, int count)
    130 {
    131     if (count < 1)
    132         return -EINVAL;
    133 
    134     ssize_t n = mInputReader.fill(data_fd);
    135     if (n < 0)
    136         return n;
    137     int numEventReceived = 0;
    138     input_event const* event;
    139 
    140     while (count && mInputReader.readEvent(&event)) {
    141         int type = event->type;
    142         if (type == EV_REL) {
    143             processEvent(event->code, event->value);
    144         } else if (type == EV_SYN) {
    145             int64_t time = timevalToNano(event->time);
    146             mPendingEvent.timestamp = time;
    147             if (mEnabled) {
    148                 *data++ = mPendingEvent;
    149                 count--;
    150                 numEventReceived++;
    151             }
    152         // accelerometer sends valid ABS events for
    153         // userspace using EVIOCGABS
    154         } else if (type != EV_ABS) {
    155             ALOGE("AccelerationSensor: unknown event (type=%d, code=%d)",
    156                     type, event->code);
    157         }
    158         mInputReader.next();
    159     }
    160 
    161     return numEventReceived;
    162 }
    163 
    164 void AccelerationSensor::processEvent(int code, int value)
    165 {
    166     switch (code) {
    167         case EVENT_TYPE_ACCEL_X:
    168             mPendingEvent.acceleration.x = value * CONVERT_A_X;
    169             break;
    170         case EVENT_TYPE_ACCEL_Y:
    171             mPendingEvent.acceleration.y = value * CONVERT_A_Y;
    172             break;
    173         case EVENT_TYPE_ACCEL_Z:
    174             mPendingEvent.acceleration.z = value * CONVERT_A_Z;
    175             break;
    176     }
    177 }
    178