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/l3g4200d.h>
     27 
     28 #include <cutils/log.h>
     29 
     30 #include "GyroSensor.h"
     31 
     32 /*****************************************************************************/
     33 
     34 GyroSensor::GyroSensor()
     35     : SensorBase(GYROSCOPE_DEVICE_NAME, "gyroscope"),
     36       mEnabled(0),
     37       mInputReader(32)
     38 {
     39     mPendingEvent.version = sizeof(sensors_event_t);
     40     mPendingEvent.sensor = ID_G;
     41     mPendingEvent.type = SENSOR_TYPE_GYROSCOPE;
     42     mPendingEvent.gyro.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, L3G4200D_IOCTL_GET_ENABLE, &flags)) {
     49         if (flags)  {
     50             mEnabled = 1;
     51         }
     52     }
     53 
     54     if (!mEnabled) {
     55         close_device();
     56     }
     57 }
     58 
     59 GyroSensor::~GyroSensor() {
     60 }
     61 
     62 int GyroSensor::enable(int32_t, int en)
     63 {
     64     int flags = en ? 1 : 0;
     65     int err = 0;
     66     if (flags != mEnabled) {
     67         if (flags) {
     68             open_device();
     69         }
     70         err = ioctl(dev_fd, L3G4200D_IOCTL_SET_ENABLE, &flags);
     71         err = err<0 ? -errno : 0;
     72         ALOGE_IF(err, "L3G4200D_IOCTL_SET_ENABLE failed (%s)", strerror(-err));
     73         if (!err) {
     74             mEnabled = flags;
     75         }
     76         if (!flags) {
     77             close_device();
     78         }
     79     }
     80     return err;
     81 }
     82 
     83 int GyroSensor::setDelay(int32_t handle, int64_t ns)
     84 {
     85     if (ns < 0)
     86         return -EINVAL;
     87 
     88     int delay = ns / 1000000;
     89     if (ioctl(dev_fd, L3G4200D_IOCTL_SET_DELAY, &delay)) {
     90         return -errno;
     91     }
     92     return 0;
     93 }
     94 
     95 int GyroSensor::readEvents(sensors_event_t* data, int count)
     96 {
     97     if (count < 1)
     98         return -EINVAL;
     99 
    100     ssize_t n = mInputReader.fill(data_fd);
    101     if (n < 0)
    102         return n;
    103     int numEventReceived = 0;
    104     input_event const* event;
    105 
    106     while (count && mInputReader.readEvent(&event)) {
    107         int type = event->type;
    108         if (type == EV_REL) {
    109             processEvent(event->code, event->value);
    110         } else if (type == EV_SYN) {
    111             int64_t time = timevalToNano(event->time);
    112             mPendingEvent.timestamp = time;
    113             if (mEnabled) {
    114                 *data++ = mPendingEvent;
    115                 count--;
    116                 numEventReceived++;
    117             }
    118         } else {
    119             ALOGE("GyroSensor: unknown event (type=%d, code=%d)",
    120                     type, event->code);
    121         }
    122         mInputReader.next();
    123     }
    124 
    125     return numEventReceived;
    126 }
    127 
    128 void GyroSensor::processEvent(int code, int value)
    129 {
    130     switch (code) {
    131         case EVENT_TYPE_GYRO_P:
    132             mPendingEvent.gyro.x = value * CONVERT_G_P;
    133             break;
    134         case EVENT_TYPE_GYRO_R:
    135             mPendingEvent.gyro.y = value * CONVERT_G_R;
    136             break;
    137         case EVENT_TYPE_GYRO_Y:
    138             mPendingEvent.gyro.z = value * CONVERT_G_Y;
    139             break;
    140     }
    141 }
    142