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 <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 40 struct 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 49 private: 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 86 sensors_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 ALOGE_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 125 sensors_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 133 int 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 ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); 145 } 146 return err; 147 } 148 149 int 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 156 int 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 ALOGE("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 ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno)); 190 ALOGE_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 202 static 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 211 static 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 217 static 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 223 static 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 231 int 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 } 250