blob: cd2136c9710699af03892eae12c63f3f24bddb76 [file] [log] [blame]
makarand.karvekar321d2202010-08-09 15:50:18 -05001/*
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
40struct 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
49private:
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
86sensors_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 LOGE_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
125sensors_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
133int 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 LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));
145 }
146 return err;
147}
148
149int 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
156int 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 LOGE("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 LOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
190 LOGE_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
202static 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
211static 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
217static 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
223static 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
231int 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}