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
34PressureSensor::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
62PressureSensor::~PressureSensor() {
63}
64
65int 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
86int 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
98int 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
131void PressureSensor::processEvent(int code, int value)
132{
133    if (code == EVENT_TYPE_PRESSURE) {
134            mPendingEvent.pressure = value * CONVERT_B;
135    }
136}
137